import efivar-36-1.el8

This commit is contained in:
CentOS Sources 2019-05-07 09:37:36 -04:00 committed by Andrew Lukoshko
commit 05b57d5cd2
42 changed files with 7032 additions and 0 deletions

1
.efivar.metadata Normal file
View File

@ -0,0 +1 @@
3c74c8a0d8bc7a39b74de52cad2a791c00cdfd67 SOURCES/efivar-36.tar.bz2

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/efivar-36.tar.bz2

View File

@ -0,0 +1,56 @@
From d5f88bb1d594451733261d62eac4b4f97d39e3f4 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 12 Jun 2018 14:36:20 -0400
Subject: [PATCH 01/39] Move the syntastic file I use out of the repo
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/.syntastic_c_config | 36 ------------------------------------
1 file changed, 36 deletions(-)
delete mode 100644 src/.syntastic_c_config
diff --git a/src/.syntastic_c_config b/src/.syntastic_c_config
deleted file mode 100644
index 3f3f0ca67c7..00000000000
--- a/src/.syntastic_c_config
+++ /dev/null
@@ -1,36 +0,0 @@
--g3
--Og
--Werror=format-security
--Wp,-D_FORTIFY_SOURCE=2
--fexceptions
--fstack-protector-strong
---param=ssp-buffer-size=4
--grecord-gcc-switches
--DFWUPDATE_HAVE_LIBSMBIOS__
--Wall
--Wextra
--Werror
--Wno-error=cpp
--Wno-unused-result
--Wno-unused-function
--Wsign-compare
--Werror=sign-compare
--fshort-wchar
---std=gnu11
--D_GNU_SOURCE
--Isrc/include
--Isrc/include/efivar
--Iinclude
--Iinclude/efivar
--fPIC
--fmath-errno
--fsigned-zeros
--ftrapping-math
--fno-trapv
--fno-openmp
--fno-openacc
--mtune=generic
--march=x86-64
--flto
--fno-merge-constants
--fvisibility=hidden
--
2.17.1

View File

