Skip to content

Commit c0ada38

Browse files
committed
arm: support MSI-X on ARM
Expose MSI properties for GIC via the FDT. Signed-off-by: Babis Chalios <[email protected]>
1 parent a0e1523 commit c0ada38

File tree

4 files changed

+47
-0
lines changed

4 files changed

+47
-0
lines changed

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ use crate::vstate::memory::{Address, GuestMemory, GuestMemoryMmap};
2828
const GIC_PHANDLE: u32 = 1;
2929
// This is a value for uniquely identifying the FDT node containing the clock definition.
3030
const CLOCK_PHANDLE: u32 = 2;
31+
// This is a value for uniquely identifying the FDT node declaring the MSI controller.
32+
const MSI_PHANDLE: u32 = 3;
3133
// You may be wondering why this big value?
3234
// This phandle is used to uniquely identify the FDT nodes containing cache information. Each cpu
3335
// can have a variable number of caches, some of these caches may be shared with other cpus.
@@ -302,6 +304,16 @@ fn create_gic_node(fdt: &mut FdtWriter, gic_device: &GICDevice) -> Result<(), Fd
302304
];
303305

304306
fdt.property_array_u32("interrupts", &gic_intr)?;
307+
308+
if let Some(msi_properties) = gic_device.msi_properties() {
309+
let msic_node = fdt.begin_node("msic")?;
310+
fdt.property_string("compatible", "arm,gic-v3-its")?;
311+
fdt.property_null("msi-controller")?;
312+
fdt.property_u32("phandle", MSI_PHANDLE)?;
313+
fdt.property_array_u64("reg", msi_properties)?;
314+
fdt.end_node(msic_node)?;
315+
}
316+
305317
fdt.end_node(interrupt)?;
306318

307319
Ok(())
@@ -471,6 +483,21 @@ fn create_pci_nodes(fdt: &mut FdtWriter, pci_devices: &PciDevices) -> Result<(),
471483
(MEM_64BIT_DEVICES_SIZE >> 32) as u32, // Range size
472484
((MEM_64BIT_DEVICES_SIZE & 0xffff_ffff) >> 32) as u32,
473485
];
486+
487+
// See kernel document Documentation/devicetree/bindings/pci/pci-msi.txt
488+
let msi_map = [
489+
// rid-base: A single cell describing the first RID matched by the entry.
490+
0x0,
491+
// msi-controller: A single phandle to an MSI controller.
492+
MSI_PHANDLE,
493+
// msi-base: An msi-specifier describing the msi-specifier produced for the
494+
// first RID matched by the entry.
495+
segment.id as u32,
496+
// length: A single cell describing how many consecutive RIDs are matched
497+
// following the rid-base.
498+
0x100,
499+
];
500+
474501
let pci_node = fdt.begin_node(&pci_node_name)?;
475502

476503
fdt.property_string("compatible", "pci-host-ecam-generic")?;
@@ -491,6 +518,9 @@ fn create_pci_nodes(fdt: &mut FdtWriter, pci_devices: &PciDevices) -> Result<(),
491518
fdt.property_null("interrupt-map")?;
492519
fdt.property_null("interrupt-map-mask")?;
493520
fdt.property_null("dma-coherent")?;
521+
fdt.property_array_u32("msi-map", &msi_map)?;
522+
fdt.property_u32("msi-parent", MSI_PHANDLE)?;
523+
494524
Ok(fdt.end_node(pci_node)?)
495525
}
496526

src/vmm/src/arch/aarch64/gic/gicv2/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ impl GICv2 {
6868
GICv2::get_cpu_addr(),
6969
GICv2::get_cpu_size(),
7070
],
71+
msi_properties: None,
7172
vcpu_count,
7273
})
7374
}

src/vmm/src/arch/aarch64/gic/gicv3/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl GICv3 {
2424
const SZ_64K: u64 = 0x0001_0000;
2525
const KVM_VGIC_V3_DIST_SIZE: u64 = GICv3::SZ_64K;
2626
const KVM_VGIC_V3_REDIST_SIZE: u64 = (2 * GICv3::SZ_64K);
27+
const GIC_V3_ITS_SIZE: u64 = 0x2_0000;
2728

2829
// Device trees specific constants
2930
const ARCH_GIC_V3_MAINT_IRQ: u32 = 9;
@@ -68,6 +69,10 @@ impl GICv3 {
6869
GICv3::get_redists_addr(vcpu_count),
6970
GICv3::get_redists_size(vcpu_count),
7071
],
72+
msi_properties: Some([
73+
Self::get_redists_addr(vcpu_count) - GICv3::GIC_V3_ITS_SIZE,
74+
GICv3::GIC_V3_ITS_SIZE,
75+
]),
7176
vcpu_count,
7277
})
7378
}

src/vmm/src/arch/aarch64/gic/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ pub struct GIC {
2121
/// GIC device properties, to be used for setting up the fdt entry
2222
properties: [u64; 4],
2323

24+
/// MSI properties of the GIC device
25+
msi_properties: Option<[u64; 2]>,
26+
2427
/// Number of CPUs handled by the device
2528
vcpu_count: u64,
2629
}
@@ -88,6 +91,14 @@ impl GICDevice {
8891
}
8992
}
9093

94+
/// Returns an array with MSI properties if GIC supports it
95+
pub fn msi_properties(&self) -> Option<&[u64; 2]> {
96+
match self {
97+
Self::V2(x) => x.msi_properties.as_ref(),
98+
Self::V3(x) => x.msi_properties.as_ref(),
99+
}
100+
}
101+
91102
/// Returns the number of vCPUs this GIC handles
92103
pub fn vcpu_count(&self) -> u64 {
93104
match self {

0 commit comments

Comments
 (0)