vmm: retrieve timebase-frequency from KVM instead of hardcoding

The RISC-V device tree's timebase-frequency was hardcoded to 10 MHz
(0x989680). Actual hardware uses different frequencies.

Read the timebase frequency from KVM_GET_ONE_REG via
KVM_REG_RISCV_TIMER (offset 0, kvm_riscv_timer.frequency),
thread it through the VMM to arch to FDT layers, and fall back to
the 10 MHz default when KVM returns no value.

Signed-off-by: Meng Zhuo <mengzhuo@iscas.ac.cn>
This commit is contained in:
Meng Zhuo
2026-06-17 19:11:10 +08:00
committed by Rob Bradford
parent 085642dd42
commit 14aa30cd2e
6 changed files with 47 additions and 5 deletions

View File

@@ -516,6 +516,14 @@ pub trait Vcpu: Send + Sync {
#[cfg(target_arch = "riscv64")]
fn get_non_core_reg(&self, non_core_reg: u32) -> Result<u64>;
///
/// Get the timebase frequency (timer frequency in Hz) on RISC-V 64-bit.
/// This is the frequency at which the RISC-V `time` CSR increments.
///
#[cfg(target_arch = "riscv64")]
fn get_timebase_frequency(&self) -> Result<u64> {
Ok(0)
}
///
/// Configure core registers for a given CPU.
///
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]

View File

@@ -124,7 +124,7 @@ use kvm_bindings::{
KVM_REG_SIZE_U32, KVM_REG_SIZE_U64, KVM_REG_SIZE_U128, kvm_regs, user_pt_regs,
};
#[cfg(target_arch = "riscv64")]
use kvm_bindings::{KVM_REG_RISCV_CORE, kvm_riscv_core};
use kvm_bindings::{KVM_REG_RISCV_CORE, KVM_REG_RISCV_TIMER, kvm_riscv_core};
#[cfg(feature = "tdx")]
use kvm_bindings::{KVM_X86_SW_PROTECTED_VM, KVMIO};
#[cfg(target_arch = "x86_64")]
@@ -2730,6 +2730,18 @@ impl cpu::Vcpu for KvmVcpu {
unimplemented!()
}
#[cfg(target_arch = "riscv64")]
fn get_timebase_frequency(&self) -> cpu::Result<u64> {
use kvm_bindings::kvm_riscv_timer;
let freq_offset = offset_of!(kvm_riscv_timer, frequency);
let id = riscv64_reg_id!(KVM_REG_RISCV_TIMER, freq_offset);
let mut freq_bytes = [0u8; 8];
self.fd
.get_one_reg(id, &mut freq_bytes)
.map_err(|e| cpu::HypervisorCpuError::GetNonCoreRegister(e.into()))?;
Ok(u64::from_le_bytes(freq_bytes))
}
///
/// Configure core registers for a given CPU.
///