feat: patched qemu 11.1.2 identity series with macos support

This commit is contained in:
2026-10-10 01:11:44 +02:00
parent f99ff1400a
commit d47e1d5fa0
15 changed files with 606 additions and 59 deletions
+17 -11
View File
@@ -5,7 +5,7 @@ Targets VMAware check: FIRMWARE
ACPI table fingerprints: PCI link-device names, PNP0A06 resource stubs, the
FADT C-state latencies and the AML the checker string-matches on.
Applies to QEMU v11.1.1. Apply from the source root with:
Applies to QEMU v11.1.2. Apply from the source root with:
patch -p1 < 01-firmware.patch
---
@@ -193,7 +193,7 @@ index 8837b69..4001d9d 100644
if (pcms->wdat_enabled == true) {
g_assert(pm.tco_io_base);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 87162ff..4c303cb 100644
index 87162ff2c..3616c580a 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -687,10 +687,10 @@ void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
@@ -209,7 +209,7 @@ index 87162ff..4c303cb 100644
/* device present, functioning, decoding, not shown in UI */
aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
crs = aml_resource_template();
@@ -699,6 +699,83 @@ void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
@@ -699,6 +699,89 @@ void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
aml_append(scope, dev);
}
@@ -251,7 +251,7 @@ index 87162ff..4c303cb 100644
+ case 5:
+ // Slot 5: USB XHCI (QEMU default often)
+ if (func == 0) sprintf(name, "XHC1");
+ else sprintf(name, "XHC%X", func);
+ else sprintf(name, "XHC%X", func + 1);
+ break;
+
+ case 6:
@@ -261,19 +261,25 @@ index 87162ff..4c303cb 100644
+ break;
+
+ case 29:
+ // Slot 29 (0x1D): USB EHCI (Intel Standard)
+ if (func == 0) sprintf(name, "EHC1");
+ else sprintf(name, "EHC%X", func);
+ // Slot 29 (0x1D): ICH9 USB, UHCI at functions 0-2 and EHCI at 7
+ if (func == 7) sprintf(name, "EHC1");
+ else sprintf(name, "UHC%X", func + 1);
+ break;
+
+ case 20:
+ // Slot 20 (0x14): LPC / SMBus / SATA 2
+ if (func == 0) sprintf(name, "LPCB"); // ISA Bridge
+ else if (func == 2) sprintf(name, "SAT1"); // 2nd SATA
+ // Slot 20 (0x14): SMBus / SATA 2; the q35 LPC bridge is 1f.0
+ if (func == 2) sprintf(name, "SATA"); // 2nd SATA; slot 6 owns SAT0-SAT7
+ else if (func == 3) sprintf(name, "SBUS"); // SMBus
+ else sprintf(name, "S20%X", func); // Fallback
+ break;
+
+ case 31:
+ // Slot 31 (0x1F): the ICH9 LPC bridge, named as 03-pci-ids' PIRQ field expects
+ if (func == 0) {
+ sprintf(name, "LPCB");
+ break;
+ }
+ /* fall through */
+ default:
+ /*
+ * For generic slots, we use "RP" (Root Port) + devfn (Hex).
@@ -293,7 +299,7 @@ index 87162ff..4c303cb 100644
bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus)
{
Aml *method;
@@ -912,7 +989,11 @@ void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
@@ -912,7 +995,11 @@ void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
}
/* start to compose PCI device descriptor */
+5 -5
View File
@@ -5,7 +5,7 @@ Targets VMAware check: VIRTUAL_DISK / DISK_SERIAL
Storage that announces itself as emulated: 'QEMU HARDDISK', 'QEMU DVD-ROM',
empty serials and the QEMU vendor string in SCSI inquiry data.
Applies to QEMU v11.1.1. Apply from the source root with:
Applies to QEMU v11.1.2. Apply from the source root with:
patch -p1 < 02-disk-identity.patch
---
@@ -13,7 +13,7 @@ diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 1b0cce1..0e8ded4 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2551,7 +2551,7 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
@@ -2556,7 +2556,7 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
s->version = g_strdup(QEMU_HW_VERSION);
}
if (!s->vendor) {
@@ -22,7 +22,7 @@ index 1b0cce1..0e8ded4 100644
}
if (s->serial && strlen(s->serial) > MAX_SERIAL_LEN) {
error_setg(errp, "The serial number can't be longer than %d characters",
@@ -2615,7 +2615,7 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
@@ -2620,7 +2620,7 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
s->qdev.blocksize = s->qdev.conf.logical_block_size;
s->qdev.type = TYPE_DISK;
if (!s->product) {
@@ -31,7 +31,7 @@ index 1b0cce1..0e8ded4 100644
}
scsi_realize(&s->qdev, errp);
}
@@ -2642,7 +2642,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
@@ -2647,7 +2647,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
s->qdev.type = TYPE_ROM;
s->features |= 1 << SCSI_DISK_F_REMOVABLE;
if (!s->product) {
@@ -59,7 +59,7 @@ diff --git a/hw/ide/core.c b/hw/ide/core.c
index fb9bf11..7f44de2 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2640,21 +2640,20 @@ int ide_init_drive(IDEState *s, IDEDevice *dev, IDEDriveKind kind, Error **errp)
@@ -2648,21 +2648,20 @@ int ide_init_drive(IDEState *s, IDEDevice *dev, IDEDriveKind kind, Error **errp)
if (dev->serial) {
pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), dev->serial);
} else {
+32 -26
View File
@@ -5,7 +5,10 @@ Targets VMAware check: PCI_VENDOR / DEVICES
PCI vendor, device and subsystem IDs that read as Red Hat / QEMU, and the
ICH9 southbridge layout OVMF expects to find at 1f:0.
Applies to QEMU v11.1.1. Apply from the source root with:
Virtio devices keep Red Hat's subsystem IDs: their vendor ID names them
anyway, and OVMF and the guest virtio drivers only bind with them.
Applies to QEMU v11.1.2. Apply from the source root with:
patch -p1 < 03-pci-ids.patch
---
@@ -24,19 +27,6 @@ index f2448e9..4eea405 100644
#define PCI_DEVICE_ID_QEMU_IPMI 0x1112
/* VMWare (0x15ad) */
@@ -77,9 +77,9 @@ extern bool pci_available;
#define PCI_DEVICE_ID_INTEL_82801IR 0x2922
/* Red Hat / Qumranet (for QEMU) -- see pci-ids.txt */
-#define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4
-#define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x1af4
-#define PCI_SUBDEVICE_ID_QEMU 0x1100
+#define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4 // VirtIO devices | IVSHMEM Driver | Looking Glass
+#define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x8086 // VirtIO devices | IVSHMEM Driver | Looking Glass
+#define PCI_SUBDEVICE_ID_QEMU 0x0000 // VirtIO devices | IVSHMEM Driver | Looking Glass
/* legacy virtio-pci devices */
#define PCI_DEVICE_ID_VIRTIO_NET 0x1000
@@ -100,21 +100,21 @@ extern bool pci_available;
*/
#define PCI_DEVICE_ID_VIRTIO_10_BASE 0x1040
@@ -166,16 +156,32 @@ index e2aab3d..9131b5d 100644
dc->user_creatable = true;
vc->get_id = device_vmstate_if_get_id;
rc->get_state = device_get_reset_state;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f064aa2..cfdbbc1 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1689,7 +1689,7 @@ static void pc_machine_class_init(ObjectClass *oc, const void *data)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d319160..7206e3d 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -355,8 +355,8 @@ static void pci_irq_handler(void *opaque, int irq_num, int level);
static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, Error **);
static void pci_del_option_rom(PCIDevice *pdev);
pcmc->pci_enabled = true;
pcmc->has_acpi_build = true;
- pcmc->smbios_defaults = true;
+ pcmc->smbios_defaults = false;
pcmc->gigabyte_align = true;
pcmc->has_reserved_memory = true;
pcmc->enforce_amd_1tb_hole = true;
-static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
-static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
+static uint16_t pci_default_sub_vendor_id = PCI_VENDOR_ID_INTEL;
+static uint16_t pci_default_sub_device_id = 0;
PCIHostStateList pci_host_bridges;
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 6f5db5f..a7e07b8 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -2029,6 +2029,9 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
modern = virtio_pci_modern(proxy);
config = proxy->pci_dev.config;
+ /* virtio drivers match Red Hat's subsystem IDs; OVMF needs a device ID >= 0x40 */
+ pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID, PCI_SUBVENDOR_ID_REDHAT_QUMRANET);
+ pci_set_word(config + PCI_SUBSYSTEM_ID, PCI_SUBDEVICE_ID_QEMU);
if (proxy->class_code) {
pci_config_set_class(config, proxy->class_code);
}
+1 -1
View File
@@ -4,7 +4,7 @@ Targets VMAware check: QEMU_FW_CFG
The fw_cfg device signature, which names QEMU literally.
Applies to QEMU v11.1.1. Apply from the source root with:
Applies to QEMU v11.1.2. Apply from the source root with:
patch -p1 < 04-fw-cfg.patch
---
+1 -1
View File
@@ -4,7 +4,7 @@ Targets VMAware check: QEMU_USB
USB HID descriptors carrying QEMU vendor strings and product IDs.
Applies to QEMU v11.1.1. Apply from the source root with:
Applies to QEMU v11.1.2. Apply from the source root with:
patch -p1 < 05-usb-hid.patch
---
+1 -1
View File
@@ -4,7 +4,7 @@ Targets VMAware check: DEVICES
Intel HDA codec and controller identity strings.
Applies to QEMU v11.1.1. Apply from the source root with:
Applies to QEMU v11.1.2. Apply from the source root with:
patch -p1 < 06-audio.patch
---
+1 -1
View File
@@ -5,7 +5,7 @@ Targets VMAware check: (display identity)
Generated EDID vendor and model. Note VMAware does not read EDID - this is
carried for other detectors, not for the score.
Applies to QEMU v11.1.1. Apply from the source root with:
Applies to QEMU v11.1.2. Apply from the source root with:
patch -p1 < 07-edid.patch
---
+1 -1
View File
@@ -4,7 +4,7 @@ Targets VMAware check: (CPU model plumbing)
CPU feature-word plumbing and an upstream backport; not aimed at a check.
Applies to QEMU v11.1.1. Apply from the source root with:
Applies to QEMU v11.1.2. Apply from the source root with:
patch -p1 < 08-cpu-misc.patch
---
+239
View File
@@ -0,0 +1,239 @@
Subject: [PATCH] acpi: clear the remaining VMAware FIRMWARE chain links
Targets VMAware check: FIRMWARE
01-firmware cleared the FIRMWARE links known when it was written. Current
VMAware adds more DSDT fingerprints to the same chain, and firmware() returns
on the first match, so the technique keeps firing until every link is gone.
This clears the rest, taking a q35 guest to 0 detections on both the v2.8.1
release and current HEAD. Each change is a rename or a byte-neutral rewrite of
emitted AML; none alters ACPI semantics.
Links cleared:
- PCI interrupt-link query methods IQST/IQCR and the PRR0/PRRI resource
template/field -> PSTA/PCRS/PRS0/PRSI
- TPM Physical Presence Interface regions/method TPP2/TPP3/TPFN -> PPI2/PPI3/PPIF
- zeroed _S5 SLP_TYP: emit the 2-element package form
- ACPI0006 _HID in \_GPE: declared by its full path \_GPE._HID; the
object stays, because macOS will not power off without it
- Q35 MMCONFIG reservation device MCFG -> PCMM
- synthetic GSI link devices: give the no-op _DIS/_SRS a body so the
empty-stub descriptor no longer matches
- PCIe _OSC capability mask: And() operands swapped (commutative)
- PIRQ link _PRS: list the identical IRQ set as {11, 10, 5} so the fixed
5/10/11 descriptor differs
Applies to QEMU v11.1.2, on top of 01-firmware. From the source root:
patch -p1 < 09-firmware-chain.patch
diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c
index 8c7ed1047..0d6a95d67 100644
--- a/hw/acpi/pci.c
+++ b/hw/acpi/pci.c
@@ -326,8 +326,8 @@ Aml *build_pci_host_bridge_osc_method(bool enable_native_pcie_hotplug)
* Allow SHPC (PCI bridges can have SHPC controller)
* Disable PCIe Native Hot-plug if ACPI PCI Hot-plug is enabled.
*/
- aml_append(if_ctx, aml_and(a_ctrl,
- aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)), a_ctrl));
+ aml_append(if_ctx, aml_and(
+ aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)), a_ctrl, a_ctrl));
if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
/* Unknown revision */
diff --git a/hw/acpi/tpm.c b/hw/acpi/tpm.c
index e70377598..d7c234cc5 100644
--- a/hw/acpi/tpm.c
+++ b/hw/acpi/tpm.c
@@ -39,10 +39,10 @@ void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev, hwaddr ppi_base)
* the PPI code and parameter (PPRQ, PPRM) to the firmware.
*/
aml_append(dev,
- aml_operation_region("TPP2", AML_SYSTEM_MEMORY,
+ aml_operation_region("PPI2", AML_SYSTEM_MEMORY,
aml_int(ppi_base + 0x100),
0x5A));
- field = aml_field("TPP2", AML_ANY_ACC, AML_NOLOCK, AML_PRESERVE);
+ field = aml_field("PPI2", AML_ANY_ACC, AML_NOLOCK, AML_PRESERVE);
aml_append(field, aml_named_field("PPIN", 8));
aml_append(field, aml_named_field("PPIP", 32));
aml_append(field, aml_named_field("PPRP", 32));
@@ -55,11 +55,11 @@ void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev, hwaddr ppi_base)
aml_append(dev,
aml_operation_region(
- "TPP3", AML_SYSTEM_MEMORY,
+ "PPI3", AML_SYSTEM_MEMORY,
aml_int(ppi_base +
0x15a /* movv, docs/specs/tpm.rst */),
0x1));
- field = aml_field("TPP3", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
+ field = aml_field("PPI3", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
aml_append(field, aml_named_field("MOVV", 8));
aml_append(dev, field);
@@ -67,7 +67,7 @@ void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev, hwaddr ppi_base)
* DerefOf in Windows is broken with SYSTEM_MEMORY. Use a dynamic
* operation region inside of a method for getting FUNC[op].
*/
- method = aml_method("TPFN", 1, AML_SERIALIZED);
+ method = aml_method("PPIF", 1, AML_SERIALIZED);
{
Aml *op = aml_arg(0);
ifctx = aml_if(aml_lgreater_equal(op, aml_int(0x100)));
@@ -164,7 +164,7 @@ void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev, hwaddr ppi_base)
/* get opcode flags */
aml_append(ifctx2,
- aml_store(aml_call1("TPFN", op), op_flags));
+ aml_store(aml_call1("PPIF", op), op_flags));
/* if func[opcode] & TPM_PPI_FUNC_NOT_IMPLEMENTED */
ifctx3 = aml_if(
@@ -325,7 +325,7 @@ void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev, hwaddr ppi_base)
op));
/* get opcode flags */
- aml_append(ifctx2, aml_store(aml_call1("TPFN", op),
+ aml_append(ifctx2, aml_store(aml_call1("PPIF", op),
op_flags));
/* if func[opcode] & TPM_PPI_FUNC_NOT_IMPLEMENTED */
ifctx3 = aml_if(
@@ -397,7 +397,7 @@ void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev, hwaddr ppi_base)
op));
/* get opcode flags */
- aml_append(ifctx2, aml_store(aml_call1("TPFN", op),
+ aml_append(ifctx2, aml_store(aml_call1("PPIF", op),
op_flags));
/* return confirmation status code */
aml_append(ifctx2,
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4001d9d69..087d5f778 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -515,7 +515,7 @@ static Aml *build_link_dev(const char *name, uint8_t uid, Aml *reg)
Aml *dev;
Aml *crs;
Aml *method;
- uint32_t irqs[] = {5, 10, 11};
+ uint32_t irqs[] = {11, 10, 5};
dev = aml_device("%s", name);
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C0F")));
@@ -527,7 +527,7 @@ static Aml *build_link_dev(const char *name, uint8_t uid, Aml *reg)
aml_append(dev, aml_name_decl("_PRS", crs));
method = aml_method("_STA", 0, AML_NOTSERIALIZED);
- aml_append(method, aml_return(aml_call1("IQST", reg)));
+ aml_append(method, aml_return(aml_call1("PSTA", reg)));
aml_append(dev, method);
method = aml_method("_DIS", 0, AML_NOTSERIALIZED);
@@ -535,12 +535,12 @@ static Aml *build_link_dev(const char *name, uint8_t uid, Aml *reg)
aml_append(dev, method);
method = aml_method("_CRS", 0, AML_NOTSERIALIZED);
- aml_append(method, aml_return(aml_call1("IQCR", reg)));
+ aml_append(method, aml_return(aml_call1("PCRS", reg)));
aml_append(dev, method);
method = aml_method("_SRS", 1, AML_NOTSERIALIZED);
- aml_append(method, aml_create_dword_field(aml_arg(0), aml_int(5), "PRRI"));
- aml_append(method, aml_store(aml_name("PRRI"), reg));
+ aml_append(method, aml_create_dword_field(aml_arg(0), aml_int(5), "PRSI"));
+ aml_append(method, aml_store(aml_name("PRSI"), reg));
aml_append(dev, method);
return dev;
@@ -569,9 +569,11 @@ static Aml *build_gsi_link_dev(const char *name, uint8_t uid, uint8_t gsi)
* _DIS can be no-op because the interrupt cannot be disabled.
*/
method = aml_method("_DIS", 0, AML_NOTSERIALIZED);
+ aml_append(method, aml_store(aml_int(0), aml_local(0)));
aml_append(dev, method);
method = aml_method("_SRS", 1, AML_NOTSERIALIZED);
+ aml_append(method, aml_store(aml_int(0), aml_local(0)));
aml_append(dev, method);
return dev;
@@ -582,28 +584,28 @@ static Aml *build_iqcr_method(bool is_piix4)
{
Aml *if_ctx;
uint32_t irqs;
- Aml *method = aml_method("IQCR", 1, AML_SERIALIZED);
+ Aml *method = aml_method("PCRS", 1, AML_SERIALIZED);
Aml *crs = aml_resource_template();
irqs = 0;
aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL,
AML_ACTIVE_HIGH, AML_SHARED, &irqs, 1));
- aml_append(method, aml_name_decl("PRR0", crs));
+ aml_append(method, aml_name_decl("PRS0", crs));
aml_append(method,
- aml_create_dword_field(aml_name("PRR0"), aml_int(5), "PRRI"));
+ aml_create_dword_field(aml_name("PRS0"), aml_int(5), "PRSI"));
if (is_piix4) {
if_ctx = aml_if(aml_lless(aml_arg(0), aml_int(0x80)));
- aml_append(if_ctx, aml_store(aml_arg(0), aml_name("PRRI")));
+ aml_append(if_ctx, aml_store(aml_arg(0), aml_name("PRSI")));
aml_append(method, if_ctx);
} else {
aml_append(method,
aml_store(aml_and(aml_arg(0), aml_int(0xF), NULL),
- aml_name("PRRI")));
+ aml_name("PRSI")));
}
- aml_append(method, aml_return(aml_name("PRR0")));
+ aml_append(method, aml_return(aml_name("PRS0")));
return method;
}
@@ -611,7 +613,7 @@ static Aml *build_iqcr_method(bool is_piix4)
static Aml *build_irq_status_method(void)
{
Aml *if_ctx;
- Aml *method = aml_method("IQST", 1, AML_NOTSERIALIZED);
+ Aml *method = aml_method("PSTA", 1, AML_NOTSERIALIZED);
if_ctx = aml_if(aml_and(aml_int(0x80), aml_arg(0), NULL));
aml_append(if_ctx, aml_return(aml_int(0x09)));
@@ -801,7 +803,7 @@ static Aml *build_q35_dram_controller(const AcpiMcfgInfo *mcfg)
Aml *resource_template;
/* DRAM controller */
- dev = aml_device("MCFG");
+ dev = aml_device("PCMM");
aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C01")));
resource_template = aml_resource_template();
@@ -986,7 +988,11 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
scope = aml_scope("_GPE");
{
- aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006")));
+ /*
+ * macOS needs the GPE block device to reach S5; naming it by full
+ * path keeps it without the byte pattern VMAware matches.
+ */
+ aml_append(scope, aml_name_decl("\\_GPE._HID", aml_string("ACPI0006")));
if (machine->nvdimms_state->is_enabled) {
method = aml_method("_E04", 0, AML_NOTSERIALIZED);
aml_append(method, aml_notify(aml_name("\\_SB.NVDR"),
@@ -1193,11 +1199,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
aml_append(scope, aml_name_decl("_S4", pkg));
}
- pkg = aml_package(4);
+ pkg = aml_package(2);
aml_append(pkg, aml_int(0)); /* PM1a_CNT.SLP_TYP */
aml_append(pkg, aml_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
- aml_append(pkg, aml_int(0)); /* reserved */
- aml_append(pkg, aml_int(0)); /* reserved */
aml_append(scope, aml_name_decl("_S5", pkg));
aml_append(dsdt, scope);
+97
View File
@@ -0,0 +1,97 @@
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)) {
+91
View File
@@ -0,0 +1,91 @@
Subject: [PATCH] acpi: keep the CPU objects macOS needs without the FIRMWARE tell
Targets VMAware check: FIRMWARE (CPU hotplug I/O signature)
macOS references \_SB.CPUS.Cxxx from its own CpuPlug SSDT, so the guest needs
QEMU's build_cpus_aml output (the \_SB.PCI0.PRES controller and the \_SB.CPUS
Processor objects) or it hangs in ACPI namespace init. 01-firmware dropped that
block because build_cpus_aml emits the CPU-hotplug register region at I/O port
0x0CD8, which VMAware v2.8.1 FIRMWARE byte-matches as the WordData sequence
0x0B 0xD8 0x0C and flips to a QEMU verdict. HEAD has no such check.
This re-adds the block for every guest (no opt-in) and removes that one tell at
the source rather than removing the whole block:
- the controller _UID is renamed from "CPU Hotplug resources" to "Reserved
resources C", clearing the FIRMWARE string match the same way 01-firmware
renamed the other reserved-resource devices.
- the PRST OperationRegion base is emitted as Add(0x0C00, 0xD8) for a SystemIO
base. It evaluates to the identical 0x0CD8 at namespace load, so the port
QEMU decodes and the port OVMF's SMM code reads directly are both unchanged.
Relocating the base instead was tried and breaks every SMM/OVMF guest (macOS
hangs at boot, Windows too), because OVMF hardcodes 0x0CD8. Splitting the
operand keeps 0x0CD8 live but never places the three matched bytes next to
each other in the AML.
The _CRS IO descriptor keeps 0x0CD8 untouched: a small-resource IO descriptor
encodes its base as 0xD8 0x0C preceded by the 0x47/0x01 descriptor bytes, never
by 0x0B, so it is not the sequence the scanner matches.
Verified against QEMU 11.1.2: macOS boots to login and powers off via S5;
VMAware v2.8.1 and HEAD both read bare metal with FIRMWARE clear on the stealth
guest; Windows and Linux boot unchanged.
Applies to QEMU v11.1.2, on top of 01-firmware. From the source root:
patch -p1 < 11-macos-cpu-hotplug.patch
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1002,6 +1002,16 @@
}
aml_append(dsdt, scope);
+ {
+ CPUHotplugFeatures opts = {
+ .acpi_1_compatible = true,
+ .smi_path = pm->smi_on_cpuhp ? "\\_SB.PCI0.SMI0.SMIC" : NULL,
+ .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
+ };
+ build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
+ pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02",
+ AML_SYSTEM_IO);
+ }
crs_range_set_init(&crs_range_set);
bus = PC_MACHINE(machine)->pcibus;
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -363,7 +363,7 @@
aml_append(cpu_ctrl_dev,
aml_name_decl("_HID", aml_eisaid("PNP0A06")));
aml_append(cpu_ctrl_dev,
- aml_name_decl("_UID", aml_string("CPU Hotplug resources")));
+ aml_name_decl("_UID", aml_string("Reserved resources C")));
aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
assert((rs == AML_SYSTEM_IO) || (rs == AML_SYSTEM_MEMORY));
@@ -379,9 +379,21 @@
aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
- /* declare CPU hotplug MMIO region with related access fields */
+ /*
+ * Declare the CPU hotplug register block. The region is at the same
+ * fixed base QEMU decodes and firmware (OVMF SMM) reads directly, so
+ * that is unchanged. Only the base operand's AML encoding is split
+ * across an Add() for a SystemIO base: emitting the 16-bit port as a
+ * single WordData leaks the exact three-byte sequence a VM-detection
+ * scanner byte-matches on. The Add() evaluates to the identical base
+ * at namespace load but never places those bytes contiguously.
+ */
+ Aml *region_base = (rs == AML_SYSTEM_IO)
+ ? aml_add(aml_int(base_addr & 0xff00),
+ aml_int(base_addr & 0x00ff), NULL)
+ : aml_int(base_addr);
aml_append(cpu_ctrl_dev,
- aml_operation_region("PRST", rs, aml_int(base_addr),
+ aml_operation_region("PRST", rs, region_base,
ACPI_CPU_HOTPLUG_REG_LEN));
field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,