On 28/10/2026 19:07, Stian Halseth wrote:
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. Include the capabilities linux-user reports,
since Linux trusts the list instead of guessing.
Without crypto, nothing changes.
Signed-off-by: Stian Halseth <[email protected]>
---
Based-on: <[email protected]>
This exposes the crypto hwcap to guests, so it should land after the
block-init series, which glibc's memset needs.
The OpenBIOS side, which copies the file onto the cpu node, is on the
OpenBIOS list as "SPARC64: set hwcap-list on the cpu node from fw_cfg".
The kernel change to read the property on sun4u goes to sparclinux.
hw/sparc64/sun4u.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index a348096aee..7e38a55102 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -121,6 +121,51 @@ 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 hwcap-list property
+ * for Linux, which gets it from the machine description on sun4v.
+ */
I wonder if we need to make it more obvious via the property name that this is
something that is not present on real hardware? As a lot of people use QEMU for
testing SPARC installations, we should make sure that people understand this property
is not expected to be present outside of an emulated environment.
+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" },
+ { CPU_FEATURE_CRYPTO, "aes" },
+ { CPU_FEATURE_CRYPTO, "sha1" },
+ { CPU_FEATURE_CRYPTO, "sha256" },
+ { CPU_FEATURE_CRYPTO, "sha512" },
+ { CPU_FEATURE_CRYPTO, "crc32c" },
+ };
For the existing CPU features we have a direct mapping between the feature and the
name, but for crypto it is split into individual instruction groups. Presumably this
is because the crypto instruction implementation is incomplete?
+ 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 +762,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);
ATB,
Mark.