Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Guide/src/reference/openvmm/management/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ describes the source definitions.

The kernel must be an uncompressed ELF64 image. The profile owns the base command line
(`earlycon=xe9 console=hvc0 reboot=t panic=-1`) and switches the primary
console to `hvc1` when `--virtio-console` is present. It appends
console to `hvc1` when `--virtio-console` is present. The portb console,
`hvc0`, takes no host input, so an interactive guest console needs
`--virtio-console console`; without a boot console on the terminal, portb
writes to stdout, and OpenVMM discards keystrokes until Ctrl-Q opens the
REPL. It appends
`nr_cpus=<capacity>` from the validated processor topology. It reserves a 1-GiB
MMIO gap from 3 to 4 GiB and exposes only PIC/IOAPIC, PIT, a CMOS RTC
anchored to UTC,
Expand Down Expand Up @@ -1006,7 +1010,8 @@ Serial devices can be configured to appear as different devices inside the guest
* `--virtio-console <BACKEND>`: Expose a virtio console device. It normally
appears as `/dev/hvc0`. Under `--machine microvm`, it occupies fixed MMIO
`0xd0002000`, IRQ 18, and is selected as `/dev/hvc1`; the raw portb path
remains available as `hvc0` for early output and recovery.
remains available as `hvc0` for early output and failure reports, and takes
no host input.

A microVM accepts these explicit attachment policies:

Expand Down
2 changes: 1 addition & 1 deletion Guide/src/reference/openvmm/management/grpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ restore flow over both transports:
absent, or may contain only the matching microVM profile, an optional exact
processor-count assertion, a `cpu_profile` that the restore accepts (see
below), serial port 0 host
attachment, matching `DevicesConfig.virtio_consoles` and
attachment, which receives portb's output and is never read, matching `DevicesConfig.virtio_consoles` and
`DevicesConfig.virtiofs_config` attachments, and guest power actions.
Guest-visible boot, memory, processor topology, other device, NUMA, and PCIe
fields are rejected. A saved listener is reconstructed from the manifest; a saved
Expand Down
25 changes: 17 additions & 8 deletions openvmm/openvmm_entry/src/microvm/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,13 @@ impl<'a> MicrovmConfigBuilder<'a> {
}
}

/// Connects the host side of the portb console (`hvc0`).
/// Connects the host side of the portb console (`hvc0`), which takes no
/// host input.
///
/// This must run before the other serial devices so that portb owns the
/// interactive console when the boot virtio-console does not.
/// When the boot virtio-console does not own the terminal, portb does: it
/// writes to stdout, and OpenVMM discards keystrokes until Ctrl-Q opens
/// the REPL. This must run before the other serial devices, which would
/// otherwise take the terminal.
pub(crate) fn setup_portb(
&mut self,
console_state: &RefCell<Option<ConsoleState<'static>>>,
Expand All @@ -273,6 +276,7 @@ impl<'a> MicrovmConfigBuilder<'a> {
"microvm-portb",
backend,
"hvc0",
false,
console_state,
serial_driver,
)?;
Expand Down Expand Up @@ -330,6 +334,7 @@ impl<'a> MicrovmConfigBuilder<'a> {
"virtio-console",
SerialConfigCli::Console,
"hvc1",
true,
console_state,
serial_driver,
)?;
Expand Down Expand Up @@ -865,11 +870,13 @@ fn aggregate_child_kind(

/// Connects a portb or boot virtio-console endpoint to the host console or
/// stderr, returning its backend, its output-relay completion, and, for the
/// console, the drain of its relay.
/// console, the drain of its relay. The device receives the console's input
/// when `input` is set; otherwise, OpenVMM discards it.
fn setup_host_console(
name: &str,
backend: SerialConfigCli,
device: &'static str,
input: bool,
console_state: &RefCell<Option<ConsoleState<'static>>>,
serial_driver: &DefaultDriver,
) -> anyhow::Result<(
Expand All @@ -885,10 +892,12 @@ fn setup_host_console(
let (config, serial, pending) =
serial_io::anonymous_serial_pair_with_pending(serial_driver)?;
let (serial_read, serial_write) = AsyncReadExt::split(serial);
*console_state.borrow_mut() = Some(ConsoleState {
device,
input: Box::new(serial_write),
});
let input: Box<dyn futures::AsyncWrite + Unpin + Send> = if input {
Box::new(serial_write)
} else {
Box::new(futures::io::sink())
};
*console_state.borrow_mut() = Some(ConsoleState { device, input });
let (completed, relay) =
spawn_drainable_output(name, serial_read, pending, term::raw_stdout())?;
(config, completed, Some(relay))
Expand Down
Loading
Loading