Skip to content

Commit decfa1b

Browse files
committed
vmm: if IRQCHIP is split, create IoApic device
If the user calls `krun_split_irqchip` with `enabled` set to `true`, then create an `IoApic` device in userspace rather than creating an IOAPIC in the guest with KVM. Signed-off-by: Jake Correnti <[email protected]>
1 parent 2416863 commit decfa1b

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/vmm/src/builder.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ use devices::legacy::Serial;
3232
use devices::legacy::VcpuList;
3333
#[cfg(target_os = "macos")]
3434
use devices::legacy::{GicV3, HvfGicV3};
35+
#[cfg(target_arch = "x86_64")]
36+
use devices::legacy::{IoApic, IrqChipT};
3537
use devices::legacy::{IrqChip, IrqChipDevice};
3638
#[cfg(feature = "net")]
3739
use devices::virtio::Net;
@@ -664,10 +666,20 @@ pub fn build_microvm(
664666
// while on aarch64 we need to do it the other way around.
665667
#[cfg(target_arch = "x86_64")]
666668
{
667-
let kvmioapic = KvmIoapic::new(vm.fd()).map_err(StartMicrovmError::CreateKvmIrqChip)?;
668-
intc = Arc::new(Mutex::new(IrqChipDevice::new(Box::new(kvmioapic))));
669+
let ioapic: Box<dyn IrqChipT> = if vm_resources.split_irqchip {
670+
Box::new(IoApic::new(vm.fd(), irq_sender).map_err(StartMicrovmError::CreateKvmIrqChip)?)
671+
} else {
672+
Box::new(KvmIoapic::new(vm.fd()).map_err(StartMicrovmError::CreateKvmIrqChip)?)
673+
};
674+
intc = Arc::new(Mutex::new(IrqChipDevice::new(ioapic)));
669675

670-
attach_legacy_devices(&vm, &mut pio_device_manager)?;
676+
attach_legacy_devices(
677+
&vm,
678+
vm_resources.split_irqchip,
679+
&mut pio_device_manager,
680+
&mut mmio_device_manager,
681+
Some(intc.clone()),
682+
)?;
671683

672684
vcpus = create_vcpus_x86_64(
673685
&vm,
@@ -1333,13 +1345,23 @@ pub fn setup_serial_device(
13331345
#[cfg(target_arch = "x86_64")]
13341346
fn attach_legacy_devices(
13351347
vm: &Vm,
1348+
split_irqchip: bool,
13361349
pio_device_manager: &mut PortIODeviceManager,
1350+
mmio_device_manager: &mut MMIODeviceManager,
1351+
intc: Option<Arc<Mutex<IrqChipDevice>>>,
13371352
) -> std::result::Result<(), StartMicrovmError> {
13381353
pio_device_manager
13391354
.register_devices()
13401355
.map_err(Error::LegacyIOBus)
13411356
.map_err(StartMicrovmError::Internal)?;
13421357

1358+
if split_irqchip {
1359+
mmio_device_manager
1360+
.register_mmio_ioapic(intc)
1361+
.map_err(Error::RegisterMMIODevice)
1362+
.map_err(StartMicrovmError::Internal)?;
1363+
}
1364+
13431365
macro_rules! register_irqfd_evt {
13441366
($evt: ident, $index: expr) => {{
13451367
vm.fd()

src/vmm/src/device_manager/kvm/mmio.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ impl MMIODeviceManager {
8888
}
8989
}
9090

91+
/// Register a MMIO IOAPIC device.
92+
#[cfg(target_arch = "x86_64")]
93+
pub fn register_mmio_ioapic(
94+
&mut self,
95+
intc: Option<Arc<Mutex<devices::legacy::IrqChipDevice>>>,
96+
) -> Result<()> {
97+
if let Some(intc) = intc {
98+
let (addr, size) = {
99+
let intc = intc.lock().unwrap();
100+
(intc.get_mmio_addr(), intc.get_mmio_size())
101+
};
102+
self.bus.insert(intc, addr, size).map_err(Error::BusError)?;
103+
}
104+
105+
Ok(())
106+
}
107+
91108
/// Register an already created MMIO device to be used via MMIO transport.
92109
pub fn register_mmio_device(
93110
&mut self,
@@ -117,6 +134,8 @@ impl MMIODeviceManager {
117134
vm.register_irqfd(mmio_device.locked_device().interrupt_evt(), self.irq)
118135
.map_err(Error::RegisterIrqFd)?;
119136

137+
mmio_device.locked_device().set_irq_line(self.irq);
138+
120139
self.bus
121140
.insert(Arc::new(Mutex::new(mmio_device)), self.mmio_base, MMIO_LEN)
122141
.map_err(Error::BusError)?;

0 commit comments

Comments
 (0)