diff options
author | Marian Postevca <posteuca@mutex.one> | 2021-01-19 02:32:13 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2021-02-05 08:52:59 -0500 |
commit | 602b458201ffd6f261fb8ee16b5175d733d3ec32 (patch) | |
tree | 7cd70e99e8b445eea3f4dff35a2cc22f93937bc8 /hw/i386/acpi-build.c | |
parent | 99f84ac0512b7ce29089a63c392da706fac14cb1 (diff) |
acpi: Permit OEM ID and OEM table ID fields to be changed
Qemu's ACPI table generation sets the fields OEM ID and OEM table ID
to "BOCHS " and "BXPCxxxx" where "xxxx" is replaced by the ACPI
table name.
Some games like Red Dead Redemption 2 seem to check the ACPI OEM ID
and OEM table ID for the strings "BOCHS" and "BXPC" and if they are
found, the game crashes(this may be an intentional detection
mechanism to prevent playing the game in a virtualized environment).
This patch allows you to override these default values.
The feature can be used in this manner:
qemu -machine oem-id=ABCDEF,oem-table-id=GHIJKLMN
The oem-id string can be up to 6 bytes in size, and the
oem-table-id string can be up to 8 bytes in size. If the string are
smaller than their respective sizes they will be padded with space.
If either of these parameters is not set, the current default values
will be used for the one missing.
Note that the the OEM Table ID field will not be extended with the
name of the table, but will use either the default name or the user
provided one.
This does not affect the -acpitable option (for user-defined ACPI
tables), which has precedence over -machine option.
Signed-off-by: Marian Postevca <posteuca@mutex.one>
Message-Id: <20210119003216.17637-3-posteuca@mutex.one>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/i386/acpi-build.c')
-rw-r--r-- | hw/i386/acpi-build.c | 86 |
1 files changed, 58 insertions, 28 deletions
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index f56d699c7f..b9190b924a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1637,12 +1637,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); build_header(linker, table_data, (void *)(table_data->data + table_data->len - dsdt->buf->len), - "DSDT", dsdt->buf->len, 1, NULL, NULL); + "DSDT", dsdt->buf->len, 1, pcms->oem_id, pcms->oem_table_id); free_aml_allocator(); } static void -build_hpet(GArray *table_data, BIOSLinker *linker) +build_hpet(GArray *table_data, BIOSLinker *linker, const char *oem_id, + const char *oem_table_id) { Acpi20Hpet *hpet; @@ -1653,11 +1654,12 @@ build_hpet(GArray *table_data, BIOSLinker *linker) hpet->timer_block_id = cpu_to_le32(0x8086a201); hpet->addr.address = cpu_to_le64(HPET_BASE); build_header(linker, table_data, - (void *)hpet, "HPET", sizeof(*hpet), 1, NULL, NULL); + (void *)hpet, "HPET", sizeof(*hpet), 1, oem_id, oem_table_id); } static void -build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog) +build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog, + const char *oem_id, const char *oem_table_id) { Acpi20Tcpa *tcpa = acpi_data_push(table_data, sizeof *tcpa); unsigned log_addr_size = sizeof(tcpa->log_area_start_address); @@ -1677,7 +1679,7 @@ build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog) ACPI_BUILD_TPMLOG_FILE, 0); build_header(linker, table_data, - (void *)tcpa, "TCPA", sizeof(*tcpa), 2, NULL, NULL); + (void *)tcpa, "TCPA", sizeof(*tcpa), 2, oem_id, oem_table_id); } #define HOLE_640K_START (640 * KiB) @@ -1812,7 +1814,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) build_header(linker, table_data, (void *)(table_data->data + srat_start), "SRAT", - table_data->len - srat_start, 1, NULL, NULL); + table_data->len - srat_start, 1, pcms->oem_id, + pcms->oem_table_id); } /* @@ -1820,7 +1823,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) * (version Oct. 2014 or later) */ static void -build_dmar_q35(GArray *table_data, BIOSLinker *linker) +build_dmar_q35(GArray *table_data, BIOSLinker *linker, const char *oem_id, + const char *oem_table_id) { int dmar_start = table_data->len; @@ -1870,7 +1874,7 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker) } build_header(linker, table_data, (void *)(table_data->data + dmar_start), - "DMAR", table_data->len - dmar_start, 1, NULL, NULL); + "DMAR", table_data->len - dmar_start, 1, oem_id, oem_table_id); } /* @@ -1881,7 +1885,8 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker) * Helpful to speedup Windows guests and ignored by others. */ static void -build_waet(GArray *table_data, BIOSLinker *linker) +build_waet(GArray *table_data, BIOSLinker *linker, const char *oem_id, + const char *oem_table_id) { int waet_start = table_data->len; @@ -1897,7 +1902,7 @@ build_waet(GArray *table_data, BIOSLinker *linker) build_append_int_noprefix(table_data, 1 << 1 /* ACPI PM timer good */, 4); build_header(linker, table_data, (void *)(table_data->data + waet_start), - "WAET", table_data->len - waet_start, 1, NULL, NULL); + "WAET", table_data->len - waet_start, 1, oem_id, oem_table_id); } /* @@ -1999,7 +2004,8 @@ ivrs_host_bridges(Object *obj, void *opaque) } static void -build_amd_iommu(GArray *table_data, BIOSLinker *linker) +build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id, + const char *oem_table_id) { int ivhd_table_len = 24; int iommu_start = table_data->len; @@ -2094,7 +2100,8 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker) } build_header(linker, table_data, (void *)(table_data->data + iommu_start), - "IVRS", table_data->len - iommu_start, 1, NULL, NULL); + "IVRS", table_data->len - iommu_start, 1, oem_id, + oem_table_id); } typedef @@ -2150,12 +2157,26 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) GArray *tables_blob = tables->table_data; AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL }; Object *vmgenid_dev; + char *oem_id; + char *oem_table_id; acpi_get_pm_info(machine, &pm); acpi_get_misc_info(&misc); acpi_get_pci_holes(&pci_hole, &pci_hole64); acpi_get_slic_oem(&slic_oem); + if (slic_oem.id) { + oem_id = slic_oem.id; + } else { + oem_id = pcms->oem_id; + } + + if (slic_oem.table_id) { + oem_table_id = slic_oem.table_id; + } else { + oem_table_id = pcms->oem_table_id; + } + table_offsets = g_array_new(false, true /* clear */, sizeof(uint32_t)); ACPI_BUILD_DPRINTF("init ACPI tables\n"); @@ -2189,32 +2210,35 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) pm.fadt.facs_tbl_offset = &facs; pm.fadt.dsdt_tbl_offset = &dsdt; pm.fadt.xdsdt_tbl_offset = &dsdt; - build_fadt(tables_blob, tables->linker, &pm.fadt, - slic_oem.id, slic_oem.table_id); + build_fadt(tables_blob, tables->linker, &pm.fadt, oem_id, oem_table_id); aml_len += tables_blob->len - fadt; acpi_add_table(table_offsets, tables_blob); acpi_build_madt(tables_blob, tables->linker, x86ms, - ACPI_DEVICE_IF(x86ms->acpi_dev)); + ACPI_DEVICE_IF(x86ms->acpi_dev), pcms->oem_id, + pcms->oem_table_id); vmgenid_dev = find_vmgenid_dev(); if (vmgenid_dev) { acpi_add_table(table_offsets, tables_blob); vmgenid_build_acpi(VMGENID(vmgenid_dev), tables_blob, - tables->vmgenid, tables->linker); + tables->vmgenid, tables->linker, pcms->oem_id); } if (misc.has_hpet) { acpi_add_table(table_offsets, tables_blob); - build_hpet(tables_blob, tables->linker); + build_hpet(tables_blob, tables->linker, pcms->oem_id, + pcms->oem_table_id); } if (misc.tpm_version != TPM_VERSION_UNSPEC) { if (misc.tpm_version == TPM_VERSION_1_2) { acpi_add_table(table_offsets, tables_blob); - build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog); + build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog, + pcms->oem_id, pcms->oem_table_id); } else { /* TPM_VERSION_2_0 */ acpi_add_table(table_offsets, tables_blob); - build_tpm2(tables_blob, tables->linker, tables->tcpalog); + build_tpm2(tables_blob, tables->linker, tables->tcpalog, + pcms->oem_id, pcms->oem_table_id); } } if (pcms->numa_nodes) { @@ -2222,34 +2246,40 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) build_srat(tables_blob, tables->linker, machine); if (machine->numa_state->have_numa_distance) { acpi_add_table(table_offsets, tables_blob); - build_slit(tables_blob, tables->linker, machine); + build_slit(tables_blob, tables->linker, machine, pcms->oem_id, + pcms->oem_table_id); } if (machine->numa_state->hmat_enabled) { acpi_add_table(table_offsets, tables_blob); - build_hmat(tables_blob, tables->linker, machine->numa_state); + build_hmat(tables_blob, tables->linker, machine->numa_state, + pcms->oem_id, pcms->oem_table_id); } } if (acpi_get_mcfg(&mcfg)) { acpi_add_table(table_offsets, tables_blob); - build_mcfg(tables_blob, tables->linker, &mcfg); + build_mcfg(tables_blob, tables->linker, &mcfg, pcms->oem_id, + pcms->oem_table_id); } if (x86_iommu_get_default()) { IommuType IOMMUType = x86_iommu_get_type(); if (IOMMUType == TYPE_AMD) { acpi_add_table(table_offsets, tables_blob); - build_amd_iommu(tables_blob, tables->linker); + build_amd_iommu(tables_blob, tables->linker, pcms->oem_id, + pcms->oem_table_id); } else if (IOMMUType == TYPE_INTEL) { acpi_add_table(table_offsets, tables_blob); - build_dmar_q35(tables_blob, tables->linker); + build_dmar_q35(tables_blob, tables->linker, pcms->oem_id, + pcms->oem_table_id); } } if (machine->nvdimms_state->is_enabled) { nvdimm_build_acpi(table_offsets, tables_blob, tables->linker, - machine->nvdimms_state, machine->ram_slots); + machine->nvdimms_state, machine->ram_slots, + pcms->oem_id, pcms->oem_table_id); } acpi_add_table(table_offsets, tables_blob); - build_waet(tables_blob, tables->linker); + build_waet(tables_blob, tables->linker, pcms->oem_id, pcms->oem_table_id); /* Add tables supplied by user (if any) */ for (u = acpi_table_first(); u; u = acpi_table_next(u)) { @@ -2262,13 +2292,13 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) /* RSDT is pointed to by RSDP */ rsdt = tables_blob->len; build_rsdt(tables_blob, tables->linker, table_offsets, - slic_oem.id, slic_oem.table_id); + oem_id, oem_table_id); /* RSDP is in FSEG memory, so allocate it separately */ { AcpiRsdpData rsdp_data = { .revision = 0, - .oem_id = ACPI_BUILD_APPNAME6, + .oem_id = pcms->oem_id, .xsdt_tbl_offset = NULL, .rsdt_tbl_offset = &rsdt, }; |