Skip to content

Commit 33dfa3f

Browse files
authored
Merge branch 'main' into memory-cleanup
2 parents c9ecb4a + 43247e4 commit 33dfa3f

File tree

1 file changed

+41
-47
lines changed

1 file changed

+41
-47
lines changed

src/vmm/src/device_manager/mmio.rs

Lines changed: 41 additions & 47 deletions
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")]
@@ -79,8 +80,8 @@ pub struct MMIODeviceInfo {
7980
pub addr: u64,
8081
/// Mmio addr range length.
8182
pub len: u64,
82-
/// Used Irq line(s) for the device.
83-
pub irqs: Vec<u32>,
83+
/// Used Irq line for the device.
84+
pub irq: Option<NonZeroU32>, // NOTE: guaranteed to be a value not 0, 0 is not allowed
8485
}
8586

8687
#[cfg(target_arch = "x86_64")]
@@ -150,15 +151,20 @@ impl MMIODeviceManager {
150151
resource_allocator: &mut ResourceAllocator,
151152
irq_count: u32,
152153
) -> Result<MMIODeviceInfo, MmioError> {
153-
let irqs = resource_allocator.allocate_gsi(irq_count)?;
154+
let irq = match resource_allocator.allocate_gsi(irq_count)?[..] {
155+
[] => None,
156+
[irq] => NonZeroU32::new(irq),
157+
_ => return Err(MmioError::InvalidIrqConfig),
158+
};
159+
154160
let device_info = MMIODeviceInfo {
155161
addr: resource_allocator.allocate_mmio_memory(
156162
MMIO_LEN,
157163
MMIO_LEN,
158164
AllocPolicy::FirstMatch,
159165
)?,
160166
len: MMIO_LEN,
161-
irqs,
167+
irq,
162168
};
163169
Ok(device_info)
164170
}
@@ -187,9 +193,9 @@ impl MMIODeviceManager {
187193
) -> Result<(), MmioError> {
188194
// Our virtio devices are currently hardcoded to use a single IRQ.
189195
// Validate that requirement.
190-
if device_info.irqs.len() != 1 {
196+
let Some(irq) = device_info.irq else {
191197
return Err(MmioError::InvalidIrqConfig);
192-
}
198+
};
193199
let identifier;
194200
{
195201
let locked_device = mmio_device.locked_device();
@@ -201,11 +207,8 @@ impl MMIODeviceManager {
201207
vm.register_ioevent(queue_evt, &io_addr, u32::try_from(i).unwrap())
202208
.map_err(MmioError::RegisterIoEvent)?;
203209
}
204-
vm.register_irqfd(
205-
&locked_device.interrupt_trigger().irq_evt,
206-
device_info.irqs[0],
207-
)
208-
.map_err(MmioError::RegisterIrqFd)?;
210+
vm.register_irqfd(&locked_device.interrupt_trigger().irq_evt, irq.get())
211+
.map_err(MmioError::RegisterIrqFd)?;
209212
}
210213

211214
self.register_mmio_device(
@@ -230,7 +233,7 @@ impl MMIODeviceManager {
230233
.add_virtio_mmio_device(
231234
device_info.len,
232235
GuestAddress(device_info.addr),
233-
device_info.irqs[0],
236+
device_info.irq.unwrap().get(),
234237
None,
235238
)
236239
.map_err(MmioError::Cmdline)
@@ -257,7 +260,7 @@ impl MMIODeviceManager {
257260
device_info.len,
258261
// We are sure that `irqs` has at least one element; allocate_mmio_resources makes
259262
// sure of it.
260-
device_info.irqs[0],
263+
device_info.irq.unwrap().get(),
261264
)?;
262265
}
263266
Ok(device_info)
@@ -289,7 +292,7 @@ impl MMIODeviceManager {
289292
.unwrap()
290293
.serial
291294
.interrupt_evt(),
292-
device_info.irqs[0],
295+
device_info.irq.unwrap().get(),
293296
)
294297
.map_err(MmioError::RegisterIrqFd)?;
295298

@@ -525,7 +528,7 @@ impl DeviceInfoForFDT for MMIODeviceInfo {
525528
self.addr
526529
}
527530
fn irq(&self) -> u32 {
528-
self.irqs[0]
531+
self.irq.unwrap().into()
529532
}
530533
fn length(&self) -> u64 {
531534
self.len
@@ -574,11 +577,10 @@ mod tests {
574577
#[cfg(target_arch = "x86_64")]
575578
/// Gets the number of interrupts used by the devices registered.
576579
pub fn used_irqs_count(&self) -> usize {
577-
let mut irq_number = 0;
578580
self.get_device_info()
579581
.iter()
580-
.for_each(|(_, device_info)| irq_number += device_info.irqs.len());
581-
irq_number
582+
.filter(|(_, device_info)| device_info.irq.is_some())
583+
.count()
582584
}
583585
}
584586

@@ -784,7 +786,10 @@ mod tests {
784786
);
785787
assert_eq!(
786788
crate::arch::IRQ_BASE,
787-
device_manager.id_to_dev_info[&(DeviceType::Virtio(type_id), id)].irqs[0]
789+
device_manager.id_to_dev_info[&(DeviceType::Virtio(type_id), id)]
790+
.irq
791+
.unwrap()
792+
.get()
788793
);
789794

790795
let id = "bar";
@@ -821,50 +826,39 @@ mod tests {
821826
}
822827

823828
#[test]
824-
fn test_slot_irq_allocation() {
829+
fn test_no_irq_allocation() {
825830
let mut device_manager = MMIODeviceManager::new();
826831
let mut resource_allocator = ResourceAllocator::new().unwrap();
832+
827833
let device_info = device_manager
828834
.allocate_mmio_resources(&mut resource_allocator, 0)
829835
.unwrap();
830-
assert_eq!(device_info.irqs.len(), 0);
836+
assert!(device_info.irq.is_none());
837+
}
838+
839+
#[test]
840+
fn test_irq_allocation() {
841+
let mut device_manager = MMIODeviceManager::new();
842+
let mut resource_allocator = ResourceAllocator::new().unwrap();
843+
831844
let device_info = device_manager
832845
.allocate_mmio_resources(&mut resource_allocator, 1)
833846
.unwrap();
834-
assert_eq!(device_info.irqs[0], crate::arch::IRQ_BASE);
835-
assert_eq!(
836-
format!(
837-
"{}",
838-
device_manager
839-
.allocate_mmio_resources(
840-
&mut resource_allocator,
841-
crate::arch::IRQ_MAX - crate::arch::IRQ_BASE + 1
842-
)
843-
.unwrap_err()
844-
),
845-
"Failed to allocate requested resource: The requested resource is not available."
846-
.to_string()
847-
);
847+
assert_eq!(device_info.irq.unwrap().get(), crate::arch::IRQ_BASE);
848+
}
848849

849-
let device_info = device_manager
850-
.allocate_mmio_resources(
851-
&mut resource_allocator,
852-
crate::arch::IRQ_MAX - crate::arch::IRQ_BASE - 1,
853-
)
854-
.unwrap();
855-
assert_eq!(device_info.irqs[16], crate::arch::IRQ_BASE + 17);
850+
#[test]
851+
fn test_allocation_failure() {
852+
let mut device_manager = MMIODeviceManager::new();
853+
let mut resource_allocator = ResourceAllocator::new().unwrap();
856854
assert_eq!(
857855
format!(
858856
"{}",
859857
device_manager
860858
.allocate_mmio_resources(&mut resource_allocator, 2)
861859
.unwrap_err()
862860
),
863-
"Failed to allocate requested resource: The requested resource is not available."
864-
.to_string()
861+
"Invalid MMIO IRQ configuration.".to_string()
865862
);
866-
device_manager
867-
.allocate_mmio_resources(&mut resource_allocator, 0)
868-
.unwrap();
869863
}
870864
}

0 commit comments

Comments
 (0)