|
| 1 | +// Copyright © 2024 Institute of Software, CAS. All rights reserved. |
| 2 | +// |
1 | 3 | // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2 | 4 | // SPDX-License-Identifier: Apache-2.0 OR MIT
|
3 | 5 |
|
@@ -322,4 +324,89 @@ mod tests {
|
322 | 324 | // when we initialize the GIC.
|
323 | 325 | assert_eq!(data, 128);
|
324 | 326 | }
|
| 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 | + } |
325 | 412 | }
|
0 commit comments