From 602b458201ffd6f261fb8ee16b5175d733d3ec32 Mon Sep 17 00:00:00 2001 From: Marian Postevca Date: Tue, 19 Jan 2021 02:32:13 +0200 Subject: 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 Message-Id: <20210119003216.17637-3-posteuca@mutex.one> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'hw/i386/pc.c') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 5458f61d10..437977c49e 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1611,6 +1611,50 @@ static void pc_machine_set_max_fw_size(Object *obj, Visitor *v, pcms->max_fw_size = value; } +static char *pc_machine_get_oem_id(Object *obj, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + return g_strdup(pcms->oem_id); +} + +static void pc_machine_set_oem_id(Object *obj, const char *value, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + size_t len = strlen(value); + + if (len > 6) { + error_setg(errp, + "User specified "PC_MACHINE_OEM_ID" value is bigger than " + "6 bytes in size"); + return; + } + + strncpy(pcms->oem_id, value, len + 1); +} + +static char *pc_machine_get_oem_table_id(Object *obj, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + return g_strdup(pcms->oem_table_id); +} + +static void pc_machine_set_oem_table_id(Object *obj, const char *value, + Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + size_t len = strlen(value); + + if (len > 8) { + error_setg(errp, + "User specified "PC_MACHINE_OEM_TABLE_ID" value is bigger than " + "8 bytes in size"); + return; + } + strncpy(pcms->oem_table_id, value, len + 1); +} + static void pc_machine_initfn(Object *obj) { PCMachineState *pcms = PC_MACHINE(obj); @@ -1623,6 +1667,8 @@ static void pc_machine_initfn(Object *obj) pcms->max_ram_below_4g = 0; /* use default */ /* acpi build is enabled by default if machine supports it */ pcms->acpi_build_enabled = PC_MACHINE_GET_CLASS(pcms)->has_acpi_build; + pcms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); + pcms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); pcms->smbus_enabled = true; pcms->sata_enabled = true; pcms->pit_enabled = true; @@ -1759,6 +1805,24 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) NULL, NULL); object_class_property_set_description(oc, PC_MACHINE_MAX_FW_SIZE, "Maximum combined firmware size"); + + object_class_property_add_str(oc, PC_MACHINE_OEM_ID, + pc_machine_get_oem_id, + pc_machine_set_oem_id); + object_class_property_set_description(oc, PC_MACHINE_OEM_ID, + "Override the default value of field OEMID " + "in ACPI table header." + "The string may be up to 6 bytes in size"); + + + object_class_property_add_str(oc, PC_MACHINE_OEM_TABLE_ID, + pc_machine_get_oem_table_id, + pc_machine_set_oem_table_id); + object_class_property_set_description(oc, PC_MACHINE_OEM_TABLE_ID, + "Override the default value of field OEM Table ID " + "in ACPI table header." + "The string may be up to 8 bytes in size"); + } static const TypeInfo pc_machine_info = { -- cgit v1.2.3 From 43e229a52b464099afa9449aef587b9a3419b470 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 2 Feb 2021 17:52:53 -0500 Subject: acpi: use constants as strncpy limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc is not smart enough to figure out length was validated before use as strncpy limit, resulting in this warning: inlined from ‘virt_set_oem_table_id’ at ../../hw/arm/virt.c:2197:5: /usr/include/aarch64-linux-gnu/bits/string_fortified.h:106:10: error: ‘__builtin_strncpy’ specified bound depends on the length of the source argument [-Werror=stringop-overflow=] Simplify things by using a constant limit instead. Fixes: 97fc5d507fca ("acpi: Permit OEM ID and OEM table ID fields to be changed") Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw/i386/pc.c') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 437977c49e..8aa85dec54 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1630,7 +1630,7 @@ static void pc_machine_set_oem_id(Object *obj, const char *value, Error **errp) return; } - strncpy(pcms->oem_id, value, len + 1); + strncpy(pcms->oem_id, value, 6); } static char *pc_machine_get_oem_table_id(Object *obj, Error **errp) @@ -1652,7 +1652,7 @@ static void pc_machine_set_oem_table_id(Object *obj, const char *value, "8 bytes in size"); return; } - strncpy(pcms->oem_table_id, value, len + 1); + strncpy(pcms->oem_table_id, value, 8); } static void pc_machine_initfn(Object *obj) -- cgit v1.2.3