Blame packages/q/qemu/bios-tables-test-teach-test-to-use-smbio.patch

Bernhard M. Wiedemann 399b1f
From: Julia Suvorova <jusual@redhat.com>
Bernhard M. Wiedemann 399b1f
Date: Tue, 11 Oct 2022 13:17:28 +0200
Bernhard M. Wiedemann 399b1f
Subject: bios-tables-test: teach test to use smbios 3.0 tables
Bernhard M. Wiedemann 399b1f
Bernhard M. Wiedemann 399b1f
Introduce the 64-bit entry point. Since we no longer have a total
Bernhard M. Wiedemann 399b1f
number of structures, stop checking for the new ones at the EOF
Bernhard M. Wiedemann 399b1f
structure (type 127).
Bernhard M. Wiedemann 399b1f
Bernhard M. Wiedemann 399b1f
Signed-off-by: Julia Suvorova <jusual@redhat.com>
Bernhard M. Wiedemann 399b1f
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Bernhard M. Wiedemann 399b1f
Message-Id: <20220731162141.178443-3-jusual@redhat.com>
Bernhard M. Wiedemann 399b1f
Message-Id: <20221011111731.101412-3-jusual@redhat.com>
Bernhard M. Wiedemann 399b1f
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Bernhard M. Wiedemann 399b1f
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Bernhard M. Wiedemann 399b1f
(cherry picked from commit 33bff4a85a2e4ad94899ecb15b6a91c8b64a6dcf)
Bernhard M. Wiedemann 399b1f
References: bsc#1202282, jsc#PED-2592
Bernhard M. Wiedemann 399b1f
Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
Bernhard M. Wiedemann 399b1f
---
Bernhard M. Wiedemann 399b1f
 tests/qtest/bios-tables-test.c | 100 +++++++++++++++++++++++++--------
Bernhard M. Wiedemann 399b1f
 1 file changed, 76 insertions(+), 24 deletions(-)
Bernhard M. Wiedemann 399b1f
Bernhard M. Wiedemann 399b1f
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
Bernhard M. Wiedemann 399b1f
index 7c5f736b513abbda7803afb2d28f..dcda3c508a77854415dad76998cc 100644
Bernhard M. Wiedemann 399b1f
--- a/tests/qtest/bios-tables-test.c
Bernhard M. Wiedemann 399b1f
+++ b/tests/qtest/bios-tables-test.c
Bernhard M. Wiedemann 399b1f
@@ -88,8 +88,8 @@ typedef struct {
Bernhard M. Wiedemann 399b1f
     uint64_t rsdp_addr;
Bernhard M. Wiedemann 399b1f
     uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */];
Bernhard M. Wiedemann 399b1f
     GArray *tables;
Bernhard M. Wiedemann 399b1f
-    uint32_t smbios_ep_addr;
Bernhard M. Wiedemann 399b1f
-    struct smbios_21_entry_point smbios_ep_table;
Bernhard M. Wiedemann 399b1f
+    uint64_t smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE__MAX];
Bernhard M. Wiedemann 399b1f
+    SmbiosEntryPoint smbios_ep_table;
Bernhard M. Wiedemann 399b1f
     uint16_t smbios_cpu_max_speed;
Bernhard M. Wiedemann 399b1f
     uint16_t smbios_cpu_curr_speed;
Bernhard M. Wiedemann 399b1f
     uint8_t *required_struct_types;
Bernhard M. Wiedemann 399b1f
@@ -533,10 +533,9 @@ static void test_acpi_asl(test_data *data)
Bernhard M. Wiedemann 399b1f
     free_test_data(&exp_data);
Bernhard M. Wiedemann 399b1f
 }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
