aarch64: Refactor KvmGicV3Its::new()

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
Michael Zhao
2022-05-24 15:44:53 +08:00
committed by Xin Wang
parent 3fe20cc09a
commit 4a2d3cb4f5

View File

@@ -372,40 +372,17 @@ pub mod kvm {
kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3 kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3
} }
/// Create the GIC device object
fn create_device(
device: Arc<dyn hypervisor::Device>,
vcpu_count: u64,
) -> Box<dyn GicDevice> {
Box::new(KvmGicV3Its {
device,
its_device: None,
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
gic_properties: [
KvmGicV3Its::get_dist_addr(),
KvmGicV3Its::get_dist_size(),
KvmGicV3Its::get_redists_addr(vcpu_count),
KvmGicV3Its::get_redists_size(vcpu_count),
],
msi_properties: [
KvmGicV3Its::get_msi_addr(vcpu_count),
KvmGicV3Its::get_msi_size(),
],
vcpu_count,
})
}
/// Setup the device-specific attributes /// Setup the device-specific attributes
fn init_device_attributes( fn init_device_attributes(
&mut self,
vm: &Arc<dyn hypervisor::Vm>, vm: &Arc<dyn hypervisor::Vm>,
gic_device: &mut dyn GicDevice,
) -> crate::aarch64::gic::Result<()> { ) -> crate::aarch64::gic::Result<()> {
// GicV3 part attributes // GicV3 part attributes
/* 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.
*/ */
Self::set_device_attribute( Self::set_device_attribute(
gic_device.device(), self.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR, kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_DIST), u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_DIST),
&KvmGicV3Its::get_dist_addr() as *const u64 as u64, &KvmGicV3Its::get_dist_addr() as *const u64 as u64,
@@ -416,10 +393,10 @@ pub mod kvm {
We are calculating here the start of the redistributors address. We have one per CPU. We are calculating here the start of the redistributors address. We have one per CPU.
*/ */
Self::set_device_attribute( Self::set_device_attribute(
gic_device.device(), self.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR, kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_REDIST), u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_REDIST),
&KvmGicV3Its::get_redists_addr(gic_device.vcpu_count()) as *const u64 as u64, &KvmGicV3Its::get_redists_addr(self.vcpu_count()) as *const u64 as u64,
0, 0,
)?; )?;
@@ -438,7 +415,7 @@ pub mod kvm {
&its_fd, &its_fd,
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR, kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
u64::from(kvm_bindings::KVM_VGIC_ITS_ADDR_TYPE), u64::from(kvm_bindings::KVM_VGIC_ITS_ADDR_TYPE),
&KvmGicV3Its::get_msi_addr(gic_device.vcpu_count()) as *const u64 as u64, &KvmGicV3Its::get_msi_addr(self.vcpu_count()) as *const u64 as u64,
0, 0,
)?; )?;
@@ -450,13 +427,37 @@ pub mod kvm {
0, 0,
)?; )?;
gic_device.set_its_device(Some(its_fd)); self.set_its_device(Some(its_fd));
/* We need to tell the kernel how many irqs to support with this vgic.
* See the `layout` module for details.
*/
let nr_irqs: u32 = layout::IRQ_NUM;
let nr_irqs_ptr = &nr_irqs as *const u32;
Self::set_device_attribute(
self.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
0,
nr_irqs_ptr as u64,
0,
)?;
/* Finalize the GIC.
* See https://code.woboq.org/linux/linux/virt/kvm/arm/vgic/vgic-kvm-device.c.html#211.
*/
Self::set_device_attribute(
self.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_CTRL_INIT),
0,
0,
)?;
Ok(()) Ok(())
} }
/// Initialize a GIC device /// Create a KVM Vgic device
fn init_device(vm: &Arc<dyn hypervisor::Vm>) -> Result<Arc<dyn hypervisor::Device>> { fn create_device(vm: &Arc<dyn hypervisor::Vm>) -> Result<Arc<dyn hypervisor::Device>> {
let mut gic_device = kvm_bindings::kvm_create_device { let mut gic_device = kvm_bindings::kvm_create_device {
type_: Self::version(), type_: Self::version(),
fd: 0, fd: 0,
@@ -488,47 +489,31 @@ pub mod kvm {
Ok(()) Ok(())
} }
/// Finalize the setup of a GIC device
fn finalize_device(gic_device: &dyn GicDevice) -> Result<()> {
/* We need to tell the kernel how many irqs to support with this vgic.
* See the `layout` module for details.
*/
let nr_irqs: u32 = layout::IRQ_NUM;
let nr_irqs_ptr = &nr_irqs as *const u32;
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
0,
nr_irqs_ptr as u64,
0,
)?;
/* Finalize the GIC.
* See https://code.woboq.org/linux/linux/virt/kvm/arm/vgic/vgic-kvm-device.c.html#211.
*/
Self::set_device_attribute(
gic_device.device(),
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL,
u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_CTRL_INIT),
0,
0,
)?;
Ok(())
}
/// Method to initialize the GIC device /// Method to initialize the GIC device
#[allow(clippy::new_ret_no_self)] #[allow(clippy::new_ret_no_self)]
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 = Self::create_device(vm)?;
let mut device = Self::create_device(vgic_fd, vcpu_count); let mut gic_device = Box::new(KvmGicV3Its {
device: vgic,
its_device: None,
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
gic_properties: [
KvmGicV3Its::get_dist_addr(),
KvmGicV3Its::get_dist_size(),
KvmGicV3Its::get_redists_addr(vcpu_count),
KvmGicV3Its::get_redists_size(vcpu_count),
],
msi_properties: [
KvmGicV3Its::get_msi_addr(vcpu_count),
KvmGicV3Its::get_msi_size(),
],
vcpu_count,
});
Self::init_device_attributes(vm, &mut *device)?; gic_device.init_device_attributes(vm)?;
Self::finalize_device(&*device)?; Ok(gic_device)
Ok(device)
} }
} }