vmm/pci/
mod.rs

1// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// Copyright 2018 The Chromium OS Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE-BSD-3-Clause file.
5//
6// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
7
8/// PCI bus logic
9pub mod bus;
10/// PCI configuration space handling
11pub mod configuration;
12/// MSI-X logic
13pub mod msix;
14
15use std::fmt::Debug;
16use std::sync::{Arc, Barrier};
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq)]
19/// Parameters for performing a BAR reprogramming operation
20pub struct BarReprogrammingParams {
21    /// Previous address of the BAR
22    pub old_base: u64,
23    /// New address of the BAR
24    pub new_base: u64,
25    /// Size of the BAR
26    pub len: u64,
27}
28
29/// Common logic of all PCI devices
30pub trait PciDevice: Send {
31    /// Sets a register in the configuration space.
32    /// * `reg_idx` - The index of the config register to modify.
33    /// * `offset` - Offset into the register.
34    fn write_config_register(
35        &mut self,
36        reg_idx: usize,
37        offset: u64,
38        data: &[u8],
39    ) -> Option<Arc<Barrier>>;
40    /// Gets a register from the configuration space.
41    /// * `reg_idx` - The index of the config register to read.
42    fn read_config_register(&mut self, reg_idx: usize) -> u32;
43    /// Detects if a BAR is being reprogrammed.
44    fn detect_bar_reprogramming(
45        &mut self,
46        _reg_idx: usize,
47        _data: &[u8],
48    ) -> Option<BarReprogrammingParams> {
49        None
50    }
51    /// Reads from a BAR region mapped into the device.
52    /// * `addr` - The guest address inside the BAR.
53    /// * `data` - Filled with the data from `addr`.
54    fn read_bar(&mut self, _base: u64, _offset: u64, _data: &mut [u8]) {}
55    /// Writes to a BAR region mapped into the device.
56    /// * `addr` - The guest address inside the BAR.
57    /// * `data` - The data to write.
58    fn write_bar(&mut self, _base: u64, _offset: u64, _data: &[u8]) -> Option<Arc<Barrier>> {
59        None
60    }
61    /// Relocates the BAR to a different address in guest address space.
62    fn move_bar(&mut self, _old_base: u64, _new_base: u64) -> Result<(), DeviceRelocationError> {
63        Ok(())
64    }
65}
66
67/// Errors for device manager.
68#[derive(Debug, thiserror::Error, displaydoc::Display)]
69pub enum DeviceRelocationError {
70    /// Device relocation not supported.
71    NotSupported,
72}
73
74/// This trait defines a set of functions which can be triggered whenever a
75/// PCI device is modified in any way.
76pub trait DeviceRelocation: Send + Sync {
77    /// The BAR needs to be moved to a different location in the guest address
78    /// space. This follows a decision from the software running in the guest.
79    fn move_bar(
80        &self,
81        old_base: u64,
82        new_base: u64,
83        len: u64,
84        pci_dev: &mut dyn PciDevice,
85    ) -> Result<(), DeviceRelocationError>;
86}