Skip to content
This repository was archived by the owner on Nov 6, 2024. It is now read-only.

Commit ea36c41

Browse files
RuoqingHerbradford
authored andcommitted
riscv64: Add device related unit-tests
Add `test_create_device` to verify that vAIA device works on riscv64. Signed-off-by: Ruoqing He <[email protected]>
1 parent e6abfa2 commit ea36c41

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

src/ioctls/device.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Copyright © 2024 Institute of Software, CAS. All rights reserved.
2+
//
13
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
24
// SPDX-License-Identifier: Apache-2.0 OR MIT
35

@@ -322,4 +324,89 @@ mod tests {
322324
// when we initialize the GIC.
323325
assert_eq!(data, 128);
324326
}
327+
328+
#[test]
329+
#[cfg(target_arch = "riscv64")]
330+
fn test_create_device() {
331+
use crate::ioctls::vm::{create_aia_device, request_aia_init, set_supported_nr_irqs};
332+
use kvm_bindings::{
333+
kvm_device_attr, kvm_device_type_KVM_DEV_TYPE_FSL_MPIC_20,
334+
KVM_DEV_RISCV_AIA_ADDR_APLIC, KVM_DEV_RISCV_AIA_CONFIG_SRCS,
335+
KVM_DEV_RISCV_AIA_GRP_ADDR, KVM_DEV_RISCV_AIA_GRP_CONFIG,
336+
};
337+
use vmm_sys_util::errno::Error;
338+
339+
let kvm = Kvm::new().unwrap();
340+
let vm = kvm.create_vm().unwrap();
341+
342+
let mut aia_device = kvm_bindings::kvm_create_device {
343+
type_: kvm_device_type_KVM_DEV_TYPE_FSL_MPIC_20,
344+
fd: 0,
345+
flags: KVM_CREATE_DEVICE_TEST,
346+
};
347+
// This fails on riscv64 as it does not use MPIC (MultiProcessor Interrupt Controller),
348+
// it uses the vAIA.
349+
vm.create_device(&mut aia_device).unwrap_err();
350+
351+
let device_fd = create_aia_device(&vm, 0);
352+
353+
// AIA on riscv64 requires at least one online vCPU prior to setting
354+
// device attributes. Otherwise it would fail when trying to set address
355+
// of IMSIC.
356+
vm.create_vcpu(0).unwrap();
357+
358+
// Following lines to re-construct device_fd are used to test
359+
// DeviceFd::from_raw_fd() and DeviceFd::as_raw_fd().
360+
let raw_fd = unsafe { libc::dup(device_fd.as_raw_fd()) };
361+
assert!(raw_fd >= 0);
362+
let device_fd = unsafe { DeviceFd::from_raw_fd(raw_fd) };
363+
364+
// Set maximum supported number of IRQs of the vAIA device to 128.
365+
set_supported_nr_irqs(&device_fd, 128);
366+
367+
// Before request vAIA device to initialize, APLIC and IMSIC must be set
368+
let aplic_addr: u64 = 0x4000;
369+
device_fd
370+
.set_device_attr(&kvm_device_attr {
371+
group: KVM_DEV_RISCV_AIA_GRP_ADDR,
372+
attr: u64::from(KVM_DEV_RISCV_AIA_ADDR_APLIC),
373+
addr: &aplic_addr as *const u64 as u64,
374+
flags: 0,
375+
})
376+
.unwrap();
377+
let imsic_addr: u64 = 0x8000;
378+
device_fd
379+
.set_device_attr(&kvm_device_attr {
380+
group: KVM_DEV_RISCV_AIA_GRP_ADDR,
381+
attr: 1u64,
382+
addr: &imsic_addr as *const u64 as u64,
383+
flags: 0,
384+
})
385+
.unwrap();
386+
387+
// Initialize valid vAIA device.
388+
request_aia_init(&device_fd);
389+
390+
// Test `get_device_attr`. Here we try to extract the maximum supported number of IRQs.
391+
// This value should be saved in the address provided to the ioctl.
392+
let mut data: u32 = 0;
393+
394+
let mut aia_attr = kvm_bindings::kvm_device_attr {
395+
group: KVM_DEV_RISCV_AIA_GRP_CONFIG,
396+
attr: u64::from(KVM_DEV_RISCV_AIA_CONFIG_SRCS),
397+
addr: data as u64,
398+
..Default::default()
399+
};
400+
401+
// Without properly providing the address to where the
402+
// value will be stored, the ioctl fails with EFAULT.
403+
let res = unsafe { device_fd.get_device_attr(&mut aia_attr) };
404+
assert_eq!(res, Err(Error::new(libc::EFAULT)));
405+
406+
aia_attr.addr = &mut data as *mut u32 as u64;
407+
unsafe { device_fd.get_device_attr(&mut aia_attr) }.unwrap();
408+
// The maximum supported number of IRQs should be 128, same as the value
409+
// when we initialize the AIA.
410+
assert_eq!(data, 128);
411+
}
325412
}

0 commit comments

Comments
 (0)