microsoft / openvmm

Home of OpenVMM and OpenHCL.
http://openvmm.dev/
MIT License
1.36k stars 59 forks source link

PCAT firmware cannot be extracted from vmfirmware.dll on windows arm64 #161

Closed wisemanny closed 1 day ago

wisemanny commented 3 days ago

I tried to load Windows x64 from vhdx on Arm64 windows (not even sure it will work, but did not get there yet, experimenting). The vhdx uses MBR partitioning. So, I use --pcat parameter. openvmm complains that it cannot find resource (the firmware), though I can see it in the dll:

Image

Versions:

❯ rustc --version
rustc 1.82.0 (f6e511eec 2024-10-15)

OS Name:                       Microsoft Windows 11 Pro
OS Version:                    10.0.26100 N/A Build 26100
OS Manufacturer:               Microsoft Corporation
OS Configuration:              Standalone Workstation
OS Build Type:                 Multiprocessor Free
Registered Owner:              ****
Registered Organization:       N/A
Product ID:                    *****
Original Install Date:         9/23/2024, 3:04:09 PM
System Boot Time:              10/8/2024, 10:46:24 PM
System Manufacturer:           Microsoft Corporation
System Model:                  Microsoft Surface Laptop, 7th Edition
System Type:                   ARM64-based PC
Processor(s):                  1 Processor(s) Installed.
                               [01]: ARMv8 (64-bit) Family 8 Model 1 Revision 201 Qualcomm Technologies Inc ~3417 Mhz

openvmm is the latest version from git compiled on windows as:

cargo build --target=x86_64-pc-windows-msvc

Backtrace:

fatal error: no entry for id found

Stack backtrace:
   0: std::backtrace_rs::backtrace::dbghelp64::trace
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/std\src\..\..\backtrace\src\backtrace\dbghelp64.rs:91
   1: std::backtrace_rs::backtrace::trace_unsynchronized
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/std\src\..\..\backtrace\src\backtrace\mod.rs:66
   2: std::backtrace::Backtrace::create
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/std\src\backtrace.rs:331
   3: std::backtrace::Backtrace::capture
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/std\src\backtrace.rs:296
   4: anyhow::context::impl$1::context<ref$<object::pe::ImageResourceDirectoryEntry>,ref$<str$> >
             at C:\Users\maxim\scoop\persist\rustup\.cargo\registry\src\index.crates.io-6f17d22bba15001f\anyhow-1.0.79\src\backtrace.rs:27
   5: hvlite_pcat_locator::resource_dll_parser::try_find_resource_from_dll
             at .\openvmm\hvlite_pcat_locator\src\resource_dll_parser.rs:42
   6: hvlite_pcat_locator::parse_rom_file
             at .\openvmm\hvlite_pcat_locator\src\lib.rs:132
   7: hvlite_pcat_locator::find_pcat_bios
             at .\openvmm\hvlite_pcat_locator\src\lib.rs:61
   8: hvlite_entry::vm_config_from_command_line<ref$<pal_async::io_pool::IoDriver<pal_async::sys::iocp::IocpBackend> > >
             at .\openvmm\hvlite_entry\src\lib.rs:714
   9: hvlite_entry::run_control::async_fn$0
             at .\openvmm\hvlite_entry\src\lib.rs:1670
  10: hvlite_entry::do_main::closure$1::async_block$0
             at .\openvmm\hvlite_entry\src\lib.rs:1434
  11: futures_util::future::maybe_done::impl$3::poll<enum2$<hvlite_entry::do_main::closure$1::async_block_env$0> >
             at C:\Users\maxim\scoop\persist\rustup\.cargo\registry\src\index.crates.io-6f17d22bba15001f\futures-util-0.3.30\src\future\maybe_done.rs:95
  12: futures_util::future::join::impl$2::poll<enum2$<hvlite_entry::do_main::closure$1::async_block_env$0>,enum2$<pal_async::task::impl$6::run::async_fn_env$0> >      
             at C:\Users\maxim\scoop\persist\rustup\.cargo\registry\src\index.crates.io-6f17d22bba15001f\futures-util-0.3.30\src\future\join.rs:55
  13: pal_async::io_pool::impl$1::run_with::async_block$1<pal_async::sys::iocp::IocpBackend,hvlite_entry::do_main::closure_env$1,enum2$<hvlite_entry::do_main::closure$1::async_block_env$0> >
             at .\support\pal\pal_async\src\io_pool.rs:78
  14: core::future::future::impl$1::poll<ref_mut$<enum2$<pal_async::io_pool::impl$1::run_with::async_block_env$1<pal_async::sys::iocp::IocpBackend,hvlite_entry::do_main::closure_env$1,enum2$<hvlite_entry::do_main::closure$1::async_block_env$0> > > > >
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library\core\src\future\future.rs:123
  15: futures_util::future::future::FutureExt::poll_unpin<core::pin::Pin<ref_mut$<enum2$<pal_async::io_pool::impl$1::run_with::async_block_env$1<pal_async::sys::iocp::IocpBackend,hvlite_entry::do_main::closure_env$1,enum2$<hvlite_entry::do_main::closure$1::async
             at C:\Users\maxim\scoop\persist\rustup\.cargo\registry\src\index.crates.io-6f17d22bba15001f\futures-util-0.3.30\src\future\future\mod.rs:558
  16: pal_async::sys::iocp::impl$2::run<enum2$<pal_async::io_pool::impl$1::run_with::async_block_env$1<pal_async::sys::iocp::IocpBackend,hvlite_entry::do_main::closure_env$1,enum2$<hvlite_entry::do_main::closure$1::async_block_env$0> > > >
             at .\support\pal\pal_async\src\windows\iocp.rs:173
  17: pal_async::io_pool::IoPool<pal_async::sys::iocp::IocpBackend>::run_with<pal_async::sys::iocp::IocpBackend,hvlite_entry::do_main::closure_env$1,enum2$<hvlite_entry::do_main::closure$1::async_block_env$0> >
             at .\support\pal\pal_async\src\io_pool.rs:76
  18: hvlite_entry::do_main
             at .\openvmm\hvlite_entry\src\lib.rs:1432
  19: hvlite_entry::hvlite_main
             at .\openvmm\hvlite_entry\src\lib.rs:141
  20: openvmm::main
             at .\openvmm\openvmm\src\main.rs:16
  21: core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library\core\src\ops\function.rs:250
  22: core::hint::black_box
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library\core\src\hint.rs:388
  23: std::sys::backtrace::__rust_begin_short_backtrace<void (*)(),tuple$<> >
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library\std\src\sys\backtrace.rs:154
  24: std::rt::lang_start::closure$0<tuple$<> >
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library\std\src\rt.rs:164
  25: std::rt::lang_start_internal::closure$2
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/std\src\rt.rs:143
  26: std::panicking::try::do_call
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/std\src\panicking.rs:554
  27: std::panicking::try
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/std\src\panicking.rs:518
  28: std::panic::catch_unwind
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/std\src\panic.rs:345
  29: std::rt::lang_start_internal
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/std\src\rt.rs:143
  30: std::rt::lang_start<tuple$<> >
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library\std\src\rt.rs:163
  31: main
  32: invoke_main
             at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
  33: __scrt_common_main_seh
             at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
  34: ExitProcess
  35: ExitProcess
  36: ZwWaitLowEventPair
