Skip to content

Commit ef69e07

Browse files
committed
fix: allow GSI allocation starting from 0 on aarch64
Set `GSI_BASE` to `0` for aarch64, enabling the use of the full interrupt range and allowing up to 96 devices to be attached. Change `MMIODeviceInfo::irq` from `Option<NonZeroU32>` to `Option<u32>` to accommodate `0` as a valid IRQ number. Adjust relevant tests to reflect this change and ensure correctness. Signed-off-by: Sheng-Wei (Way) Chen <waychensw@gmail.com>
1 parent 211a8b8 commit ef69e07

File tree

3 files changed

+14
-19
lines changed

3 files changed

+14
-19
lines changed

src/vmm/src/arch/aarch64/fdt.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,6 @@ fn create_devices_node(
439439
#[cfg(test)]
440440
mod tests {
441441
use std::ffi::CString;
442-
use std::num::NonZeroU32;
443442

444443
use kvm_ioctls::Kvm;
445444

@@ -470,23 +469,23 @@ mod tests {
470469
(DeviceType::Serial, DeviceType::Serial.to_string()),
471470
MMIODeviceInfo {
472471
addr: 0x00,
473-
irq: NonZeroU32::new(1),
472+
irq: Some(1u32),
474473
len: LEN,
475474
},
476475
),
477476
(
478477
(DeviceType::Virtio(1), "virtio".to_string()),
479478
MMIODeviceInfo {
480479
addr: LEN,
481-
irq: NonZeroU32::new(2),
480+
irq: Some(2u32),
482481
len: LEN,
483482
},
484483
),
485484
(
486485
(DeviceType::Rtc, "rtc".to_string()),
487486
MMIODeviceInfo {
488487
addr: 2 * LEN,
489-
irq: NonZeroU32::new(3),
488+
irq: Some(3u32),
490489
len: LEN,
491490
},
492491
),

src/vmm/src/arch/aarch64/layout.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,8 @@ pub const IRQ_BASE: u32 = 32;
8282

8383
// The Linux kernel automatically shifts the GSI by 32 if it is an SPI,
8484
// allowing us to start numbering from 0 instead of 32.
85-
// But device_manager/mmio.rs states that 0 is not allowed for GSIs
86-
// So we start with 1 instead.
8785
/// The first usable GSI on aarch64.
88-
pub const GSI_BASE: u32 = 1;
86+
pub const GSI_BASE: u32 = 0;
8987

9088
/// The maximum usable GSI on aarch64.
9189
pub const GSI_MAX: u32 = IRQ_MAX - IRQ_BASE - 1;

src/vmm/src/device_manager/mmio.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
use std::collections::HashMap;
99
use std::fmt::Debug;
10-
use std::num::NonZeroU32;
1110
use std::sync::{Arc, Mutex};
1211

1312
#[cfg(target_arch = "x86_64")]
@@ -79,7 +78,7 @@ pub struct MMIODeviceInfo {
7978
/// Mmio addr range length.
8079
pub len: u64,
8180
/// Used Irq line for the device.
82-
pub irq: Option<NonZeroU32>, // NOTE: guaranteed to be a value not 0, 0 is not allowed
81+
pub irq: Option<u32>,
8382
}
8483

8584
#[cfg(target_arch = "x86_64")]
@@ -89,7 +88,7 @@ fn add_virtio_aml(
8988
len: u64,
9089
irq: u32,
9190
) -> Result<(), aml::AmlError> {
92-
let dev_id = irq - crate::arch::IRQ_BASE;
91+
let dev_id = irq - crate::arch::GSI_BASE;
9392
debug!(
9493
"acpi: Building AML for VirtIO device _SB_.V{:03}. memory range: {:#010x}:{} irq: {}",
9594
dev_id, addr, len, irq
@@ -151,7 +150,7 @@ impl MMIODeviceManager {
151150
) -> Result<MMIODeviceInfo, MmioError> {
152151
let irq = match resource_allocator.allocate_gsi(irq_count)?[..] {
153152
[] => None,
154-
[irq] => NonZeroU32::new(irq),
153+
[irq] => Some(irq),
155154
_ => return Err(MmioError::InvalidIrqConfig),
156155
};
157156

@@ -205,7 +204,7 @@ impl MMIODeviceManager {
205204
vm.register_ioevent(queue_evt, &io_addr, u32::try_from(i).unwrap())
206205
.map_err(MmioError::RegisterIoEvent)?;
207206
}
208-
vm.register_irqfd(&locked_device.interrupt_trigger().irq_evt, irq.get())
207+
vm.register_irqfd(&locked_device.interrupt_trigger().irq_evt, irq)
209208
.map_err(MmioError::RegisterIrqFd)?;
210209
}
211210

@@ -231,7 +230,7 @@ impl MMIODeviceManager {
231230
.add_virtio_mmio_device(
232231
device_info.len,
233232
GuestAddress(device_info.addr),
234-
device_info.irq.unwrap().get(),
233+
device_info.irq.unwrap(),
235234
None,
236235
)
237236
.map_err(MmioError::Cmdline)
@@ -258,7 +257,7 @@ impl MMIODeviceManager {
258257
device_info.len,
259258
// We are sure that `irqs` has at least one element; allocate_mmio_resources makes
260259
// sure of it.
261-
device_info.irq.unwrap().get(),
260+
device_info.irq.unwrap(),
262261
)?;
263262
}
264263
Ok(device_info)
@@ -290,7 +289,7 @@ impl MMIODeviceManager {
290289
.unwrap()
291290
.serial
292291
.interrupt_evt(),
293-
device_info.irq.unwrap().get(),
292+
device_info.irq.unwrap(),
294293
)
295294
.map_err(MmioError::RegisterIrqFd)?;
296295

@@ -693,7 +692,7 @@ mod tests {
693692
#[cfg(target_arch = "aarch64")]
694693
vm.setup_irqchip(1).unwrap();
695694

696-
for _i in crate::arch::IRQ_BASE..=crate::arch::IRQ_MAX {
695+
for _i in crate::arch::GSI_BASE..=crate::arch::GSI_MAX {
697696
device_manager
698697
.register_virtio_test_device(
699698
vm.fd(),
@@ -773,11 +772,10 @@ mod tests {
773772
device_manager.id_to_dev_info[&(DeviceType::Virtio(type_id), id.clone())].addr
774773
);
775774
assert_eq!(
776-
crate::arch::IRQ_BASE,
775+
crate::arch::GSI_BASE,
777776
device_manager.id_to_dev_info[&(DeviceType::Virtio(type_id), id)]
778777
.irq
779778
.unwrap()
780-
.get()
781779
);
782780

783781
let id = "bar";
@@ -834,7 +832,7 @@ mod tests {
834832
let device_info = device_manager
835833
.allocate_mmio_resources(&mut resource_allocator, 1)
836834
.unwrap();
837-
assert_eq!(device_info.irq.unwrap().get(), crate::arch::GSI_BASE);
835+
assert_eq!(device_info.irq.unwrap(), crate::arch::GSI_BASE);
838836
}
839837

840838
#[test]

0 commit comments

Comments
 (0)