Skip to content
Open
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
45 changes: 43 additions & 2 deletions src/zone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ pub struct ZoneInner {
mmio: Vec<MMIOConfig>,
cpu_num: usize,
cpu_set: CpuSet,
// Guest-visible CPU ids are not guaranteed to be dense or equal to pCPU ids.
// Keep explicit maps here; CpuSet only records physical CPU ownership.
guest_to_phys_cpu: [Option<usize>; MAX_CPU_NUM],
phys_to_guest_cpu: [Option<usize>; MAX_CPU_NUM],
irq_bitmap: [u32; 1024 / 32],
gpm: MemorySet<Stage2PageTable>,
iommu_pt: Option<MemorySet<Stage2PageTable>>,
Expand Down Expand Up @@ -174,6 +178,8 @@ impl ZoneInner {
mmio: Vec::new(),
cpu_num: 0,
cpu_set: CpuSet::new(MAX_CPU_NUM as usize, 0),
guest_to_phys_cpu: [None; MAX_CPU_NUM],
phys_to_guest_cpu: [None; MAX_CPU_NUM],
irq_bitmap: [0; 1024 / 32],
iommu_pt: if cfg!(iommu) {
Some(new_s2_memory_set())
Expand Down Expand Up @@ -276,6 +282,36 @@ impl ZoneInner {
&mut self.cpu_set
}

pub fn map_cpu(&mut self, guest_cpu: usize, phys_cpu: usize) {
if guest_cpu >= MAX_CPU_NUM || phys_cpu >= MAX_CPU_NUM {
warn!(
"ignore invalid CPU map guest_cpu={}, phys_cpu={}",
guest_cpu, phys_cpu
);
return;
}
if let Some(old_phys_cpu) = self.guest_to_phys_cpu[guest_cpu] {
if self.phys_to_guest_cpu[old_phys_cpu] == Some(guest_cpu) {
self.phys_to_guest_cpu[old_phys_cpu] = None;
}
}
if let Some(old_guest_cpu) = self.phys_to_guest_cpu[phys_cpu] {
if self.guest_to_phys_cpu[old_guest_cpu] == Some(phys_cpu) {
self.guest_to_phys_cpu[old_guest_cpu] = None;
}
}
self.guest_to_phys_cpu[guest_cpu] = Some(phys_cpu);
self.phys_to_guest_cpu[phys_cpu] = Some(guest_cpu);
}

pub fn guest_to_phys_cpu(&self, guest_cpu: usize) -> Option<usize> {
self.guest_to_phys_cpu.get(guest_cpu).copied().flatten()
}

pub fn phys_to_guest_cpu(&self, phys_cpu: usize) -> Option<usize> {
self.phys_to_guest_cpu.get(phys_cpu).copied().flatten()
}

pub fn irq_bitmap(&self) -> &[u32; 1024 / 32] {
&self.irq_bitmap
}
Expand Down Expand Up @@ -798,7 +834,7 @@ pub fn zone_create(config: &HvZoneConfig) -> HvResult<Arc<Zone>> {
zone.mmio_init(&config.arch_config);

let mut cpu_num = 0;
for cpu_id in config.cpus().iter() {
for (guest_cpu, cpu_id) in config.cpus().iter().enumerate() {
if let Some(existing_zone) = get_cpu_data(*cpu_id as _).zone.clone() {
return hv_result_err!(
EBUSY,
Expand All @@ -809,7 +845,12 @@ pub fn zone_create(config: &HvZoneConfig) -> HvResult<Arc<Zone>> {
)
);
}
zone.write().cpu_set_mut().set_bit(*cpu_id as _);
let cpu_id = *cpu_id as usize;
let mut zone_inner = zone.write();
zone_inner.cpu_set_mut().set_bit(cpu_id);
// The config lists physical CPUs, while guests use dense CPU ids from
// zero. Preserve that distinction for non-root SMP zones.
zone_inner.map_cpu(guest_cpu, cpu_id);
cpu_num += 1;
}
zone.write().set_cpu_num(cpu_num);
Expand Down
Loading