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}