Skip to content

Commit 67d0278

Browse files
ppennaCopilot
andauthored
openvmm: pin the microVM byte channel without host input
Move the openvmm gitlink from 5aa8b0285, the head of microsoft/openvmm#4894, to 4713c539a, the head of microsoft/openvmm#4887, which is stacked on microsoft/openvmm#4886 and - de29849a4 vmm_tests: drive the microVM guests without portb input - 4713c539a microVM: remove portb's host input The byte channel, portb, no longer reads its host endpoint: its status bit 0 stays clear, a read of its data port without a selected record returns zeros, and a restore refuses saved state that holds host input, as a snapshot of an earlier OpenVMM can. Since no read reports that a peer of a listening endpoint left, portb asks the backend instead, and waits for the next peer, which receives the output buffered meanwhile. A terminal without a boot console keeps the channel's output and raw mode, OpenVMM discards its keystrokes, and Ctrl-Q still opens the REPL. Host input reaches a guest only through its boot or control console, which nvx-rs run, one-shot sandboxes, and the test and benchmark harnesses now attach. The microVM ABI version stays, since a host that sends no input is one that every guest already handles. The platform control device's specification drops host input, the receive buffer, input gating, and the input flag of status bit 0, and the consoles, the boot protocol, and the run guide say that the boot console is the guest's only interactive input. The protocol vectors, the excerpts and contract versions that nvx-rs copies from OpenVMM, and its CPU profiles match the revision's. On nvx-kvm-test (Linux/KVM, virtual machine), with a release build of the revision before the boot console's exit drain and the disconnect handling, input piped into OpenVMM without a boot console no longer reached the guest, which timed out, while the guest's output stayed on the terminal; with --virtio-console console the input reached the guest's shell. On a terminal, OpenVMM discarded keystrokes and Ctrl-Q opened its REPL. Every default Alpine test-microvm scenario, CI's Ubuntu and Azure Linux sets, and one sample of the benchmark suites passed there with the harnesses of the boot console. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ae236d6 commit 67d0278

5 files changed

Lines changed: 41 additions & 35 deletions

File tree

‎doc/design/3.1-platform-control-device.md‎

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ platform uses.
1010

1111
| Port | Function | Architectural purpose |
1212
| ---: | --- | --- |
13-
| `0xe9..0xeb` | Host/guest byte channel | Early console data, bounded host input, restore metadata, generation identity, and host time samples |
13+
| `0xe9..0xeb` | Host/guest byte channel | Early console data, restore metadata, generation identity, and host time samples |
1414
| `0x604` | Shutdown | Guest-requested process termination with a status byte |
1515
| `0x605` | Snapshot request | Guest-initiated capture and post-restore acknowledgement |
1616

@@ -26,8 +26,10 @@ machine omits, and carries:
2626

