Skip to content

Commit

Permalink
system: Added an API get_max_vcpu_id to kvm
Browse files Browse the repository at this point in the history
Added a new API `get_max_vcpu_id` that returns the
`KVM_CAP_MAX_VCPU_ID` if the Extension is present or `get_max_vcpus`.

Also updated the test case for `vm.create_cpu` to use `max_vcpu_id`
obtained using the above API.

Updated coverage score to 91.3 to fix build issue

Signed-off-by: Abhijit Gadgil <gabhijit@iitbombay.org>
  • Loading branch information
gabhijit authored and alexandruag committed Jan 15, 2021
1 parent 4f61bba commit 69d03d9
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 21 deletions.
2 changes: 1 addition & 1 deletion coverage_config_x86_64.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"coverage_score": 91.2,
"coverage_score": 91.3,
"exclude_path": "",
"crate_features": ""
}
21 changes: 21 additions & 0 deletions src/ioctls/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,27 @@ impl Kvm {
}
}

/// Gets the Maximum VCPU ID per VM.
///
/// See the documentation for `KVM_CAP_MAX_VCPU_ID`
/// Returns [get_max_vcpus()](struct.Kvm.html#method.get_max_vcpus) when
/// `KVM_CAP_MAX_VCPU_ID` is not implemented
///
/// # Example
///
/// ```
/// # use kvm_ioctls::Kvm;
/// let kvm = Kvm::new().unwrap();
/// assert!(kvm.get_max_vcpu_id() > 0);
/// ```
///
pub fn get_max_vcpu_id(&self) -> usize {
match self.check_extension_int(Cap::MaxVcpuId) {
0 => self.get_max_vcpus(),
x => x as usize,
}
}

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn get_cpuid(&self, kind: u64, num_entries: usize) -> Result<CpuId> {
if num_entries > KVM_MAX_CPUID_ENTRIES {
Expand Down
25 changes: 5 additions & 20 deletions src/ioctls/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1800,34 +1800,19 @@ mod tests {
}

#[test]
fn create_vcpu_different_cpuids() {
fn test_create_vcpu_different_ids() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();

// Fails when an arbitrarily large value
let err = vm.create_vcpu(65537 as u64).err();
assert_eq!(err.unwrap().errno(), libc::EINVAL);

// Note: We can request up to KVM_MAX_VCPU_ID if it exists or up to KVM_MAX_VCPUS or
// NR_CPUS or 4. This is determined by the appropriate capability being present.
// We check near boundry conditions `max_vcpus - 1` should succeed but `max_vcpus` as
// determined by the appropriate capability should fail.
//
// Ref: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-create-vcpu
//
let mut max_vcpus = vm.check_extension_int(Cap::MaxVcpuId);
if max_vcpus == 0 {
max_vcpus = vm.check_extension_int(Cap::MaxVcpus);
}
if max_vcpus == 0 {
max_vcpus = vm.check_extension_int(Cap::NrVcpus);
}
if max_vcpus == 0 {
max_vcpus = 4
}
let vcpu = vm.create_vcpu((max_vcpus - 1) as u64);
// Fails when input `id` = `max_vcpu_id`
let max_vcpu_id = kvm.get_max_vcpu_id();
let vcpu = vm.create_vcpu((max_vcpu_id - 1) as u64);
assert!(vcpu.is_ok());
let vcpu_err = vm.create_vcpu(max_vcpus as u64).err();
let vcpu_err = vm.create_vcpu(max_vcpu_id as u64).err();
assert_eq!(vcpu_err.unwrap().errno(), libc::EINVAL);
}

Expand Down

0 comments on commit 69d03d9

Please sign in to comment.