mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-02 11:35:46 +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
|
/// Error configuring the MPIDR register
|
||||||
VcpuRegMpidr(hypervisor::HypervisorCpuError),
|
VcpuRegMpidr(hypervisor::HypervisorCpuError),
|
||||||
|
|
||||||
|
/// Error initializing PMU for vcpu
|
||||||
|
VcpuInitPmu,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for super::Error {
|
impl From<Error> for super::Error {
|
||||||
|
@ -104,6 +104,9 @@ pub enum Error {
|
|||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
InitializeTdx(hypervisor::HypervisorCpuError),
|
InitializeTdx(hypervisor::HypervisorCpuError),
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
InitPmu(hypervisor::HypervisorCpuError),
|
||||||
|
|
||||||
/// Failed scheduling the thread on the expected CPU set.
|
/// Failed scheduling the thread on the expected CPU set.
|
||||||
ScheduleCpuSet,
|
ScheduleCpuSet,
|
||||||
}
|
}
|
||||||
@ -312,6 +315,7 @@ impl Vcpu {
|
|||||||
.map_err(Error::VcpuArmPreferredTarget)?;
|
.map_err(Error::VcpuArmPreferredTarget)?;
|
||||||
// We already checked that the capability is supported.
|
// 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_PSCI_0_2;
|
||||||
|
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PMU_V3;
|
||||||
// Non-boot cpus are powered off initially.
|
// Non-boot cpus are powered off initially.
|
||||||
if self.id > 0 {
|
if self.id > 0 {
|
||||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
|
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
|
||||||
@ -699,6 +703,51 @@ impl CpuManager {
|
|||||||
Ok(())
|
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(
|
fn start_vcpu(
|
||||||
&mut self,
|
&mut self,
|
||||||
vcpu: Arc<Mutex<Vcpu>>,
|
vcpu: Arc<Mutex<Vcpu>>,
|
||||||
|
@ -1151,6 +1151,16 @@ impl Vm {
|
|||||||
Error::ConfigureSystem(arch::Error::AArch64Setup(arch::aarch64::Error::SetupGic(e)))
|
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(
|
arch::configure_system(
|
||||||
&mem,
|
&mem,
|
||||||
cmdline.as_str(),
|
cmdline.as_str(),
|
||||||
|
Loading…
Reference in New Issue
Block a user