2727
- The guest's console. The kernel writes its boot messages to the channel
2828
from early in its initialization, before it probes any driver, and the
29-
channel is also the kernel console, with host input, unless a
30-
[boot console](3.3-consoles.md#331-boot-console) is configured.
29+
channel is also the kernel console unless a
30+
[boot console](3.3-consoles.md#331-boot-console) is configured. The channel
31+
takes no host input, so host input reaches the guest only through its
32+
[consoles](3.3-consoles.md).
3133
- Failure reports from the guest agents, including failures of the control
3234
console.
3335
- The one-time [restore packet](5.5-restore-protocol.md#555-restore-packet),
@@ -54,10 +56,10 @@ silently lost; see
5456

5557
The channel's protocol is also minimal: it needs no feature negotiation,
5658
queues in guest memory, or interrupt line. Each output byte is one port write,
57-
and the guest polls a status port for input. Every access to the channel's
58-
ports is a synchronous exit that the VMM completes before the guest continues,
59-
so a host time that the VMM records during an access lies between two guest
60-
TSC reads taken around it. The guest checks each
59+
and the guest reads records and status with port reads. Every access to the
60+
channel's ports is a synchronous exit that the VMM completes before the guest
61+
continues, so a host time that the VMM records during an access lies between
62+
two guest TSC reads taken around it. The guest checks each
6163
[time sample](3.2-clock-and-time.md#329-time-samples)'s pairing of host UTC
6264
with its TSC against them.
6365

@@ -68,7 +70,7 @@ port, a status and record-selector port, and a time-sample window.
6870

6971
| Port | Access | Behavior |
7072
| ---: | --- | --- |
71-
| `0xe9` | Read and write | Raw byte input and output. A console read consumes one pending byte and zero-fills the rest of the access. With a record selected, a 1-, 2-, or 4-byte read returns that many bytes of the record, little-endian and zero-filled past its end. |
73+
| `0xe9` | Read and write | Raw byte output. Without a selected record, a read returns zeros. With a record selected, a 1-, 2-, or 4-byte read returns that many bytes of the record, little-endian and zero-filled past its end. |
7274
| `0xea` | Read | Status bits, listed in Table 3.3 |
7375
| `0xea` | Write | Record selector: `0xa5` selects the one-time [restore packet](5.5-restore-protocol.md#555-restore-packet), `0xa6` selects the 16-byte generation ID, and `0xa7` latches a fresh [time sample](3.2-clock-and-time.md#329-time-samples) without changing the `0xe9` selection |
7476
| `0xeb` | Read | The next bytes of the latched time sample, zero-filled past its end or when no sample is latched |
@@ -79,7 +81,7 @@ Table 3.3 lists the status bits.
7981

8082
| Status bit | Meaning |
8183
| ---: | --- |
82-
| 0 | Host input is pending |
84+
| 0 | Zero: the channel takes no host input |
8385
| 1 | A fresh restore packet is available |
8486
| 2 | The restore carries a processor target |
8587
| 3 | The restore carries a memory target |
@@ -99,22 +101,22 @@ how a restored guest checks the ID, and
99101
[Entropy Refresh](5.5-restore-protocol.md#558-entropy-refresh) how it obtains
100102
fresh random numbers.
101103

102-
The time-sample window is separate from the data port because the guest
103-
console driver polls status and reads data from a timer context, so a sample
104-
on the console stream could interleave with input bytes. Guest users of the
105-
selectors serialize their transactions. Every byte the guest reads is a port
106-
exit, so records are small and readable four bytes per exit.
107-
108-
The receive and transmit buffers are each bounded at 1 MiB. Output overflow
109-
drops the newest bytes and emits a rate-limited warning; input applies
110-
backpressure by not reading the host endpoint while its buffer is full.
111-
Pending bytes are saved, so capture does not silently lose VMM-owned I/O. The
112-
time-sample window is not saved state.
113-
114-
While host input is gated for a snapshot boundary or post-restore repair, the
115-
channel stops reading its host endpoint, returns zero for console reads, and
116-
clears the input-pending bit. Guest output, the generation ID, any restore
117-
packet, and the time-sample window remain available.
104+
The time-sample window is separate from the data port, so that the guest can
105+
latch and read a sample without changing the data port's record selection.
106+
Guest users of the selectors serialize their transactions. Every byte the
107+
guest reads is a port exit, so records are small and readable four bytes per
108+
exit.
109+
110+
The transmit buffer is bounded at 1 MiB. Overflow drops the newest bytes and
111+
emits a rate-limited warning. Pending output is saved, so capture does not
112+
silently lose VMM-owned output, and a restore refuses saved state that holds
113+
host input, as a snapshot of an earlier VMM can. The time-sample window is not
114+
saved state.
115+
116+
Since the channel takes no host input, gating host input for a snapshot
117+
boundary or post-restore repair leaves it unchanged: guest output, the
118+
generation ID, any restore packet, and the time-sample window remain
119+
available.
118120

119121
## 3.1.2 Shutdown
120122

‎doc/design/3.3-consoles.md‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ endpoints, saved state, and reconnect policies.
1515
## 3.3.1 Boot Console
1616

1717
The optional boot console carries boot messages and an ordinary byte stream.
18-
The kernel console uses it once its driver is ready, and the byte channel
19-
remains the early console. Host RX accepted by the device and partial guest TX
20-
progress are device-private saved state, so restore never replays a
18+
It is the only console for interactive host input, since the
19+
[byte channel](3.1-platform-control-device.md#311-hostguest-byte-channel)
20+
takes none. The kernel console uses it once its driver is ready, and the byte
21+
channel remains the early console. Host RX accepted by the device and partial
22+
guest TX progress are device-private saved state, so restore never replays a
2123
descriptor from byte zero or silently loses VMM-owned data.
2224

2325
The host attachment is one of:

‎doc/design/5.1-boot-protocol.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ earlycon=xe9 console=hvc0 reboot=t panic=-1
5555
```
5656

5757
When the boot virtio-console is present, the kernel console becomes `hvc1`,
58-
and the byte channel remains the early console. User arguments follow the
58+
and the byte channel remains the early console. Without it, the kernel console
59+
stays on the byte channel, which takes no host input. User arguments follow the
5960
base tokens. A fresh boot then appends host-owned tokens in this order:
6061

6162
1. `nr_cpus=<capacity>`, so Linux sizes its processor state to the validated

‎doc/run.md‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,12 @@ Most `nvx-rs run` options pass through unchanged: `--machine`, `--processors`,
377377

378378
Always include `--single-process`. Include `--virtio-console console` to type
379379
into the guest's shell on a fresh boot: without a boot console, the guest's
380-
console is the byte channel, `hvc0`. A restore keeps the console of its
381-
snapshot. OpenVMM requires `--virtio-console console` again to restore a
382-
snapshot of a boot that passed it, and refuses `--virtio-console` for a
383-
snapshot without a boot console. `nvx-rs run` passes the option to a fresh boot
384-
only, so it cannot yet restore a snapshot of a boot with it
380+
console is the byte channel, `hvc0`, which takes no input, so OpenVMM discards
381+
the terminal's keystrokes, though Ctrl-Q still opens its REPL. A restore keeps
382+
the console of its snapshot. OpenVMM requires `--virtio-console console` again
383+
to restore a snapshot of a boot that passed it, and refuses `--virtio-console`
384+
for a snapshot without a boot console. `nvx-rs run` passes the option to a
385+
fresh boot only, so it cannot yet restore a snapshot of a boot with it
385386
([#1254](https://github.com/microsoft/nvx/issues/1254)). When restoring, omit
386387
`--memory`, `--kernel`, `--initrd`, and `--net`, whose addresses the snapshot
387388
keeps; see [Networked snapshots](#networked-snapshots). Every restore gives the

0 commit comments

Comments
 (0)