Expand description

IO Device Manager to handle trapped MMIO/PIO access requests.

The IoManager is responsible for managing all trapped MMIO/PIO accesses for virtual devices. It cooperates with the Secure Sandbox/VMM and device drivers to handle trapped accesses. The flow is as below:

  • device drivers allocate resources from the VMM/resource manager, including trapped MMIO/PIO address ranges.
  • the device manager registers devices to the IoManager with trapped MMIO/PIO address ranges.
  • VM IO Exit events get triggered when the guest accesses those trapped address ranges.
  • the vmm handle those VM IO Exit events, and dispatch them to the IoManager.
  • the IoManager invokes registered callbacks/device drivers to handle those accesses, if there is a device registered for the address.

Examples

Creating a dummy deivce which implement DeviceIo trait, and register it to IoManager with trapped MMIO/PIO address ranges:

use std::sync::Arc;
use std::any::Any;

use dbs_device::device_manager::IoManager;
use dbs_device::resources::{DeviceResources, Resource};
use dbs_device::{DeviceIo, IoAddress, PioAddress};

struct DummyDevice {}

impl DeviceIo for DummyDevice {
    fn read(&self, base: IoAddress, offset: IoAddress, data: &mut [u8]) {
        println!(
            "mmio read, base: 0x{:x}, offset: 0x{:x}",
            base.raw_value(),
            offset.raw_value()
        );
    }

    fn write(&self, base: IoAddress, offset: IoAddress, data: &[u8]) {
        println!(
            "mmio write, base: 0x{:x}, offset: 0x{:x}",
            base.raw_value(),
            offset.raw_value()
        );
    }

    fn pio_read(&self, base: PioAddress, offset: PioAddress, data: &mut [u8]) {
        println!(
            "pio read, base: 0x{:x}, offset: 0x{:x}",
            base.raw_value(),
            offset.raw_value()
        );
    }

    fn pio_write(&self, base: PioAddress, offset: PioAddress, data: &[u8]) {
        println!(
            "pio write, base: 0x{:x}, offset: 0x{:x}",
            base.raw_value(),
            offset.raw_value()
        );
    }

    fn as_any(&self) -> &dyn Any {
        self
    }
}

// Allocate resources for device
let mut resources = DeviceResources::new();
resources.append(Resource::MmioAddressRange {
    base: 0,
    size: 4096,
});
resources.append(Resource::PioAddressRange { base: 0, size: 32 });

// Register device to `IoManager` with resources
let device = Arc::new(DummyDevice {});
let mut manager = IoManager::new();
manager.register_device_io(device, &resources).unwrap();

// Dispatch I/O event from `IoManager` to device
manager.mmio_write(0, &vec![0, 1]).unwrap();
{
    let mut buffer = vec![0; 4];
    manager.pio_read(0, &mut buffer);
}

Structs

IO manager to handle all trapped MMIO/PIO access requests.
Structure representing an IO address range.

Enums

Error types for IoManager related operations.

Traits

Trait for IO manager context object to support device hotplug at runtime.

Type Definitions

A specialized version of std::result::Result for IoManager realted operations.