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 , 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-"), 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)) {