Skip to content

Commit 3ab548e

Browse files
committed
kvm-ioctls: add support for vm device_attr ioctls on aarch64
Add support for HAS_DEVICE_ATTR and SET_DEVICE_ATTR vm ioctls on aarch64 to support configuring SMCCC filter. Signed-off-by: kylin-wangdi <[email protected]>
1 parent 8c0590a commit 3ab548e

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

kvm-ioctls/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
## Upcoming Release
44

5+
### Added
6+
57
- Plumb through KVM_CAP_X2APIC_API as X2ApicApi cap.
8+
- [[#334]](https://github.com/rust-vmm/kvm/pull/334) Added support for
9+
`KVM_HAS_DEVICE_ATTR` and `KVM_SET_DEVICE_ATTR` vm ioctl on aarch64.
610

711
## v0.23.0
812

kvm-ioctls/src/ioctls/vm.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,6 +1908,95 @@ impl VmFd {
19081908
}
19091909
Ok(())
19101910
}
1911+
1912+
/// Sets a specified piece of vm configuration and/or state.
1913+
///
1914+
/// See the documentation for `KVM_SET_DEVICE_ATTR` in
1915+
/// [KVM API doc](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt)
1916+
/// # Arguments
1917+
///
1918+
/// * `device_attr` - The vm attribute to be set.
1919+
///
1920+
/// # Example
1921+
///
1922+
/// ```rust
1923+
/// # extern crate kvm_ioctls;
1924+
/// # extern crate kvm_bindings;
1925+
/// # use kvm_ioctls::Kvm;
1926+
/// # use kvm_bindings::{
1927+
/// PSCI_0_2_FN64_BASE, kvm_smccc_filter_action_KVM_SMCCC_FILTER_FWD_TO_USER,
1928+
/// KVM_ARM_VM_SMCCC_CTRL, KVM_ARM_VM_SMCCC_FILTER
1929+
/// };
1930+
/// let kvm = Kvm::new().unwrap();
1931+
/// let vm = kvm.create_vm().unwrap();
1932+
///
1933+
/// const PSCI_0_2_FN64_CPU_ON: u32 = PSCI_0_2_FN64_BASE + 3;
1934+
/// let smccc_filter = kvm_bindings::kvm_smccc_filter {
1935+
/// base: PSCI_0_2_FN64_CPU_ON,
1936+
/// nr_functions: 1,
1937+
/// action: kvm_smccc_filter_action_KVM_SMCCC_FILTER_FWD_TO_USER as u8,
1938+
/// pad: [0u8; 15],
1939+
/// };
1940+
///
1941+
/// let dist_attr = kvm_bindings::kvm_device_attr {
1942+
/// group: KVM_ARM_VM_SMCCC_CTRL,
1943+
/// attr: KVM_ARM_VM_SMCCC_FILTER as u64,
1944+
/// addr: &smccc_filter as *const _ as u64,
1945+
/// flags: 0,
1946+
/// };
1947+
///
1948+
/// if (vm.has_device_attr(&dist_attr).is_ok()) {
1949+
/// vm.set_device_attr(&dist_attr).unwrap();
1950+
/// }
1951+
/// ```
1952+
#[cfg(target_arch = "aarch64")]
1953+
pub fn set_device_attr(&self, device_attr: &kvm_device_attr) -> Result<()> {
1954+
// SAFETY: Safe because we call this with a Vm fd and we trust the kernel.
1955+
let ret = unsafe { ioctl_with_ref(self, KVM_SET_DEVICE_ATTR(), device_attr) };
1956+
if ret != 0 {
1957+
return Err(errno::Error::last());
1958+
}
1959+
Ok(())
1960+
}
1961+
1962+
/// Tests whether a vm supports a particular attribute.
1963+
///
1964+
/// See the documentation for `KVM_HAS_DEVICE_ATTR` in
1965+
/// [KVM API doc](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt)
1966+
/// # Arguments
1967+
///
1968+
/// * `device_attr` - The vm attribute to be tested. `addr` field is ignored.
1969+
///
1970+
/// # Example
1971+
///
1972+
/// ```rust
1973+
/// # extern crate kvm_ioctls;
1974+
/// # extern crate kvm_bindings;
1975+
/// # use kvm_ioctls::Kvm;
1976+
/// # use kvm_bindings::{
1977+
/// KVM_ARM_VM_SMCCC_CTRL, KVM_ARM_VM_SMCCC_FILTER
1978+
/// };
1979+
/// let kvm = Kvm::new().unwrap();
1980+
/// let vm = kvm.create_vm().unwrap();
1981+
///
1982+
/// let dist_attr = kvm_bindings::kvm_device_attr {
1983+
/// group: KVM_ARM_VM_SMCCC_CTRL,
1984+
/// attr: KVM_ARM_VM_SMCCC_FILTER as u64,
1985+
/// addr: 0x0,
1986+
/// flags: 0,
1987+
/// };
1988+
///
1989+
/// vm.has_device_attr(&dist_attr);
1990+
/// ```
1991+
#[cfg(target_arch = "aarch64")]
1992+
pub fn has_device_attr(&self, device_attr: &kvm_device_attr) -> Result<()> {
1993+
// SAFETY: Safe because we call this with a Vm fd and we trust the kernel.
1994+
let ret = unsafe { ioctl_with_ref(self, KVM_HAS_DEVICE_ATTR(), device_attr) };
1995+
if ret != 0 {
1996+
return Err(errno::Error::last());
1997+
}
1998+
Ok(())
1999+
}
19112000
}
19122001

19132002
/// Helper function to create a new `VmFd`.
@@ -2787,4 +2876,29 @@ mod tests {
27872876
vm.register_enc_memory_region(&memory_region).unwrap();
27882877
vm.unregister_enc_memory_region(&memory_region).unwrap();
27892878
}
2879+
2880+
#[test]
2881+
#[cfg(target_arch = "aarch64")]
2882+
fn test_set_smccc_filter() {
2883+
let kvm = Kvm::new().unwrap();
2884+
let vm = kvm.create_vm().unwrap();
2885+
2886+
const PSCI_0_2_FN64_CPU_ON: u32 = PSCI_0_2_FN64_BASE + 3;
2887+
let smccc_filter = kvm_bindings::kvm_smccc_filter {
2888+
base: PSCI_0_2_FN64_CPU_ON,
2889+
nr_functions: 1,
2890+
action: kvm_smccc_filter_action_KVM_SMCCC_FILTER_FWD_TO_USER as u8,
2891+
pad: [0u8; 15],
2892+
};
2893+
2894+
let dist_attr = kvm_bindings::kvm_device_attr {
2895+
group: KVM_ARM_VM_SMCCC_CTRL,
2896+
attr: KVM_ARM_VM_SMCCC_FILTER as u64,
2897+
addr: &smccc_filter as *const _ as u64,
2898+
flags: 0,
2899+
};
2900+
2901+
vm.has_device_attr(&dist_attr).unwrap();
2902+
vm.set_device_attr(&dist_attr).unwrap();
2903+
}
27902904
}

0 commit comments

Comments
 (0)