98 lines
4.0 KiB
Diff
98 lines
4.0 KiB
Diff
Subject: [PATCH] smbios: CTYPE / SMBIOS_VM_BIT / FIRMWARE
|
|
|
|
Targets VMAware check: CTYPE / SMBIOS_VM_BIT / FIRMWARE
|
|
|
|
QEMU keeps synthesising every required SMBIOS structure the domain does not
|
|
supply, so identity can be set with -smbios type=N field arguments and real
|
|
structures passed with -smbios file= only where they are wanted. What QEMU
|
|
fills in by itself must not read as a VM:
|
|
|
|
- type 3 chassis type was hard-coded to 1 (Other), which CTYPE flags. It
|
|
defaults to 3 (Desktop) and is set with type=3,chassis-type=N.
|
|
- the type 0 "virtual machine" characteristics bit now defaults off, so a
|
|
type 0 from libvirt <sysinfo>, which cannot pass vm=off, stays clean.
|
|
- unset product and version strings in types 1-4 default to "Unknown"
|
|
instead of the machine description and name ("Standard PC (Q35 + ICH9,
|
|
2009)", "pc-q35-<ver>"), which FIRMWARE matches when it scans SMBIOS on
|
|
Windows.
|
|
|
|
Applies to QEMU v11.1.2, on top of 04-fw-cfg. Apply from the source root with:
|
|
patch -p1 < 10-smbios.patch
|
|
|
|
---
|
|
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
|
index e5fddbc..bfc193c 100644
|
|
--- a/hw/i386/fw_cfg.c
|
|
+++ b/hw/i386/fw_cfg.c
|
|
@@ -71,13 +71,12 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
|
|
unsigned i, array_count;
|
|
MachineState *ms = MACHINE(pcms);
|
|
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
|
|
- MachineClass *mc = MACHINE_GET_CLASS(pcms);
|
|
X86CPU *cpu = X86_CPU(ms->possible_cpus->cpus[0].cpu);
|
|
int nr_e820;
|
|
|
|
if (pcmc->smbios_defaults) {
|
|
/* These values are guest ABI, do not change */
|
|
- smbios_set_defaults("Unknown", mc->desc, mc->name);
|
|
+ smbios_set_defaults("Unknown", "Unknown", "Unknown");
|
|
}
|
|
|
|
/* tell smbios about cpuid version and features */
|
|
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
|
index 7d71418..c557069 100644
|
|
--- a/hw/smbios/smbios.c
|
|
+++ b/hw/smbios/smbios.c
|
|
@@ -62,7 +62,8 @@ static struct {
|
|
|
|
static struct {
|
|
const char *manufacturer, *version, *serial, *asset, *sku;
|
|
-} type3;
|
|
+ uint64_t chassis_type;
|
|
+} type3 = { .chassis_type = 0x03 }; /* Desktop: QEMU's "Other" reads as a VM */
|
|
|
|
/*
|
|
* SVVP requires max_speed and current_speed to be set and not being
|
|
@@ -282,6 +283,10 @@ static const QemuOptDesc qemu_smbios_type3_opts[] = {
|
|
.name = "sku",
|
|
.type = QEMU_OPT_STRING,
|
|
.help = "SKU number",
|
|
+ },{
|
|
+ .name = "chassis-type",
|
|
+ .type = QEMU_OPT_NUMBER,
|
|
+ .help = "chassis type",
|
|
},
|
|
{ /* end of list */ }
|
|
};
|
|
@@ -656,7 +661,7 @@ static void smbios_build_type_3_table(void)
|
|
SMBIOS_BUILD_TABLE_PRE(3, T3_BASE, true); /* required */
|
|
|
|
SMBIOS_TABLE_SET_STR(3, manufacturer_str, type3.manufacturer);
|
|
- t->type = 0x01; /* Other */
|
|
+ t->type = type3.chassis_type;
|
|
SMBIOS_TABLE_SET_STR(3, version_str, type3.version);
|
|
SMBIOS_TABLE_SET_STR(3, serial_number_str, type3.serial);
|
|
SMBIOS_TABLE_SET_STR(3, asset_tag_number_str, type3.asset);
|
|
@@ -1413,7 +1418,7 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
|
save_opt(&smbios_type0.version, opts, "version");
|
|
save_opt(&smbios_type0.date, opts, "date");
|
|
smbios_type0.uefi = qemu_opt_get_bool(opts, "uefi", false);
|
|
- smbios_type0.vm = qemu_opt_get_bool(opts, "vm", true);
|
|
+ smbios_type0.vm = qemu_opt_get_bool(opts, "vm", false);
|
|
|
|
val = qemu_opt_get(opts, "release");
|
|
if (val) {
|
|
@@ -1465,6 +1470,12 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
|
save_opt(&type3.serial, opts, "serial");
|
|
save_opt(&type3.asset, opts, "asset");
|
|
save_opt(&type3.sku, opts, "sku");
|
|
+ type3.chassis_type = qemu_opt_get_number(opts, "chassis-type",
|
|
+ type3.chassis_type);
|
|
+ if (type3.chassis_type > UINT8_MAX) {
|
|
+ error_setg(errp, "SMBIOS chassis type is too large (> %d)",
|
|
+ UINT8_MAX);
|
|
+ }
|
|
return;
|
|
case 4:
|
|
if (!qemu_opts_validate(opts, qemu_smbios_type4_opts, errp)) {
|