-static bool smbios_ep_table_ok(test_data *data)
Bernhard M. Wiedemann 399b1f
+static bool smbios_ep2_table_ok(test_data *data, uint32_t addr)
Bernhard M. Wiedemann 399b1f
 {
Bernhard M. Wiedemann 399b1f
-    struct smbios_21_entry_point *ep_table = &data->smbios_ep_table;
Bernhard M. Wiedemann 399b1f
-    uint32_t addr = data->smbios_ep_addr;
Bernhard M. Wiedemann 399b1f
+    struct smbios_21_entry_point *ep_table = &data->smbios_ep_table.ep21;
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
     qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
Bernhard M. Wiedemann 399b1f
     if (memcmp(ep_table->anchor_string, "_SM_", 4)) {
Bernhard M. Wiedemann 399b1f
@@ -559,13 +558,29 @@ static bool smbios_ep_table_ok(test_data *data)
Bernhard M. Wiedemann 399b1f
     return true;
Bernhard M. Wiedemann 399b1f
 }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
-static void test_smbios_entry_point(test_data *data)
Bernhard M. Wiedemann 399b1f
+static bool smbios_ep3_table_ok(test_data *data, uint64_t addr)
Bernhard M. Wiedemann 399b1f
+{
Bernhard M. Wiedemann 399b1f
+    struct smbios_30_entry_point *ep_table = &data->smbios_ep_table.ep30;
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+    qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
Bernhard M. Wiedemann 399b1f
+    if (memcmp(ep_table->anchor_string, "_SM3_", 5)) {
Bernhard M. Wiedemann 399b1f
+        return false;
Bernhard M. Wiedemann 399b1f
+    }
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+    if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table)) {
Bernhard M. Wiedemann 399b1f
+        return false;
Bernhard M. Wiedemann 399b1f
+    }
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+    return true;
Bernhard M. Wiedemann 399b1f
+}
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+static SmbiosEntryPointType test_smbios_entry_point(test_data *data)
Bernhard M. Wiedemann 399b1f
 {
Bernhard M. Wiedemann 399b1f
     uint32_t off;
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
     /* find smbios entry point structure */
Bernhard M. Wiedemann 399b1f
     for (off = 0xf0000; off < 0x100000; off += 0x10) {
Bernhard M. Wiedemann 399b1f
-        uint8_t sig[] = "_SM_";
Bernhard M. Wiedemann 399b1f
+        uint8_t sig[] = "_SM_", sig3[] = "_SM3_";
Bernhard M. Wiedemann 399b1f
         int i;
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
         for (i = 0; i < sizeof sig - 1; ++i) {
Bernhard M. Wiedemann 399b1f
@@ -574,14 +589,30 @@ static void test_smbios_entry_point(test_data *data)
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
         if (!memcmp(sig, "_SM_", sizeof sig)) {
Bernhard M. Wiedemann 399b1f
             /* signature match, but is this a valid entry point? */
Bernhard M. Wiedemann 399b1f
-            data->smbios_ep_addr = off;
Bernhard M. Wiedemann 399b1f
-            if (smbios_ep_table_ok(data)) {
Bernhard M. Wiedemann 399b1f
+            if (smbios_ep2_table_ok(data, off)) {
Bernhard M. Wiedemann 399b1f
+                data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] = off;
Bernhard M. Wiedemann 399b1f
+            }
Bernhard M. Wiedemann 399b1f
+        }
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+        for (i = 0; i < sizeof sig3 - 1; ++i) {
Bernhard M. Wiedemann 399b1f
+            sig3[i] = qtest_readb(data->qts, off + i);
Bernhard M. Wiedemann 399b1f
+        }
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+        if (!memcmp(sig3, "_SM3_", sizeof sig3)) {
Bernhard M. Wiedemann 399b1f
+            if (smbios_ep3_table_ok(data, off)) {
Bernhard M. Wiedemann 399b1f
+                data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] = off;
Bernhard M. Wiedemann 399b1f
+                /* found 64-bit entry point, no need to look for 32-bit one */
Bernhard M. Wiedemann 399b1f
                 break;
Bernhard M. Wiedemann 399b1f
             }
Bernhard M. Wiedemann 399b1f
         }
Bernhard M. Wiedemann 399b1f
     }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
-    g_assert_cmphex(off, <, 0x100000);
Bernhard M. Wiedemann 399b1f
+    /* found at least one entry point */
Bernhard M. Wiedemann 399b1f
+    g_assert_true(data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] ||
Bernhard M. Wiedemann 399b1f
+                  data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64]);
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+    return data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] ?
Bernhard M. Wiedemann 399b1f
+           SMBIOS_ENTRY_POINT_TYPE_64 : SMBIOS_ENTRY_POINT_TYPE_32;
Bernhard M. Wiedemann 399b1f
 }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
 static inline bool smbios_single_instance(uint8_t type)
Bernhard M. Wiedemann 399b1f
@@ -625,16 +656,23 @@ static bool smbios_cpu_test(test_data *data, uint32_t addr)
Bernhard M. Wiedemann 399b1f
     return true;
Bernhard M. Wiedemann 399b1f
 }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
-static void test_smbios_structs(test_data *data)
Bernhard M. Wiedemann 399b1f
+static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type)
Bernhard M. Wiedemann 399b1f
 {
Bernhard M. Wiedemann 399b1f
     DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
Bernhard M. Wiedemann 399b1f
-    struct smbios_21_entry_point *ep_table = &data->smbios_ep_table;
Bernhard M. Wiedemann 399b1f
-    uint32_t addr = le32_to_cpu(ep_table->structure_table_address);
Bernhard M. Wiedemann 399b1f
-    int i, len, max_len = 0;
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+    SmbiosEntryPoint *ep_table = &data->smbios_ep_table;
Bernhard M. Wiedemann 399b1f
+    int i = 0, len, max_len = 0;
Bernhard M. Wiedemann 399b1f
     uint8_t type, prv, crt;
Bernhard M. Wiedemann 399b1f
+    uint64_t addr;
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+    if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) {
Bernhard M. Wiedemann 399b1f
+        addr = le32_to_cpu(ep_table->ep21.structure_table_address);
Bernhard M. Wiedemann 399b1f
+    } else {
Bernhard M. Wiedemann 399b1f
+        addr = le64_to_cpu(ep_table->ep30.structure_table_address);
Bernhard M. Wiedemann 399b1f
+    }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
     /* walk the smbios tables */
