Bug 266248 - efi comconsole does not work with ARM64 Hyper-V
Summary: efi comconsole does not work with ARM64 Hyper-V
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 13.1-STABLE
Hardware: arm64 Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-09-06 06:45 UTC by schakrabarti@microsoft.com
Modified: 2023-06-22 18:48 UTC (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description schakrabarti@microsoft.com 2022-09-06 06:45:26 UTC
The current implementation of efi comconsole does not work with ARM64 version of Microsoft Hyper-V. During boot up process, if the virtual serial console has been enabled, then the boot gets stuck in comc_probe(). 

In a Hyper-V VM on ARM64, "COM1" refers to a virtual PL011 UART that Hyper-V provides to the guest.
Set-VMFirmware  -VMName <vm> -console COM1 adds a ACPI table for SPCR.


The steps to reproduce this problem:

It is very easy to reproduce:

1) In Windows Hyper-V set a FreeBSD 13.0 VM

2) Use Powershell in Admin privileged mode and run following:

 Set-VMComPort -VMName <vm_name> -number 1 -path \\.\pipe\Testpipe

2) In another Powershell with Admin privilege run following:

3) start the VM and open putty to connect the \\.\pipe\Testpipe in serial mode.

No output will be seen on putty.

This problem is not there in FreeBSD 12.3 as there efi comconsole was not there in available consoles list.

ConOut value
efivar --device-path 8be4df61-93ca-11d2-aa0d-00e098032b8c-ConOut

8be4df61-93ca-11d2-aa0d-00e098032b8c-ConOut

: AcpiEx(VMBus,,)/VenHw(9b17e5a2-0891-42dd-b653-80b5c22809ba,02780ada77e3ac4a8e770558eb1073f8c7e020566280ce4daeb7520c7ef76171)
Comment 1 Warner Losh freebsd_committer freebsd_triage 2022-09-06 16:15:37 UTC
Is there a publicly available place to try to run thus?
Comment 2 schakrabarti@microsoft.com 2022-10-06 06:27:08 UTC
Is there any update on the fix?
Comment 3 Andrew Turner freebsd_committer freebsd_triage 2022-10-27 11:52:24 UTC
The hang is in the call to comc_port->sio->SetAttributes in efiserialio.c. If I comment it out I can get into the loader with the console set to comconsole.

I tried setting the receive fifo depth and timeout to be non-zero, but this didn't fix the issue.

