arch: gic: Extend GicV3Its with its_device field

In current code, the ITS device fd of GICv3 will be lost after the
creation of GIC. This commit adds a new `its_device` field for the
`GicV3Its` struct, which will be useful to save the ITS device fd.
This fd will be used in restoring the ITS device.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
This commit is contained in:
Henry Wang 2021-06-30 18:00:45 +08:00 committed by Sebastien Boeuf
parent 6e63df98ba
commit 957d3deeea
3 changed files with 36 additions and 8 deletions

View File

@ -1,5 +1,8 @@
// Copyright 2021 Arm Limited (or its affiliates). All rights reserved.
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
//
// This file implements the GicV3 device.
pub mod kvm { pub mod kvm {
use crate::aarch64::gic::dist_regs::{get_dist_regs, read_ctlr, set_dist_regs, write_ctlr}; use crate::aarch64::gic::dist_regs::{get_dist_regs, read_ctlr, set_dist_regs, write_ctlr};
@ -50,7 +53,7 @@ pub mod kvm {
type Result<T> = result::Result<T, Error>; type Result<T> = result::Result<T, Error>;
pub struct KvmGicV3 { pub struct KvmGicV3 {
/// The hypervisor agnostic device /// The hypervisor agnostic device for the GicV3
device: Arc<dyn hypervisor::Device>, device: Arc<dyn hypervisor::Device>,
/// Vector holding values of GICR_TYPER for each vCPU /// Vector holding values of GICR_TYPER for each vCPU
@ -168,6 +171,8 @@ pub mod kvm {
self.vcpu_count self.vcpu_count
} }
fn set_its_device(&mut self, _its_device: Option<Arc<dyn hypervisor::Device>>) {}
fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]) { fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]) {
let gicr_typers = construct_gicr_typers(vcpu_states); let gicr_typers = construct_gicr_typers(vcpu_states);
self.gicr_typers = gicr_typers; self.gicr_typers = gicr_typers;
@ -202,7 +207,7 @@ pub mod kvm {
fn init_device_attributes( fn init_device_attributes(
_vm: &Arc<dyn hypervisor::Vm>, _vm: &Arc<dyn hypervisor::Vm>,
gic_device: &dyn GicDevice, gic_device: &mut dyn GicDevice,
) -> crate::aarch64::gic::Result<()> { ) -> crate::aarch64::gic::Result<()> {
/* Setting up the distributor attribute. /* Setting up the distributor attribute.
We are placing the GIC below 1GB so we need to substract the size of the distributor. We are placing the GIC below 1GB so we need to substract the size of the distributor.

View File

@ -1,5 +1,7 @@
// Copyright 2020 ARM Limited // Copyright 2021 Arm Limited (or its affiliates). All rights reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
//
// This file implements the GicV3 device with ITS (Virtual Interrupt Translation Service).
pub mod kvm { pub mod kvm {
use std::any::Any; use std::any::Any;
@ -13,9 +15,12 @@ pub mod kvm {
use hypervisor::CpuState; use hypervisor::CpuState;
pub struct KvmGicV3Its { pub struct KvmGicV3Its {
/// The hypervisor agnostic device /// The hypervisor agnostic device for the GicV3
device: Arc<dyn hypervisor::Device>, device: Arc<dyn hypervisor::Device>,
/// The hypervisor agnostic device for the Its device
its_device: Option<Arc<dyn hypervisor::Device>>,
/// 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],
@ -43,6 +48,10 @@ pub mod kvm {
&self.device &self.device
} }
fn its_device(&self) -> Option<&Arc<dyn hypervisor::Device>> {
self.its_device.as_ref()
}
fn fdt_compatibility(&self) -> &str { fn fdt_compatibility(&self) -> &str {
"arm,gic-v3" "arm,gic-v3"
} }
@ -71,6 +80,10 @@ pub mod kvm {
self.vcpu_count self.vcpu_count
} }
fn set_its_device(&mut self, its_device: Option<Arc<dyn hypervisor::Device>>) {
self.its_device = its_device;
}
fn set_gicr_typers(&mut self, _vcpu_states: &[CpuState]) {} fn set_gicr_typers(&mut self, _vcpu_states: &[CpuState]) {}
fn as_any_concrete_mut(&mut self) -> &mut dyn Any { fn as_any_concrete_mut(&mut self) -> &mut dyn Any {
@ -89,6 +102,7 @@ pub mod kvm {
) -> Box<dyn GicDevice> { ) -> Box<dyn GicDevice> {
Box::new(KvmGicV3Its { Box::new(KvmGicV3Its {
device, device,
its_device: None,
gic_properties: [ gic_properties: [
KvmGicV3::get_dist_addr(), KvmGicV3::get_dist_addr(),
KvmGicV3::get_dist_size(), KvmGicV3::get_dist_size(),
@ -105,7 +119,7 @@ pub mod kvm {
fn init_device_attributes( fn init_device_attributes(
vm: &Arc<dyn hypervisor::Vm>, vm: &Arc<dyn hypervisor::Vm>,
gic_device: &dyn GicDevice, gic_device: &mut dyn GicDevice,
) -> Result<()> { ) -> Result<()> {
KvmGicV3::init_device_attributes(vm, gic_device)?; KvmGicV3::init_device_attributes(vm, gic_device)?;
@ -135,6 +149,8 @@ pub mod kvm {
0, 0,
)?; )?;
gic_device.set_its_device(Some(its_fd));
Ok(()) Ok(())
} }
} }

View File

@ -31,6 +31,11 @@ pub trait GicDevice: Send {
/// Returns the hypervisor agnostic Device of the GIC device /// Returns the hypervisor agnostic Device of the GIC device
fn device(&self) -> &Arc<dyn hypervisor::Device>; fn device(&self) -> &Arc<dyn hypervisor::Device>;
/// Returns the hypervisor agnostic Device of the ITS device
fn its_device(&self) -> Option<&Arc<dyn hypervisor::Device>> {
None
}
/// Returns the fdt compatibility property of the device /// Returns the fdt compatibility property of the device
fn fdt_compatibility(&self) -> &str; fn fdt_compatibility(&self) -> &str;
@ -58,6 +63,8 @@ pub trait GicDevice: Send {
&[] &[]
} }
fn set_its_device(&mut self, its_device: Option<Arc<dyn hypervisor::Device>>);
/// Get the values of GICR_TYPER for each vCPU. /// Get the values of GICR_TYPER for each vCPU.
fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]); fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]);
@ -88,7 +95,7 @@ pub mod kvm {
/// Setup the device-specific attributes /// Setup the device-specific attributes
fn init_device_attributes( fn init_device_attributes(
vm: &Arc<dyn hypervisor::Vm>, vm: &Arc<dyn hypervisor::Vm>,
gic_device: &dyn GicDevice, gic_device: &mut dyn GicDevice,
) -> Result<()>; ) -> Result<()>;
/// Initialize a GIC device /// Initialize a GIC device
@ -179,9 +186,9 @@ pub mod kvm {
fn new(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GicDevice>> { fn new(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GicDevice>> {
let vgic_fd = Self::init_device(vm)?; let vgic_fd = Self::init_device(vm)?;
let device = Self::create_device(vgic_fd, vcpu_count); let mut device = Self::create_device(vgic_fd, vcpu_count);
Self::init_device_attributes(vm, &*device)?; Self::init_device_attributes(vm, &mut *device)?;
Self::finalize_device(&*device)?; Self::finalize_device(&*device)?;