Bernhard M. Wiedemann 399b1f
-    for (i = 0; i < le16_to_cpu(ep_table->number_of_structures); i++) {
Bernhard M. Wiedemann 399b1f
+    do {
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
         /* grab type and formatted area length from struct header */
Bernhard M. Wiedemann 399b1f
         type = qtest_readb(data->qts, addr);
Bernhard M. Wiedemann 399b1f
@@ -660,19 +698,33 @@ static void test_smbios_structs(test_data *data)
Bernhard M. Wiedemann 399b1f
         }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
         /* keep track of max. struct size */
Bernhard M. Wiedemann 399b1f
-        if (max_len < len) {
Bernhard M. Wiedemann 399b1f
+        if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 && max_len < len) {
Bernhard M. Wiedemann 399b1f
             max_len = len;
Bernhard M. Wiedemann 399b1f
-            g_assert_cmpuint(max_len, <=, ep_table->max_structure_size);
Bernhard M. Wiedemann 399b1f
+            g_assert_cmpuint(max_len, <=, ep_table->ep21.max_structure_size);
Bernhard M. Wiedemann 399b1f
         }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
         /* start of next structure */
Bernhard M. Wiedemann 399b1f
         addr += len;
Bernhard M. Wiedemann 399b1f
-    }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
-    /* total table length and max struct size must match entry point values */
Bernhard M. Wiedemann 399b1f
-    g_assert_cmpuint(le16_to_cpu(ep_table->structure_table_length), ==,
Bernhard M. Wiedemann 399b1f
-                     addr - le32_to_cpu(ep_table->structure_table_address));
Bernhard M. Wiedemann 399b1f
-    g_assert_cmpuint(le16_to_cpu(ep_table->max_structure_size), ==, max_len);
Bernhard M. Wiedemann 399b1f
+    /*
Bernhard M. Wiedemann 399b1f
+     * Until all structures have been scanned (ep21)
Bernhard M. Wiedemann 399b1f
+     * or an EOF structure is found (ep30)
Bernhard M. Wiedemann 399b1f
+     */
Bernhard M. Wiedemann 399b1f
+    } while (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 ?
Bernhard M. Wiedemann 399b1f
+                ++i < le16_to_cpu(ep_table->ep21.number_of_structures) :
Bernhard M. Wiedemann 399b1f
+                type != 127);
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+    if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) {
Bernhard M. Wiedemann 399b1f
+        /*
Bernhard M. Wiedemann 399b1f
+         * Total table length and max struct size
Bernhard M. Wiedemann 399b1f
+         * must match entry point values
Bernhard M. Wiedemann 399b1f
+         */
Bernhard M. Wiedemann 399b1f
+        g_assert_cmpuint(le16_to_cpu(ep_table->ep21.structure_table_length), ==,
Bernhard M. Wiedemann 399b1f
+            addr - le32_to_cpu(ep_table->ep21.structure_table_address));
Bernhard M. Wiedemann 399b1f
+
Bernhard M. Wiedemann 399b1f
+        g_assert_cmpuint(le16_to_cpu(ep_table->ep21.max_structure_size), ==,
Bernhard M. Wiedemann 399b1f
+            max_len);
Bernhard M. Wiedemann 399b1f
+    }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
     /* required struct types must all be present */
Bernhard M. Wiedemann 399b1f
     for (i = 0; i < data->required_struct_types_len; i++) {
Bernhard M. Wiedemann 399b1f
@@ -756,8 +808,8 @@ static void test_acpi_one(const char *params, test_data *data)
Bernhard M. Wiedemann 399b1f
      * https://bugs.launchpad.net/qemu/+bug/1821884
Bernhard M. Wiedemann 399b1f
      */
Bernhard M. Wiedemann 399b1f
     if (!use_uefi) {
Bernhard M. Wiedemann 399b1f
-        test_smbios_entry_point(data);
Bernhard M. Wiedemann 399b1f
-        test_smbios_structs(data);
Bernhard M. Wiedemann 399b1f
+        SmbiosEntryPointType ep_type = test_smbios_entry_point(data);
Bernhard M. Wiedemann 399b1f
+        test_smbios_structs(data, ep_type);
Bernhard M. Wiedemann 399b1f
     }
Bernhard M. Wiedemann 399b1f
 
Bernhard M. Wiedemann 399b1f
     qtest_quit(data->qts);