Module device_manager

Source
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§

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

Enums§

Error
Error types for IoManager related operations.

Traits§

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

Type Aliases§

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