error: process didn't exit successfully: `target\x86_64-pc-windows-msvc\debug\openvmm.exe --pcat` (exit code: 1)

It fails here: https://github.com/microsoft/openvmm/blob/main/openvmm/hvlite_pcat_locator/src/resource_dll_parser.rs#L24

Calling "rsrc.root()" returns back Err:

Image

Should I submit the report directly to object?

daprilik commented 2 days ago

I tried to load Windows x64 from vhdx on Arm64 windows (not even sure it will work, but did not get there yet, experimenting).

Unfortunately, that will not work.

Like most other VMMs, OpenVMM requires the Host and Guest architectures to match (i.e: x86 on x86, Aarch64 on Aarch64, etc...). It would be awesome if OpenVMM could someday support a CPU-emulation mode (e.g: similar to QEMU's TCG) to support these sorts of mixed-arch use-cases, but this is not a supported scenario at this time.

As for your error regarding no entry for id found: OpenVMM searches for the PCAT BIOS firmware that is packaged alongside Hyper-V, and I believe that Aarch64 builds of vmfirmware.dll do not include a copy of the x86 PCAT BIOS, given that Hyper-V does not support booting x86 BIOS-based VMs on ARM. As such, its no surprise that it wasn't able to find the corresponding ID in the DLL.


As a follow-up, we may want to look into adding some better user-facing error messages when --pcat is used on non-x86 platforms.

wisemanny commented 1 day ago

@daprilik thank you for the detailed answer.

Regarding the firmware, I see it is there, but ID seems to be different (probably because of aarch64), it has id of 13505 while it looks for 13500. I will close the issue.

smalis-msft commented 1 day ago

13505 is a different firmware blob, not the PCAT blob. We definitely could improve the messaging here, but yeah there's no PCAT blob to be found on the ARM64 vmfirmware.dll.