The ACPI SPCR (Serial Port Console Redirection) table allows firmware
to specify a preferred serial console device to the operating system.
On ARM64 systems, Linux by default respects this table: even if the
kernel command line does not include a hardware serial console (e.g.,
"console=ttyAMA0"), the kernel still register the serial device
referenced by SPCR as a printk console.
While this behavior is standard-compliant, it can lead to situations
where guest console behavior is influenced by platform firmware rather
than user-specified configuration. To make guest console behavior more
predictable and under user control, this patch introduces a machine
option to explicitly disable SPCR table exposure:
-machine spcr=off
By default, the option is enabled (spcr=on), preserving existing
behavior. When disabled, QEMU will omit the SPCR table from the guest's
ACPI namespace, ensuring that only consoles explicitly declared in the
kernel command line are registered.
Signed-off-by: Li Chen <chenl311@chinatelecom.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
Message-Id: <
20250528105404.457729-2-me@linux.beauty>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
}
acpi_add_table(table_offsets, tables_blob);
- spcr_setup(tables_blob, tables->linker, vms);
+
+ if (ms->acpi_spcr_enabled) {
+ spcr_setup(tables_blob, tables->linker, vms);
+ }
acpi_add_table(table_offsets, tables_blob);
build_dbg2(tables_blob, tables->linker, vms);
ms->nvdimms_state->is_enabled = value;
}
+static bool machine_get_spcr(Object *obj, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ return ms->acpi_spcr_enabled;
+}
+
+static void machine_set_spcr(Object *obj, bool value, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ ms->acpi_spcr_enabled = value;
+}
+
static bool machine_get_hmat(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
"Table (HMAT)");
}
+ /* SPCR */
+ ms->acpi_spcr_enabled = true;
+ object_property_add_bool(obj, "spcr", machine_get_spcr, machine_set_spcr);
+ object_property_set_description(obj, "spcr",
+ "Set on/off to enable/disable "
+ "ACPI Serial Port Console Redirection "
+ "Table (spcr)");
+
/* default to mc->default_cpus */
ms->smp.cpus = mc->default_cpus;
ms->smp.max_cpus = mc->default_cpus;
acpi_add_table(table_offsets, tables_blob);
build_srat(tables_blob, tables->linker, machine);
acpi_add_table(table_offsets, tables_blob);
- spcr_setup(tables_blob, tables->linker, machine);
+
+ if (machine->acpi_spcr_enabled)
+ spcr_setup(tables_blob, tables->linker, machine);
if (machine->numa_state->num_nodes) {
if (machine->numa_state->have_numa_distance) {
}
acpi_add_table(table_offsets, tables_blob);
- spcr_setup(tables_blob, tables->linker, s);
+
+ if (ms->acpi_spcr_enabled) {
+ spcr_setup(tables_blob, tables->linker, s);
+ }
acpi_add_table(table_offsets, tables_blob);
{
SmpCache smp_cache;
struct NVDIMMState *nvdimms_state;
struct NumaState *numa_state;
+ bool acpi_spcr_enabled;
};
/*
" nvdimm=on|off controls NVDIMM support (default=off)\n"
" memory-encryption=@var{} memory encryption object to use (default=none)\n"
" hmat=on|off controls ACPI HMAT support (default=off)\n"
+ " spcr=on|off controls ACPI SPCR support (default=on)\n"
#ifdef CONFIG_POSIX
" aux-ram-share=on|off allocate auxiliary guest RAM as shared (default: off)\n"
#endif
Enables or disables ACPI Heterogeneous Memory Attribute Table
(HMAT) support. The default is off.
+ ``spcr=on|off``
+ Enables or disables ACPI Serial Port Console Redirection Table
+ (SPCR) support. The default is on.
+
``aux-ram-share=on|off``
Allocate auxiliary guest RAM as an anonymous file that is
shareable with an external process. This option applies to