Skip to content

Commit 4f61bba

Browse files
gabhijitalexandruag
authored andcommitted
vm: create_vcpu takes u64 argument #123
Changed the passed parameter type from `u8` to `u64`, which the underlying `ioctl` uses. Added a missing cap `MaxVcpuId` (It is defined in kvm-bindings for both arm* and x86* but was missing inside cap.rs. This was required by a test case.) Added a test case to assert failure if we pass parameter higher than the `max_vcpu_id`. Signed-off-by: Abhijit Gadgil <[email protected]>
1 parent 6aa32c7 commit 4f61bba

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

src/cap.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ pub enum Cap {
9797
PpcSmt = KVM_CAP_PPC_SMT,
9898
PpcRma = KVM_CAP_PPC_RMA,
9999
MaxVcpus = KVM_CAP_MAX_VCPUS,
100+
MaxVcpuId = KVM_CAP_MAX_VCPU_ID,
100101
PpcHior = KVM_CAP_PPC_HIOR,
101102
PpcPapr = KVM_CAP_PPC_PAPR,
102103
SwTlb = KVM_CAP_SW_TLB,

src/ioctls/vcpu.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,7 +1411,7 @@ mod tests {
14111411
assert!(ncpuids <= KVM_MAX_CPUID_ENTRIES);
14121412
let nr_vcpus = kvm.get_nr_vcpus();
14131413
for cpu_idx in 0..nr_vcpus {
1414-
let vcpu = vm.create_vcpu(cpu_idx as u8).unwrap();
1414+
let vcpu = vm.create_vcpu(cpu_idx as u64).unwrap();
14151415
vcpu.set_cpuid2(&cpuid).unwrap();
14161416
let retrieved_cpuid = vcpu.get_cpuid2(ncpuids).unwrap();
14171417
// Only check the first few leafs as some (e.g. 13) are reserved.
@@ -1443,7 +1443,7 @@ mod tests {
14431443
assert!(ncpuids <= KVM_MAX_CPUID_ENTRIES);
14441444
let nr_vcpus = kvm.get_nr_vcpus();
14451445
for cpu_idx in 0..nr_vcpus {
1446-
let vcpu = vm.create_vcpu(cpu_idx as u8).unwrap();
1446+
let vcpu = vm.create_vcpu(cpu_idx as u64).unwrap();
14471447
vcpu.set_cpuid2(&cpuid).unwrap();
14481448
let err = vcpu.get_cpuid2(ncpuids - 1 as usize).err();
14491449
assert_eq!(err.unwrap().errno(), libc::E2BIG);

src/ioctls/vm.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,7 @@ impl VmFd {
10211021
/// let vcpu = vm.create_vcpu(0);
10221022
/// ```
10231023
///
1024-
pub fn create_vcpu(&self, id: u8) -> Result<VcpuFd> {
1024+
pub fn create_vcpu(&self, id: u64) -> Result<VcpuFd> {
10251025
// Safe because we know that vm is a VM fd and we verify the return result.
10261026
#[allow(clippy::cast_lossless)]
10271027
let vcpu_fd = unsafe { ioctl_with_val(&self.vm, KVM_CREATE_VCPU(), id as c_ulong) };
@@ -1799,6 +1799,38 @@ mod tests {
17991799
assert!(vm.set_gsi_routing(&irq_routing).is_ok());
18001800
}
18011801

1802+
#[test]
1803+
fn create_vcpu_different_cpuids() {
1804+
let kvm = Kvm::new().unwrap();
1805+
let vm = kvm.create_vm().unwrap();
1806+
1807+
// Fails when an arbitrarily large value
1808+
let err = vm.create_vcpu(65537 as u64).err();
1809+
assert_eq!(err.unwrap().errno(), libc::EINVAL);
1810+
1811+
// Note: We can request up to KVM_MAX_VCPU_ID if it exists or up to KVM_MAX_VCPUS or
1812+
// NR_CPUS or 4. This is determined by the appropriate capability being present.
1813+
// We check near boundry conditions `max_vcpus - 1` should succeed but `max_vcpus` as
1814+
// determined by the appropriate capability should fail.
1815+
//
1816+
// Ref: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-create-vcpu
1817+
//
1818+
let mut max_vcpus = vm.check_extension_int(Cap::MaxVcpuId);
1819+
if max_vcpus == 0 {
1820+
max_vcpus = vm.check_extension_int(Cap::MaxVcpus);
1821+
}
1822+
if max_vcpus == 0 {
1823+
max_vcpus = vm.check_extension_int(Cap::NrVcpus);
1824+
}
1825+
if max_vcpus == 0 {
1826+
max_vcpus = 4
1827+
}
1828+
let vcpu = vm.create_vcpu((max_vcpus - 1) as u64);
1829+
assert!(vcpu.is_ok());
1830+
let vcpu_err = vm.create_vcpu(max_vcpus as u64).err();
1831+
assert_eq!(vcpu_err.unwrap().errno(), libc::EINVAL);
1832+
}
1833+
18021834
#[test]
18031835
fn test_check_extension() {
18041836
let kvm = Kvm::new().unwrap();

0 commit comments

Comments
 (0)