mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-01 17:35:19 +00:00
vmm: Init PMU for vcpu when create vm
PMU is needed in guest for performance profiling, thus should be enabled. Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
This commit is contained in:
parent
9bcb984962
commit
53060874a7
@ -43,6 +43,9 @@ pub enum Error {
|
||||
|
||||
/// Error configuring the MPIDR register
|
||||
VcpuRegMpidr(hypervisor::HypervisorCpuError),
|
||||
|
||||
/// Error initializing PMU for vcpu
|
||||
VcpuInitPmu,
|
||||
}
|
||||
|
||||
impl From<Error> for super::Error {
|
||||
|
@ -104,6 +104,9 @@ pub enum Error {
|
||||
#[cfg(feature = "tdx")]
|
||||
InitializeTdx(hypervisor::HypervisorCpuError),
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
InitPmu(hypervisor::HypervisorCpuError),
|
||||
|
||||
/// Failed scheduling the thread on the expected CPU set.
|
||||
ScheduleCpuSet,
|
||||
}
|
||||
@ -312,6 +315,7 @@ impl Vcpu {
|
||||
.map_err(Error::VcpuArmPreferredTarget)?;
|
||||
// We already checked that the capability is supported.
|
||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PSCI_0_2;
|
||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PMU_V3;
|
||||
// Non-boot cpus are powered off initially.
|
||||
if self.id > 0 {
|
||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
|
||||
@ -699,6 +703,51 @@ impl CpuManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub fn init_pmu(&self, irq: u32) -> Result<bool> {
|
||||
let cpu_attr = kvm_bindings::kvm_device_attr {
|
||||
group: kvm_bindings::KVM_ARM_VCPU_PMU_V3_CTRL,
|
||||
attr: u64::from(kvm_bindings::KVM_ARM_VCPU_PMU_V3_INIT),
|
||||
addr: 0x0,
|
||||
flags: 0,
|
||||
};
|
||||
|
||||
for cpu in self.vcpus.iter() {
|
||||
let tmp = irq;
|
||||
let cpu_attr_irq = kvm_bindings::kvm_device_attr {
|
||||
group: kvm_bindings::KVM_ARM_VCPU_PMU_V3_CTRL,
|
||||
attr: u64::from(kvm_bindings::KVM_ARM_VCPU_PMU_V3_IRQ),
|
||||
addr: &tmp as *const u32 as u64,
|
||||
flags: 0,
|
||||
};
|
||||
|
||||
// Check if PMU attr is available, if not, log the information.
|
||||
if cpu.lock().unwrap().vcpu.has_vcpu_attr(&cpu_attr).is_ok() {
|
||||
// Set irq for PMU
|
||||
cpu.lock()
|
||||
.unwrap()
|
||||
.vcpu
|
||||
.set_vcpu_attr(&cpu_attr_irq)
|
||||
.map_err(Error::InitPmu)?;
|
||||
|
||||
// Init PMU
|
||||
cpu.lock()
|
||||
.unwrap()
|
||||
.vcpu
|
||||
.set_vcpu_attr(&cpu_attr)
|
||||
.map_err(Error::InitPmu)?;
|
||||
} else {
|
||||
debug!(
|
||||
"PMU attribute is not supported in vCPU{}, skip PMU init!",
|
||||
cpu.lock().unwrap().id
|
||||
);
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn start_vcpu(
|
||||
&mut self,
|
||||
vcpu: Arc<Mutex<Vcpu>>,
|
||||
|
@ -1151,6 +1151,16 @@ impl Vm {
|
||||
Error::ConfigureSystem(arch::Error::AArch64Setup(arch::aarch64::Error::SetupGic(e)))
|
||||
})?;
|
||||
|
||||
// PMU interrupt sticks to PPI, so need to be added by 16 to get real irq number.
|
||||
let pmu_supported = self
|
||||
.cpu_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.init_pmu(arch::aarch64::fdt::AARCH64_PMU_IRQ + 16)
|
||||
.map_err(|_| {
|
||||
Error::ConfigureSystem(arch::Error::AArch64Setup(arch::aarch64::Error::VcpuInitPmu))
|
||||
})?;
|
||||
|
||||
arch::configure_system(
|
||||
&mem,
|
||||
cmdline.as_str(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user