Reading and writing in a vdev
When a guest reads from or writes to a vdev, the vdev must perform actions analogous to the actions that hardware performs in response to reads and writes.
*_vread() and *_vwrite()
When you implement a vdev it is important to remember that you are creating a device that, from the perspective of the guest, is indistinguishable from hardware. Thus, when the guest reads, your vdev must write what it is trying to read; when the guest writes, your vdev must read what it has written.
The diagram below illustrates how *_vread() and *_vwrite() functions call the corresponding guest_cpu_write() and guest_cpu_read() functions.
Remember that if the vdev acts as an intermediary between the guest and a hardware device (e.g., vdev ser8250), to the guest the vdev is indistinguishable from hardware, but in the hypervisor host (where vdevs run) the vdev is just another application interacting with a hardware driver.
Para-virtualized devicesin the
Advanced Topicschapter).
vopnd and oopnd
The *_vread() and *_vwrite() functions in the source
code examples that call guest_cpu_*() functions (see the guest.h
chapter in the Virtual Device Developer's API Reference)
use vopnd and oopnd in their arguments. For example,
in the trace vdev's vdtrace_vwrite() function, you
will find the following:
...
if (vopnd->location == vdp->v_block.location) {
const int err = guest_cpu_read(gcp, GXF_NONE, oopnd, 1, &counter, vopnd->length);
if (err != EOK) {
return guest_cpu_to_vrs(err);
}
...
- vopnd
- Virtual device operand. The operand that caused the guest exit. Typically this will be a guest-physical memory location, though it might be something else (e.g., on x86, it could be a guest I/O port location).
- oopnd
- Other operand. Refers to another data element; the data type and
its location (e.g., PCI, CPU registers) depend on the value of the
qvm_state_block
type member (see
Data elements and their types
in this chapter).
