]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
vmm: Add smbios_find_oem_string()
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 30 Jan 2023 15:26:14 +0000 (16:26 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 23 Feb 2023 08:50:18 +0000 (09:50 +0100)
This function can be used to find SMBIOS strings in the SMBIOS Type 11
table.

src/boot/efi/vmm.c
src/boot/efi/vmm.h

index c526ca08548658af30ffff129d758660e9809176..1e6d4de4a6395e3082569d91bd131ab2b45dd967 100644 (file)
@@ -204,6 +204,12 @@ typedef struct {
         uint8_t bios_characteristics_ext[2];
 } _packed_ SmbiosTableType0;
 
+typedef struct {
+        SmbiosHeader header;
+        uint8_t count;
+        char contents[];
+} _packed_ SmbiosTableType11;
+
 static const void *find_smbios_configuration_table(uint64_t *ret_size) {
         assert(ret_size);
 
@@ -224,7 +230,7 @@ static const void *find_smbios_configuration_table(uint64_t *ret_size) {
         return NULL;
 }
 
-static const SmbiosHeader *get_smbios_table(uint8_t type) {
+static const SmbiosHeader *get_smbios_table(uint8_t type, uint64_t *ret_size_left) {
         uint64_t size = 0;
         const uint8_t *p = find_smbios_configuration_table(&size);
         if (!p)
@@ -243,8 +249,11 @@ static const SmbiosHeader *get_smbios_table(uint8_t type) {
                 if (size < header->length)
                         return NULL;
 
-                if (header->type == type)
+                if (header->type == type) {
+                        if (ret_size_left)
+                                *ret_size_left = size;
                         return header; /* Yay! */
+                }
 
                 /* Skip over formatted area. */
                 size -= header->length;
@@ -276,7 +285,7 @@ static const SmbiosHeader *get_smbios_table(uint8_t type) {
 
 static bool smbios_in_hypervisor(void) {
         /* Look up BIOS Information (Type 0). */
-        const SmbiosTableType0 *type0 = (const SmbiosTableType0 *) get_smbios_table(0);
+        const SmbiosTableType0 *type0 = (const SmbiosTableType0 *) get_smbios_table(0, NULL);
         if (!type0 || type0->header.length < sizeof(SmbiosTableType0))
                 return false;
 
@@ -292,3 +301,32 @@ bool in_hypervisor(void) {
         cache = cpuid_in_hypervisor() || smbios_in_hypervisor();
         return cache;
 }
+
+const char* smbios_find_oem_string(const char *name) {
+        uint64_t left;
+
+        assert(name);
+
+        const SmbiosTableType11 *type11 = (const SmbiosTableType11 *) get_smbios_table(11, &left);
+        if (!type11 || type11->header.length < sizeof(SmbiosTableType11))
+                return NULL;
+
+        assert(left >= type11->header.length);
+
+        const char *s = type11->contents;
+        left -= type11->header.length;
+
+        for (const char *p = s; p < s + left; ) {
+                const char *e = memchr(p, 0, s + left - p);
+                if (!e || e == p) /* Double NUL byte means we've reached the end of the OEM strings. */
+                        break;
+
+                const char *eq = startswith8(p, name);
+                if (eq && *eq == '=')
+                        return eq + 1;
+
+                p = e + 1;
+        }
+
+        return NULL;
+}
index 32f4fa3345e3ca0e9d3b44b597639436a553abdd..061ad692ec51479de00c48379b14e3dff6bf6782 100644 (file)
@@ -7,3 +7,5 @@ bool is_direct_boot(EFI_HANDLE device);
 EFI_STATUS vmm_open(EFI_HANDLE *ret_qemu_dev, EFI_FILE **ret_qemu_dir);
 
 bool in_hypervisor(void);
+
+const char* smbios_find_oem_string(const char *name);