https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=299090

            Bug ID: 299090
           Summary: loader.efi: hw.uart.console in loader.conf is replaced
                    by the SPCR value
           Product: Base System
           Version: 15.1-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: [email protected]
          Reporter: [email protected]

Created attachment 275337
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=275337&action=edit
[PATCH] loader.efi: Don't replace a hw.uart.console set by the user

DESCRIPTION

When the firmware provides an ACPI SPCR table, a hw.uart.console line in
loader.conf has no effect.  At the OK prompt, "show hw.uart.console" prints
the value derived from the SPCR, not the one from loader.conf.

check_acpi_spcr() sets hw.uart.console unconditionally.  It is called from
parse_uefi_con_out(), which runs once in main() and again from
efi_console.c whenever the console mode is updated.  loader.lua runs
efi-autoresizecons right after config.load(), so the order is:

  1. main(): hw.uart.console = SPCR value
  2. loader.conf: hw.uart.console = the user's value (setenv succeeds)
  3. efi-autoresizecons -> parse_uefi_con_out() -> check_acpi_spcr():
     hw.uart.console = SPCR value again

I confirmed step 2 by printing from config.lua's setEnv(): the user's value
is set and reads back, and it is gone by the time local.lua runs.  Setting
the variable at the OK prompt works, because nothing runs the SPCR code
after that.

This leaves no persistent way to correct or override what the SPCR says,
for example when the table describes the UART wrongly or the user wants a
different port or speed.

Related: PR 292206, fixed by d82698ac68 ("loader.efi: Only use SPCR if
enabled"), was a case of the SPCR producing a bad hw.uart.console.  Its
commit message notes "While one could unset this value to boot, you
couldn't do that automatically very easily."  This is the same problem in
general: with this patch, loader.conf can correct whatever the SPCR says.

The attached patch skips the SPCR translation when hw.uart.console is
already set, as the x86 code in bootinfo.c already does ("if someone
specifically setup hw.uart.console, don't override that").  At the first
call nothing has set it yet, so the default behaviour doesn't change.


AFFECTED VERSIONS

main, stable/15 and releng/15.1.  check_acpi_spcr() came in with
70253b538f68 ("loader.efi: Parse SPCR table entry in ACPI tables"), so 14.x
is not affected.


HOW TO REPEAT

On an EFI system whose firmware provides SPCR, put a hw.uart.console line
in /boot/loader.conf, stop at the OK prompt and run
"show hw.uart.console".

I used QEMU's riscv virt machine with its bundled EDK2 firmware, which
provides SPCR, and hw.uart.console="mm:0x10000000,rs:0,br:115200".  That
table gives a 32-bit register stride for a byte-spaced UART (being reported
to QEMU), so the SPCR value can't boot the kernel and the loader.conf value
is needed.


TESTED

riscv64 15.1-RELEASE-p3 world, kernel with the uart_cpu_fdt.c NULL-tag fix
from PR 299089, hw.uart.console in loader.conf:

  loader             result
  15.1-RELEASE-p3    loader.conf value replaced; kernel faults (rs:2)
  with patch         loader.conf value kept; boots to multi-user

Without a loader.conf setting the patched loader passes the SPCR value as
before.  Not tested on arm64 or amd64.


ATTACHMENTS

0001-loader.efi-Don-t-replace-a-hw.uart.console-set-by-th.patch
  against main ff2efe65a89a

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to