devices: virtio: Always inject interrupts if hypervisor can handle

Gunyah hypervisor supports virtio-mmio transport only in some
products on which CrosVM is also used. Qualcomm has developed
a wrapper program which uses CrosVM's libdevices crate.

Gunyah hypervisor has some optimizations for how virtio-mmio
register access are handled. Normally they are synchronous access -
meaning any access of virtio-mmio register by a guest will cause
a fault, which requires blocking the guest VCPU until the access
can be served by CrosVM running in a different VM. Since that could
induce long delays for guest (esp since the OS in which CrosVM is
hosted is considered untrusted), Gunyah hypervisor caches all
virtio-mmio registers in its address space.
Any read access is handled without requiring intervention from CrosVM.
Write access is handled asynchronously - i,e a write will cause
hypervisor to updates its copy of the register, unblock the guest vcpu
and simultaneously notify CrosVM about the update.
By the time CrosVM gets to notice the update, guest could have
progressed lot more.

This works reasonably well for many devices and registers.
One problem case is writes to VIRTIO_MMIO_INTERRUPT_ACK, which signals
the guest having seen an interrupt. CrosVM seems to rely on synchronous
handling of this register write. Any attempts to kick guest via signal
method of 'struct Interrupt' (devices/src/virtio/interrupt.rs) skips
sending a kick if prior kick is "not yet" acknowledged, which fails
if writes to VIRTIO_MMIO_INTERRUPT_ACK is asynchronous.

This patch introduces a 'async_intr_status' flag in signal method which allows
the kick to be always delivered to guest independent of the status of
acknowledgement of prior kicks. Hypervisor will queue kick requests and
deliver another kick after current kick is processed.

Its expected that only the Qualcomm wrapper program will initialize the
interrupt object with 'async_intr_status' flag set and hence the upstream
CrosVM should not be affected because of this change.

BUG=b:243368499

Change-Id: I76568d9d8bc3be00c75c52d4a51d39410c5c35b3
3 files changed
tree: 3daa3f9d47adcf0b77259012b8cf4acc5efc7d96
  1. .cargo/
  2. .config/
  3. .devcontainer/
  4. .github/
  5. .vscode/
  6. aarch64/
  7. acpi_tables/
  8. anti_tamper/
  9. arch/
  10. argh_helpers/
  11. base/
  12. bit_field/
  13. broker_ipc/
  14. common/
  15. crash_report/
  16. cros_async/
  17. cros_fdt/
  18. cros_tracing/
  19. crosvm-fuzz/
  20. crosvm_cli/
  21. crosvm_control/
  22. crosvm_plugin/
  23. cuttlefish/
  24. devices/
  25. disk/
  26. docs/
  27. e2e_tests/
  28. fuse/
  29. gpu_display/
  30. hypervisor/
  31. infra/
  32. io_uring/
  33. jail/
  34. kernel_cmdline/
  35. kernel_loader/
  36. kvm/
  37. kvm_sys/
  38. libcras_stub/
  39. linux_input_sys/
  40. logo/
  41. media/
  42. metrics/
  43. net_sys/
  44. net_util/
  45. patches/
  46. power_monitor/
  47. prebuilts/
  48. proto_build_tools/
  49. protos/
  50. qcow_utils/
  51. resources/
  52. rutabaga_gfx/
  53. sandbox/
  54. serde_keyvalue/
  55. src/
  56. swap/
  57. system_api/
  58. tests/
  59. third_party/
  60. tools/
  61. tpm2/
  62. tpm2-sys/
  63. tube_transporter/
  64. usb_sys/
  65. usb_util/
  66. vfio_sys/
  67. vhost/
  68. virtio_sys/
  69. vm_control/
  70. vm_memory/
  71. win_audio/
  72. win_util/
  73. x86_64/
  74. .dockerignore
  75. .gitignore
  76. .rustfmt.toml
  77. android-fork-stats.sh
  78. android-merge-1-setup.sh
  79. android-merge-2-cargo-embargo.sh
  80. Android.bp
  81. ARCHITECTURE.md
  82. Cargo.lock
  83. Cargo.toml
  84. cargo2android_defaults.bp
  85. cargo2android_module.bp.patch
  86. cargo_embargo.json
  87. CONTRIBUTING.md
  88. DIR_METADATA
  89. LICENSE
  90. METADATA
  91. mypy.ini
  92. OWNERS
  93. OWNERS.android
  94. OWNERS_COUNCIL
  95. PRESUBMIT.cfg
  96. PREUPLOAD.cfg
  97. pyproject.toml
  98. README.chromeos.md
  99. README.md
  100. rust-toolchain
  101. TEST_MAPPING
README.md

crosvm - The ChromeOS Virtual Machine Monitor

crosvm is a virtual machine monitor (VMM) based on Linux’s KVM hypervisor, with a focus on simplicity, security, and speed. crosvm is intended to run Linux guests, originally as a security boundary for running native applications on the ChromeOS platform. Compared to QEMU, crosvm doesn’t emulate architectures or real hardware, instead concentrating on paravirtualized devices, such as the virtio standard.

crosvm is currently used to run Linux/Android guests on ChromeOS devices.

Logo