mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 03:12:27 +00:00
vm-virtio: Update VirtioPciCap and introduce VirtioPciCap64
Based on the latest version of the virtio specification, the structure virtio_pci_cap has been updated and a new structure virtio_pci_cap64 has been introduced. virtio_pci_cap now includes a field "id" that does not modify the existing structure size since there was a 3 bytes reserved field already there. The id is used in the context of shared memory regions which need to be identified since there could be more than one of this kind of capability. virtio_pci_cap64 is a new structure that includes virtio_pci_cap and extends it to allow 64 bits offsets and 64 bits region length. This is used in the context of shared memory regions capability, as we might need to describe regions of 4G or more, that could be placed at a 4G offset or more in the associated BAR. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
d180deb679
commit
d97079d793
@ -42,6 +42,7 @@ enum PciCapabilityType {
|
||||
IsrConfig = 3,
|
||||
DeviceConfig = 4,
|
||||
PciConfig = 5,
|
||||
SharedMemoryConfig = 8,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -51,7 +52,8 @@ struct VirtioPciCap {
|
||||
cap_len: u8, // Generic PCI field: capability length
|
||||
cfg_type: u8, // Identifies the structure.
|
||||
pci_bar: u8, // Where to find it.
|
||||
padding: [u8; 3], // Pad to full dword.
|
||||
id: u8, // Multiple capabilities of the same type
|
||||
padding: [u8; 2], // Pad to full dword.
|
||||
offset: Le32, // Offset within bar.
|
||||
length: Le32, // Length of the structure, in bytes.
|
||||
}
|
||||
@ -76,7 +78,8 @@ impl VirtioPciCap {
|
||||
cap_len: (std::mem::size_of::<VirtioPciCap>() as u8) + VIRTIO_PCI_CAP_LEN_OFFSET,
|
||||
cfg_type: cfg_type as u8,
|
||||
pci_bar,
|
||||
padding: [0; 3],
|
||||
id: 0,
|
||||
padding: [0; 2],
|
||||
offset: Le32::from(offset),
|
||||
length: Le32::from(length),
|
||||
}
|
||||
@ -117,7 +120,8 @@ impl VirtioPciNotifyCap {
|
||||
+ VIRTIO_PCI_CAP_LEN_OFFSET,
|
||||
cfg_type: cfg_type as u8,
|
||||
pci_bar,
|
||||
padding: [0; 3],
|
||||
id: 0,
|
||||
padding: [0; 2],
|
||||
offset: Le32::from(offset),
|
||||
length: Le32::from(length),
|
||||
},
|
||||
@ -126,6 +130,45 @@ impl VirtioPciNotifyCap {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(packed)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
struct VirtioPciCap64 {
|
||||
cap: VirtioPciCap,
|
||||
offset_hi: Le32,
|
||||
length_hi: Le32,
|
||||
}
|
||||
// It is safe to implement ByteValued. All members are simple numbers and any value is valid.
|
||||
unsafe impl ByteValued for VirtioPciCap64 {}
|
||||
|
||||
impl PciCapability for VirtioPciCap64 {
|
||||
fn bytes(&self) -> &[u8] {
|
||||
self.as_slice()
|
||||
}
|
||||
|
||||
fn id(&self) -> PciCapabilityID {
|
||||
PciCapabilityID::VendorSpecific
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtioPciCap64 {
|
||||
pub fn new(cfg_type: PciCapabilityType, pci_bar: u8, id: u8, offset: u64, length: u64) -> Self {
|
||||
VirtioPciCap64 {
|
||||
cap: VirtioPciCap {
|
||||
cap_len: (std::mem::size_of::<VirtioPciCap64>() as u8) + VIRTIO_PCI_CAP_LEN_OFFSET,
|
||||
cfg_type: cfg_type as u8,
|
||||
pci_bar,
|
||||
id,
|
||||
padding: [0; 2],
|
||||
offset: Le32::from(offset as u32),
|
||||
length: Le32::from(length as u32),
|
||||
},
|
||||
offset_hi: Le32::from((offset >> 32) as u32),
|
||||
length_hi: Le32::from((length >> 32) as u32),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum PciVirtioSubclass {
|
||||
@ -351,6 +394,17 @@ impl VirtioPciDevice {
|
||||
.add_capability(&configuration_cap)
|
||||
.map_err(PciDeviceError::CapabilitiesSetup)?;
|
||||
|
||||
let shm_cap = VirtioPciCap64::new(
|
||||
PciCapabilityType::SharedMemoryConfig,
|
||||
settings_bar,
|
||||
0,
|
||||
0u64,
|
||||
0u64,
|
||||
);
|
||||
self.configuration
|
||||
.add_capability(&shm_cap)
|
||||
.map_err(PciDeviceError::CapabilitiesSetup)?;
|
||||
|
||||
if self.msix_config.is_some() {
|
||||
let msix_cap = MsixCap::new(
|
||||
settings_bar,
|
||||
|
Loading…
x
Reference in New Issue
Block a user