@ -0,0 +1,53 @@
From daf3b6c6ae8a766f362c87dc80e40005428a1b2a Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 12 Jun 2018 14:36:20 -0400
Subject: [PATCH 02/39] Move verbosity headers to be public
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/include/efivar/efivar.h | 8 ++++++++
src/util.h | 4 ----
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/include/efivar/efivar.h b/src/include/efivar/efivar.h
index ddcc6771bdb..316891ccae9 100644
--- a/src/include/efivar/efivar.h
+++ b/src/include/efivar/efivar.h
@@ -25,6 +25,7 @@
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
+#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -227,6 +228,13 @@ efi_error_clear(void)
#define efi_error_val(errval, msg, args...) \
efi_error_real__(errval, __FILE__, __func__, __LINE__, (fmt), ## args)
+extern void efi_set_verbose(int verbosity, FILE *errlog)
+ __attribute__((__visibility__("default")));
+extern int efi_get_verbose(void)
+ __attribute__((__visibility__("default")));
+extern FILE * efi_get_logfile(void)
+ __attribute__((__visibility__("default")));
+
#include <efivar/efivar-dp.h>
#endif /* EFIVAR_H */
diff --git a/src/util.h b/src/util.h
index 96ca66bd54d..cc5f669e6ec 100644
--- a/src/util.h
+++ b/src/util.h
@@ -369,8 +369,4 @@ swizzle_guid_to_uuid(efi_guid_t *guid)
#define DEBUG 1
-extern void PUBLIC efi_set_verbose(int verbosity, FILE *errlog);
-extern int PUBLIC efi_get_verbose(void);
-extern FILE PUBLIC *efi_get_logfile(void);
-
#endif /* EFIVAR_UTIL_H */
--
2.17.1

View File

@ -0,0 +1,45 @@
From bd609a59369574c95f7f31b15caae8bb86b71f39 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 12 Jun 2018 14:36:20 -0400
Subject: [PATCH 03/39] Pacify some coverity nits.
Coverity has trouble tracking data flow sometimes, and believes that
sysfs_readlink() and read_sysfs_file() will sometimes return >= 0 when
the buffer has not been filled out. This changes the check to also test
for a NULL pointer, hopefully pacifying it.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-pci.c | 2 +-
src/linux.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/linux-pci.c b/src/linux-pci.c
index 87878c39c94..0d2a90ab166 100644
--- a/src/linux-pci.c
+++ b/src/linux-pci.c
@@ -166,7 +166,7 @@ parse_pci(struct device *dev, const char *current)
tmp[devpart - current] = '\0';
rc = sysfs_readlink(&linkbuf, "class/block/%s/driver", tmp);
free(tmp);
- if (rc < 0) {
+ if (rc < 0 || !linkbuf) {
efi_error("Could not find driver for pci device");
return -1;
}
diff --git a/src/linux.c b/src/linux.c
index c8d1b3a9285..fe45c6004b9 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -356,7 +356,7 @@ struct device HIDDEN
if (dev->part == -1) {
rc = read_sysfs_file(&tmpbuf, "dev/block/%s/partition", dev->link);
- if (rc < 0) {
+ if (rc < 0 || !tmpbuf) {
efi_error("device has no /partition node; not a partition");
} else {
rc = sscanf((char *)tmpbuf, "%d\n", &dev->part);
--
2.17.1

View File

@ -0,0 +1,38 @@
From 4becb1303fee8bd7b377292c74589d6ec69009ae Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 12 Jun 2018 14:36:20 -0400
Subject: [PATCH 04/39] efivar: Fix some types in -L behavior to pacify
coverity.
Coverity doesn't realize that efi_well_known_guids is /actually/ an
array, because we didn't tell it so. So fix the declaration so we've
told it so.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/efivar.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/efivar.c b/src/efivar.c
index 9ee3b397e29..228bdb745a7 100644
--- a/src/efivar.c
+++ b/src/efivar.c
@@ -485,13 +485,13 @@ int main(int argc, char *argv[])
case ACTION_LIST_GUIDS: {
efi_guid_t sentinal = {0xffffffff,0xffff,0xffff,0xffff,
{0xff,0xff,0xff,0xff,0xff,0xff}};
- extern struct guidname efi_well_known_guids;
+ extern struct guidname efi_well_known_guids[];
extern struct guidname efi_well_known_guids_end;
intptr_t start = (intptr_t)&efi_well_known_guids;
intptr_t end = (intptr_t)&efi_well_known_guids_end;
unsigned int i;
- struct guidname *guid = &efi_well_known_guids;
+ struct guidname *guid = &efi_well_known_guids[0];
for (i = 0; i < (end-start) / sizeof(*guid); i++) {
if (!efi_guid_cmp(&sentinal, &guid[i].guid))
break;
--
2.17.1

View File

@ -0,0 +1,88 @@
From bd8fc0ebe86da82468b40a4998c3000819e73afe Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 12 Jun 2018 14:36:20 -0400
Subject: [PATCH 05/39] Promote _make_hd_dn() to make_hd_dn() and get rid of
the wrapper.
The wrapper is just hiding what the code's doing, and all the other code
around where we use it does the same thing anyway. This hopefully
convinces coverity we're not really dereferencing "buf" there unless
it's nonzero.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/creator.c | 3 ++-
src/disk.c | 4 ++--
src/dp-media.c | 2 ++
src/disk.h | 7 ++-----
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/creator.c b/src/creator.c
index 93f185fc0bc..76c1c1f7a99 100644
--- a/src/creator.c
+++ b/src/creator.c
@@ -281,7 +281,8 @@ efi_va_generate_file_device_path_from_esp(uint8_t *buf, ssize_t size,
goto err;
}
- sz = make_hd_dn(buf, size, off, disk_fd, dev->part, options);
+ sz = make_hd_dn(buf+off, size?size-off:0,
+ disk_fd, dev->part, options);
saved_errno = errno;
close(disk_fd);
errno = saved_errno;
diff --git a/src/disk.c b/src/disk.c
index deac512cf71..3efee03b804 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -257,8 +257,8 @@ is_partitioned(int fd)
}
ssize_t HIDDEN
-_make_hd_dn(uint8_t *buf, ssize_t size, int fd, int32_t partition,
- uint32_t options)
+make_hd_dn(uint8_t *buf, ssize_t size, int fd, int32_t partition,
+ uint32_t options)
{
uint64_t part_start=0, part_size = 0;
uint8_t signature[16]="", format=0, signature_type=0;
diff --git a/src/dp-media.c b/src/dp-media.c
index 0a0993ec3f4..cec6b8bb58d 100644
--- a/src/dp-media.c
+++ b/src/dp-media.c
@@ -161,6 +161,7 @@ efidp_make_file(uint8_t *buf, ssize_t size, char *filepath)
ssize_t sz;
ssize_t len = utf8len(lf, -1) + 1;
ssize_t req = sizeof (*file) + len * sizeof (uint16_t);
+
sz = efidp_make_generic(buf, size, EFIDP_MEDIA_TYPE, EFIDP_MEDIA_FILE,
req);
if (size && sz == req) {
@@ -182,6 +183,7 @@ efidp_make_hd(uint8_t *buf, ssize_t size, uint32_t num, uint64_t part_start,
efidp_hd *hd = (efidp_hd *)buf;
ssize_t sz;
ssize_t req = sizeof (*hd);
+
sz = efidp_make_generic(buf, size, EFIDP_MEDIA_TYPE, EFIDP_MEDIA_HD,
req);
if (size && sz == req) {
diff --git a/src/disk.h b/src/disk.h
index c040cc92a91..f0fa7f9f42d 100644
--- a/src/disk.h
+++ b/src/disk.h
@@ -23,10 +23,7 @@
extern bool HIDDEN is_partitioned(int fd);
-extern HIDDEN ssize_t _make_hd_dn(uint8_t *buf, ssize_t size, int fd,
- int32_t partition, uint32_t options);
-#define make_hd_dn(buf, size, off, fd, partition, option) \
- _make_hd_dn(((buf)+(off)), ((size)?((size)-(off)):0), (fd),\
- (partition), (options))
+extern HIDDEN ssize_t make_hd_dn(uint8_t *buf, ssize_t size, int fd,
+ int32_t partition, uint32_t options);
#endif /* _EFIBOOT_DISK_H */
--
2.17.1

View File

@ -0,0 +1,138 @@
From 5e2174acaf1a51ead0a079776229e0df89c7fd81 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 13 Jun 2018 09:15:17 -0400
Subject: [PATCH 06/39] Try to convince covscan that sysfs_read_file() doesn't
leak on error.
Basically, covscan gets confused about some of our return paths and
doesn't think the error condition correlates with not having allocated
(or having freed) the ram we're using to pass the file data back.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux.h | 5 +++++
src/util.h | 38 ++++++++++++++++++++------------------
2 files changed, 25 insertions(+), 18 deletions(-)
diff --git a/src/linux.h b/src/linux.h
index 2f9eb0fe66f..39826224a53 100644
--- a/src/linux.h
+++ b/src/linux.h
@@ -173,6 +173,11 @@ extern ssize_t HIDDEN make_mac_path(uint8_t *buf, ssize_t size,
free(buf_); \
*(buf) = (__typeof__(*(buf)))buf2_; \
errno = error_; \
+ } else if (buf_) { \
+ /* covscan is _sure_ we leak buf_ if bufsize_ */\
+ /* is <= 0, which is wrong, but appease it. */\
+ free(buf_); \
+ buf_ = NULL; \
} \
bufsize_; \
})
diff --git a/src/util.h b/src/util.h
index cc5f669e6ec..ef85a4c277e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -149,22 +149,24 @@
#endif
static inline int UNUSED
-read_file(int fd, uint8_t **buf, size_t *bufsize)
+read_file(int fd, uint8_t **result, size_t *bufsize)
{
uint8_t *p;
size_t size = 4096;
size_t filesize = 0;
ssize_t s = 0;
+ uint8_t *buf, *newbuf;
- uint8_t *newbuf;
if (!(newbuf = calloc(size, sizeof (uint8_t)))) {
efi_error("could not allocate memory");
+ *result = buf = NULL;
+ *bufsize = 0;
return -1;
}
- *buf = newbuf;
+ buf = newbuf;
do {
- p = *buf + filesize;
+ p = buf + filesize;
/* size - filesize shouldn't exceed SSIZE_MAX because we're
* only allocating 4096 bytes at a time and we're checking that
* before doing so. */
@@ -179,8 +181,8 @@ read_file(int fd, uint8_t **buf, size_t *bufsize)
continue;
} else if (s < 0) {
int saved_errno = errno;
- free(*buf);
- *buf = NULL;
+ free(buf);
+ *result = buf = NULL;
*bufsize = 0;
errno = saved_errno;
efi_error("could not read from file");
@@ -194,38 +196,38 @@ read_file(int fd, uint8_t **buf, size_t *bufsize)
/* See if we're going to overrun and return an error
* instead. */
if (size > (size_t)-1 - 4096) {
- free(*buf);
- *buf = NULL;
+ free(buf);
+ *result = buf = NULL;
*bufsize = 0;
errno = ENOMEM;
efi_error("could not read from file");
return -1;
}
- newbuf = realloc(*buf, size + 4096);
+ newbuf = realloc(buf, size + 4096);
if (newbuf == NULL) {
int saved_errno = errno;
- free(*buf);
- *buf = NULL;
+ free(buf);
+ *result = buf = NULL;
*bufsize = 0;
errno = saved_errno;
efi_error("could not allocate memory");
return -1;
}
- *buf = newbuf;
- memset(*buf + size, '\0', 4096);
+ buf = newbuf;
+ memset(buf + size, '\0', 4096);
size += 4096;
}
} while (1);
- newbuf = realloc(*buf, filesize+1);
+ newbuf = realloc(buf, filesize+1);
if (!newbuf) {
- free(*buf);
- *buf = NULL;
+ free(buf);
+ *result = buf = NULL;
efi_error("could not allocate memory");
return -1;
}
newbuf[filesize] = '\0';
- *buf = newbuf;
+ *result = newbuf;
*bufsize = filesize+1;
return 0;
}
@@ -329,7 +331,7 @@ get_file(uint8_t **result, const char * const fmt, ...)
close(fd);
errno = error;
- if (rc < 0) {
+ if (rc < 0 || bufsize < 1) {
efi_error("could not read file \"%s\"", path);
return -1;
}
--
2.17.1

View File

@ -0,0 +1,58 @@
From 9bc1e24859630c933410bfb77658bd69ee400e16 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 13 Jun 2018 09:25:58 -0400
Subject: [PATCH 07/39] Make efidp_make_file() have even more, better input
constraints.
This is all in the effort to convince coverity that it doesn't
dereference buf when size==0, which it already doesn't.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/dp-media.c | 6 ++++++
src/dp.c | 10 +++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/dp-media.c b/src/dp-media.c
index cec6b8bb58d..96a576fdc2a 100644
--- a/src/dp-media.c
+++ b/src/dp-media.c
@@ -162,6 +162,12 @@ efidp_make_file(uint8_t *buf, ssize_t size, char *filepath)
ssize_t len = utf8len(lf, -1) + 1;
ssize_t req = sizeof (*file) + len * sizeof (uint16_t);
+ if (len == 0) {
+ errno = EINVAL;
+ efi_error("%s() called with %s file path", __func__,
+ filepath == NULL ? "NULL" : "empty");
+ return -1;
+ }
sz = efidp_make_generic(buf, size, EFIDP_MEDIA_TYPE, EFIDP_MEDIA_FILE,
req);
if (size && sz == req) {
diff --git a/src/dp.c b/src/dp.c
index 4e76e25b1a1..82d60b4f9be 100644
--- a/src/dp.c
+++ b/src/dp.c
@@ -443,9 +443,17 @@ efidp_make_generic(uint8_t *buf, ssize_t size, uint8_t type, uint8_t subtype,
if (!size)
return total_size;
+
+ if (!buf) {
+ errno = EINVAL;
+ efi_error("%s was called with nonzero size and NULL buffer",
+ __func__);
+ return -1;
+ }
+
if (size < total_size) {
+ errno = ENOSPC;
efi_error("total size is bigger than size limit");
- errno = ENOSPC;
return -1;
}
--
2.17.1

View File

@ -0,0 +1,25 @@
From 025f791b57c988d33249c5c33250229fa0e7e8f1 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 14 Jun 2018 12:15:03 -0400
Subject: [PATCH 08/39] Make path-helpers.c also import fix_coverity.h
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/path-helpers.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/path-helpers.c b/src/path-helpers.c
index 1de00860d92..1b328071587 100644
--- a/src/path-helpers.c
+++ b/src/path-helpers.c
@@ -16,6 +16,7 @@
* License along with this library; if not, see
* <http://www.gnu.org/licenses/>.
*/
+#include "fix_coverity.h"
#include "efivar.h"
--
2.17.1

View File

@ -0,0 +1,34 @@
From bf5225b0445cc1b7b69c2a80162d3c1b514a27cf Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 20 Jun 2018 14:12:42 -0400
Subject: [PATCH 09/39] Fix a makeguids building problem with generics.h.
Guard generics.h with EFIVAR_BUILD_ENVIRONMENT to keep it from
interfering with the makeguids build if libefivar.so isn't around
already.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/generics.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/generics.h b/src/generics.h
index e6af2fad79e..66be4bd76ab 100644
--- a/src/generics.h
+++ b/src/generics.h
@@ -17,6 +17,7 @@
*
*/
+#ifndef EFIVAR_BUILD_ENVIRONMENT
#ifndef LIBEFIVAR_GENERIC_NEXT_VARIABLE_NAME_H
#define LIBEFIVAR_GENERIC_NEXT_VARIABLE_NAME_H 1
@@ -182,3 +183,4 @@ generic_append_variable(efi_guid_t guid, const char *name,
}
#endif /* LIBEFIVAR_GENERIC_NEXT_VARIABLE_NAME_H */
+#endif /* EFIVAR_BUILD_ENVIRONMENT */
--
2.17.1

View File

@ -0,0 +1,402 @@
From eb7db33c6cf4172551fe0f9f7cf4aa047dc16d88 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 20 Jun 2018 14:27:11 -0400
Subject: [PATCH 10/39] Improve ACPI device path formatting
This factors a bunch of the duplication out to another function, which
also does a better job of it.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/dp-acpi.c | 296 ++++++++++++++++++---------------
src/include/efivar/efivar-dp.h | 2 +-
2 files changed, 159 insertions(+), 139 deletions(-)
diff --git a/src/dp-acpi.c b/src/dp-acpi.c
index 70162f320dc..a49ef38488c 100644
--- a/src/dp-acpi.c
+++ b/src/dp-acpi.c
@@ -44,6 +44,59 @@ _format_acpi_adr(char *buf, size_t size,
#define format_acpi_adr(buf, size, off, dp) \
format_helper(_format_acpi_adr, buf, size, off, "AcpiAdr", dp)
+static ssize_t
+_format_acpi_hid_ex(char *buf, size_t size, const char *dp_type UNUSED,
+ const_efidp dp,
+ const char *hidstr, const char *cidstr, const char *uidstr)
+{
+ ssize_t off = 0;
+
+ debug(DEBUG, "hid:0x%08x hidstr:\"%s\"", dp->acpi_hid_ex.hid, hidstr);
+ debug(DEBUG, "cid:0x%08x cidstr:\"%s\"", dp->acpi_hid_ex.cid, cidstr);
+ debug(DEBUG, "uid:0x%08x uidstr:\"%s\"", dp->acpi_hid_ex.uid, uidstr);
+
+ if (!hidstr && !cidstr && (uidstr || dp->acpi_hid_ex.uid)) {
+ format(buf, size, off, "AcpiExp",
+ "AcpiExp(0x%"PRIx32",0x%"PRIx32",",
+ dp->acpi_hid_ex.hid, dp->acpi_hid_ex.cid);
+ if (uidstr) {
+ format(buf, size, off, "AcpiExp", "%s)", uidstr);
+ } else {
+ format(buf, size, off, "AcpiExp", "0x%"PRIx32")",
+ dp->acpi_hid_ex.uid);
+ }
+ return off;
+ }
+
+ format(buf, size, off, "AcpiEx", "AcpiEx(");
+ if (hidstr) {
+ format(buf, size, off, "AcpiEx", "%s,", hidstr);
+ } else {
+ format(buf, size, off, "AcpiEx", "0x%"PRIx32",",
+ dp->acpi_hid_ex.hid);
+ }
+
+ if (cidstr) {
+ format(buf, size, off, "AcpiEx", "%s,", cidstr);
+ } else {
+ format(buf, size, off, "AcpiEx", "0x%"PRIx32",",
+ dp->acpi_hid_ex.cid);
+ }
+
+ if (uidstr) {
+ format(buf, size, off, "AcpiEx", "%s)", uidstr);
+ } else {
+ format(buf, size, off, "AcpiEx", "0x%"PRIx32")",
+ dp->acpi_hid_ex.uid);
+ }
+
+ return off;
+}
+
+#define format_acpi_hid_ex(buf, size, off, dp, hidstr, cidstr, uidstr) \
+ format_helper(_format_acpi_hid_ex, buf, size, off, "AcpiEx", dp,\
+ hidstr, cidstr, uidstr)
+
ssize_t
_format_acpi_dn(char *buf, size_t size, const_efidp dp)
{
@@ -53,13 +106,15 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
const char *uidstr = NULL;
size_t uidlen = 0;
const char *cidstr = NULL;
- size_t cidlen = 0;
+ // size_t cidlen = 0;
if (dp->subtype == EFIDP_ACPI_ADR) {
+ debug(DEBUG, "formatting ACPI _ADR");
format_acpi_adr(buf, size, off, dp);
return off;
} else if (dp->subtype != EFIDP_ACPI_HID_EX &&
dp->subtype != EFIDP_ACPI_HID) {
+ debug(DEBUG, "DP subtype %d, formatting as ACPI Path", dp->subtype);
format(buf, size, off, "AcpiPath", "AcpiPath(%d,", dp->subtype);
format_hex(buf, size, off, "AcpiPath", (uint8_t *)dp+4,
(efidp_node_size(dp)-4) / 2);
@@ -69,6 +124,7 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
ssize_t limit = efidp_node_size(dp)
- offsetof(efidp_acpi_hid_ex, hidstr);
+ debug(DEBUG, "formatting ACPI HID EX");
hidstr = dp->acpi_hid_ex.hidstr;
hidlen = strnlen(hidstr, limit);
limit -= hidlen + 1;
@@ -81,7 +137,7 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
if (limit) {
cidstr = uidstr + uidlen + 1;
- cidlen = strnlen(cidstr, limit);
+ // cidlen = strnlen(cidstr, limit);
// limit -= cidlen + 1;
}
@@ -96,143 +152,102 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
"PcieRoot(%s)", uidstr);
return off;
default:
- format(buf, size, off, "AcpiEx", "AcpiEx(");
- if (hidlen)
- format(buf, size, off, "AcpiEx", "%s",
- hidstr);
- else
- format(buf, size, off, "AcpiEx", "0x%"PRIx32,
- dp->acpi_hid_ex.hid);
- if (cidlen)
- format(buf, size, off, "AcpiEx", ",%s",
- cidstr);
- else
- format(buf, size, off, "AcpiEx", ",0x%"PRIx32,
- dp->acpi_hid_ex.cid);
- if (uidlen)
- format(buf, size, off, "AcpiEx", ",%s",
- uidstr);
- else
- format(buf, size, off, "AcpiEx", ",0x%"PRIx32,
- dp->acpi_hid_ex.uid);
- format(buf, size, off, "AcpiEx", ")");
- break;
+ format_acpi_hid_ex(buf, size, off, dp,
+ hidstr, cidstr, uidstr);
+ return off;
}
}
- }
-
- switch (dp->acpi_hid.hid) {
- case EFIDP_ACPI_PCI_ROOT_HID:
- format(buf, size, off, "PciRoot", "PciRoot(0x%"PRIx32")",
- dp->acpi_hid.uid);
- break;
- case EFIDP_ACPI_PCIE_ROOT_HID:
- format(buf, size, off, "PcieRoot", "PcieRoot(0x%"PRIx32")",
- dp->acpi_hid.uid);
- break;
- case EFIDP_ACPI_FLOPPY_HID:
- format(buf, size, off, "Floppy", "Floppy(0x%"PRIx32")",
- dp->acpi_hid.uid);
- break;
- case EFIDP_ACPI_KEYBOARD_HID:
- format(buf, size, off, "Keyboard", "Keyboard(0x%"PRIx32")",
- dp->acpi_hid.uid);
- break;
- case EFIDP_ACPI_SERIAL_HID:
- format(buf, size, off, "Keyboard", "Serial(0x%"PRIx32")",
- dp->acpi_hid.uid);
- break;
- case EFIDP_ACPI_NVDIMM_HID: {
- int rc;
- const_efidp next = NULL;
- efidp_acpi_adr *adrdp;
- int end;
-
- format(buf, size, off, "NvRoot()", "NvRoot()");
-
- rc = efidp_next_node(dp, &next);
- if (rc < 0 || !next) {
- efi_error("could not format DP");
- return rc;
- }
+ } else if (dp->subtype == EFIDP_ACPI_HID_EX) {
+ switch (dp->acpi_hid.hid) {
+ case EFIDP_ACPI_PCI_ROOT_HID:
+ format(buf, size, off, "PciRoot",
+ "PciRoot(0x%"PRIx32")",
+ dp->acpi_hid.uid);
+ break;
+ case EFIDP_ACPI_PCIE_ROOT_HID:
+ format(buf, size, off, "PcieRoot",
+ "PcieRoot(0x%"PRIx32")",
+ dp->acpi_hid.uid);
+ break;
+ case EFIDP_ACPI_FLOPPY_HID:
+ format(buf, size, off, "Floppy",
+ "Floppy(0x%"PRIx32")",
+ dp->acpi_hid.uid);
+ break;
+ case EFIDP_ACPI_KEYBOARD_HID:
+ format(buf, size, off, "Keyboard",
+ "Keyboard(0x%"PRIx32")",
+ dp->acpi_hid.uid);
+ break;
+ case EFIDP_ACPI_SERIAL_HID:
+ format(buf, size, off, "Serial",
+ "Serial(0x%"PRIx32")",
+ dp->acpi_hid.uid);
+ break;
+ case EFIDP_ACPI_NVDIMM_HID: {
+ int rc;
+ const_efidp next = NULL;
+ efidp_acpi_adr *adrdp;
+ int end;
- if (efidp_type(next) != EFIDP_ACPI_TYPE ||
- efidp_subtype(next) != EFIDP_ACPI_ADR) {
- efi_error("Invalid child node type (0x%02x,0x%02x)",
- efidp_type(next), efidp_subtype(next));
- return -EINVAL;
- }
- adrdp = (efidp_acpi_adr *)next;
+ format(buf, size, off, "NvRoot()", "NvRoot()");
- end = efidp_size_after(adrdp, header)
- / sizeof(adrdp->adr[0]);
+ rc = efidp_next_node(dp, &next);
+ if (rc < 0 || !next) {
+ efi_error("could not format DP");
+ return rc;
+ }
- for (int i = 0; i < end; i++) {
- uint32_t node_controller, socket, memory_controller;
- uint32_t memory_channel, dimm;
- uint32_t adr = adrdp->adr[i];
+ if (efidp_type(next) != EFIDP_ACPI_TYPE ||
+ efidp_subtype(next) != EFIDP_ACPI_ADR) {
+ efi_error("Invalid child node type (0x%02x,0x%02x)",
+ efidp_type(next), efidp_subtype(next));
+ return -EINVAL;
+ }
+ adrdp = (efidp_acpi_adr *)next;
- efidp_decode_acpi_nvdimm_adr(adr, &node_controller,
- &socket,
- &memory_controller,
- &memory_channel, &dimm);
+ end = efidp_size_after(adrdp, header)
+ / sizeof(adrdp->adr[0]);
- if (i != 0)
- format(buf, size, off, "NvDimm", ",");
+ for (int i = 0; i < end; i++) {
+ uint32_t node_controller, socket, memory_controller;
+ uint32_t memory_channel, dimm;
+ uint32_t adr = adrdp->adr[i];
- format(buf, size, off, "NvDimm",
- "NvDimm(0x%03x,0x%01x,0x%01x,0x%01x,0x%01x)",
- node_controller, socket, memory_controller,
- memory_channel, dimm);
- }
- break;
- }
- default:
- switch (dp->subtype) {
- case EFIDP_ACPI_HID_EX:
- if (!hidstr && !cidstr &&
- (uidstr || dp->acpi_hid_ex.uid)){
- format(buf, size, off, "AcpiExp",
- "AcpiExp(0x%"PRIx32",0x%"PRIx32",",
- dp->acpi_hid_ex.hid,
- dp->acpi_hid_ex.cid);
- if (uidstr) {
- format(buf, size, off, "AcpiExp",
- "%s)", uidstr);
- } else {
- format(buf, size, off, "AcpiExp",
- "0x%"PRIx32")",
- dp->acpi_hid.uid);
- }
- break;
- }
- format(buf, size, off, "AcpiEx", "AcpiEx(");
- if (hidstr) {
- format(buf, size, off, "AcpiEx", "%s,", hidstr);
- } else {
- format(buf, size, off, "AcpiEx", "0x%"PRIx32",",
- dp->acpi_hid.hid);
- }
+ efidp_decode_acpi_nvdimm_adr(adr,
+ &node_controller, &socket,
+ &memory_controller, &memory_channel,
+ &dimm);
- if (cidstr) {
- format(buf, size, off, "AcpiEx", "%s,", cidstr);
- } else {
- format(buf, size, off, "AcpiEx", "0x%"PRIx32",",
- dp->acpi_hid_ex.cid);
- }
+ if (i != 0)
+ format(buf, size, off, "NvDimm", ",");
- if (uidstr) {
- format(buf, size, off, "AcpiEx", "%s)", uidstr);
- } else {
- format(buf, size, off, "AcpiEx", "0x%"PRIx32")",
- dp->acpi_hid.uid);
+ format(buf, size, off, "NvDimm",
+ "NvDimm(0x%03x,0x%01x,0x%01x,0x%01x,0x%01x)",
+ node_controller, socket, memory_controller,
+ memory_channel, dimm);
}
break;
- case EFIDP_ACPI_HID:
- format(buf, size, off, "Acpi",
- "Acpi(0x%"PRIx32",0x%"PRIx32")",
- dp->acpi_hid.hid, dp->acpi_hid.uid);
- break;
+ }
+ default:
+ debug(DEBUG, "Decoding non-well-known HID");
+ switch (dp->subtype) {
+ case EFIDP_ACPI_HID_EX:
+ format_acpi_hid_ex(buf, size, off, dp,
+ hidstr, cidstr, uidstr);
+ break;
+ case EFIDP_ACPI_HID:
+ debug(DEBUG, "Decoding ACPI HID");
+ format(buf, size, off, "Acpi",
+ "Acpi(0x%08x,0x%"PRIx32")",
+ dp->acpi_hid.hid, dp->acpi_hid.uid);
+ break;
+ default:
+ debug(DEBUG, "ACPI subtype %d???",
+ dp->subtype);
+ errno = EINVAL;
+ return -1;
+ }
}
}
@@ -259,7 +274,7 @@ efidp_make_acpi_hid(uint8_t *buf, ssize_t size, uint32_t hid, uint32_t uid)
return sz;
}
-ssize_t PUBLIC NONNULL(6, 7, 8)
+ssize_t PUBLIC
efidp_make_acpi_hid_ex(uint8_t *buf, ssize_t size,
uint32_t hid, uint32_t uid, uint32_t cid,
const char *hidstr, const char *uidstr,
@@ -268,21 +283,26 @@ efidp_make_acpi_hid_ex(uint8_t *buf, ssize_t size,
efidp_acpi_hid_ex *acpi_hid = (efidp_acpi_hid_ex *)buf;
ssize_t req;
ssize_t sz;
+ size_t hidlen = hidstr ? strlen(hidstr) : 0;
+ size_t uidlen = uidstr ? strlen(uidstr) : 0;
+ size_t cidlen = cidstr ? strlen(cidstr) : 0;
- req = sizeof (*acpi_hid) + 3 +
- strlen(hidstr) + strlen(uidstr) + strlen(cidstr);
+ req = sizeof (*acpi_hid) + 3 + hidlen + uidlen + cidlen;
sz = efidp_make_generic(buf, size, EFIDP_ACPI_TYPE, EFIDP_ACPI_HID_EX,
req);
if (size && sz == req) {
- acpi_hid->uid = uid;
- acpi_hid->hid = hid;
- acpi_hid->cid = cid;
+ acpi_hid->hid = hidlen ? 0 : hid;
+ acpi_hid->uid = uidlen ? 0 : uid;
+ acpi_hid->cid = cidlen ? 0 : cid;
char *next = (char *)buf+offsetof(efidp_acpi_hid_ex, hidstr);
- strcpy(next, hidstr);
- next += strlen(hidstr) + 1;
- strcpy(next, uidstr);
- next += strlen(uidstr) + 1;
- strcpy(next, cidstr);
+ if (hidlen)
+ strcpy(next, hidstr);
+ next += hidlen + 1;
+ if (uidlen)
+ strcpy(next, uidstr);
+ next += uidlen + 1;
+ if (cidlen)
+ strcpy(next, cidstr);
}
if (sz < 0)
diff --git a/src/include/efivar/efivar-dp.h b/src/include/efivar/efivar-dp.h
index 106d3645e21..1b05775ae7e 100644
--- a/src/include/efivar/efivar-dp.h
+++ b/src/include/efivar/efivar-dp.h
@@ -133,7 +133,7 @@ typedef struct {
/* three ascii string fields follow */
char hidstr[];
} EFIVAR_PACKED efidp_acpi_hid_ex;
-extern ssize_t __attribute__((__nonnull__ (6,7,8)))
+extern ssize_t
efidp_make_acpi_hid_ex(uint8_t *buf, ssize_t size,
uint32_t hid, uint32_t uid, uint32_t cid,
const char *hidstr, const char *uidstr,
--
2.17.1

View File

@ -0,0 +1,177 @@
From ba0655c62978ba64c227f1f87d9da3e1dea4f821 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 20 Jun 2018 14:37:14 -0400
Subject: [PATCH 11/39] Give linux-*'s ->parse() functions the unmodified
device link as well
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-ata.c | 2 +-
src/linux-i2o.c | 2 +-
src/linux-nvme.c | 2 +-
src/linux-pci.c | 2 +-
src/linux-pmem.c | 2 +-
src/linux-sas.c | 2 +-
src/linux-sata.c | 2 +-
src/linux-scsi.c | 2 +-
src/linux-virtblk.c | 2 +-
src/linux.c | 4 ++--
src/linux.h | 3 ++-
11 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/src/linux-ata.c b/src/linux-ata.c
index 6a47ff3f279..dab02f3d224 100644
--- a/src/linux-ata.c
+++ b/src/linux-ata.c
@@ -58,7 +58,7 @@ is_pata(struct device *dev)
* 11:0 -> ../../devices/pci0000:00/0000:00:11.5/ata3/host2/target2:0:0/2:0:0:0/block/sr0
*/
static ssize_t
-parse_ata(struct device *dev, const char *current)
+parse_ata(struct device *dev, const char *current, const char *root UNUSED)
{
uint32_t scsi_host, scsi_bus, scsi_device, scsi_target;
uint64_t scsi_lun;
diff --git a/src/linux-i2o.c b/src/linux-i2o.c
index e57c0cb344f..4fe79e5719f 100644
--- a/src/linux-i2o.c
+++ b/src/linux-i2o.c
@@ -33,7 +33,7 @@
* ... probably doesn't work.
*/
static ssize_t
-parse_i2o(struct device *dev, const char *current UNUSED)
+parse_i2o(struct device *dev, const char *current UNUSED, const char *root UNUSED)
{
debug(DEBUG, "entry");
/* I2O disks can have up to 16 partitions, or 4 bits worth. */
diff --git a/src/linux-nvme.c b/src/linux-nvme.c
index 6d5196fc082..00f53d5a9a7 100644
--- a/src/linux-nvme.c
+++ b/src/linux-nvme.c
@@ -48,7 +48,7 @@
*/
static ssize_t
-parse_nvme(struct device *dev, const char *current)
+parse_nvme(struct device *dev, const char *current, const char *root UNUSED)
{
int rc;
int32_t tosser0, tosser1, tosser2, ctrl_id, ns_id, partition;
diff --git a/src/linux-pci.c b/src/linux-pci.c
index 0d2a90ab166..4fbd108e3ed 100644
--- a/src/linux-pci.c
+++ b/src/linux-pci.c
@@ -41,7 +41,7 @@
*
*/
static ssize_t
-parse_pci(struct device *dev, const char *current)
+parse_pci(struct device *dev, const char *current, const char *root UNUSED)
{
int rc;
int pos;
diff --git a/src/linux-pmem.c b/src/linux-pmem.c
index 045650bc471..9a075716f7f 100644
--- a/src/linux-pmem.c
+++ b/src/linux-pmem.c
@@ -70,7 +70,7 @@
*/
static ssize_t
-parse_pmem(struct device *dev, const char *current)
+parse_pmem(struct device *dev, const char *current, const char *root UNUSED)
{
uint8_t *filebuf = NULL;
uint8_t system, sysbus, acpi_id;
diff --git a/src/linux-sas.c b/src/linux-sas.c
index 4a11147aef1..5f44f2c1f7b 100644
--- a/src/linux-sas.c
+++ b/src/linux-sas.c
@@ -45,7 +45,7 @@
* I'm not sure at the moment if they're the same or not.
*/
static ssize_t
-parse_sas(struct device *dev, const char *current)
+parse_sas(struct device *dev, const char *current, const char *root UNUSED)
{
struct stat statbuf = { 0, };
int rc;
diff --git a/src/linux-sata.c b/src/linux-sata.c
index a670ad9907e..d9a62efdbe6 100644
--- a/src/linux-sata.c
+++ b/src/linux-sata.c
@@ -138,7 +138,7 @@ sysfs_sata_get_port_info(uint32_t print_id, struct device *dev)
}
static ssize_t
-parse_sata(struct device *dev, const char *devlink)
+parse_sata(struct device *dev, const char *devlink, const char *root UNUSED)
{
const char *current = devlink;
uint32_t print_id;
diff --git a/src/linux-scsi.c b/src/linux-scsi.c
index 87f2f7f7c92..153a4ff87ad 100644
--- a/src/linux-scsi.c
+++ b/src/linux-scsi.c
@@ -160,7 +160,7 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
}
static ssize_t
-parse_scsi(struct device *dev, const char *current)
+parse_scsi(struct device *dev, const char *current, const char *root UNUSED)
{
uint32_t scsi_host, scsi_bus, scsi_device, scsi_target;
uint64_t scsi_lun;
diff --git a/src/linux-virtblk.c b/src/linux-virtblk.c
index 6dedf0f27ee..9ee7994aeb3 100644
--- a/src/linux-virtblk.c
+++ b/src/linux-virtblk.c
@@ -45,7 +45,7 @@
* But usually we just write the HD() entry, of course.
*/
static ssize_t
-parse_virtblk(struct device *dev, const char *current)
+parse_virtblk(struct device *dev, const char *current, const char *root UNUSED)
{
uint32_t tosser;
int pos;
diff --git a/src/linux.c b/src/linux.c
index fe45c6004b9..ef560753481 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -352,7 +352,7 @@ struct device HIDDEN
efi_error("strdup(\"%s\") failed", linkbuf);
goto err;
}
- debug(DEBUG, "dev->link: %s\n", dev->link);
+ debug(DEBUG, "dev->link: %s", dev->link);
if (dev->part == -1) {
rc = read_sysfs_file(&tmpbuf, "dev/block/%s/partition", dev->link);
@@ -431,7 +431,7 @@ struct device HIDDEN
}
debug(DEBUG, "trying %s", probe->name);
- pos = probe->parse(dev, current);
+ pos = probe->parse(dev, current, dev->link);
if (pos < 0) {
efi_error("parsing %s failed", probe->name);
goto err;
diff --git a/src/linux.h b/src/linux.h
index 39826224a53..35951bb4d16 100644
--- a/src/linux.h
+++ b/src/linux.h
@@ -244,7 +244,8 @@ struct dev_probe {
char *name;
enum interface_type *iftypes;
uint32_t flags;
- ssize_t (*parse)(struct device *dev, const char * const current);
+ ssize_t (*parse)(struct device *dev,
+ const char * const current, const char * const root);
ssize_t (*create)(struct device *dev,
uint8_t *buf, ssize_t size, ssize_t off);
char *(*make_part_name)(struct device *dev);
--
2.17.1

View File

@ -0,0 +1,391 @@
From e2f68c8f9f4fab48f1ef3a4585932f757593fa92 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 20 Jun 2018 14:43:32 -0400
Subject: [PATCH 12/39] Move ACPI ID parsing to a shared location.
This is getting out of PCI because we have some other platforms that do
ACPI root parsing, but don't use the PCI roots.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-acpi.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++
src/linux-pci.c | 112 +++++---------------------------------------
src/linux.c | 11 ++++-
src/linux.h | 19 +++++---
4 files changed, 152 insertions(+), 109 deletions(-)
create mode 100644 src/linux-acpi.c
diff --git a/src/linux-acpi.c b/src/linux-acpi.c
new file mode 100644
index 00000000000..cb93a113ee2
--- /dev/null
+++ b/src/linux-acpi.c
@@ -0,0 +1,119 @@
+/*
+ * libefiboot - library for the manipulation of EFI boot variables
+ * Copyright 2012-2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "fix_coverity.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "efiboot.h"
+
+int HIDDEN
+parse_acpi_hid_uid(struct device *dev, const char *fmt, ...)
+{
+ int rc;
+ char *path = NULL;
+ va_list ap;
+ char *fbuf = NULL;
+ uint16_t tmp16;
+ uint32_t acpi_hid = 0;
+ uint64_t acpi_uid_int = 0;
+
+ debug(DEBUG, "entry");
+
+ va_start(ap, fmt);
+ rc = vasprintfa(&path, fmt, ap);
+ va_end(ap);
+ debug(DEBUG, "path:%s rc:%d", path, rc);
+ if (rc < 0 || path == NULL)
+ return -1;
+
+ rc = read_sysfs_file(&fbuf, "%s/firmware_node/path", path);
+ if (rc > 0) {
+ size_t l = strlen(fbuf);
+ if (l > 1) {
+ fbuf[l-1] = 0;
+ dev->acpi_root.acpi_cid_str = strdup(fbuf);
+ debug(DEBUG, "Setting ACPI root path to \"%s\"", fbuf);
+ }
+ }
+
+ rc = read_sysfs_file(&fbuf, "%s/firmware_node/hid", path);
+ if (rc < 0 || fbuf == NULL) {
+ efi_error("could not read %s/firmware_node/hid", path);
+ return -1;
+ }
+
+ rc = strlen(fbuf);
+ if (rc < 4) {
+hid_err:
+ efi_error("could not parse %s/firmware_node/hid", path);
+ return -1;
+ }
+ rc -= 4;
+
+ rc = sscanf((char *)fbuf + rc, "%04hx", &tmp16);
+ debug(DEBUG, "rc:%d hid:0x%08x\n", rc, tmp16);
+ if (rc != 1)
+ goto hid_err;
+
+ acpi_hid = EFIDP_EFI_PNP_ID(tmp16);
+
+ /*
+ * Apparently basically nothing can look up a PcieRoot() node,
+ * because they just check _CID. So since _CID for the root pretty
+ * much always has to be PNP0A03 anyway, just use that no matter
+ * what.
+ */
+ if (acpi_hid == EFIDP_ACPI_PCIE_ROOT_HID)
+ acpi_hid = EFIDP_ACPI_PCI_ROOT_HID;
+ dev->acpi_root.acpi_hid = acpi_hid;
+ debug(DEBUG, "acpi root HID:0x%08x", acpi_hid);
+
+ errno = 0;
+ fbuf = NULL;
+ rc = read_sysfs_file(&fbuf, "%s/firmware_node/uid", path);
+ if ((rc <= 0 && errno != ENOENT) || fbuf == NULL) {
+ efi_error("could not read %s/firmware_node/uid", path);
+ return -1;
+ }
+ if (rc > 0) {
+ rc = sscanf((char *)fbuf, "%"PRIu64"\n", &acpi_uid_int);
+ if (rc == 1) {
+ dev->acpi_root.acpi_uid = acpi_uid_int;
+ } else {
+ /* kernel uses "%s\n" to print it, so there
+ * should always be some value and a newline... */
+ int l = strlen((char *)fbuf);
+ if (l >= 1) {
+ fbuf[l-1] = '\0';
+ dev->acpi_root.acpi_uid_str = strdup(fbuf);
+ }
+ }
+ }
+ debug(DEBUG, "acpi root UID:0x%"PRIx64" uidstr:\"%s\"",
+ dev->acpi_root.acpi_uid, dev->acpi_root.acpi_uid_str);
+
+ errno = 0;
+ return 0;
+}
diff --git a/src/linux-pci.c b/src/linux-pci.c
index 4fbd108e3ed..aa3e40c0f7c 100644
--- a/src/linux-pci.c
+++ b/src/linux-pci.c
@@ -37,21 +37,17 @@
* ^ root hub ^device ^device
*
* for network devices, we also get:
- * /sys/class/net/$IFACE -> ../../devices/$PCI_STUFF/net/$IFACE
+ * /sys/class/net/$IFACE -> ../../devices/$PCI_DEVICES/net/$IFACE
+ *
+ * In both cases our "current" pointer should be at $PCI_DEVICES.
*
*/
static ssize_t
-parse_pci(struct device *dev, const char *current, const char *root UNUSED)
+parse_pci(struct device *dev, const char *current, const char *root)
{
int rc;
int pos;
- uint16_t root_domain;
- uint8_t root_bus;
- uint32_t acpi_hid = 0;
- uint64_t acpi_uid_int = 0;
const char *devpart = current;
- char *fbuf = NULL;
- uint16_t tmp16 = 0;
char *spaces;
pos = strlen(current);
@@ -62,66 +58,6 @@ parse_pci(struct device *dev, const char *current, const char *root UNUSED)
debug(DEBUG, "entry");
- /*
- * find the pci root domain and port; they basically look like:
- * pci0000:00/
- * ^d ^p
- */
- rc = sscanf(devpart, "../../devices/pci%hx:%hhx/%n", &root_domain, &root_bus, &pos);
- /*
- * If we can't find that, it's not a PCI device.
- */
- if (rc != 2)
- return 0;
- devpart += pos;
-
- dev->pci_root.pci_root_domain = root_domain;
- dev->pci_root.pci_root_bus = root_bus;
-
- rc = read_sysfs_file(&fbuf,
- "devices/pci%04hx:%02hhx/firmware_node/hid",
- root_domain, root_bus);
- if (rc < 0 || fbuf == NULL)
- return -1;
-
- rc = sscanf((char *)fbuf, "PNP%hx", &tmp16);
- if (rc != 1)
- return -1;
- acpi_hid = EFIDP_EFI_PNP_ID(tmp16);
-
- /*
- * Apparently basically nothing can look up a PcieRoot() node,
- * because they just check _CID. So since _CID for the root pretty
- * much always has to be PNP0A03 anyway, just use that no matter
- * what.
- */
- if (acpi_hid == EFIDP_ACPI_PCIE_ROOT_HID)
- acpi_hid = EFIDP_ACPI_PCI_ROOT_HID;
- dev->pci_root.pci_root_acpi_hid = acpi_hid;
-
- errno = 0;
- fbuf = NULL;
- rc = read_sysfs_file(&fbuf,
- "devices/pci%04hx:%02hhx/firmware_node/uid",
- root_domain, root_bus);
- if ((rc <= 0 && errno != ENOENT) || fbuf == NULL)
- return -1;
- if (rc > 0) {
- rc = sscanf((char *)fbuf, "%"PRIu64"\n", &acpi_uid_int);
- if (rc == 1) {
- dev->pci_root.pci_root_acpi_uid = acpi_uid_int;
- } else {
- /* kernel uses "%s\n" to print it, so there
- * should always be some value and a newline... */
- int l = strlen((char *)fbuf);
- if (l >= 1) {
- fbuf[l-1] = '\0';
- dev->pci_root.pci_root_acpi_uid_str = fbuf;
- }
- }
- }
- errno = 0;
-
/* find the pci domain/bus/device/function:
* 0000:00:01.0/0000:01:00.0/
* ^d ^b ^d ^f (of the last one in the series)
@@ -136,7 +72,7 @@ parse_pci(struct device *dev, const char *current, const char *root UNUSED)
debug(DEBUG, "searching for 0000:00:00.0/");
rc = sscanf(devpart, "%hx:%hhx:%hhx.%hhx/%n",
&domain, &bus, &device, &function, &pos);
- debug(DEBUG, "current:\"%s\" rc:%d pos:%d\n", devpart, rc, pos);
+ debug(DEBUG, "current:\"%s\" rc:%d pos:%d", devpart, rc, pos);
arrow(DEBUG, spaces, 9, pos, rc, 3);
if (rc != 4)
break;
@@ -157,24 +93,26 @@ parse_pci(struct device *dev, const char *current, const char *root UNUSED)
dev->pci_dev[i].pci_bus = bus;
dev->pci_dev[i].pci_device = device;
dev->pci_dev[i].pci_function = function;
- char *tmp = strndup(current, devpart-current+1);
+ char *tmp = strndup(root, devpart-root+1);
char *linkbuf = NULL;
if (!tmp) {
efi_error("could not allocate memory");
return -1;
}
- tmp[devpart - current] = '\0';
+ tmp[devpart - root] = '\0';
rc = sysfs_readlink(&linkbuf, "class/block/%s/driver", tmp);
- free(tmp);
if (rc < 0 || !linkbuf) {
- efi_error("Could not find driver for pci device");
+ efi_error("Could not find driver for pci device %s", tmp);
+ free(tmp);
return -1;
}
+ free(tmp);
dev->pci_dev[i].driverlink = strdup(linkbuf);
debug(DEBUG, "driver:%s\n", linkbuf);
dev->n_pci_devs += 1;
}
+ debug(DEBUG, "next:\"%s\"", devpart);
return devpart - current;
}
@@ -186,34 +124,6 @@ dp_create_pci(struct device *dev,
debug(DEBUG, "entry buf:%p size:%zd off:%zd", buf, size, off);
- if (dev->pci_root.pci_root_acpi_uid_str) {
- debug(DEBUG, "creating acpi_hid_ex dp hid:0x%08x uid:\"%s\"",
- dev->pci_root.pci_root_acpi_hid,
- dev->pci_root.pci_root_acpi_uid_str);
- new = efidp_make_acpi_hid_ex(buf + off, size ? size - off : 0,
- dev->pci_root.pci_root_acpi_hid,
- 0, 0, "",
- dev->pci_root.pci_root_acpi_uid_str,
- "");
- if (new < 0) {
- efi_error("efidp_make_acpi_hid_ex() failed");
- return new;
- }
- } else {
- debug(DEBUG, "creating acpi_hid dp hid:0x%08x uid:0x%0"PRIx64,
- dev->pci_root.pci_root_acpi_hid,
- dev->pci_root.pci_root_acpi_uid);
- new = efidp_make_acpi_hid(buf + off, size ? size - off : 0,
- dev->pci_root.pci_root_acpi_hid,
- dev->pci_root.pci_root_acpi_uid);
- if (new < 0) {
- efi_error("efidp_make_acpi_hid() failed");
- return new;
- }
- }
- off += new;
- sz += new;
-
debug(DEBUG, "creating PCI device path nodes");
for (unsigned int i = 0; i < dev->n_pci_devs; i++) {
debug(DEBUG, "creating PCI device path node %u", i);
diff --git a/src/linux.c b/src/linux.c
index ef560753481..9f3a22f7025 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -272,6 +272,13 @@ device_free(struct device *dev)
if (dev->probes)
free(dev->probes);
+ if (dev->acpi_root.acpi_hid_str)
+ free(dev->acpi_root.acpi_hid_str);
+ if (dev->acpi_root.acpi_uid_str)
+ free(dev->acpi_root.acpi_uid_str);
+ if (dev->acpi_root.acpi_cid_str)
+ free(dev->acpi_root.acpi_cid_str);
+
if (dev->interface_type == network) {
if (dev->ifname)
free(dev->ifname);
@@ -325,8 +332,8 @@ struct device HIDDEN
goto err;
}
- dev->pci_root.pci_root_domain = 0xffff;
- dev->pci_root.pci_root_bus = 0xff;
+ dev->pci_root.pci_domain = 0xffff;
+ dev->pci_root.pci_bus = 0xff;
if (S_ISBLK(dev->stat.st_mode)) {
dev->major = major(dev->stat.st_rdev);
diff --git a/src/linux.h b/src/linux.h
index 35951bb4d16..aa9e3d14a83 100644
--- a/src/linux.h
+++ b/src/linux.h
@@ -21,12 +21,18 @@
#ifndef _EFIBOOT_LINUX_H
#define _EFIBOOT_LINUX_H
+struct acpi_root_info {
+ uint32_t acpi_hid;
+ uint64_t acpi_uid;
+ uint32_t acpi_cid;
+ char *acpi_hid_str;
+ char *acpi_uid_str;
+ char *acpi_cid_str;
+};
+
struct pci_root_info {
- uint16_t pci_root_domain;
- uint8_t pci_root_bus;
- uint32_t pci_root_acpi_hid;
- uint64_t pci_root_acpi_uid;
- char *pci_root_acpi_uid_str;
+ uint16_t pci_domain;
+ uint8_t pci_bus;
};
struct pci_dev_info {
@@ -121,6 +127,7 @@ struct device {
char *disk_name;
char *part_name;
+ struct acpi_root_info acpi_root;
struct pci_root_info pci_root;
unsigned int n_pci_devs;
struct pci_dev_info *pci_dev;
@@ -147,7 +154,7 @@ extern int HIDDEN set_disk_name(struct device *dev, const char * const fmt, ...)
extern bool HIDDEN is_pata(struct device *dev);
extern int HIDDEN make_blockdev_path(uint8_t *buf, ssize_t size,
struct device *dev);
-
+extern int HIDDEN parse_acpi_hid_uid(struct device *dev, const char *fmt, ...);
extern int HIDDEN eb_nvme_ns_id(int fd, uint32_t *ns_id);
int HIDDEN get_sector_size(int filedes);
--
2.17.1

View File

@ -0,0 +1,425 @@
From 6b62aa40cfa1feb924609a065098da98c99e925c Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 20 Jun 2018 14:45:14 -0400
Subject: [PATCH 13/39] Make a platform ACPI root parser separate from PCI
roots.
Because apparently PNP0A03 and PNP0A0C weren't good enough.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-acpi-root.c | 199 ++++++++++++++++++++++++++++++++++++++++++
src/linux-pci-root.c | 136 +++++++++++++++++++++++++++++
src/linux-pci.c | 1 -
src/linux.c | 4 +-
src/linux.h | 4 +-
5 files changed, 341 insertions(+), 3 deletions(-)
create mode 100644 src/linux-acpi-root.c
create mode 100644 src/linux-pci-root.c
diff --git a/src/linux-acpi-root.c b/src/linux-acpi-root.c
new file mode 100644
index 00000000000..c7d8276a642
--- /dev/null
+++ b/src/linux-acpi-root.c
@@ -0,0 +1,199 @@
+/*
+ * libefiboot - library for the manipulation of EFI boot variables
+ * Copyright 2012-2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "fix_coverity.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "efiboot.h"
+
+/*
+ * support for ACPI-like platform root hub and devices
+ *
+ * various devices /sys/dev/block/$major:$minor start with:
+ * maj:min -> ../../devices/ACPI0000:00/$PCI_DEVICES/$BLOCKDEV_STUFF/block/$DISK/$PART
+ * i.e.: APMC0D0D:00/ata1/host0/target0:0:0/0:0:0:0/block/sda
+ * ^ root hub ^blockdev stuff
+ * or:
+ * maj:min -> ../../devices/ACPI0000:00/$PCI_DEVICES/$BLOCKDEV_STUFF/block/$DISK/$PART
+ * i.e.: APMC0D0D:00/0000:00:1d.0/0000:05:00.0/ata1/host0/target0:0:0/0:0:0:0/block/sda
+ * ^ root hub ^pci dev ^pci dev ^ blockdev stuff
+ */
+static ssize_t
+parse_acpi_root(struct device *dev, const char *current, const char *root UNUSED)
+{
+ int rc;
+ int pos;
+ uint16_t pad0;
+ uint8_t pad1;
+ char *acpi_header = NULL;
+ char *colon;
+
+ const char *devpart = current;
+ char *spaces;
+
+ pos = strlen(current);
+ spaces = alloca(pos+1);
+ memset(spaces, ' ', pos+1);
+ spaces[pos] = '\0';
+ pos = 0;
+
+ debug(DEBUG, "entry");
+
+ /*
+ * find the ACPI root dunno0 and dunno1; they basically look like:
+ * ABCD0000:00/
+ * ^d0 ^d1
+ * This is annoying because "/%04ms%h:%hhx/" won't bind from the right
+ * side in sscanf.
+ */
+ rc = sscanf(devpart, "../../devices/platform/%n", &pos);
+ debug(DEBUG, "devpart:\"%s\" rc:%d pos:%d", devpart, rc, pos);
+ if (rc != 0 || pos < 1)
+ return 0;
+ devpart += pos;
+
+ /*
+ * If it's too short to be A0000:00, it's not an ACPI string
+ */
+ if (strlen(devpart) < 8)
+ return 0;
+
+ colon = strchr(devpart, ':');
+ if (!colon)
+ return 0;
+ pos = colon - devpart;
+
+ /*
+ * If colon doesn't point at something between one of these:
+ * A0000:00 ACPI0000:00
+ * ^ 5 ^ 8
+ * Then it's not an ACPI string.
+ */
+ if (pos < 5 || pos > 8)
+ return 0;
+
+ dev->acpi_root.acpi_hid_str = strndup(devpart, pos + 1);
+ if (!dev->acpi_root.acpi_hid_str) {
+ efi_error("Could not allocate memory");
+ return -1;
+ }
+ dev->acpi_root.acpi_hid_str[pos] = 0;
+ debug(DEBUG, "acpi_hid_str:\"%s\"", dev->acpi_root.acpi_hid_str);
+
+ pos -= 4;
+ debug(DEBUG, "devpart:\"%s\" rc:%d pos:%d", devpart, rc, pos);
+ acpi_header = strndupa(devpart, pos);
+ if (!acpi_header)
+ return 0;
+ acpi_header[pos] = 0;
+ debug(DEBUG, "devpart:\"%s\" acpi_header:\"%s\"", devpart, acpi_header);
+ devpart += pos;
+
+ /*
+ * If we can't find these numbers, it's not an ACPI string
+ */
+ rc = sscanf(devpart, "%hx:%hhx/%n", &pad0, &pad1, &pos);
+ if (rc != 2) {
+ efi_error("Could not parse ACPI path \"%s\"", devpart);
+ return 0;
+ }
+ debug(DEBUG, "devpart:\"%s\" parsed:%04hx:%02hhx pos:%d rc:%d",
+ devpart, pad0, pad1, pos, rc);
+
+ devpart += pos;
+
+ rc = parse_acpi_hid_uid(dev, "devices/platform/%s%04hX:%02hhX",
+ acpi_header, pad0, pad1);
+ debug(DEBUG, "rc:%d acpi_header:%s pad0:%04hX pad1:%02hhX",
+ rc, acpi_header, pad0, pad1);
+ if (rc < 0 && errno == ENOENT) {
+ rc = parse_acpi_hid_uid(dev, "devices/platform/%s%04hx:%02hhx",
+ acpi_header, pad0, pad1);
+ debug(DEBUG, "rc:%d acpi_header:%s pad0:%04hx pad1:%02hhx",
+ rc, acpi_header, pad0, pad1);
+ }
+ if (rc < 0) {
+ efi_error("Could not parse hid/uid");
+ return rc;
+ }
+ debug(DEBUG, "Parsed HID:0x%08x UID:0x%"PRIx64" uidstr:\"%s\" path:\"%s\"",
+ dev->acpi_root.acpi_hid, dev->acpi_root.acpi_uid,
+ dev->acpi_root.acpi_uid_str,
+ dev->acpi_root.acpi_cid_str);
+
+ return devpart - current;
+}
+
+static ssize_t
+dp_create_acpi_root(struct device *dev,
+ uint8_t *buf, ssize_t size, ssize_t off)
+{
+ ssize_t sz = 0, new = 0;
+
+ debug(DEBUG, "entry buf:%p size:%zd off:%zd", buf, size, off);
+
+ if (dev->acpi_root.acpi_uid_str || dev->acpi_root.acpi_cid_str) {
+ debug(DEBUG, "creating acpi_hid_ex dp hid:0x%08x uid:0x%"PRIx64" uidstr:\"%s\" cidstr:\"%s\"",
+ dev->acpi_root.acpi_hid, dev->acpi_root.acpi_uid,
+ dev->acpi_root.acpi_uid_str, dev->acpi_root.acpi_cid_str);
+ new = efidp_make_acpi_hid_ex(buf + off, size ? size - off : 0,
+ dev->acpi_root.acpi_hid,
+ dev->acpi_root.acpi_uid,
+ dev->acpi_root.acpi_cid,
+ dev->acpi_root.acpi_hid_str,
+ dev->acpi_root.acpi_uid_str,
+ dev->acpi_root.acpi_cid_str);
+ if (new < 0) {
+ efi_error("efidp_make_acpi_hid_ex() failed");
+ return new;
+ }
+ } else {
+ debug(DEBUG, "creating acpi_hid dp hid:0x%08x uid:0x%0"PRIx64,
+ dev->acpi_root.acpi_hid,
+ dev->acpi_root.acpi_uid);
+ new = efidp_make_acpi_hid(buf + off, size ? size - off : 0,
+ dev->acpi_root.acpi_hid,
+ dev->acpi_root.acpi_uid);
+ if (new < 0) {
+ efi_error("efidp_make_acpi_hid() failed");
+ return new;
+ }
+ }
+ off += new;
+ sz += new;
+
+ debug(DEBUG, "returning %zd", sz);
+ return sz;
+}
+
+enum interface_type acpi_root_iftypes[] = { acpi_root, unknown };
+
+struct dev_probe HIDDEN acpi_root_parser = {
+ .name = "acpi_root",
+ .iftypes = acpi_root_iftypes,
+ .flags = DEV_PROVIDES_ROOT,
+ .parse = parse_acpi_root,
+ .create = dp_create_acpi_root,
+};
diff --git a/src/linux-pci-root.c b/src/linux-pci-root.c
new file mode 100644
index 00000000000..8f556a066f3
--- /dev/null
+++ b/src/linux-pci-root.c
@@ -0,0 +1,136 @@
+/*
+ * libefiboot - library for the manipulation of EFI boot variables
+ * Copyright 2012-2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "fix_coverity.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "efiboot.h"
+
+/*
+ * support for PCI root hub and devices
+ *
+ * various devices /sys/dev/block/$major:$minor start with:
+ * maj:min -> ../../devices/pci$PCIROOT/$PCI_DEVICES/$BLOCKDEV_STUFF/block/$DISK/$PART
+ * i.e.: pci0000:00/0000:00:1d.0/0000:05:00.0/
+ * ^ root hub ^device ^device
+ *
+ * for network devices, we also get:
+ * /sys/class/net/$IFACE -> ../../devices/$PCI_STUFF/net/$IFACE
+ *
+ */
+static ssize_t
+parse_pci_root(struct device *dev, const char *current, const char *root UNUSED)
+{
+ int rc;
+ int pos;
+ uint16_t root_domain;
+ uint8_t root_bus;
+ const char *devpart = current;
+ char *spaces;
+
+ pos = strlen(current);
+ spaces = alloca(pos+1);
+ memset(spaces, ' ', pos+1);
+ spaces[pos] = '\0';
+ pos = 0;
+
+ debug(DEBUG, "entry");
+
+ /*
+ * find the pci root domain and port; they basically look like:
+ * pci0000:00/
+ * ^d ^p
+ */
+ rc = sscanf(devpart, "../../devices/pci%hx:%hhx/%n", &root_domain, &root_bus, &pos);
+ /*
+ * If we can't find that, it's not a PCI device.
+ */
+ if (rc != 2)
+ return 0;
+ devpart += pos;
+
+ dev->pci_root.pci_domain = root_domain;
+ dev->pci_root.pci_bus = root_bus;
+
+ rc = parse_acpi_hid_uid(dev, "devices/pci%04hx:%02hhx",
+ root_domain, root_bus);
+ if (rc < 0)
+ return -1;
+
+ errno = 0;
+ return devpart - current;
+}
+
+static ssize_t
+dp_create_pci_root(struct device *dev UNUSED,
+ uint8_t *buf, ssize_t size, ssize_t off)
+{
+ debug(DEBUG, "entry buf:%p size:%zd off:%zd", buf, size, off);
+ debug(DEBUG, "returning 0");
+#if 0
+ if (dev->acpi_root.acpi_uid_str) {
+ debug(DEBUG, "creating acpi_hid_ex dp hid:0x%08x uid:\"%s\"",
+ dev->acpi_root.acpi_hid,
+ dev->acpi_root.acpi_uid_str);
+ new = efidp_make_acpi_hid_ex(buf + off, size ? size - off : 0,
+ dev->acpi_root.acpi_hid,
+ 0, 0, "",
+ dev->acpi_root.acpi_uid_str,
+ "");
+ if (new < 0) {
+ efi_error("efidp_make_acpi_hid_ex() failed");
+ return new;
+ }
+ } else {
+ debug(DEBUG, "creating acpi_hid dp hid:0x%08x uid:0x%0"PRIx64,
+ dev->acpi_root.acpi_hid,
+ dev->acpi_root.acpi_uid);
+ new = efidp_make_acpi_hid(buf + off, size ? size - off : 0,
+ dev->acpi_root.acpi_hid,
+ dev->acpi_root.acpi_uid);
+ if (new < 0) {
+ efi_error("efidp_make_acpi_hid() failed");
+ return new;
+ }
+ }
+ off += new;
+ sz += new;
+
+ debug(DEBUG, "returning %zd", sz);
+ return sz;
+#else
+ return 0;
+#endif
+}
+
+enum interface_type pci_root_iftypes[] = { pci_root, unknown };
+
+struct dev_probe HIDDEN pci_root_parser = {
+ .name = "pci_root",
+ .iftypes = pci_root_iftypes,
+ .flags = DEV_PROVIDES_ROOT,
+ .parse = parse_pci_root,
+ .create = dp_create_pci_root,
+};
diff --git a/src/linux-pci.c b/src/linux-pci.c
index aa3e40c0f7c..0f59d3e840d 100644
--- a/src/linux-pci.c
+++ b/src/linux-pci.c
@@ -147,7 +147,6 @@ enum interface_type pci_iftypes[] = { pci, unknown };
struct dev_probe HIDDEN pci_parser = {
.name = "pci",
.iftypes = pci_iftypes,
- .flags = DEV_PROVIDES_ROOT,
.parse = parse_pci,
.create = dp_create_pci,
};
diff --git a/src/linux.c b/src/linux.c
index 9f3a22f7025..436fb882a98 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -235,6 +235,8 @@ static struct dev_probe *dev_probes[] = {
* be found first.
*/
&pmem_parser,
+ &acpi_root_parser,
+ &pci_root_parser,
&pci_parser,
&virtblk_parser,
&sas_parser,
@@ -447,7 +449,7 @@ struct device HIDDEN
}
debug(DEBUG, "%s matched %s", probe->name, current);
- if (probe->flags & DEV_PROVIDES_HD)
+ if (probe->flags & DEV_PROVIDES_HD || probe->flags & DEV_PROVIDES_ROOT)
needs_root = false;
dev->probes[n++] = dev_probes[i];
current += pos;
diff --git a/src/linux.h b/src/linux.h
index aa9e3d14a83..7b18bda31c6 100644
--- a/src/linux.h
+++ b/src/linux.h
@@ -95,7 +95,7 @@ struct nvdimm_info {
enum interface_type {
unknown,
- isa, pci, network,
+ isa, acpi_root, pci_root, pci, network,
ata, atapi, scsi, sata, sas,
usb, i1394, fibre, i2o,
md, virtblk,
@@ -264,6 +264,8 @@ extern ssize_t parse_scsi_link(const char *current, uint32_t *host,
/* device support implementations */
extern struct dev_probe pmem_parser;
+extern struct dev_probe pci_root_parser;
+extern struct dev_probe acpi_root_parser;
extern struct dev_probe pci_parser;
extern struct dev_probe sas_parser;
extern struct dev_probe sata_parser;
--
2.17.1

View File

@ -0,0 +1,71 @@
From ca71ba77abee7cea805e71a7faded706d19e4c58 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 20 Jun 2018 16:16:00 -0400
Subject: [PATCH 14/39] Make a way to say "-e 3" isn't viable for a kind of
device.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/creator.c | 7 +++++++
src/linux.c | 5 ++++-
src/linux.h | 2 ++
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/creator.c b/src/creator.c
index 76c1c1f7a99..55b411ee3da 100644
--- a/src/creator.c
+++ b/src/creator.c
@@ -243,6 +243,13 @@ efi_va_generate_file_device_path_from_esp(uint8_t *buf, ssize_t size,
va_end(aq);
}
+ if (!(options & (EFIBOOT_ABBREV_FILE|EFIBOOT_ABBREV_HD)) &&
+ (dev->flags & DEV_ABBREV_ONLY)) {
+ errno = EINVAL;
+ efi_error("Device must use File() or HD() device path");
+ goto err;
+ }
+
if ((options & EFIBOOT_ABBREV_EDD10)
&& (!(options & EFIBOOT_ABBREV_FILE)
&& !(options & EFIBOOT_ABBREV_HD))) {
diff --git a/src/linux.c b/src/linux.c
index 436fb882a98..83adc510944 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -448,8 +448,11 @@ struct device HIDDEN
continue;
}
debug(DEBUG, "%s matched %s", probe->name, current);
+ dev->flags |= probe->flags;
- if (probe->flags & DEV_PROVIDES_HD || probe->flags & DEV_PROVIDES_ROOT)
+ if (probe->flags & DEV_PROVIDES_HD ||
+ probe->flags & DEV_PROVIDES_ROOT ||
+ probe->flags & DEV_ABBREV_ONLY)
needs_root = false;
dev->probes[n++] = dev_probes[i];
current += pos;
diff --git a/src/linux.h b/src/linux.h
index 7b18bda31c6..ef7dba769bd 100644
--- a/src/linux.h
+++ b/src/linux.h
@@ -106,6 +106,7 @@ struct dev_probe;
struct device {
enum interface_type interface_type;
+ uint32_t flags;
char *link;
char *device;
char *driver;
@@ -246,6 +247,7 @@ extern ssize_t HIDDEN make_mac_path(uint8_t *buf, ssize_t size,
#define DEV_PROVIDES_ROOT 1
#define DEV_PROVIDES_HD 2
+#define DEV_ABBREV_ONLY 4
struct dev_probe {
char *name;
--
2.17.1

View File

@ -0,0 +1,131 @@
From d8637ea2b540fc9d16f1d1c1312e49a24082eefe Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 20 Jun 2018 16:16:35 -0400
Subject: [PATCH 15/39] Make a linux device root for SOC devices that use FDT.
Add parsing for FDT devices in sysfs. These devices have to use HD() or
File() because we don't have a way to express FDT nodes in a Device
Path.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-soc-root.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
src/linux.c | 1 +
src/linux.h | 3 +-
3 files changed, 75 insertions(+), 1 deletion(-)
create mode 100644 src/linux-soc-root.c
diff --git a/src/linux-soc-root.c b/src/linux-soc-root.c
new file mode 100644
index 00000000000..57dd9b04f2c
--- /dev/null
+++ b/src/linux-soc-root.c
@@ -0,0 +1,72 @@
+/*
+ * libefiboot - library for the manipulation of EFI boot variables
+ * Copyright 2012-2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "fix_coverity.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "efiboot.h"
+
+/*
+ * support for soc platforms
+ *
+ * various devices /sys/dev/block/$major:$minor start with:
+ * maj:min -> ../../devices/platform/soc/$DEVICETREE_NODE/$BLOCKDEV_STUFF/block/$DISK/$PART
+ * i.e.: soc/1a400000.sata/ata1/host0/target0:0:0/0:0:0:0/block/sda/sda1
+ * ^ dt node ^ blockdev stuff ^ disk
+ * I don't *think* the devicetree nodes stack.
+ */
+static ssize_t
+parse_soc_root(struct device *dev UNUSED, const char *current, const char *root UNUSED)
+{
+ int rc;
+ int pos;
+ const char *devpart = current;
+ char *spaces;
+
+ pos = strlen(current);
+ spaces = alloca(pos+1);
+ memset(spaces, ' ', pos+1);
+ spaces[pos] = '\0';
+ pos = 0;
+
+ debug(DEBUG, "entry");
+
+ rc = sscanf(devpart, "../../devices/platform/soc/%*[^/]/%n", &pos);
+ if (rc != 0)
+ return 0;
+ devpart += pos;
+ debug(DEBUG, "new position is \"%s\"", devpart);
+
+ return devpart - current;
+}
+
+enum interface_type soc_root_iftypes[] = { soc_root, unknown };
+
+struct dev_probe HIDDEN soc_root_parser = {
+ .name = "soc_root",
+ .iftypes = soc_root_iftypes,
+ .flags = DEV_ABBREV_ONLY|DEV_PROVIDES_ROOT,
+ .parse = parse_soc_root,
+};
diff --git a/src/linux.c b/src/linux.c
index 83adc510944..1e7db4e3f61 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -237,6 +237,7 @@ static struct dev_probe *dev_probes[] = {
&pmem_parser,
&acpi_root_parser,
&pci_root_parser,
+ &soc_root_parser,
&pci_parser,
&virtblk_parser,
&sas_parser,
diff --git a/src/linux.h b/src/linux.h
index ef7dba769bd..99d61013e02 100644
--- a/src/linux.h
+++ b/src/linux.h
@@ -95,7 +95,7 @@ struct nvdimm_info {
enum interface_type {
unknown,
- isa, acpi_root, pci_root, pci, network,
+ isa, acpi_root, pci_root, soc_root, pci, network,
ata, atapi, scsi, sata, sas,
usb, i1394, fibre, i2o,
md, virtblk,
@@ -268,6 +268,7 @@ extern ssize_t parse_scsi_link(const char *current, uint32_t *host,
extern struct dev_probe pmem_parser;
extern struct dev_probe pci_root_parser;
extern struct dev_probe acpi_root_parser;
+extern struct dev_probe soc_root_parser;
extern struct dev_probe pci_parser;
extern struct dev_probe sas_parser;
extern struct dev_probe sata_parser;
--
2.17.1

View File

@ -0,0 +1,110 @@
From bc215d06720b346ba0d888a6149cf90f544a90ad Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 20 Jun 2018 17:00:24 -0400
Subject: [PATCH 16/39] If we can't parse part of the device link, skip it and
set DEV_ABBREV_ONLY
If we can't parse some part of the device symlink, we can't write a full
device path, but we can write an abbreviated HD() or File() path. So if
we've exausted all possibilities, skip to the next node, set
DEV_ABBREV_ONLY in the device's flags, and try parsing again. Then when
creator.c checks if that flag conflicts, it'll throw an error if it
does.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux.c | 62 ++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 47 insertions(+), 15 deletions(-)
diff --git a/src/linux.c b/src/linux.c
index 1e7db4e3f61..8fe21f19f78 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -429,14 +429,17 @@ struct device HIDDEN
const char *current = dev->link;
bool needs_root = true;
+ int last_successful_probe = -1;
debug(DEBUG, "searching for device nodes in %s", dev->link);
for (i = 0; dev_probes[i] && dev_probes[i]->parse; i++) {
struct dev_probe *probe = dev_probes[i];
ssize_t pos;
- if (!needs_root && (probe->flags & DEV_PROVIDES_ROOT)) {
- debug(DEBUG, "not testing %s because flags is 0x%x", probe->name, probe->flags);
+ if (!needs_root &&
+ (probe->flags & DEV_PROVIDES_ROOT)) {
+ debug(DEBUG, "not testing %s because flags is 0x%x",
+ probe->name, probe->flags);
continue;
}
@@ -445,22 +448,51 @@ struct device HIDDEN
if (pos < 0) {
efi_error("parsing %s failed", probe->name);
goto err;
- } else if (pos == 0) {
+ } else if (pos > 0) {
+ debug(DEBUG, "%s matched %s", probe->name, current);
+ dev->flags |= probe->flags;
+
+ if (probe->flags & DEV_PROVIDES_HD ||
+ probe->flags & DEV_PROVIDES_ROOT ||
+ probe->flags & DEV_ABBREV_ONLY)
+ needs_root = false;
+
+ dev->probes[n++] = dev_probes[i];
+ current += pos;
+ debug(DEBUG, "current:%s", current);
+ last_successful_probe = i;
+
+ if (!*current || !strncmp(current, "block/", 6))
+ break;
+
continue;
}
- debug(DEBUG, "%s matched %s", probe->name, current);
- dev->flags |= probe->flags;
- if (probe->flags & DEV_PROVIDES_HD ||
- probe->flags & DEV_PROVIDES_ROOT ||
- probe->flags & DEV_ABBREV_ONLY)
- needs_root = false;
- dev->probes[n++] = dev_probes[i];
- current += pos;
- debug(DEBUG, "current:%s", current);
-
- if (!*current || !strncmp(current, "block/", 6))
- break;
+ debug(DEBUG, "dev_probes[i+1]: %p dev->interface_type: %d\n",
+ dev_probes[i+1], dev->interface_type);
+ if (dev_probes[i+1] == NULL && dev->interface_type == unknown) {
+ int new_pos = 0;
+ rc = sscanf(current, "%*[^/]/%n", &new_pos);
+ if (rc < 0) {
+ efi_error(
+ "Cannot parse device link segment \"%s\"",
+ current);
+ goto err;
+ }
+ debug(DEBUG,
+ "Cannot parse device link segment \"%s\"",
+ current);
+ debug(DEBUG, "Skipping to \"%s\"", current + new_pos);
+ debug(DEBUG,
+ "This means we can only write abbreviated paths");
+ if (rc < 0)
+ goto err;
+ if (new_pos == 0)
+ goto err;
+ dev->flags |= DEV_ABBREV_ONLY;
+ i = last_successful_probe;
+ current += new_pos;
+ }
}
if (dev->interface_type == unknown) {
--
2.17.1

View File

@ -0,0 +1,25 @@
From 8f9c1406a2a50d0c67b1380ad6fddc2c266d39f6 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 21 Jun 2018 11:13:39 -0400
Subject: [PATCH 17/39] Pacify clang analyzer just a little.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-acpi-root.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/linux-acpi-root.c b/src/linux-acpi-root.c
index c7d8276a642..e55af5fa385 100644
--- a/src/linux-acpi-root.c
+++ b/src/linux-acpi-root.c
@@ -181,7 +181,6 @@ dp_create_acpi_root(struct device *dev,
return new;
}
}
- off += new;
sz += new;
debug(DEBUG, "returning %zd", sz);
--
2.17.1

View File

@ -0,0 +1,32 @@
From 576b89de7d1a49d64efab9d494eeea5a296bdccd Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 21 Jun 2018 12:23:20 -0400
Subject: [PATCH 18/39] Try even harder to convince coverity that get_file
isn't leaking memory...
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/util.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/util.h b/src/util.h
index ef85a4c277e..441ced84fcf 100644
--- a/src/util.h
+++ b/src/util.h
@@ -332,6 +332,13 @@ get_file(uint8_t **result, const char * const fmt, ...)
errno = error;
if (rc < 0 || bufsize < 1) {
+ /*
+ * I don't think this can happen, but I can't convince
+ * cov-scan
+ */
+ if (buf)
+ free(buf);
+ *result = NULL;
efi_error("could not read file \"%s\"", path);
return -1;
}
--
2.17.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
From bc11451222cc77d8c1b4e752167adabd3c7f64c9 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 21 Jun 2018 13:33:26 -0400
Subject: [PATCH 20/39] efiboot: Make the device node skipping code pass
coverity.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/src/linux.c b/src/linux.c
index f919dee5b67..6d20c2dbe25 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -308,7 +308,8 @@ struct device HIDDEN
{
struct device *dev;
char *linkbuf = NULL, *tmpbuf = NULL;
- unsigned int i, n = 0;
+ int i = 0;
+ unsigned int n = 0;
int rc;
size_t nmemb = (sizeof(dev_probes)
@@ -432,9 +433,11 @@ struct device HIDDEN
int last_successful_probe = -1;
debug("searching for device nodes in %s", dev->link);
- for (i = 0; dev_probes[i] && dev_probes[i]->parse; i++) {
+ for (i = 0;
+ dev_probes[i] && dev_probes[i]->parse && *current;
+ i++) {
struct dev_probe *probe = dev_probes[i];
- ssize_t pos;
+ int pos;
if (!needs_root &&
(probe->flags & DEV_PROVIDES_ROOT)) {
@@ -471,24 +474,26 @@ struct device HIDDEN
debug("dev_probes[i+1]: %p dev->interface_type: %d\n",
dev_probes[i+1], dev->interface_type);
if (dev_probes[i+1] == NULL && dev->interface_type == unknown) {
- int new_pos = 0;
- rc = sscanf(current, "%*[^/]/%n", &new_pos);
+ pos = 0;
+ rc = sscanf(current, "%*[^/]/%n", &pos);
if (rc < 0) {
- efi_error(
- "Cannot parse device link segment \"%s\"",
- current);
+slash_err:
+ efi_error("Cannot parse device link segment \"%s\"", current);
goto err;
}
+
+ while (current[pos] == '/')
+ pos += 1;
+
+ if (!current[pos])
+ goto slash_err;
+
debug("Cannot parse device link segment \"%s\"", current);
debug("Skipping to \"%s\"", current + pos);
debug("This means we can only create abbreviated paths");
- if (rc < 0)
- goto err;
- if (new_pos == 0)
- goto err;
dev->flags |= DEV_ABBREV_ONLY;
i = last_successful_probe;
- current += new_pos;
+ current += pos;
}
}
--
2.17.1

View File

@ -0,0 +1,35 @@
From 22b1a7477c5ef72821e6491c67ad85ca52c1ae85 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 21 Jun 2018 13:55:32 -0400
Subject: [PATCH 21/39] efiboot: don't error on unknown type with
DEV_ABBREV_ONLY
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/linux.c b/src/linux.c
index 6d20c2dbe25..7fac339c50e 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -494,10 +494,15 @@ slash_err:
dev->flags |= DEV_ABBREV_ONLY;
i = last_successful_probe;
current += pos;
+
+ if (!*current || !strncmp(current, "block/", 6))
+ break;
}
}
- if (dev->interface_type == unknown) {
+ if (dev->interface_type == unknown &&
+ !(dev->flags & DEV_ABBREV_ONLY) &&
+ !strcmp(current, "block/")) {
efi_error("unknown storage interface");
errno = ENOSYS;
goto err;
--
2.17.1

View File

@ -0,0 +1,26 @@
From 6d87113fc3d9b2b0f520fc97eab9f5a60fda7d30 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 21 Jun 2018 13:55:45 -0400
Subject: [PATCH 22/39] efiboot: fix a bad error check
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-acpi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/linux-acpi.c b/src/linux-acpi.c
index 3eac526525f..88f0084a37e 100644
--- a/src/linux-acpi.c
+++ b/src/linux-acpi.c
@@ -93,7 +93,7 @@ hid_err:
errno = 0;
fbuf = NULL;
rc = read_sysfs_file(&fbuf, "%s/firmware_node/uid", path);
- if ((rc <= 0 && errno != ENOENT) || fbuf == NULL) {
+ if ((rc < 0 && errno != ENOENT) || (rc > 0 && fbuf == NULL)) {
efi_error("could not read %s/firmware_node/uid", path);
return -1;
}
--
2.17.1

View File

@ -0,0 +1,27 @@
From 50e8c66f92b2d93d20c2524936f6858fd2b07afe Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 21 Jun 2018 14:23:40 -0400
Subject: [PATCH 23/39] efiboot: parse_scsi_link(): fix the offset searching
for the port
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-scsi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/linux-scsi.c b/src/linux-scsi.c
index 80c2fb7d82e..2e4f710badf 100644
--- a/src/linux-scsi.c
+++ b/src/linux-scsi.c
@@ -92,7 +92,7 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
pos0 = 0;
debug("searching for port-4:0 or port-4:0:0");
- rc = sscanf(current, "port-%d:%d%n:%d%n", &tosser0,
+ rc = sscanf(current+sz, "port-%d:%d%n:%d%n", &tosser0,
&tosser1, &pos0, &tosser2, &pos1);
debug("current:\"%s\" rc:%d pos0:%d pos1:%d\n", current+sz, rc, pos0, pos1);
arrow(LOG_DEBUG, spaces, 9, pos0, rc, 2);
--
2.17.1

View File

@ -0,0 +1,28 @@
From c2223eb4638c6d8562626917651a11b8aa1e8f9e Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 21 Jun 2018 16:18:32 -0400
Subject: [PATCH 24/39] Coverity still doesn't believe in error codes...
So also test fbuf here.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-acpi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/linux-acpi.c b/src/linux-acpi.c
index 88f0084a37e..346eba09041 100644
--- a/src/linux-acpi.c
+++ b/src/linux-acpi.c
@@ -49,7 +49,7 @@ parse_acpi_hid_uid(struct device *dev, const char *fmt, ...)
return -1;
rc = read_sysfs_file(&fbuf, "%s/firmware_node/path", path);
- if (rc > 0) {
+ if (rc > 0 && fbuf) {
size_t l = strlen(fbuf);
if (l > 1) {
fbuf[l-1] = 0;
--
2.17.1

View File

@ -0,0 +1,28 @@
From d8d7e54fe01a7a255e649a7734820800edf82633 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 16 Jul 2018 15:40:22 -0400
Subject: [PATCH 25/39] Don't require NVME to have an EUI
Resolves: rhbz#1593784
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-nvme.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/linux-nvme.c b/src/linux-nvme.c
index ce931b7e237..d68d11a3409 100644
--- a/src/linux-nvme.c
+++ b/src/linux-nvme.c
@@ -117,8 +117,6 @@ parse_nvme(struct device *dev, const char *current, const char *root UNUSED)
}
dev->nvme_info.has_eui = 1;
memcpy(dev->nvme_info.eui, eui, sizeof(eui));
- } else {
- return -1;
}
return pos0;
--
2.17.1

View File

@ -0,0 +1,27 @@
From 50d7b979d1aa1c4afbb60a702bd16f9ff3066c50 Mon Sep 17 00:00:00 2001
From: "Bernhard M. Wiedemann" <bwiedemann@suse.de>
Date: Tue, 24 Jul 2018 09:34:21 +0200
Subject: [PATCH 26/39] makeguids: initialize memory
so that we do not write uninitialized memory into guids.bin and names.bin
which made the resulting libefivar.so.1.36 unreproducible.
See https://reproducible-builds.org/ for why this matters.
---
src/makeguids.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/makeguids.c b/src/makeguids.c
index f84fbb81166..a15356b152e 100644
--- a/src/makeguids.c
+++ b/src/makeguids.c
@@ -147,6 +147,7 @@ main(int argc, char *argv[])
outbuf = realloc(outbuf, line * sizeof (struct guidname));
if (!outbuf)
err(1, "makeguids");
+ memset(outbuf + line - 1, 0, sizeof(struct guidname));
char *symbol = strchr(guidstr, '\t');
if (symbol == NULL)
--
2.17.1

View File

@ -0,0 +1,255 @@
From d6a526a0c819c439a894af625f45b657576f8744 Mon Sep 17 00:00:00 2001
From: Alek Du <alek.du@intel.com>
Date: Fri, 27 Jul 2018 21:31:01 +0800
Subject: [PATCH 27/39] emmc_parser: add emmc_parser
Signed-off-by: Alek Du <alek.du@intel.com>
---
src/dp-message.c | 18 +++++
src/linux-emmc.c | 129 +++++++++++++++++++++++++++++++++
src/linux.c | 1 +
src/include/efivar/efivar-dp.h | 2 +
src/linux.h | 7 ++
src/libefivar.map.in | 1 +
6 files changed, 158 insertions(+)
create mode 100644 src/linux-emmc.c
diff --git a/src/dp-message.c b/src/dp-message.c
index 5af66438bfc..3724e5f57bd 100644
--- a/src/dp-message.c
+++ b/src/dp-message.c
@@ -826,3 +826,21 @@ efidp_make_nvdimm(uint8_t *buf, ssize_t size, efi_guid_t *uuid)
return sz;
}
+
+ssize_t PUBLIC
+efidp_make_emmc(uint8_t *buf, ssize_t size, uint32_t slot_id)
+{
+ efidp_emmc *emmc = (efidp_emmc *)buf;
+ ssize_t req = sizeof (*emmc);
+ ssize_t sz;
+
+ sz = efidp_make_generic(buf, size, EFIDP_MESSAGE_TYPE,
+ EFIDP_MSG_NVME, sizeof (*emmc));
+ if (size && sz == req)
+ emmc->slot = slot_id;
+
+ if (sz < 0)
+ efi_error("efidp_make_generic failed");
+
+ return sz;
+}
diff --git a/src/linux-emmc.c b/src/linux-emmc.c
new file mode 100644
index 00000000000..f0c9e635cb6
--- /dev/null
+++ b/src/linux-emmc.c
@@ -0,0 +1,129 @@
+/*
+ * libefiboot - library for the manipulation of EFI boot variables
+ * Copyright 2012-2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "fix_coverity.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "efiboot.h"
+
+/*
+ * support for emmc devices
+ *
+ * /sys/dev/block/$major:$minor looks like:
+ * 179:0 -> ../../devices/pci0000:00/0000:00:1c.0/mmc_host/mmc0/mmc0:0001/block/mmcblk0
+ * 179:1 -> ../../devices/pci0000:00/0000:00:1c.0/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p1
+ *
+ * /sys/dev/block/179:0/device looks like:
+ * device -> ../../../mmc0:0001
+ *
+ * /sys/dev/block/179:1/partition looks like:
+ * $ cat partition
+ * 1
+ *
+ */
+
+static ssize_t
+parse_emmc(struct device *dev, const char *current, const char *root UNUSED)
+{
+ int rc;
+ int32_t tosser0, tosser1, tosser2, tosser3, slot_id, partition;
+ int pos0 = 0, pos1 = 0;
+ char *spaces;
+
+ pos0 = strlen(current);
+ spaces = alloca(pos0+1);
+ memset(spaces, ' ', pos0+1);
+ spaces[pos0] = '\0';
+ pos0 = 0;
+
+ debug(DEBUG, "entry");
+
+ debug(DEBUG, "searching for mmc_host/mmc0/mmc0:0001/block/mmcblk0 or mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p1");
+ rc = sscanf(current, "mmc_host/mmc%d/mmc%d:%d/block/mmcblk%d%n/mmcblk%dp%d%n",
+ &tosser0, &tosser1, &tosser2, &slot_id,
+ &pos0, &tosser3, &partition, &pos1);
+ debug(DEBUG, "current:\"%s\" rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
+ arrow(DEBUG, spaces, 9, pos0, rc, 4);
+ arrow(DEBUG, spaces, 9, pos1, rc, 6);
+ /*
+ * If it isn't of that form, it's not one of our emmc devices.
+ */
+ if (rc != 4 && rc != 6)
+ return 0;
+
+ dev->emmc_info.slot_id = slot_id;
+ dev->interface_type = emmc;
+
+ if (rc == 6) {
+ if (dev->part == -1)
+ dev->part = partition;
+
+ pos0 = pos1;
+ }
+
+ return pos0;
+}
+
+static ssize_t
+dp_create_emmc(struct device *dev,
+ uint8_t *buf, ssize_t size, ssize_t off)
+{
+ ssize_t sz;
+
+ debug(DEBUG, "entry");
+
+ sz = efidp_make_emmc(buf + off, size ? size - off : 0,
+ dev->emmc_info.slot_id);
+ return sz;
+}
+
+static char *
+make_part_name(struct device *dev)
+{
+ char *ret = NULL;
+ ssize_t rc;
+
+ if (dev->part < 1)
+ return NULL;
+
+ rc = asprintf(&ret, "%sp%d", dev->disk_name, dev->part);
+ if (rc < 0) {
+ efi_error("could not allocate memory");
+ return NULL;
+ }
+
+ return ret;
+}
+
+static enum interface_type emmc_iftypes[] = { emmc, unknown };
+
+struct dev_probe HIDDEN emmc_parser = {
+ .name = "emmc",
+ .iftypes = emmc_iftypes,
+ .flags = DEV_PROVIDES_HD,
+ .parse = parse_emmc,
+ .create = dp_create_emmc,
+ .make_part_name = make_part_name,
+};
diff --git a/src/linux.c b/src/linux.c
index 7fac339c50e..ff8db812ad3 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -246,6 +246,7 @@ static struct dev_probe *dev_probes[] = {
&ata_parser,
&scsi_parser,
&i2o_parser,
+ &emmc_parser,
NULL
};
diff --git a/src/include/efivar/efivar-dp.h b/src/include/efivar/efivar-dp.h
index 1b05775ae7e..f9ebb059d06 100644
--- a/src/include/efivar/efivar-dp.h
+++ b/src/include/efivar/efivar-dp.h
@@ -689,6 +689,8 @@ typedef struct {
uint8_t slot;
} EFIVAR_PACKED efidp_emmc;
+extern ssize_t efidp_make_emmc(uint8_t *buf, ssize_t size, uint32_t slot_id);
+
#define EFIDP_MSG_BTLE 0x1e
typedef struct {
efidp_header header;
diff --git a/src/linux.h b/src/linux.h
index 99d61013e02..7c7ea91e771 100644
--- a/src/linux.h
+++ b/src/linux.h
@@ -93,6 +93,10 @@ struct nvdimm_info {
efi_guid_t nvdimm_label;
};
+struct emmc_info {
+ int32_t slot_id;
+};
+
enum interface_type {
unknown,
isa, acpi_root, pci_root, soc_root, pci, network,
@@ -100,6 +104,7 @@ enum interface_type {
usb, i1394, fibre, i2o,
md, virtblk,
nvme, nd_pmem,
+ emmc,
};
struct dev_probe;
@@ -139,6 +144,7 @@ struct device {
struct sata_info sata_info;
struct ata_info ata_info;
struct nvme_info nvme_info;
+ struct emmc_info emmc_info;
struct nvdimm_info nvdimm_info;
};
};
@@ -277,5 +283,6 @@ extern struct dev_probe virtblk_parser;
extern struct dev_probe i2o_parser;
extern struct dev_probe scsi_parser;
extern struct dev_probe ata_parser;
+extern struct dev_probe emmc_parser;
#endif /* _EFIBOOT_LINUX_H */
diff --git a/src/libefivar.map.in b/src/libefivar.map.in
index 31f696d3cb5..b5ee1ce334a 100644
--- a/src/libefivar.map.in
+++ b/src/libefivar.map.in
@@ -51,6 +51,7 @@ libefivar.so.0 {
efidp_make_sata;
efidp_make_scsi;
efidp_make_vendor;
+ efidp_make_emmc;
efidp_parse_device_node;
efidp_parse_device_path;
efidp_set_node_data;
--
2.17.1

View File

@ -0,0 +1,55 @@
From 1f385ff1bde1e783eba03df37af9421bac0df82b Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Fri, 3 Aug 2018 09:56:01 -0400
Subject: [PATCH 28/39] abignore: work around an abidw bug
Some versions of abignore mistakenly treat brackets as section headers,
thus ignoring the rest of the stanza after them. It's fixed upstream,
but I don't have the newer version yet. Moving the braces to be after
the change-kind and other things works around the issue.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/abignore | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/abignore b/src/abignore
index a4597b1029c..1badb2dab35 100644
--- a/src/abignore
+++ b/src/abignore
@@ -14,28 +14,28 @@
# 'efidp_wifi __anonymous_union__::wifi' at efivar-dp.h:868:1
#
[suppress_type]
- soname_regexp = libefi(var|boot)\\.so\\..*
name = efidp_data
type_kind = typedef
has_data_member_inserted_at = end
+ soname_regexp = libefi(var|boot)\\.so\\..*
# 1 Added variable:
#
# 'const __anonymous_struct__ efi_guid_ux_capsule' {efi_guid_ux_capsule@@LIBEFIVAR_1.33}
#
[suppress_variable]
+ change_kind = added-variable
soname_regexp = libefivar\\.so\\..*
symbol_name_regexp = ^efi_guid_[[:alnum:]_]+$
- change_kind = added-variable
# allow new functions that are prefixed correctly
[suppress_function]
+ change_kind = added-function
soname_regexp = ^libefi(var|boot)\\.so\\..*
name_regexp = ^(efidp_|efi_)[[:alnum:]_]+
- change_kind = added-function
# allow new variables that are prefixed correctly
[suppress_variable]
+ change_kind = added-variable
soname_regexp = libefi(var|boot)\\.so\\..*
symbol_name_regexp = ^(efidp_|efi_)[[:alnum:]_]+
- change_kind = added-variable
--
2.17.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
From 0c44e3d75a9c3a2a1d4cef3c1b836aa0d7fb004f Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Fri, 3 Aug 2018 10:02:02 -0400
Subject: [PATCH 30/39] linux-emmc: update for internal API breakage.
Alek wrote his code before I made debug() imply LOG_DEBUG, so we need to
change that here as well.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-emmc.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/linux-emmc.c b/src/linux-emmc.c
index f0c9e635cb6..87e92477554 100644
--- a/src/linux-emmc.c
+++ b/src/linux-emmc.c
@@ -58,15 +58,15 @@ parse_emmc(struct device *dev, const char *current, const char *root UNUSED)
spaces[pos0] = '\0';
pos0 = 0;
- debug(DEBUG, "entry");
+ debug("entry");
- debug(DEBUG, "searching for mmc_host/mmc0/mmc0:0001/block/mmcblk0 or mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p1");
+ debug("searching for mmc_host/mmc0/mmc0:0001/block/mmcblk0 or mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p1");
rc = sscanf(current, "mmc_host/mmc%d/mmc%d:%d/block/mmcblk%d%n/mmcblk%dp%d%n",
&tosser0, &tosser1, &tosser2, &slot_id,
&pos0, &tosser3, &partition, &pos1);
- debug(DEBUG, "current:\"%s\" rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
- arrow(DEBUG, spaces, 9, pos0, rc, 4);
- arrow(DEBUG, spaces, 9, pos1, rc, 6);
+ debug("current:\"%s\" rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
+ arrow(LOG_DEBUG, spaces, 9, pos0, rc, 4);
+ arrow(LOG_DEBUG, spaces, 9, pos1, rc, 6);
/*
* If it isn't of that form, it's not one of our emmc devices.
*/
@@ -92,7 +92,7 @@ dp_create_emmc(struct device *dev,
{
ssize_t sz;
- debug(DEBUG, "entry");
+ debug("entry");
sz = efidp_make_emmc(buf + off, size ? size - off : 0,
dev->emmc_info.slot_id);
--
2.17.1

View File

@ -0,0 +1,64 @@
From da30e9f2eee235ce11d47bb2e32f976b8c187e5d Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 10 Sep 2018 15:00:03 -0400
Subject: [PATCH 31/39] Fix another buggy fake acpi pci root driver
In this case, the platform driver that creates the PCI(e) root device
doesn't fill in its driver link, so we can't look up what driver is in
use - but since it's the root, it *really* doesn't matter. And in
general, we only really care if it's the last node in our path, because
that'll be the controller for the boot device anyway.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-pci.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/src/linux-pci.c b/src/linux-pci.c
index e7c864b2d33..f63f5914d9f 100644
--- a/src/linux-pci.c
+++ b/src/linux-pci.c
@@ -67,7 +67,9 @@ parse_pci(struct device *dev, const char *current, const char *root)
uint8_t bus, device, function;
struct pci_dev_info *pci_dev;
unsigned int i = dev->n_pci_devs;
+ struct stat statbuf;
+ debug("devpart is \"%s\"", devpart);
pos = 0;
debug("searching for 0000:00:00.0/");
rc = sscanf(devpart, "%hx:%hhx:%hhx.%hhx/%n",
@@ -100,15 +102,23 @@ parse_pci(struct device *dev, const char *current, const char *root)
return -1;
}
tmp[devpart - root] = '\0';
- rc = sysfs_readlink(&linkbuf, "class/block/%s/driver", tmp);
- if (rc < 0 || !linkbuf) {
- efi_error("Could not find driver for pci device %s", tmp);
- free(tmp);
- return -1;
+ rc = sysfs_stat(&statbuf, "class/block/%s/driver", tmp);
+ if (rc < 0 && errno == ENOENT) {
+ debug("No driver link for /sys/class/block/%s", tmp);
+ debug("Assuming this is just a buggy platform core driver");
+ dev->pci_dev[i].driverlink = NULL;
+ } else {
+ rc = sysfs_readlink(&linkbuf, "class/block/%s/driver", tmp);
+ if (rc < 0 || !linkbuf) {
+ efi_error("Could not find driver for pci device %s", tmp);
+ free(tmp);
+ return -1;
+ } else {
+ dev->pci_dev[i].driverlink = strdup(linkbuf);
+ debug("driver:%s\n", linkbuf);
+ }
}
free(tmp);
- dev->pci_dev[i].driverlink = strdup(linkbuf);
- debug("driver:%s\n", linkbuf);
dev->n_pci_devs += 1;
}
--
2.17.1

View File

@ -0,0 +1,28 @@
From e56cf8d480c27bf3ea81af63efb4704896282c6a Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 17 Sep 2018 16:12:25 -0400
Subject: [PATCH 32/39] Fix dev->probes intialization test
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/linux.c b/src/linux.c
index ff8db812ad3..19eb488c992 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -117,7 +117,9 @@ reset_part_name(struct device *dev)
if (dev->part < 1)
return 0;
- if (dev->probes[dev->n_probes]->make_part_name) {
+ if (dev->n_probes > 0 &&
+ dev->probes[dev->n_probes-1] &&
+ dev->probes[dev->n_probes-1]->make_part_name) {
part = dev->probes[dev->n_probes]->make_part_name(dev);
dev->part_name = part;
rc = 0;
--
2.17.1

View File

@ -0,0 +1,92 @@
From e83002b08aa6db57b90d89968ab8d34f6c7f73cf Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 17 Sep 2018 16:13:24 -0400
Subject: [PATCH 33/39] Deal with devices that don't have a ->device link in
sysfs
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux.c | 53 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 30 insertions(+), 23 deletions(-)
diff --git a/src/linux.c b/src/linux.c
index 19eb488c992..6d405af8a76 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -389,43 +389,50 @@ struct device HIDDEN
rc = sysfs_readlink(&tmpbuf, "block/%s/device", dev->disk_name);
if (rc < 0 || !tmpbuf) {
- efi_error("readlink of /sys/block/%s/device failed",
+ debug("readlink of /sys/block/%s/device failed",
dev->disk_name);
- goto err;
+
+ dev->device = strdup("");
+ } else {
+ dev->device = strdup(tmpbuf);
}
- dev->device = strdup(tmpbuf);
if (!dev->device) {
efi_error("strdup(\"%s\") failed", tmpbuf);
goto err;
}
- rc = sysfs_readlink(&tmpbuf, "block/%s/device/driver", dev->disk_name);
- if (rc < 0 || !tmpbuf) {
- if (errno == ENOENT) {
- /*
- * nvme, for example, will have nvme0n1/device point
- * at nvme0, and we need to look for device/driver
- * there.
- */
- rc = sysfs_readlink(&tmpbuf,
- "block/%s/device/device/driver",
- dev->disk_name);
- }
+ if (dev->device[0] != 0) {
+ rc = sysfs_readlink(&tmpbuf, "block/%s/device/driver", dev->disk_name);
if (rc < 0 || !tmpbuf) {
- efi_error("readlink of /sys/block/%s/device/driver failed",
- dev->disk_name);
+ if (errno == ENOENT) {
+ /*
+ * nvme, for example, will have nvme0n1/device point
+ * at nvme0, and we need to look for device/driver
+ * there.
+ */
+ rc = sysfs_readlink(&tmpbuf,
+ "block/%s/device/device/driver",
+ dev->disk_name);
+ }
+ if (rc < 0 || !tmpbuf) {
+ efi_error("readlink of /sys/block/%s/device/driver failed",
+ dev->disk_name);
+ goto err;
+ }
+ }
+
+ linkbuf = pathseg(tmpbuf, -1);
+ if (!linkbuf) {
+ efi_error("could not get segment -1 of \"%s\"", tmpbuf);
goto err;
}
- }
- linkbuf = pathseg(tmpbuf, -1);
- if (!linkbuf) {
- efi_error("could not get segment -1 of \"%s\"", tmpbuf);
- goto err;
+ dev->driver = strdup(linkbuf);
+ } else {
+ dev->driver = strdup("");
}
- dev->driver = strdup(linkbuf);
if (!dev->driver) {
efi_error("strdup(\"%s\") failed", linkbuf);
goto err;
--
2.17.1

View File

@ -0,0 +1,124 @@
From 576f55b02d9ec478bd5157352c884e3543bcca58 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 17 Sep 2018 16:52:57 -0400
Subject: [PATCH 34/39] Handle partition name parsing and formatting for
partitioned md.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-md.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
create mode 100644 src/linux-md.c
diff --git a/src/linux-md.c b/src/linux-md.c
new file mode 100644
index 00000000000..0a5c1cdb435
--- /dev/null
+++ b/src/linux-md.c
@@ -0,0 +1,103 @@
+/*
+ * libefiboot - library for the manipulation of EFI boot variables
+ * Copyright 2012-2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "fix_coverity.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "efiboot.h"
+
+/*
+ * "support" for partitioned md devices - basically we just need to format
+ * the partition name.
+ *
+ * /sys/dev/block/$major:$minor looks like:
+ * 259:0 -> ../../devices/virtual/block/md1/md1p1
+ * 9:1 -> ../../devices/virtual/block/md1
+ *
+ */
+
+static ssize_t
+parse_md(struct device *dev, const char *current, const char *root UNUSED)
+{
+ int rc;
+ int32_t md, tosser0, part;
+ int pos0 = 0, pos1 = 0;
+ char *spaces;
+
+ pos0 = strlen(current);
+ spaces = alloca(pos0+1);
+ memset(spaces, ' ', pos0+1);
+ spaces[pos0] = '\0';
+ pos0 = 0;
+
+ debug("entry");
+
+ debug("searching for mdM/mdMpN");
+ rc = sscanf(current, "md%d/%nmd%dp%d%n",
+ &md, &pos0, &tosser0, &part, &pos1);
+ debug("current:\"%s\" rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
+ arrow(LOG_DEBUG, spaces, 9, pos0, rc, 3);
+ /*
+ * If it isn't of that form, it's not one of our partitioned md devices.
+ */
+ if (rc != 3)
+ return 0;
+
+ dev->interface_type = md;
+
+ if (dev->part == -1)
+ dev->part = part;
+
+ return pos1;
+}
+
+
+static char *
+make_part_name(struct device *dev)
+{
+ char *ret = NULL;
+ ssize_t rc;
+
+ if (dev->part < 1)
+ return NULL;
+
+ rc = asprintf(&ret, "%sp%d", dev->disk_name, dev->part);
+ if (rc < 0) {
+ efi_error("could not allocate memory");
+ return NULL;
+ }
+
+ return ret;
+}
+
+static enum interface_type md_iftypes[] = { md, unknown };
+
+struct dev_probe HIDDEN md_parser = {
+ .name = "md",
+ .iftypes = md_iftypes,
+ .flags = DEV_PROVIDES_HD,
+ .parse = parse_md,
+ .make_part_name = make_part_name,
+};
--
2.17.1

View File

@ -0,0 +1,79 @@
From cff35642eac6699e30549db2db3341e7657bf4a6 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 18 Sep 2018 14:57:13 -0400
Subject: [PATCH 35/39] Fix partition number detection when it's not provided.
We need to actually get the partition number from the child device when
we're called without it.
Resolves: rhbz#1616305
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/creator.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/src/creator.c b/src/creator.c
index ef782e2b647..987fa033e5b 100644
--- a/src/creator.c
+++ b/src/creator.c
@@ -350,6 +350,36 @@ efi_generate_file_device_path_from_esp(uint8_t *buf, ssize_t size,
return ret;
}
+static int
+get_part(char *devpath)
+{
+ int fd;
+ int partition = -1;
+ struct device *dev = NULL;
+
+ fd = open(devpath, O_RDONLY);
+ if (fd < 0) {
+ efi_error("could not open device for ESP");
+ goto err;
+ }
+
+ dev = device_get(fd, -1);
+ if (dev == NULL) {
+ efi_error("could not get ESP disk info");
+ goto err;
+ }
+
+ partition = dev->part;
+ if (partition < 0)
+ partition = 0;
+err:
+ if (dev)
+ device_free(dev);
+ if (fd >= 0)
+ close(fd);
+ return partition;
+}
+
ssize_t NONNULL(3) PUBLIC
efi_generate_file_device_path(uint8_t *buf, ssize_t size,
const char * const filepath,
@@ -374,6 +404,19 @@ efi_generate_file_device_path(uint8_t *buf, ssize_t size,
efi_error("could not find parent device for file");
goto err;
}
+ debug("child_devpath:%s", child_devpath);
+
+ debug("parent_devpath:%s", parent_devpath);
+ debug("child_devpath:%s", child_devpath);
+ debug("rc:%d", rc);
+
+ rc = get_part(child_devpath);
+ if (rc < 0) {
+ efi_error("Couldn't get partition number for %s",
+ child_devpath);
+ goto err;
+ }
+ debug("detected partition:%d", rc);
va_start(ap, options);
--
2.17.1

View File

@ -0,0 +1,38 @@
From ebc0b14923faa8da19dbdc2501a6fef0728906a1 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 Oct 2018 14:27:04 -0400
Subject: [PATCH 36/39] dp-acpi: fix HID vs HID_EX formatting bug.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/dp-acpi.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/dp-acpi.c b/src/dp-acpi.c
index 6f3e94443e5..019f910c164 100644
--- a/src/dp-acpi.c
+++ b/src/dp-acpi.c
@@ -157,7 +157,9 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
return off;
}
}
- } else if (dp->subtype == EFIDP_ACPI_HID_EX) {
+ } else if (dp->subtype == EFIDP_ACPI_HID) {
+ debug("formatting ACPI HID 0x%08x", dp->acpi_hid.hid);
+
switch (dp->acpi_hid.hid) {
case EFIDP_ACPI_PCI_ROOT_HID:
format(buf, size, off, "PciRoot",
@@ -249,6 +251,9 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
return -1;
}
}
+ } else {
+ debug("Unknown ACPI device path type {0x%04hhx,0x%04hhx}",
+ dp->type, dp->subtype);
}
return off;
--
2.17.1

View File

@ -0,0 +1,75 @@
From 7775b2fdd12151f78f575026bb5e416575dad455 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 Oct 2018 14:31:06 -0400
Subject: [PATCH 37/39] Support decoding ACPI Generic Container and Embedded
Controller dp nodes
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/dp-acpi.c | 18 ++++++++++++++++++
src/include/efivar/efivar-dp.h | 3 +++
2 files changed, 21 insertions(+)
diff --git a/src/dp-acpi.c b/src/dp-acpi.c
index 019f910c164..3a80ba9e006 100644
--- a/src/dp-acpi.c
+++ b/src/dp-acpi.c
@@ -147,10 +147,19 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
format(buf, size, off, "PciRoot",
"PciRoot(%s)", uidstr);
return off;
+ case EFIDP_ACPI_CONTAINER_0A05_HID:
+ case EFIDP_ACPI_CONTAINER_0A06_HID:
+ format(buf, size, off, "AcpiContainer",
+ "AcpiContainer(%s)", uidstr);
+ break;
case EFIDP_ACPI_PCIE_ROOT_HID:
format(buf, size, off, "PcieRoot",
"PcieRoot(%s)", uidstr);
return off;
+ case EFIDP_ACPI_EC_HID:
+ format(buf, size, off, "EmbeddedController",
+ "EmbeddedController()");
+ return off;
default:
format_acpi_hid_ex(buf, size, off, dp,
hidstr, cidstr, uidstr);
@@ -166,11 +175,20 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
"PciRoot(0x%"PRIx32")",
dp->acpi_hid.uid);
break;
+ case EFIDP_ACPI_CONTAINER_0A05_HID:
+ case EFIDP_ACPI_CONTAINER_0A06_HID:
+ format(buf, size, off, "AcpiContainer",
+ "AcpiContainer()");
+ break;
case EFIDP_ACPI_PCIE_ROOT_HID:
format(buf, size, off, "PcieRoot",
"PcieRoot(0x%"PRIx32")",
dp->acpi_hid.uid);
break;
+ case EFIDP_ACPI_EC_HID:
+ format(buf, size, off, "EmbeddedController",
+ "EmbeddedController()");
+ break;
case EFIDP_ACPI_FLOPPY_HID:
format(buf, size, off, "Floppy",
"Floppy(0x%"PRIx32")",
diff --git a/src/include/efivar/efivar-dp.h b/src/include/efivar/efivar-dp.h
index f9ebb059d06..eab04f2dfac 100644
--- a/src/include/efivar/efivar-dp.h
+++ b/src/include/efivar/efivar-dp.h
@@ -155,7 +155,10 @@ efidp_make_acpi_hid_ex(uint8_t *buf, ssize_t size,
#define EFIDP_ACPI_ID_TO_NUM(_HID) ((_HID) >> 16)
#define EFIDP_ACPI_PCI_ROOT_HID EFIDP_EFI_PNP_ID(0x0a03)
+#define EFIDP_ACPI_CONTAINER_0A05_HID EFIDP_EFI_PNP_ID(0x0a05)
+#define EFIDP_ACPI_CONTAINER_0A06_HID EFIDP_EFI_PNP_ID(0x0a06)
#define EFIDP_ACPI_PCIE_ROOT_HID EFIDP_EFI_PNP_ID(0x0a08)
+#define EFIDP_ACPI_EC_HID EFIDP_EFI_PNP_ID(0x0a09)
#define EFIDP_ACPI_FLOPPY_HID EFIDP_EFI_PNP_ID(0x0604)
#define EFIDP_ACPI_KEYBOARD_HID EFIDP_EFI_PNP_ID(0x0301)
#define EFIDP_ACPI_SERIAL_HID EFIDP_EFI_PNP_ID(0x0501)
--
2.17.1

View File

@ -0,0 +1,38 @@
From 0d63973b32767e1c4d44c0c172ae6222d9acefff Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 Oct 2018 14:33:20 -0400
Subject: [PATCH 38/39] pci-root: actually create the device path node.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-pci-root.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/linux-pci-root.c b/src/linux-pci-root.c
index 269e30e2c31..a2d9fb04a11 100644
--- a/src/linux-pci-root.c
+++ b/src/linux-pci-root.c
@@ -87,9 +87,9 @@ static ssize_t
dp_create_pci_root(struct device *dev UNUSED,
uint8_t *buf, ssize_t size, ssize_t off)
{
+ ssize_t new = 0, sz = 0;
debug("entry buf:%p size:%zd off:%zd", buf, size, off);
debug("returning 0");
-#if 0
if (dev->acpi_root.acpi_uid_str) {
debug("creating acpi_hid_ex dp hid:0x%08x uid:\"%s\"",
dev->acpi_root.acpi_hid,
@@ -120,9 +120,6 @@ dp_create_pci_root(struct device *dev UNUSED,
debug("returning %zd", sz);
return sz;
-#else
- return 0;
-#endif
}
enum interface_type pci_root_iftypes[] = { pci_root, unknown };
--
2.17.1

View File

@ -0,0 +1,431 @@
From 3e687d8072f3ed53ae727ec2cb99ae56dbcdf02b Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 Oct 2018 14:35:01 -0400
Subject: [PATCH 39/39] sas: handle port expanders at all.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux-ata.c | 3 +-
src/linux-sas.c | 168 ++++++++++++++++++++++++++++++++++++++++++-----
src/linux-scsi.c | 105 +++++++++++++++++++++++++----
src/linux.h | 6 +-
4 files changed, 250 insertions(+), 32 deletions(-)
diff --git a/src/linux-ata.c b/src/linux-ata.c
index 32cb99361e5..43e5f4c5d23 100644
--- a/src/linux-ata.c
+++ b/src/linux-ata.c
@@ -114,7 +114,8 @@ parse_ata(struct device *dev, const char *current, const char *root UNUSED)
pos = parse_scsi_link(host + 1, &scsi_host,
&scsi_bus, &scsi_device,
- &scsi_target, &scsi_lun);
+ &scsi_target, &scsi_lun,
+ NULL, NULL, NULL);
if (pos < 0)
return -1;
diff --git a/src/linux-sas.c b/src/linux-sas.c
index 4d77d39a24d..bb04fe83064 100644
--- a/src/linux-sas.c
+++ b/src/linux-sas.c
@@ -28,6 +28,91 @@
#include "efiboot.h"
+static int
+get_port_expander_sas_address(uint64_t *sas_address, uint32_t scsi_host,
+ uint32_t local_port_id,
+ uint32_t remote_port_id, uint32_t remote_scsi_target)
+{
+ uint8_t *filebuf = NULL;
+ int rc;
+
+ /*
+ * We find sas_address via this insanity:
+ * /sys/class/scsi_host/host2 -> ../../devices/pci0000:74/0000:74:02.0/host2/scsi_host/host2
+ * /sys/devices/pci0000:74/0000:74:02.0/host2/scsi_host/host2/device -> ../../../host2
+ * /sys/devices/pci0000:74/0000:74:02.0/host2/device -> ../../../host2
+ * /sys/devices/host2/port-2:0/expander-2:0/sas_device/expander-2:0/sas_address
+ *
+ * But since host2 is always host2, we can skip most of that and just
+ * go for:
+ * /sys/devices/pci0000:74/0000:74:02.0/host2/port-2:0/expander-2:0/port-2:0:2/end_device-2:0:2/sas_device/end_device-2:0:2/sas_address
+ */
+
+#if 0 /* previously thought this was right, but it's the expander's address, not the target's address */
+ /*
+ * /sys/class/scsi_host/host2/device/port-2:0/expander-2:0/sas_device/expander-2:0/sas_address
+ * ... I think. I would have expected that to be port-2:0:0 and I
+ * don't understand why it isn't. (I do now; this is the expander not
+ * the port.)
+ */
+
+ debug("looking for /sys/class/scsi_host/host%d/device/port-%d:%d/expander-%d:%d/sas_device/expander-%d:%d/sas_address",
+ scsi_host, scsi_host, port_id, scsi_host, remote_scsi_target, scsi_host, remote_scsi_target);
+ rc = read_sysfs_file(&filebuf,
+ "class/scsi_host/host%d/device/port-%d:%d/expander-%d:%d/sas_device/expander-%d:%d/sas_address",
+ scsi_host, scsi_host, port_id, scsi_host, remote_scsi_target, scsi_host, remote_scsi_target);
+ if (rc < 0 || filebuf == NULL) {
+ debug("didn't find it.");
+ return -1;
+ }
+#else
+ debug("looking for /sys/class/scsi_host/host%d/device/port-%d:%d/expander-%d:%d/port-%d:%d:%d/end_device-%d:%d:%d/sas_device/end_device-%d:%d:%d/sas_address",
+ scsi_host,
+ scsi_host, local_port_id,
+ scsi_host, remote_scsi_target,
+ scsi_host, remote_scsi_target, remote_port_id,
+ scsi_host, remote_scsi_target, remote_port_id,
+ scsi_host, remote_scsi_target, remote_port_id);
+ rc = read_sysfs_file(&filebuf,
+ "class/scsi_host/host%d/device/port-%d:%d/expander-%d:%d/port-%d:%d:%d/end_device-%d:%d:%d/sas_device/end_device-%d:%d:%d/sas_address",
+ scsi_host,
+ scsi_host, local_port_id,
+ scsi_host, remote_scsi_target,
+ scsi_host, remote_scsi_target, remote_port_id,
+ scsi_host, remote_scsi_target, remote_port_id,
+ scsi_host, remote_scsi_target, remote_port_id);
+ if (rc < 0 || filebuf == NULL) {
+ debug("didn't find it.");
+ return -1;
+ }
+#endif
+
+ rc = sscanf((char *)filebuf, "%"PRIx64, sas_address);
+ if (rc != 1)
+ return -1;
+
+ return 0;
+}
+
+static int
+get_local_sas_address(uint64_t *sas_address, struct device *dev)
+{
+ int rc;
+ char *filebuf = NULL;
+
+ rc = read_sysfs_file(&filebuf,
+ "class/block/%s/device/sas_address",
+ dev->disk_name);
+ if (rc < 0 || filebuf == NULL)
+ return -1;
+
+ rc = sscanf((char *)filebuf, "%"PRIx64, sas_address);
+ if (rc != 1)
+ return -1;
+
+ return 0;
+}
+
/*
* support for SAS devices
*
@@ -43,6 +128,24 @@
* /sys/class/block/sdc/device/sas_address
*
* I'm not sure at the moment if they're the same or not.
+ *
+ * There are also other devices that look like:
+ *
+ * 8:0 -> ../../devices/pci0000:74/0000:74:02.0/host2/port-2:0/expander-2:0/port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda
+ * 8:1 -> ../../devices/pci0000:74/0000:74:02.0/host2/port-2:0/expander-2:0/port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda/sda1
+ *
+ * /sys/dev/block/8:0/device -> ../../../2:0:0:0
+ *
+ * This exists:
+ *
+ * /sys/class/scsi_host/host2 -> ../../devices/pci0000:74/0000:74:02.0/host2/scsi_host/host2
+ * /sys/devices/pci0000:74/0000:74:02.0/host2/scsi_host/host2/device -> ../../../host2
+ * /sys/devices/pci0000:74/0000:74:02.0/host2/device -> ../../../host2
+ * /sys/devices/pci0000:74/0000:74:02.0/host2/port-2:0/expander-2:0/sas_device/expander-2:0/sas_address
+ *
+ * but the device doesn't actually have a sas_host_address, because it's on a
+ * port expander, and sas_address doesn't directly exist under /sys/class/
+ * anywhere.
*/
static ssize_t
parse_sas(struct device *dev, const char *current, const char *root UNUSED)
@@ -50,16 +153,19 @@ parse_sas(struct device *dev, const char *current, const char *root UNUSED)
struct stat statbuf = { 0, };
int rc;
uint32_t scsi_host, scsi_bus, scsi_device, scsi_target;
+ uint32_t local_port_id = 0, remote_port_id = 0;
+ uint32_t remote_scsi_target = 0;
uint64_t scsi_lun;
ssize_t pos;
- uint8_t *filebuf = NULL;
- uint64_t sas_address;
+ uint64_t sas_address = 0;
debug("entry");
pos = parse_scsi_link(current, &scsi_host,
&scsi_bus, &scsi_device,
- &scsi_target, &scsi_lun);
+ &scsi_target, &scsi_lun,
+ &local_port_id, &remote_port_id,
+ &remote_scsi_target);
/*
* If we can't parse the scsi data, it isn't a sas device, so return 0
* not error.
@@ -71,6 +177,7 @@ parse_sas(struct device *dev, const char *current, const char *root UNUSED)
* Make sure it has the actual /SAS/ bits before we continue
* validating all this junk.
*/
+ debug("looking for /sys/class/scsi_host/host%d/host_sas_address", scsi_host);
rc = sysfs_stat(&statbuf,
"class/scsi_host/host%d/host_sas_address",
scsi_host);
@@ -79,21 +186,48 @@ parse_sas(struct device *dev, const char *current, const char *root UNUSED)
* 0 not error. Later errors mean it is an ata device, but we can't
* parse it right, so they return -1.
*/
- if (rc < 0)
- return 0;
+ if (rc < 0) {
+ debug("didn't find it.");
+ /*
+ * If it's on a port expander, it won't have the
+ * host_sas_address, so we need to check if it's a sas_host
+ * instead.
+ * It may work to just check this to begin with, but I don't
+ * have such a device in front of me right now.
+ */
+ debug("looking for /sys/class/sas_host/host%d", scsi_host);
+ rc = sysfs_stat(&statbuf,
+ "class/sas_host/host%d", scsi_host);
+ if (rc < 0) {
+ debug("didn't find it.");
+ return 0;
+ }
+ debug("found it.");
- /*
- * we also need to get the actual sas_address from someplace...
- */
- rc = read_sysfs_file(&filebuf,
- "class/block/%s/device/sas_address",
- dev->disk_name);
- if (rc < 0 || filebuf == NULL)
- return -1;
-
- rc = sscanf((char *)filebuf, "%"PRIx64, &sas_address);
- if (rc != 1)
- return -1;
+ /*
+ * So it *is* a sas_host, and we have to fish the sas_address
+ * from the remote port
+ */
+ rc = get_port_expander_sas_address(&sas_address, scsi_host,
+ local_port_id,
+ remote_port_id,
+ remote_scsi_target);
+ if (rc < 0) {
+ debug("Couldn't find port expander sas address");
+ return 0;
+ }
+ } else {
+ /*
+ * we also need to get the actual sas_address from someplace...
+ */
+ debug("found it.");
+ rc = get_local_sas_address(&sas_address, dev);
+ if (rc < 0) {
+ debug("Couldn't find sas address");
+ return 0;
+ }
+ }
+ debug("sas address is 0x%"PRIx64, sas_address);
dev->sas_info.sas_address = sas_address;
diff --git a/src/linux-scsi.c b/src/linux-scsi.c
index 2e4f710badf..a5e81cf9cb6 100644
--- a/src/linux-scsi.c
+++ b/src/linux-scsi.c
@@ -38,7 +38,9 @@
ssize_t HIDDEN
parse_scsi_link(const char *current, uint32_t *scsi_host,
uint32_t *scsi_bus, uint32_t *scsi_device,
- uint32_t *scsi_target, uint64_t *scsi_lun)
+ uint32_t *scsi_target, uint64_t *scsi_lun,
+ uint32_t *local_port_id, uint32_t *remote_port_id,
+ uint32_t *remote_target_id)
{
int rc;
int sz = 0;
@@ -70,11 +72,32 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
* /sys/block/sdc/device looks like:
* device-> ../../../4:2:0:0
*
+ * OR
+ *
+ * 8:0 -> ../../devices/pci0000:74/0000:74:02.0/host2/port-2:0/expander-2:0/port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda
+ * 8:1 -> ../../devices/pci0000:74/0000:74:02.0/host2/port-2:0/expander-2:0/port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda/sda1
+ *
+ * /sys/block/sda/device looks like:
+ * device -> ../../../2:0:0:0 *
+ *
+ * sas_address exists, but it's hard to find:
+ * /sys/devices/pci0000:74/0000:74:02.0/host2/port-2:0/expander-2:0/sas_device/expander-2:0/sas_address
+ * but sas_host_address is nowhere to be found, and sas_address
+ * doesn't directly exist under /sys/class/ anywhere. So you actually
+ * have to go to
+ * /sys/devices/pci0000:74/0000:74:02.0/host2/port-2:0/expander-2:0/sas_device/expander-2:0/sas_address
+ * and chop that off to
+ * /sys/devices/pci0000:74/0000:74:02.0/host2/port-2:0/expander-2:0/
+ * and then add a bunch of port and end device crap to it to get:
+ * /sys/devices/pci0000:74/0000:74:02.0/host2/port-2:0/expander-2:0/port-2:0:2/end_device-2:0:2/sas_device/end_device-2:0:2/sas_address
+
*/
/*
* So we start when current is:
* host4/port-4:0/end_device-4:0/target4:0:0/4:0:0:0/block/sdc/sdc1
+ * or
+ * host2/port-2:0/expander-2:0/port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda/sda1
*/
uint32_t tosser0, tosser1, tosser2;
@@ -91,6 +114,14 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
sz += pos0;
pos0 = 0;
+ /*
+ * We might have this next:
+ * port-2:0/expander-2:0/port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda/sda1
+ * or:
+ * port-2:0/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda/sda1
+ * or maybe (not sure):
+ * port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda/sda1
+ */
debug("searching for port-4:0 or port-4:0:0");
rc = sscanf(current+sz, "port-%d:%d%n:%d%n", &tosser0,
&tosser1, &pos0, &tosser2, &pos1);
@@ -100,6 +131,52 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
if (rc == 2 || rc == 3) {
sz += pos0;
pos0 = 0;
+ if (local_port_id && rc == 2)
+ *local_port_id = tosser1;
+ if (remote_port_id && rc == 3)
+ *remote_port_id = tosser2;
+
+ if (current[sz] == '/')
+ sz += 1;
+
+ /*
+ * We might have this next:
+ * expander-2:0/port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda/sda1
+ * ^ port id
+ * ^ scsi target id
+ * ^ host number
+ * ^ host number
+ * We don't actually care about either number in expander-.../,
+ * because they're replicated in all the other places. We just need
+ * to get past it.
+ */
+ debug("searching for expander-4:0/");
+ rc = sscanf(current+sz, "expander-%d:%d/%n", &tosser0, &tosser1, &pos0);
+ debug("current:\"%s\" rc:%d pos0:%d\n", current+sz, rc, pos0);
+ arrow(LOG_DEBUG, spaces, 9, pos0, rc, 2);
+ if (rc == 2) {
+ if (!remote_target_id) {
+ efi_error("Device is PHY is a remote target, but remote_target_id is NULL");
+ return -1;
+ }
+ *remote_target_id = tosser1;
+ sz += pos0;
+ pos0 = 0;
+
+ /*
+ * if we have that, we should have a 3-part port next
+ */
+ debug("searching for port-2:0:2/");
+ rc = sscanf(current+sz, "port-%d:%d:%d/%n", &tosser0, &tosser1, &tosser2, &pos0);
+ debug("current:\"%s\" rc:%d pos0:%d\n", current+sz, rc, pos0);
+ arrow(LOG_DEBUG, spaces, 9, pos0, rc, 3);
+ if (rc != 3) {
+ efi_error("Couldn't parse port expander port string");
+ return -1;
+ }
+ sz += pos0;
+ }
+ pos0 = 0;
/* next:
* /end_device-4:0
@@ -107,22 +184,24 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
* awesomely these are the exact same fields that go into port-blah,
* but we don't care for now about any of them anyway.
*/
- debug("searching for /end_device-4:0/ or /end_device-4:0:0/");
- rc = sscanf(current + sz, "/end_device-%d:%d%n", &tosser0, &tosser1, &pos0);
+ debug("searching for end_device-4:0/ or end_device-4:0:0/");
+ rc = sscanf(current + sz, "end_device-%d:%d%n", &tosser0, &tosser1, &pos0);
debug("current:\"%s\" rc:%d pos0:%d\n", current+sz, rc, pos0);
- arrow(LOG_DEBUG, spaces, 9, pos0, rc, 2);
if (rc != 2)
return -1;
- sz += pos0;
- pos0 = 0;
- rc = sscanf(current + sz, ":%d%n", &tosser0, &pos0);
- debug("current:\"%s\" rc:%d pos0:%d\n", current+sz, rc, pos0);
- arrow(LOG_DEBUG, spaces, 9, pos0, rc, 2);
+ pos1 = 0;
+ rc = sscanf(current + sz + pos0, ":%d%n", &tosser2, &pos1);
+ arrow(LOG_DEBUG, spaces, 9, pos0, rc + 2, 2);
+ arrow(LOG_DEBUG, spaces, 9, pos0 + pos1, rc + 2, 3);
if (rc != 0 && rc != 1)
return -1;
- sz += pos0;
- pos0 = 0;
+ if (remote_port_id && rc == 1)
+ *remote_port_id = tosser2;
+ if (local_port_id && rc == 0)
+ *local_port_id = tosser1;
+ sz += pos0 + pos1;
+ pos0 = pos1 = 0;
if (current[sz] == '/')
sz += 1;
@@ -156,6 +235,7 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
return -1;
sz += pos0;
+ debug("returning %d", sz);
return sz;
}
@@ -191,7 +271,8 @@ parse_scsi(struct device *dev, const char *current, const char *root UNUSED)
sz = parse_scsi_link(current, &scsi_host,
&scsi_bus, &scsi_device,
- &scsi_target, &scsi_lun);
+ &scsi_target, &scsi_lun,
+ NULL, NULL, NULL);
if (sz < 0)
return 0;
diff --git a/src/linux.h b/src/linux.h
index 7c7ea91e771..43a9b7899f5 100644
--- a/src/linux.h
+++ b/src/linux.h
@@ -267,8 +267,10 @@ struct dev_probe {
};
extern ssize_t parse_scsi_link(const char *current, uint32_t *host,
- uint32_t *bus, uint32_t *device,
- uint32_t *target, uint64_t *lun);
+ uint32_t *bus, uint32_t *device,
+ uint32_t *target, uint64_t *lun,
+ uint32_t *local_port_id, uint32_t *remote_port_id,
+ uint32_t *remote_target_id);
/* device support implementations */
extern struct dev_probe pmem_parser;
--
2.17.1

309
SPECS/efivar.spec Normal file
View File

@ -0,0 +1,309 @@
Name: efivar
Version: 36
Release: 1%{?dist}
Summary: Tools to manage UEFI variables
License: LGPLv2.1
URL: https://github.com/rhboot/efivar
Requires: %{name}-libs = %{version}-%{release}
ExclusiveArch: %{ix86} x86_64 aarch64 %{arm}
BuildRequires: popt-devel git glibc-static libabigail
# please don't fix this to reflect github's incomprehensible url that goes
# to a different tarball.
Source0: https://github.com/rhboot/efivar/archive/efivar-%{version}.tar.bz2
Patch0001: 0001-Move-the-syntastic-file-I-use-out-of-the-repo.patch
Patch0002: 0002-Move-verbosity-headers-to-be-public.patch
Patch0003: 0003-Pacify-some-coverity-nits.patch
Patch0004: 0004-efivar-Fix-some-types-in-L-behavior-to-pacify-coveri.patch
Patch0005: 0005-Promote-_make_hd_dn-to-make_hd_dn-and-get-rid-of-the.patch
Patch0006: 0006-Try-to-convince-covscan-that-sysfs_read_file-doesn-t.patch
Patch0007: 0007-Make-efidp_make_file-have-even-more-better-input-con.patch
Patch0008: 0008-Make-path-helpers.c-also-import-fix_coverity.h.patch
Patch0009: 0009-Fix-a-makeguids-building-problem-with-generics.h.patch
Patch0010: 0010-Improve-ACPI-device-path-formatting.patch
Patch0011: 0011-Give-linux-s-parse-functions-the-unmodified-device-l.patch
Patch0012: 0012-Move-ACPI-ID-parsing-to-a-shared-location.patch
Patch0013: 0013-Make-a-platform-ACPI-root-parser-separate-from-PCI-r.patch
Patch0014: 0014-Make-a-way-to-say-e-3-isn-t-viable-for-a-kind-of-dev.patch
Patch0015: 0015-Make-a-linux-device-root-for-SOC-devices-that-use-FD.patch
Patch0016: 0016-If-we-can-t-parse-part-of-the-device-link-skip-it-an.patch
Patch0017: 0017-Pacify-clang-analyzer-just-a-little.patch
Patch0018: 0018-Try-even-harder-to-convince-coverity-that-get_file-i.patch
Patch0019: 0019-Make-the-debug-code-less-intrusive.patch
Patch0020: 0020-efiboot-Make-the-device-node-skipping-code-pass-cove.patch
Patch0021: 0021-efiboot-don-t-error-on-unknown-type-with-DEV_ABBREV_.patch
Patch0022: 0022-efiboot-fix-a-bad-error-check.patch
Patch0023: 0023-efiboot-parse_scsi_link-fix-the-offset-searching-for.patch
Patch0024: 0024-Coverity-still-doesn-t-believe-in-error-codes.patch
Patch0025: 0025-Don-t-require-NVME-to-have-an-EUI.patch
Patch0026: 0026-makeguids-initialize-memory.patch
Patch0027: 0027-emmc_parser-add-emmc_parser.patch
Patch0028: 0028-abignore-work-around-an-abidw-bug.patch
Patch0029: 0029-Update-abidw-for-newer-tools.patch
Patch0030: 0030-linux-emmc-update-for-internal-API-breakage.patch
Patch0031: 0031-Fix-another-buggy-fake-acpi-pci-root-driver.patch
Patch0032: 0032-Fix-dev-probes-intialization-test.patch
Patch0033: 0033-Deal-with-devices-that-don-t-have-a-device-link-in-s.patch
Patch0034: 0034-Handle-partition-name-parsing-and-formatting-for-par.patch
Patch0035: 0035-Fix-partition-number-detection-when-it-s-not-provide.patch
Patch0036: 0036-dp-acpi-fix-HID-vs-HID_EX-formatting-bug.patch
Patch0037: 0037-Support-decoding-ACPI-Generic-Container-and-Embedded.patch
Patch0038: 0038-pci-root-actually-create-the-device-path-node.patch
Patch0039: 0039-sas-handle-port-expanders-at-all.patch
%description
efivar provides a simple command line interface to the UEFI variable facility.
%package libs
Summary: Library to manage UEFI variables
%description libs
Library to allow for the simple manipulation of UEFI variables.
%package devel
Summary: Development headers for libefivar
Requires: %{name}-libs = %{version}-%{release}
%description devel
development headers required to use libefivar.
%prep
%setup -q -n %{name}-%{version}
git init
git config user.email "%{name}-owner@fedoraproject.org"
git config user.name "Fedora Ninjas"
git add .
git commit -a -q -m "%{version} baseline."
git am %{patches} </dev/null
git config --unset user.email
git config --unset user.name
%build
make libdir=%{_libdir} bindir=%{_bindir} CFLAGS="$RPM_OPT_FLAGS -flto" LDFLAGS="$RPM_LD_FLAGS -flto"
%install
%makeinstall
%check
%ifarch x86_64
#make abicheck
%endif
%post libs -p /sbin/ldconfig
%postun libs -p /sbin/ldconfig
%files
%{!?_licensedir:%global license %%doc}
%license COPYING
%doc README.md
%{_bindir}/efivar
%exclude %{_bindir}/efivar-static
%{_mandir}/man1/*
%files devel
%{_mandir}/man3/*
%{_includedir}/*
%{_libdir}/*.so
%{_libdir}/pkgconfig/*.pc
%files libs
%{_libdir}/*.so.*
%changelog
* Tue Oct 02 2018 Peter Jones <pjones@redhat.com> - 36-1
- Update to efivar 36 (and some change)
Resolves: rhbz#1635019
- Add NVDIMM support
- Re-written linux interface parser to handle how devices are
partitioned better, and for cleaner code, with one file per device
type.
- lots of verbosity updates
- better CI
- analysis with clang's analyzer as well as coverity
- Better handling of immutable bits in sysfs
- LIBEFIVAR_OPS=help
- lots of code cleanups.
- Add emmc device support
- Add SAS port expander support
- Support for ACPI root nodes that are less common
(i.e. ACPI Generic Container and Embedded Controller PNP nodes)
- Make abbreviated device paths if we can't parse a device's info
- Don't require NVME to have an EUI
* Mon Apr 09 2018 Peter Jones <pjones@redhat.com> - 35-1
- Update to efivar 35
- fixes for older compilers
- efi_get_variable_exists()
- Lots of stuff to make CI work.
- use usleep() to avoid hitting the kernel rate limiter on efivarfs
- better EFI_GUID macro
- add efi_guid_fwupdate (0abba7dc-e516-4167-bbf5-4d9d1c739416)
* Tue Feb 27 2018 Peter Jones <pjones@redhat.com> - 34-1
- Update to efivar 34, and include a patch to avoid upstream rate limiting.
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 33-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Tue Jan 30 2018 Peter Robinson <pbrobinson@fedoraproject.org> 33-2
- Enable ARMv7, minor spec cleanups
* Tue Jan 23 2018 Peter Jones <pjones@redhat.com> - 33-1
- Add NVDIMM support
- Bump version to 33
* Tue Sep 12 2017 Peter Jones <pjones@redhat.com> - 32-2
- Make efi_guid_ux_capsule actually get exported right.
* Tue Sep 12 2017 Peter Jones <pjones@redhat.com> - 32-1
- efivar 32
- lots of coverity fixes; mostly leaked memory and fds and the like
- fix sysfs pci path formats
- handle device paths for dns, nfit, bluetooth, wifi, emmc, btle.
- improved abi checking on releases
- Fix failures on EDIT_WRITE in edit_variable() when the variable doesn't exist
- Add efi_guid_ux_capsule_guid to our guids
- Now with %%check
* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 31-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 31-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Mon Mar 06 2017 Peter Jones <pjones@redhat.com> - 31-1
- Update to efivar 31
- Work around NVMe EUI sysfs change
- Provide some oldish version strings we should have kept.
- lots of overflow checking on our pointer math in dp parsing
- fix major/minor device number handling in the linux code
- Do better formatting checks for MBR partitions
- Fixes for gcc 7
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 30-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Mon Oct 17 2016 Peter Jones <pjones@redhat.com> - 30-4
- Handle NVMe device attributes paths moving around in sysfs.
* Wed Sep 28 2016 Peter Jones <pjones@redhat.com> - 30-3
- Maybe even provide the *right* old linker deps.
* Tue Sep 27 2016 Peter Jones <pjones@redhat.com> - 30-2
- Try not to screw up SONAME stuff quite so badly.
* Tue Sep 27 2016 Peter Jones <pjones@redhat.com> - 30-1
- Fix efidp_*() functions with __pure__ that break with some optimizations
- Fix NVMe EUI parsing.
* Tue Sep 27 2016 Peter Jones <pjones@redhat.com> - 29-1
- Use -pie not -PIE in our linker config
- Fix some overflow checks for gcc < 5.x
- Make variable class probes other than the first one actually work
- Move -flto to CFLAGS
- Pack all of the efi device path headers
- Fix redundant decl of efi_guid_zero()
* Wed Aug 17 2016 Peter Jones <pjones@redhat.com> - 28-1
- Make our sonames always lib$FOO.1 , not lib$FOO.$VERSION .
* Tue Aug 16 2016 Peter Jones <pjones@redhat.com> - 27-1
- Bug fix for 086eeb17 in efivar 26.
* Wed Aug 10 2016 Peter Jones <pjones@redhat.com> - 26-1
- Update to efivar-26 .
* Thu Jun 30 2016 Peter Jones <pjones@redhat.com> - 0.24-1
- Update to 0.24
* Mon Feb 15 2016 Peter Jones <pjones@redhat.com> - 0.23-1
- Update to 0.23
* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 0.21-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Mon Nov 02 2015 Peter Jones <pjones@redhat.com> - 0.21-2
- Bump the release here so f22->f23->f24 updates work.
* Mon Jul 13 2015 Peter Jones <pjones@redhat.com> - 0.21-1
- Rename "make test" so packagers don't think it's a good idea to run it
during builds.
- Error check sizes in vars_get_variable()
- Fix some file size comparisons
- make SONAME reflect the correct values.
- Fix some uses of "const"
- Compile with -O2 by default
- Fix some strict-aliasing violations
- Fix some of the .pc files and how we do linking to work better.
* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.20-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
* Tue Jun 02 2015 Peter Jones <pjones@redhat.com> - 0.20-1
- Update to 0.20
- Make sure tester is build with the right link order for libraries.
- Adjust linker order for pkg-config
- Work around LocateDevicePath() not grokking PcieRoot() devices properly.
- Rectify some missing changelog entries
* Thu May 28 2015 Peter Jones <pjones@redhat.com> - 0.19-1
- Update to 0.19
- add API from efibootmgr so fwupdate and other tools can use it.
* Wed Oct 15 2014 Peter Jones <pjones@redhat.com> - 0.15-1
- Update to 0.15
- Make 32-bit builds set variables' DataSize correctly.
* Wed Oct 08 2014 Peter Jones <pjones@redhat.com> - 0.14-1
- Update to 0.14
- add efi_id_guid_to_guid() and efi_guid_to_id_guid(), which support {ID GUID}
as a concept.
- Add some vendor specific guids to our guid list.
- Call "empty" "zero" now, as many other places do. References to
efi_guid_is_empty() and efi_guid_empty still exist for ABI compatibility.
- add "efivar -L" to the man page.
* Tue Oct 07 2014 Peter Jones <pjones@redhat.com> - 0.13-1
- Update to 0.13:
- add efi_symbol_to_guid()
- efi_name_to_guid() will now fall back on efi_symbol_to_guid() as a last
resort
- "efivar -L" to list all the guids we know about
- better namespacing on libefivar.so (rename well_known_* -> efi_well_known_*)
* Thu Sep 25 2014 Peter Jones <pjones@redhat.com> - 0.12-1
- Update to 0.12
* Wed Aug 20 2014 Peter Jones <pjones@redhat.com> - 0.11-1
- Update to 0.11
* Fri May 02 2014 Peter Jones <pjones@redhat.com> - 0.10-1
- Update package to 0.10.
- Fixes a build error due to different cflags in the builders vs updstream
makefile.
* Fri May 02 2014 Peter Jones <pjones@redhat.com> - 0.9-0.1
- Update package to 0.9.
* Tue Apr 01 2014 Peter Jones <pjones@redhat.com> - 0.8-0.1
- Update package to 0.8 as well.
* Fri Oct 25 2013 Peter Jones <pjones@redhat.com> - 0.7-1
- Update package to 0.7
- adds --append support to the binary.
* Fri Sep 06 2013 Peter Jones <pjones@redhat.com> - 0.6-1
- Update package to 0.6
- fixes to documentation from lersek
- more validation of uefi guids
- use .xz for archives
* Thu Sep 05 2013 Peter Jones <pjones@redhat.com> - 0.5-0.1
- Update to 0.5
* Mon Jun 17 2013 Peter Jones <pjones@redhat.com> - 0.4-0.2
- Fix ldconfig invocation
* Mon Jun 17 2013 Peter Jones <pjones@redhat.com> - 0.4-0.1
- Initial spec file