Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions platform/aarch64/qemu-gicv3/image/dts/zone1-linux.dts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,43 @@
reg = <0x0 0x50000000 0x0 0x30000000>;
};

gic@8000000 {
intc@8000000 {
phandle = <0x01>;
interrupts = <0x01 0x09 0x04>;
reg = <0x00 0x8000000 0x00 0x10000 0x00 0x80a0000 0x00 0xf60000>;
#redistributor-regions = <0x01>;
compatible = "arm,gic-v3";
#interrupt-cells = <0x03>;
ranges;
#size-cells = <0x02>;
#address-cells = <0x02>;
interrupt-controller;
reg = <0x00 0x8000000 0x00 0x10000 0x00 0x80a0000 0x00 0xf60000>;
phandle = <0x01>;
#interrupt-cells = <0x03>;

its@8080000 {
phandle = <0x8006>;
reg = <0x00 0x8080000 0x00 0x20000>;
#msi-cells = <0x01>;
msi-controller;
compatible = "arm,gic-v3-its";
};
};

pcie@10000000 {
interrupt-map-mask = <0x1800 0x00 0x00 0x07>;
interrupt-map = <0x00 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x03 0x04 0x00 0x00 0x00 0x02 0x01 0x00 0x00 0x00 0x04 0x04 0x00 0x00 0x00 0x03 0x01 0x00 0x00 0x00 0x05 0x04 0x00 0x00 0x00 0x04 0x01 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x04 0x04 0x800 0x00 0x00 0x02 0x01 0x00 0x00 0x00 0x05 0x04 0x800 0x00 0x00 0x03 0x01 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x04 0x01 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x05 0x04 0x1000 0x00 0x00 0x02 0x01 0x00 0x00 0x00 0x06 0x04 0x1000 0x00 0x00 0x03 0x01 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x04 0x01 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x06 0x04 0x1800 0x00 0x00 0x02 0x01 0x00 0x00 0x00 0x03 0x04 0x1800 0x00 0x00 0x03 0x01 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x04 0x01 0x00 0x00 0x00 0x05 0x04>;
#interrupt-cells = <0x01>;
ranges = <0x1000000 0x00 0x00 0x00 0x3eff0000 0x00 0x10000
0x2000000 0x00 0x10000000 0x00 0x10000000 0x00 0x2eff0000
0x3000000 0x80 0x00 0x80 0x00 0x80 0x00>;
reg = <0x40 0x10000000 0x00 0x10000000>;
msi-map = <0x00 0x8006 0x00 0x10000>;
dma-coherent;
bus-range = <0x00 0xff>;
linux,pci-domain = <0x00>;
#size-cells = <0x02>;
#address-cells = <0x03>;
device_type = "pci";
compatible = "pci-host-ecam-generic";
};

apb-pclk {
Expand Down
79 changes: 8 additions & 71 deletions src/arch/aarch64/iommu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,6 @@ impl CmdQueue {
pub struct Smmuv3 {
rp: &'static RegisterPage,
strtab: LinearStreamTable,
iommu_pt_list: Vec<MemorySet<Stage2PageTable>>,
cmdq: CmdQueue,
}

Expand All @@ -358,20 +357,13 @@ impl Smmuv3 {
let mut r = Self {
rp: rp,
strtab: LinearStreamTable::new(),
iommu_pt_list: vec![],
cmdq: CmdQueue::new(),
};

for _ in 0..MAX_ZONE_NUM {
r.iommu_pt_list.push(new_s2_memory_set());
}

info!("pagetables for iommu, init done!");

r.check_env();
r.init_limited_pt();
r.init_structures();
r.device_reset();

r
}

Expand Down Expand Up @@ -413,47 +405,6 @@ impl Smmuv3 {
}
}

fn init_limited_pt(&mut self) {
// its
for pt in self.iommu_pt_list.iter_mut() {
pt.insert(MemoryRegion::new_with_offset_mapper(
0x8080000 as GuestPhysAddr,
0x8080000,
0x20000,
MemFlags::READ | MemFlags::WRITE,
))
.ok();
}

// ram
self.iommu_pt_list[0]
.insert(MemoryRegion::new_with_offset_mapper(
0x80000000 as GuestPhysAddr,
0x80000000,
0x50000000,
MemFlags::READ | MemFlags::WRITE,
))
.ok();

self.iommu_pt_list[1]
.insert(MemoryRegion::new_with_offset_mapper(
0x50000000 as GuestPhysAddr,
0x50000000,
0x30000000,
MemFlags::READ | MemFlags::WRITE,
))
.ok();

self.iommu_pt_list[2]
.insert(MemoryRegion::new_with_offset_mapper(
0x80000000 as GuestPhysAddr,
0x80000000,
0x10000000,
MemFlags::READ | MemFlags::WRITE,
))
.ok();
}

fn init_structures(&mut self) {
self.init_strtab();
self.init_queues();
Expand Down Expand Up @@ -545,13 +496,12 @@ impl Smmuv3 {
}

// s1 bypass and s2 translate
fn write_ste(&mut self, sid: usize, vmid: usize) {
fn write_ste(&mut self, sid: usize, vmid: usize, root_pt: usize) {
self.sync_ste(sid);

assert!(vmid < MAX_ZONE_NUM, "Invalid zone id!");

self.strtab
.write_ste(sid, vmid, self.iommu_pt_list[vmid].root_paddr());
self.strtab.write_ste(sid, vmid, root_pt);
}

// invalidate the ste
Expand Down Expand Up @@ -582,13 +532,8 @@ static SMMUV3: spin::Once<Mutex<Smmuv3>> = spin::Once::new();

/// smmuv3 init
pub fn iommu_init() {
#[cfg(feature = "iommu")]
{
info!("Smmuv3 init...");
SMMUV3.call_once(|| Mutex::new(Smmuv3::new()));
}
#[cfg(not(feature = "iommu"))]
info!("Smmuv3 init: do nothing now");
info!("Smmuv3 init...");
SMMUV3.call_once(|| Mutex::new(Smmuv3::new()));
}

/// smmuv3_base
Expand All @@ -604,15 +549,7 @@ pub fn smmuv3_size() -> usize {
}

/// write ste
pub fn iommu_add_device(vmid: usize, sid: usize) {
#[cfg(feature = "iommu")]
{
let mut smmu = SMMUV3.get().unwrap().lock();
smmu.write_ste(sid as _, vmid as _);
}
#[cfg(not(feature = "iommu"))]
info!(
"aarch64: iommu_add_device: do nothing now, vmid: {}, sid: {}",
vmid, sid
);
pub fn iommu_add_device(vmid: usize, sid: usize, root_pt: usize) {
let mut smmu = SMMUV3.get().unwrap().lock();
smmu.write_ste(sid as _, vmid as _, root_pt as _);
}
52 changes: 52 additions & 0 deletions src/arch/aarch64/zone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,58 @@ impl Zone {
Ok(())
}

pub fn iommu_pt_init(
&mut self,
mem_regions: &[HvConfigMemoryRegion],
hv_config: &HvArchZoneConfig,
) -> HvResult {
// Create a new stage 2 page table for iommu.
// Only map the memory regions that are possible to be accessed by devices as DMA buffer.

let pt = self.iommu_pt.as_mut().unwrap();
let flags = MemFlags::READ | MemFlags::WRITE;
for mem_region in mem_regions.iter() {
match mem_region.mem_type {
MEM_TYPE_RAM => {
pt.insert(MemoryRegion::new_with_offset_mapper(
mem_region.virtual_start as GuestPhysAddr,
mem_region.physical_start as HostPhysAddr,
mem_region.size as _,
flags,
))?;
info!(
"iommu map: vaddr:{} - paddr:{}",
mem_region.virtual_start, mem_region.physical_start
);
}
_ => {
// pass
}
}
}

match hv_config.gic_config {
GicConfig::Gicv3(ref gicv3_config) => {
if gicv3_config.gits_size != 0 {
// map gits
pt.insert(MemoryRegion::new_with_offset_mapper(
gicv3_config.gits_base as GuestPhysAddr,
gicv3_config.gits_base as HostPhysAddr,
gicv3_config.gits_size as _,
flags | MemFlags::IO,
))?;
info!(
"iommu map: vaddr:{} - paddr:{}",
gicv3_config.gits_base, gicv3_config.gits_base
);
}
}
_ => {}
}

Ok(())
}

pub fn arch_zone_configuration(&mut self, config: &HvZoneConfig) -> HvResult {
self.ivc_init(config.ivc_config());
Ok(())
Expand Down
Loading