aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/i386/pc_piix.c4
-rw-r--r--hw/i386/pc_q35.c4
-rw-r--r--hw/i386/smbios.c27
3 files changed, 30 insertions, 5 deletions
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index ce8745df25..200ea4f009 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -63,6 +63,7 @@ static bool has_acpi_build = true;
static int legacy_acpi_table_size;
static bool smbios_defaults = true;
static bool smbios_legacy_mode;
+static bool smbios_uuid_encoded = true;
/* Make sure that guest addresses aligned at 1Gbyte boundaries get mapped to
* host addresses aligned at 1Gbyte boundaries. This way we can use 1GByte
* pages in the host.
@@ -172,7 +173,7 @@ static void pc_init1(MachineState *machine,
MachineClass *mc = MACHINE_GET_CLASS(machine);
/* These values are guest ABI, do not change */
smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)",
- mc->name, smbios_legacy_mode);
+ mc->name, smbios_legacy_mode, smbios_uuid_encoded);
}
/* allocate ram and load rom/bios */
@@ -304,6 +305,7 @@ static void pc_init_pci(MachineState *machine)
static void pc_compat_2_1(MachineState *machine)
{
+ smbios_uuid_encoded = false;
}
static void pc_compat_2_0(MachineState *machine)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index aef4628f92..f69e4a1bfa 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -52,6 +52,7 @@
static bool has_acpi_build = true;
static bool smbios_defaults = true;
static bool smbios_legacy_mode;
+static bool smbios_uuid_encoded = true;
/* Make sure that guest addresses aligned at 1Gbyte boundaries get mapped to
* host addresses aligned at 1Gbyte boundaries. This way we can use 1GByte
* pages in the host.
@@ -163,7 +164,7 @@ static void pc_q35_init(MachineState *machine)
MachineClass *mc = MACHINE_GET_CLASS(machine);
/* These values are guest ABI, do not change */
smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)",
- mc->name, smbios_legacy_mode);
+ mc->name, smbios_legacy_mode, smbios_uuid_encoded);
}
/* allocate ram and load rom/bios */
@@ -283,6 +284,7 @@ static void pc_q35_init(MachineState *machine)
static void pc_compat_2_1(MachineState *machine)
{
+ smbios_uuid_encoded = false;
}
static void pc_compat_2_0(MachineState *machine)
diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c
index 0ae5960b8c..8a7ad48921 100644
--- a/hw/i386/smbios.c
+++ b/hw/i386/smbios.c
@@ -48,6 +48,7 @@ struct smbios_table {
static uint8_t *smbios_entries;
static size_t smbios_entries_len;
static bool smbios_legacy = true;
+static bool smbios_uuid_encoded = true;
/* end: legacy structures & constants for <= 2.0 machines */
@@ -391,6 +392,11 @@ static void smbios_build_type_1_fields(void)
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
type1.family);
if (qemu_uuid_set) {
+ /* We don't encode the UUID in the "wire format" here because this
+ * function is for legacy mode and needs to keep the guest ABI, and
+ * because we don't know what's the SMBIOS version advertised by the
+ * BIOS.
+ */
smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
qemu_uuid, 16);
}
@@ -523,6 +529,19 @@ static void smbios_build_type_0_table(void)
SMBIOS_BUILD_TABLE_POST;
}
+/* Encode UUID from the big endian encoding described on RFC4122 to the wire
+ * format specified by SMBIOS version 2.6.
+ */
+static void smbios_encode_uuid(struct smbios_uuid *uuid, const uint8_t *buf)
+{
+ memcpy(uuid, buf, 16);
+ if (smbios_uuid_encoded) {
+ uuid->time_low = bswap32(uuid->time_low);
+ uuid->time_mid = bswap16(uuid->time_mid);
+ uuid->time_hi_and_version = bswap16(uuid->time_hi_and_version);
+ }
+}
+
static void smbios_build_type_1_table(void)
{
SMBIOS_BUILD_TABLE_PRE(1, 0x100, true); /* required */
@@ -532,9 +551,9 @@ static void smbios_build_type_1_table(void)
SMBIOS_TABLE_SET_STR(1, version_str, type1.version);
SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial);
if (qemu_uuid_set) {
- memcpy(t->uuid, qemu_uuid, 16);
+ smbios_encode_uuid(&t->uuid, qemu_uuid);
} else {
- memset(t->uuid, 0, 16);
+ memset(&t->uuid, 0, 16);
}
t->wake_up_type = 0x06; /* power switch */
SMBIOS_TABLE_SET_STR(1, sku_number_str, type1.sku);
@@ -746,10 +765,12 @@ void smbios_set_cpuid(uint32_t version, uint32_t features)
}
void smbios_set_defaults(const char *manufacturer, const char *product,
- const char *version, bool legacy_mode)
+ const char *version, bool legacy_mode,
+ bool uuid_encoded)
{
smbios_have_defaults = true;
smbios_legacy = legacy_mode;
+ smbios_uuid_encoded = uuid_encoded;
/* drop unwanted version of command-line file blob(s) */
if (smbios_legacy) {