device.rs0.00%
1
// Copyright 2024 Google LLC2
//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 at6
//7
// https://www.apache.org/licenses/LICENSE-2.08
//9
// Unless required by applicable law or agreed to in writing, software10
// 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 and13
// limitations under the License.14
15
use std::mem::{MaybeUninit, size_of_val};16
use std::os::fd::{AsFd, BorrowedFd, FromRawFd, OwnedFd};17
18
use snafu::ResultExt;19
20
use crate::hv::kvm::kvm_error;21
use crate::hv::kvm::vm::KvmVm;22
use crate::hv::{KvmError, Result};23
use crate::sys::kvm::{24
KvmCreateDevice, KvmDevType, KvmDeviceAttr, kvm_create_device, kvm_get_device_attr,25
kvm_set_device_attr,26
};27
28
#[derive(Debug)]29
pub(super) struct KvmDevice(pub OwnedFd);30
31
impl 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
44
impl AsFd for KvmDevice {45
fn as_fd(&self) -> BorrowedFd<'_> {46
self.0.as_fd()47
}48
}49
50
impl 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
057
} 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