mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-01 11:05:46 +00:00
arch: AArch64: add a field gicr_typers
for GIC implementations
The value of GIC register `GICR_TYPER` is needed in restoring the GIC states. This commit adds a field in the GIC device struct and a method to construct its value. Signed-off-by: Henry Wang <Henry.Wang@arm.com>
This commit is contained in:
parent
dcf6d9d731
commit
7ddcad1d8b
@ -8,6 +8,7 @@ pub mod kvm {
|
|||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
use crate::layout;
|
use crate::layout;
|
||||||
use hypervisor::kvm::kvm_bindings;
|
use hypervisor::kvm::kvm_bindings;
|
||||||
|
use std::convert::TryInto;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Represent a GIC v2 device
|
/// Represent a GIC v2 device
|
||||||
@ -15,6 +16,11 @@ pub mod kvm {
|
|||||||
/// The hypervisor agnostic device
|
/// The hypervisor agnostic device
|
||||||
device: Arc<dyn hypervisor::Device>,
|
device: Arc<dyn hypervisor::Device>,
|
||||||
|
|
||||||
|
/// Vector holding values of GICR_TYPER for each vCPU
|
||||||
|
/// As GICv2 does not have redistributor, this field is always
|
||||||
|
/// a zero vector.
|
||||||
|
gicr_typers: Vec<u64>,
|
||||||
|
|
||||||
/// GIC device properties, to be used for setting up the fdt entry
|
/// GIC device properties, to be used for setting up the fdt entry
|
||||||
properties: [u64; 4],
|
properties: [u64; 4],
|
||||||
|
|
||||||
@ -72,6 +78,10 @@ pub mod kvm {
|
|||||||
fn vcpu_count(&self) -> u64 {
|
fn vcpu_count(&self) -> u64 {
|
||||||
self.vcpu_count
|
self.vcpu_count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_gicr_typers(&mut self, gicr_typers: Vec<u64>) {
|
||||||
|
self.gicr_typers = gicr_typers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KvmGICDevice for KvmGICv2 {
|
impl KvmGICDevice for KvmGICv2 {
|
||||||
@ -85,6 +95,7 @@ pub mod kvm {
|
|||||||
) -> Box<dyn GICDevice> {
|
) -> Box<dyn GICDevice> {
|
||||||
Box::new(KvmGICv2 {
|
Box::new(KvmGICv2 {
|
||||||
device,
|
device,
|
||||||
|
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
|
||||||
properties: [
|
properties: [
|
||||||
KvmGICv2::get_dist_addr(),
|
KvmGICv2::get_dist_addr(),
|
||||||
KvmGICv2::get_dist_size(),
|
KvmGICv2::get_dist_size(),
|
||||||
|
@ -6,6 +6,7 @@ pub mod kvm {
|
|||||||
use crate::aarch64::gic::{Error, GICDevice};
|
use crate::aarch64::gic::{Error, GICDevice};
|
||||||
use crate::layout;
|
use crate::layout;
|
||||||
use hypervisor::kvm::kvm_bindings;
|
use hypervisor::kvm::kvm_bindings;
|
||||||
|
use std::convert::TryInto;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{boxed::Box, result};
|
use std::{boxed::Box, result};
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
@ -14,6 +15,9 @@ pub mod kvm {
|
|||||||
/// The hypervisor agnostic device
|
/// The hypervisor agnostic device
|
||||||
device: Arc<dyn hypervisor::Device>,
|
device: Arc<dyn hypervisor::Device>,
|
||||||
|
|
||||||
|
/// Vector holding values of GICR_TYPER for each vCPU
|
||||||
|
gicr_typers: Vec<u64>,
|
||||||
|
|
||||||
/// GIC device properties, to be used for setting up the fdt entry
|
/// GIC device properties, to be used for setting up the fdt entry
|
||||||
properties: [u64; 4],
|
properties: [u64; 4],
|
||||||
|
|
||||||
@ -72,6 +76,10 @@ pub mod kvm {
|
|||||||
fn vcpu_count(&self) -> u64 {
|
fn vcpu_count(&self) -> u64 {
|
||||||
self.vcpu_count
|
self.vcpu_count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_gicr_typers(&mut self, gicr_typers: Vec<u64>) {
|
||||||
|
self.gicr_typers = gicr_typers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KvmGICDevice for KvmGICv3 {
|
impl KvmGICDevice for KvmGICv3 {
|
||||||
@ -85,6 +93,7 @@ pub mod kvm {
|
|||||||
) -> Box<dyn GICDevice> {
|
) -> Box<dyn GICDevice> {
|
||||||
Box::new(KvmGICv3 {
|
Box::new(KvmGICv3 {
|
||||||
device,
|
device,
|
||||||
|
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
|
||||||
properties: [
|
properties: [
|
||||||
KvmGICv3::get_dist_addr(),
|
KvmGICv3::get_dist_addr(),
|
||||||
KvmGICv3::get_dist_size(),
|
KvmGICv3::get_dist_size(),
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
pub mod kvm {
|
pub mod kvm {
|
||||||
|
use std::convert::TryInto;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{boxed::Box, result};
|
use std::{boxed::Box, result};
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
@ -14,6 +15,9 @@ pub mod kvm {
|
|||||||
/// The hypervisor agnostic device
|
/// The hypervisor agnostic device
|
||||||
device: Arc<dyn hypervisor::Device>,
|
device: Arc<dyn hypervisor::Device>,
|
||||||
|
|
||||||
|
/// Vector holding values of GICR_TYPER for each vCPU
|
||||||
|
gicr_typers: Vec<u64>,
|
||||||
|
|
||||||
/// GIC device properties, to be used for setting up the fdt entry
|
/// GIC device properties, to be used for setting up the fdt entry
|
||||||
gic_properties: [u64; 4],
|
gic_properties: [u64; 4],
|
||||||
|
|
||||||
@ -68,6 +72,10 @@ pub mod kvm {
|
|||||||
fn vcpu_count(&self) -> u64 {
|
fn vcpu_count(&self) -> u64 {
|
||||||
self.vcpu_count
|
self.vcpu_count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_gicr_typers(&mut self, gicr_typers: Vec<u64>) {
|
||||||
|
self.gicr_typers = gicr_typers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KvmGICDevice for KvmGICv3ITS {
|
impl KvmGICDevice for KvmGICv3ITS {
|
||||||
@ -81,6 +89,7 @@ pub mod kvm {
|
|||||||
) -> Box<dyn GICDevice> {
|
) -> Box<dyn GICDevice> {
|
||||||
Box::new(KvmGICv3ITS {
|
Box::new(KvmGICv3ITS {
|
||||||
device,
|
device,
|
||||||
|
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
|
||||||
gic_properties: [
|
gic_properties: [
|
||||||
KvmGICv3::get_dist_addr(),
|
KvmGICv3::get_dist_addr(),
|
||||||
KvmGICv3::get_dist_size(),
|
KvmGICv3::get_dist_size(),
|
||||||
|
@ -56,6 +56,9 @@ pub trait GICDevice: Send {
|
|||||||
fn msi_properties(&self) -> &[u64] {
|
fn msi_properties(&self) -> &[u64] {
|
||||||
&[]
|
&[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the values of GICR_TYPER for each vCPU.
|
||||||
|
fn set_gicr_typers(&mut self, gicr_typers: Vec<u64>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod kvm {
|
pub mod kvm {
|
||||||
|
@ -50,6 +50,8 @@ use hypervisor::kvm_ioctls;
|
|||||||
use hypervisor::kvm_ioctls::*;
|
use hypervisor::kvm_ioctls::*;
|
||||||
#[cfg(feature = "mmio_support")]
|
#[cfg(feature = "mmio_support")]
|
||||||
use hypervisor::vm::DataMatch;
|
use hypervisor::vm::DataMatch;
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
use hypervisor::CpuState;
|
||||||
use libc::TIOCGWINSZ;
|
use libc::TIOCGWINSZ;
|
||||||
use libc::{MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE};
|
use libc::{MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE};
|
||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
@ -1171,6 +1173,41 @@ impl DeviceManager {
|
|||||||
pub fn get_gic_device_entity(&self) -> Option<&Arc<Mutex<Box<dyn GICDevice>>>> {
|
pub fn get_gic_device_entity(&self) -> Option<&Arc<Mutex<Box<dyn GICDevice>>>> {
|
||||||
self.gic_device_entity.as_ref()
|
self.gic_device_entity.as_ref()
|
||||||
}
|
}
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
pub fn construct_gicr_typers(&self, vcpu_states: &[CpuState]) {
|
||||||
|
/* Pre-construct the GICR_TYPER:
|
||||||
|
* For our implementation:
|
||||||
|
* Top 32 bits are the affinity value of the associated CPU
|
||||||
|
* CommonLPIAff == 01 (redistributors with same Aff3 share LPI table)
|
||||||
|
* Processor_Number == CPU index starting from 0
|
||||||
|
* DPGS == 0 (GICR_CTLR.DPG* not supported)
|
||||||
|
* Last == 1 if this is the last redistributor in a series of
|
||||||
|
* contiguous redistributor pages
|
||||||
|
* DirectLPI == 0 (direct injection of LPIs not supported)
|
||||||
|
* VLPIS == 0 (virtual LPIs not supported)
|
||||||
|
* PLPIS == 0 (physical LPIs not supported)
|
||||||
|
*/
|
||||||
|
let mut gicr_typers: Vec<u64> = Vec::new();
|
||||||
|
for (index, state) in vcpu_states.iter().enumerate() {
|
||||||
|
let last = {
|
||||||
|
if index == vcpu_states.len() - 1 {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//calculate affinity
|
||||||
|
let mut cpu_affid = state.mpidr & 1095233437695;
|
||||||
|
cpu_affid = ((cpu_affid & 0xFF00000000) >> 8) | (cpu_affid & 0xFFFFFF);
|
||||||
|
gicr_typers.push((cpu_affid << 32) | (1 << 24) | (index as u64) << 8 | (last << 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.get_gic_device_entity()
|
||||||
|
.unwrap()
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.set_gicr_typers(gicr_typers)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub fn enable_interrupt_controller(&self) -> DeviceManagerResult<()> {
|
pub fn enable_interrupt_controller(&self) -> DeviceManagerResult<()> {
|
||||||
|
Loading…
Reference in New Issue
Block a user