Skip to content

Commit c9fe5ad

Browse files
committed
--Utilized Option instead of Vector to store IRQ lines for MMIO devices.
-Add test to test this. -Update existing tests
1 parent 81e8b68 commit c9fe5ad

File tree

1 file changed

+42
-43
lines changed

1 file changed

+42
-43
lines changed

Diff for: src/vmm/src/device_manager/mmio.rs

+42-43
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use std::collections::HashMap;
99
use std::fmt::Debug;
10+
use std::num::NonZeroU32;
1011
use std::sync::{Arc, Mutex};
1112

1213
#[cfg(target_arch = "x86_64")]
@@ -76,8 +77,8 @@ pub struct MMIODeviceInfo {
7677
pub addr: u64,
7778
/// Mmio addr range length.
7879
pub len: u64,
79-
/// Used Irq line(s) for the device.
80-
pub irqs: Vec<u32>,
80+
/// Used Irq line for the device.
81+
pub irq: Option<NonZeroU32>, // NOTE: guaranteed to be a value not 0, 0 is not allowed
8182
}
8283

8384
#[cfg(target_arch = "x86_64")]
@@ -142,15 +143,20 @@ impl MMIODeviceManager {
142143
resource_allocator: &mut ResourceAllocator,
143144
irq_count: u32,
144145
) -> Result<MMIODeviceInfo, MmioError> {
145-
let irqs = resource_allocator.allocate_gsi(irq_count)?;
146+
let irq = match &resource_allocator.allocate_gsi(irq_count)?[..] {
147+
&[] => None,
148+
&[irq] => NonZeroU32::new(irq),
149+
_ => return Err(MmioError::InvalidIrqConfig),
150+
};
151+
146152
let device_info = MMIODeviceInfo {
147153
addr: resource_allocator.allocate_mmio_memory(
148154
MMIO_LEN,
149155
MMIO_LEN,
150156
AllocPolicy::FirstMatch,
151157
)?,
152158
len: MMIO_LEN,
153-
irqs,
159+
irq,
154160
};
155161
Ok(device_info)
156162
}
@@ -179,9 +185,9 @@ impl MMIODeviceManager {
179185
) -> Result<(), MmioError> {
180186
// Our virtio devices are currently hardcoded to use a single IRQ.
181187
// Validate that requirement.
182-
if device_info.irqs.len() != 1 {
188+
let Some(irq) = device_info.irq else {
183189
return Err(MmioError::InvalidIrqConfig);
184-
}
190+
};
185191
let identifier;
186192
{
187193
let locked_device = mmio_device.locked_device();
@@ -193,7 +199,7 @@ impl MMIODeviceManager {
193199
vm.register_ioevent(queue_evt, &io_addr, u32::try_from(i).unwrap())
194200
.map_err(MmioError::RegisterIoEvent)?;
195201
}
196-
vm.register_irqfd(locked_device.interrupt_evt(), device_info.irqs[0])
202+
vm.register_irqfd(locked_device.interrupt_evt(), irq.get())
197203
.map_err(MmioError::RegisterIrqFd)?;
198204
}
199205

@@ -219,7 +225,7 @@ impl MMIODeviceManager {
219225
.add_virtio_mmio_device(
220226
device_info.len,
221227
GuestAddress(device_info.addr),
222-
device_info.irqs[0],
228+
device_info.irq.unwrap().get(),
223229
None,
224230
)
225231
.map_err(MmioError::Cmdline)
@@ -246,7 +252,7 @@ impl MMIODeviceManager {
246252
device_info.len,
247253
// We are sure that `irqs` has at least one element; allocate_mmio_resources makes
248254
// sure of it.
249-
device_info.irqs[0],
255+
device_info.irq.unwrap().get(),
250256
);
251257
}
252258
Ok(device_info)
@@ -278,7 +284,7 @@ impl MMIODeviceManager {
278284
.unwrap()
279285
.serial
280286
.interrupt_evt(),
281-
device_info.irqs[0],
287+
device_info.irq.unwrap().get(),
282288
)
283289
.map_err(MmioError::RegisterIrqFd)?;
284290

@@ -504,7 +510,7 @@ impl DeviceInfoForFDT for MMIODeviceInfo {
504510
self.addr
505511
}
506512
fn irq(&self) -> u32 {
507-
self.irqs[0]
513+
self.irq.unwrap()
508514
}
509515
fn length(&self) -> u64 {
510516
self.len
@@ -552,10 +558,11 @@ mod tests {
552558
#[cfg(target_arch = "x86_64")]
553559
/// Gets the number of interrupts used by the devices registered.
554560
pub fn used_irqs_count(&self) -> usize {
555-
let mut irq_number = 0;
556-
self.get_device_info()
561+
let irq_number = self
562+
.get_device_info()
557563
.iter()
558-
.for_each(|(_, device_info)| irq_number += device_info.irqs.len());
564+
.map(|(_, device_info)| device_info.irq.is_some())
565+
.count();
559566
irq_number
560567
}
561568
}
@@ -763,7 +770,10 @@ mod tests {
763770
);
764771
assert_eq!(
765772
crate::arch::IRQ_BASE,
766-
device_manager.id_to_dev_info[&(DeviceType::Virtio(type_id), id)].irqs[0]
773+
device_manager.id_to_dev_info[&(DeviceType::Virtio(type_id), id)]
774+
.irq
775+
.unwrap()
776+
.get()
767777
);
768778

769779
let id = "bar";
@@ -800,50 +810,39 @@ mod tests {
800810
}
801811

802812
#[test]
803-
fn test_slot_irq_allocation() {
813+
fn test_no_irq_allocation() {
804814
let mut device_manager = MMIODeviceManager::new();
805815
let mut resource_allocator = ResourceAllocator::new().unwrap();
816+
806817
let device_info = device_manager
807818
.allocate_mmio_resources(&mut resource_allocator, 0)
808819
.unwrap();
809-
assert_eq!(device_info.irqs.len(), 0);
820+
assert!(device_info.irq.is_none());
821+
}
822+
823+
#[test]
824+
fn test_irq_allocation() {
825+
let mut device_manager = MMIODeviceManager::new();
826+
let mut resource_allocator = ResourceAllocator::new().unwrap();
827+
810828
let device_info = device_manager
811829
.allocate_mmio_resources(&mut resource_allocator, 1)
812830
.unwrap();
813-
assert_eq!(device_info.irqs[0], crate::arch::IRQ_BASE);
814-
assert_eq!(
815-
format!(
816-
"{}",
817-
device_manager
818-
.allocate_mmio_resources(
819-
&mut resource_allocator,
820-
crate::arch::IRQ_MAX - crate::arch::IRQ_BASE + 1
821-
)
822-
.unwrap_err()
823-
),
824-
"Failed to allocate requested resource: The requested resource is not available."
825-
.to_string()
826-
);
831+
assert_eq!(device_info.irq.unwrap().get(), crate::arch::IRQ_BASE);
832+
}
827833

828-
let device_info = device_manager
829-
.allocate_mmio_resources(
830-
&mut resource_allocator,
831-
crate::arch::IRQ_MAX - crate::arch::IRQ_BASE - 1,
832-
)
833-
.unwrap();
834-
assert_eq!(device_info.irqs[16], crate::arch::IRQ_BASE + 17);
834+
#[test]
835+
fn test_allocation_failure() {
836+
let mut device_manager = MMIODeviceManager::new();
837+
let mut resource_allocator = ResourceAllocator::new().unwrap();
835838
assert_eq!(
836839
format!(
837840
"{}",
838841
device_manager
839842
.allocate_mmio_resources(&mut resource_allocator, 2)
840843
.unwrap_err()
841844
),
842-
"Failed to allocate requested resource: The requested resource is not available."
843-
.to_string()
845+
"Invalid MMIO IRQ configuration.".to_string()
844846
);
845-
device_manager
846-
.allocate_mmio_resources(&mut resource_allocator, 0)
847-
.unwrap();
848847
}
849848
}

0 commit comments

Comments
 (0)