Alioth Code Coverage

device.rs0.00%

1// Copyright 2024 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::mem::{MaybeUninit, size_of_val};
16use std::os::fd::{AsFd, BorrowedFd, FromRawFd, OwnedFd};
17
18use snafu::ResultExt;
19
20use crate::hv::kvm::kvm_error;
21use crate::hv::kvm::vm::KvmVm;
22use crate::hv::{KvmError, Result};
23use crate::sys::kvm::{
24 KvmCreateDevice, KvmDevType, KvmDeviceAttr, kvm_create_device, kvm_get_device_attr,
25 kvm_set_device_attr,
26};
27
28#[derive(Debug)]
29pub(super) struct KvmDevice(pub OwnedFd);
30
31impl KvmDevice {
32 pub fn new(vm: &KvmVm, type_: KvmDevType) -> Result<KvmDevice, KvmError> {
33 let mut create_device = KvmCreateDevice {
34 type_,
35 fd: 0,
36 flags: 0,
37 };
38 unsafe { kvm_create_device(&vm.vm.fd, &mut create_device) }
39 .context(kvm_error::CreateDevice { type_ })?;
40 Ok(KvmDevice(unsafe { OwnedFd::from_raw_fd(create_device.fd) }))
41 }
42}
43
44impl AsFd for KvmDevice {
45 fn as_fd(&self) -> BorrowedFd<'_> {
46 self.0.as_fd()
47 }
48}
49
50impl KvmDevice {
51 pub fn set_attr<T>(&self, group: u32, attr: u64, val: &T) -> Result<(), KvmError> {
52 let attr = KvmDeviceAttr {
53 group,
54 attr,
55 addr: if size_of_val(val) == 0 {
56 0
57 } else {
58 val as *const _ as _
59 },
60 _flags: 0,
61 };
62 unsafe { kvm_set_device_attr(self, &attr) }.context(kvm_error::DeviceAttr)?;
63 Ok(())
64 }
65
66 pub fn get_attr<T>(&self, group: u32, attr: u64) -> Result<T, KvmError> {
67 let mut val = MaybeUninit::uninit();
68 let attr = KvmDeviceAttr {
69 group,
70 attr,
71 addr: val.as_mut_ptr() as _,
72 _flags: 0,
73 };
74 unsafe { kvm_get_device_attr(self, &attr) }.context(kvm_error::DeviceAttr)?;
75 Ok(unsafe { val.assume_init() })
76 }
77}
78