Commit a1eb9a1720 for qemu.org

commit a1eb9a1720eb2738a54fa16ff9fe4ce0b9da9caf
Author: Stian Halseth <stian@itx.no>
Date:   Sat Oct 31 10:48:41 2026 +0100

    hw/sparc64: Pass hwcap-list to OpenBIOS via fw_cfg

    Linux needs hwcap-list to enable crypto instructions, but only sun4v
    firmware provides it.

    When the CPU has crypto, pass the list through fw_cfg for OpenBIOS
    to copy onto the cpu node as qemu,hwcap-list. Include the capabilities
    linux-user reports, since Linux trusts the list instead of guessing.

    Without crypto, nothing changes.

    Signed-off-by: Stian Halseth <stian@itx.no>
    Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
    Message-ID: <20261031094841.3407049-1-stian@itx.no>
    Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index a348096aee..1057c59152 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -121,6 +121,52 @@ static void fw_cfg_boot_set(void *opaque, const char *boot_device,
     fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
 }

+/*
+ * OpenBIOS copies this list to the cpu node's qemu,hwcap-list property
+ * for Linux, which gets it from the machine description on sun4v.
+ */
+static void fw_cfg_build_hwcap_list(FWCfgState *fw_cfg, SPARCCPU *cpu)
+{
+    static const struct {
+        uint32_t mask;
+        const char *name;
+    } capabilities[] = {
+        { 0, "popc" },
+        { CPU_FEATURE_FSMULD, "fsmuld" },
+        { CPU_FEATURE_VIS1, "vis" },
+        { CPU_FEATURE_VIS2, "vis2" },
+        { CPU_FEATURE_FMAF, "fmaf" },
+        { CPU_FEATURE_VIS3, "vis3" },
+        { CPU_FEATURE_IMA, "ima" },
+        /* The groups in the CFR value, see CFR_* in target/sparc/translate.c */
+        { CPU_FEATURE_CRYPTO, "aes" },
+        { CPU_FEATURE_CRYPTO, "sha1" },
+        { CPU_FEATURE_CRYPTO, "sha256" },
+        { CPU_FEATURE_CRYPTO, "sha512" },
+        { CPU_FEATURE_CRYPTO, "crc32c" },
+    };
+    uint32_t features = cpu->env.def.features;
+    GByteArray *array;
+    size_t len;
+
+    if (!(features & CPU_FEATURE_CRYPTO)) {
+        return;
+    }
+
+    array = g_byte_array_new();
+    for (size_t i = 0; i < ARRAY_SIZE(capabilities); i++) {
+        if ((features & capabilities[i].mask) == capabilities[i].mask) {
+            const char *name = capabilities[i].name;
+
+            g_byte_array_append(array, (const guint8 *)name, strlen(name) + 1);
+        }
+    }
+
+    len = array->len;
+    fw_cfg_add_file(fw_cfg, "etc/sparc64/hwcap-list",
+                    g_byte_array_free(array, FALSE), len);
+}
+
 static int sun4u_NVRAM_set_params(Nvram *nvram, uint16_t NVRAM_size,
                                   const char *arch, ram_addr_t RAM_size,
                                   const char *boot_devices,
@@ -717,6 +763,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height);
     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_DEPTH, graphic_depth);
+    fw_cfg_build_hwcap_list(fw_cfg, cpu);

     qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);