This would appear to be a bug in the Hyper-V UEFI implementation as the data passed in looks valid.
Comment 4 schakrabarti@microsoft.com 2022-10-27 16:27:45 UTC
(In reply to Andrew Turner from comment #3)
But grub in Linux and also serial console implementation of FreeBSD kernel seems to work with the same. Only it is not working in comconsole of efiserial.
Comment 5 schakrabarti@microsoft.com 2022-10-27 16:27:45 UTC
(In reply to Andrew Turner from comment #3)
But grub in Linux and also serial console implementation of FreeBSD kernel seems to work with the same. Only it is not working in comconsole of efiserial.
Comment 6 schakrabarti@microsoft.com 2022-10-27 17:01:16 UTC
(In reply to Andrew Turner from comment #3)
Also if we use https://github.com/tianocore/edk2/tree/UDK2018/ShellBinPkg/UefiShell, for arm64 that works for the serial connection on Hyper-V arm64.
Comment 7 schakrabarti@microsoft.com 2022-10-27 17:01:16 UTC
(In reply to Andrew Turner from comment #3)
Also if we use https://github.com/tianocore/edk2/tree/UDK2018/ShellBinPkg/UefiShell, for arm64 that works for the serial connection on Hyper-V arm64.
Comment 8 Andrew Turner freebsd_committer freebsd_triage 2022-10-27 17:47:43 UTC
I don't know why it works there. All I can say is it enters into SetAttributes and deosn't appear to return, while running loader without calling SetAttributes will succeed in gettiong into the kernel.
Comment 9 Ed Maste freebsd_committer freebsd_triage 2022-10-27 17:59:35 UTC
It looks like EDK UefiShell only invokes SetAttributes() from the sermode command (ShellCommandRunSerMode), perhaps this is not executed in any default code path.

The FreeBSD kernel doesn't use UEFI SetAttributes, and I don't see it in Grub either.
Comment 10 Ed Maste freebsd_committer freebsd_triage 2022-10-27 18:10:33 UTC
Andy pointed out the call in grub -- they use different struct field names

static void
do_real_config (struct grub_serial_port *port)
{
...
  status = efi_call_7 (port->interface->set_attributes, port->interface,
                       port->config.speed,
                       0, 0, parities[port->config.parity],
                       port->config.word_len,
                       stop_bits[port->config.stop_bits]);
...
}
Comment 11 Warner Losh freebsd_committer freebsd_triage 2022-10-27 18:12:04 UTC
(In reply to Ed Maste from comment #10)
Have we verified that our EFI definition for the SetAttribute matches?
Comment 12 Andrew Turner freebsd_committer freebsd_triage 2022-10-27 18:32:50 UTC
It matches the UEFI 2.9 spec.
Comment 13 Toomas Soome freebsd_committer freebsd_triage 2022-11-09 06:13:37 UTC
What is the output from show efi-version?

I did test this code with qemu (when I did develop it) and vmware fusion tech preview (just today), both working as expected.

In mail to lwhsu@freebsd.org, I did suggest:

For an experiment, I’d suggest to use attribute values for defaults (0 for baud rate, 0 for fifo depth, 0 for timeout, DefaultParity, 0 for data bits and DefaultStopBits). This should not change anything but if system will still freeze, it would clearly suggest bug in firmware… And if so, I guess, we can not use SetAttributes there and must rely on values set in firmware. The archsw has function to test hypervisor, so that could be used to detect hyperv on arm… note, this code is not used on x86, there we use bios version.

Hope this helps...
Comment 14 Toomas Soome freebsd_committer freebsd_triage 2022-11-09 06:16:29 UTC
(In reply to Toomas Soome from comment #13)

this vmware fusion is reporting version 2.60;
Comment 15 Andrew Turner freebsd_committer freebsd_triage 2022-11-09 09:58:09 UTC
> What is the output from show efi-version?

On Hyper-V on a MS Dev Kit 2023 I get 2.70
Comment 16 schakrabarti@microsoft.com 2022-12-07 07:54:29 UTC
Any progress on this bug?
Comment 17 schakrabarti@microsoft.com 2022-12-14 10:46:31 UTC
(In reply to Toomas Soome from comment #13)
I have tried this, and it has worked on ARM64 Hyper-V.
diff --git a/stand/efi/loader/efiserialio.c b/stand/efi/loader/efiserialio.c
index 8b3f8e83e0b3..2a4357af5f24 100644
--- a/stand/efi/loader/efiserialio.c
+++ b/stand/efi/loader/efiserialio.c
@@ -494,8 +494,8 @@ comc_setup(void)
                return (false);

        status = comc_port->sio->SetAttributes(comc_port->sio,
-           comc_port->baudrate, 0, 0, comc_port->parity,
-           comc_port->databits, comc_port->stopbits);
+           0, 0, 0, DefaultParity,
+           0, DefaultStopBits);
        if (EFI_ERROR(status))
                return (false);

Should I put this to review?
Comment 18 Toomas Soome freebsd_committer freebsd_triage 2022-12-14 11:59:39 UTC
(In reply to schakrabarti@microsoft.com from comment #17)

Hm, ok, so with defaults (that is, use values provided by system firmware), there is no problem. In that case, I would suggest to set defaults in comc_probe() and leave this function as is -- so we still use defaults, but (in theory) can also support setting something non-default (on platform where there is no problem about it).

Does this make sense?
Comment 19 schakrabarti@microsoft.com 2022-12-15 19:48:44 UTC
(In reply to Toomas Soome from comment #18)
I have updated the review with the change
https://reviews.freebsd.org/D36052
Comment 20 Li-Wen Hsu freebsd_committer freebsd_triage 2023-01-06 10:32:43 UTC
(In reply to schakrabarti@microsoft.com from comment #19)
I've also tested this with QEMU (https://wiki.freebsd.org/arm64/QEMU) as I have no real arm64 hardware with UEFI. It also works fine.  I also asked other people with physical arm64 server with UEFI to test. I think this can be merged once we have good result from them.

BTW, after seeing https://reviews.freebsd.org/D36295 , I somehow suspect that Hyper-V just doesn't accept setting 9600 baud rate and cause hang since I believe "8, N, 1" is still widely used.

Souradeep, if you have time, can you help do tests of setting baud rate to 9600 and 115200?  I think using the firmware default is fine, but not sure if we should just set it to 115200.
Comment 21 Toomas Soome freebsd_committer freebsd_triage 2023-01-06 10:38:22 UTC
(In reply to Li-Wen Hsu from comment #20)

If system does allow setting [serial] console properties in firmware, it means that boot program should accept those settings, or the unsuspecting user will have bad surprise.
Comment 22 commit-hook freebsd_committer freebsd_triage 2023-02-03 10:02:10 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=a1f8a0c793c67ab5854035e017f34d3d016b6d0d

commit a1f8a0c793c67ab5854035e017f34d3d016b6d0d
Author:     Toomas Soome <tsoome@FreeBSD.org>
AuthorDate: 2023-02-02 14:01:02 +0000
Commit:     Toomas Soome <tsoome@FreeBSD.org>
CommitDate: 2023-02-03 09:53:32 +0000

    efiserialio: use port settings (sio->Mode) for initial setup

    Use serial port setup done by system firmware.
    ARM64 Hyper-V does hung if we attempt to override the defaults,
    therefore we should default to use settings from firmware.

    Tested by: schakrabarti@microsoft.com
    PR:             266248
    MFC after:      1 week

 stand/efi/loader/efiserialio.c | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)
Comment 23 commit-hook freebsd_committer freebsd_triage 2023-02-10 07:39:29 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=4b2322bba19d26f91d0f1a993798c52ebf45d41b

commit 4b2322bba19d26f91d0f1a993798c52ebf45d41b
Author:     Toomas Soome <tsoome@FreeBSD.org>
AuthorDate: 2023-02-02 14:01:02 +0000
Commit:     Toomas Soome <tsoome@FreeBSD.org>
CommitDate: 2023-02-10 07:37:49 +0000

    efiserialio: use port settings (sio->Mode) for initial setup

    Use serial port setup done by system firmware.
    ARM64 Hyper-V does hung if we attempt to override the defaults,
    therefore we should default to use settings from firmware.

    Tested by: schakrabarti@microsoft.com
    PR:             266248
    MFC after:      1 week

    (cherry picked from commit c243de11cf7c4bb3d67bbc1655b149037e5b04f1)

 stand/efi/loader/efiserialio.c | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)