Merge pull request #4543 from openanolis/anolis/add_vcpu_configure_aarch64

runtime-rs: Dragonball sandbox - add Vcpu::configure() function for aarch64
This commit is contained in:
Peng Tao 2022-07-05 17:47:40 +08:00 committed by GitHub
commit 514b4e7235
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 21 deletions

View File

@ -51,9 +51,11 @@ hotplug = ["virtio-vsock"]
virtio-vsock = ["dbs-virtio-devices/virtio-vsock", "virtio-queue"]
[patch.'crates-io']
dbs-device = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "127621db934af5ffba558e44b77afa00cdf62af6" }
dbs-interrupt = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "127621db934af5ffba558e44b77afa00cdf62af6" }
dbs-legacy-devices = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "127621db934af5ffba558e44b77afa00cdf62af6" }
dbs-upcall = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "127621db934af5ffba558e44b77afa00cdf62af6" }
dbs-utils = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "127621db934af5ffba558e44b77afa00cdf62af6" }
dbs-virtio-devices = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "127621db934af5ffba558e44b77afa00cdf62af6" }
dbs-device = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "7a8e832b53d66994d6a16f0513d69f540583dcd0" }
dbs-interrupt = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "7a8e832b53d66994d6a16f0513d69f540583dcd0" }
dbs-legacy-devices = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "7a8e832b53d66994d6a16f0513d69f540583dcd0" }
dbs-upcall = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "7a8e832b53d66994d6a16f0513d69f540583dcd0" }
dbs-utils = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "7a8e832b53d66994d6a16f0513d69f540583dcd0" }
dbs-virtio-devices = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "7a8e832b53d66994d6a16f0513d69f540583dcd0" }
dbs-boot = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "7a8e832b53d66994d6a16f0513d69f540583dcd0" }
dbs-arch = { git = "https://github.com/openanolis/dragonball-sandbox.git", rev = "7a8e832b53d66994d6a16f0513d69f540583dcd0" }

View File

@ -8,15 +8,18 @@
use std::sync::mpsc::{channel, Sender};
use std::sync::Arc;
use std::ops::Deref;
use crate::IoManagerCached;
use dbs_utils::time::TimestampUs;
use dbs_arch::regs;
use dbs_boot::get_fdt_addr;
use kvm_ioctls::{VcpuFd, VmFd};
use vm_memory::GuestAddress;
use vm_memory::{Address, GuestAddress, GuestAddressSpace};
use vmm_sys_util::eventfd::EventFd;
use crate::address_space_manager::GuestAddressSpaceImpl;
use crate::vcpu::vcpu_impl::{Result, Vcpu, VcpuStateEvent};
use crate::vcpu::vcpu_impl::{Result, Vcpu, VcpuStateEvent, VcpuError};
use crate::vcpu::VcpuConfig;
#[allow(unused)]
@ -83,7 +86,34 @@ impl Vcpu {
kernel_load_addr: Option<GuestAddress>,
_pgtable_addr: Option<GuestAddress>,
) -> Result<()> {
// TODO: add arm vcpu configure() function. issue: #4445
let mut kvi: kvm_bindings::kvm_vcpu_init = kvm_bindings::kvm_vcpu_init::default();
// This reads back the kernel's preferred target type.
vm_fd
.get_preferred_target(&mut kvi)
.map_err(VcpuError::VcpuArmPreferredTarget)?;
// We already checked that the capability is supported.
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PSCI_0_2;
// Non-boot cpus are powered off initially.
if self.id > 0 {
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
}
self.fd.vcpu_init(&kvi).map_err(VcpuError::VcpuArmInit)?;
if let Some(address) = kernel_load_addr {
regs::setup_regs(
&self.fd,
self.id,
address.raw_value(),
get_fdt_addr(vm_as.memory().deref()),
)
.map_err(VcpuError::REGSConfiguration)?;
}
self.mpidr =
regs::read_mpidr(&self.fd).map_err(VcpuError::REGSConfiguration)?;
Ok(())
}

View File

@ -452,9 +452,6 @@ impl Vcpu {
Ok(VcpuEmulation::Handled)
}
VcpuExit::MmioWrite(addr, data) => {
#[cfg(target_arch = "aarch64")]
self.check_boot_complete_signal(addr, data);
let _ = self.io_mgr.mmio_write(addr, data);
METRICS.vcpu.exit_mmio_write.inc();
Ok(VcpuEmulation::Handled)
@ -851,20 +848,52 @@ pub mod tests {
(vcpu, rx)
}
#[cfg(target_arch = "x86_64")]
#[cfg(target_arch = "aarch64")]
fn create_vcpu() -> (Vcpu, Receiver<VcpuStateEvent>) {
// Call for kvm too frequently would cause error in some host kernel.
std::thread::sleep(std::time::Duration::from_millis(5));
let kvm = Kvm::new().unwrap();
let vm = Arc::new(kvm.create_vm().unwrap());
let kvm_context = KvmContext::new(Some(kvm.as_raw_fd())).unwrap();
let vcpu_fd = Arc::new(vm.create_vcpu(0).unwrap());
let io_manager = IoManagerCached::new(Arc::new(ArcSwap::new(Arc::new(IoManager::new()))));
let reset_event_fd = EventFd::new(libc::EFD_NONBLOCK).unwrap();
let vcpu_state_event = EventFd::new(libc::EFD_NONBLOCK).unwrap();
let (tx, rx) = channel();
let time_stamp = TimestampUs::default();
let vcpu = Vcpu::new_aarch64(
0,
vcpu_fd,
io_manager,
reset_event_fd,
vcpu_state_event,
tx,
time_stamp,
false,
)
.unwrap();
(vcpu, rx)
}
#[test]
fn test_vcpu_run_emulation() {
let (mut vcpu, _) = create_vcpu();
// Io in
*(EMULATE_RES.lock().unwrap()) = EmulationCase::IoIn;
let res = vcpu.run_emulation();
assert!(matches!(res, Ok(VcpuEmulation::Handled)));
#[cfg(target_arch = "x86_64")]
{
// Io in
*(EMULATE_RES.lock().unwrap()) = EmulationCase::IoIn;
let res = vcpu.run_emulation();
assert!(matches!(res, Ok(VcpuEmulation::Handled)));
// Io out
*(EMULATE_RES.lock().unwrap()) = EmulationCase::IoOut;
let res = vcpu.run_emulation();
assert!(matches!(res, Ok(VcpuEmulation::Handled)));
// Io out
*(EMULATE_RES.lock().unwrap()) = EmulationCase::IoOut;
let res = vcpu.run_emulation();
assert!(matches!(res, Ok(VcpuEmulation::Handled)));
}
// Mmio read
*(EMULATE_RES.lock().unwrap()) = EmulationCase::MmioRead;