-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for KVM_ENABLE_CAP ioctl #49
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -610,6 +610,62 @@ impl VmFd { | |
Ok(()) | ||
} | ||
|
||
/// Enable the specified capability as per the `KVM_ENABLE_CAP` ioctl. | ||
/// | ||
/// See the documentation for `KVM_ENABLE_CAP`. | ||
/// | ||
/// Returns an io::Error when the capability could not be enabled. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * kvm_enable_cap - KVM capability structure. For details check the `kvm_enable_cap` | ||
/// structure in the | ||
/// [KVM API doc](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt). | ||
/// | ||
/// # Example | ||
/// | ||
/// ```rust | ||
/// # extern crate kvm_ioctls; | ||
/// extern crate kvm_bindings; | ||
/// | ||
/// # use kvm_ioctls::{Cap, Kvm, VmFd}; | ||
/// use kvm_bindings::{kvm_enable_cap, KVM_CAP_SPLIT_IRQCHIP}; | ||
/// | ||
/// let kvm = Kvm::new().unwrap(); | ||
/// let vm = kvm.create_vm().unwrap(); | ||
/// let mut cap: kvm_enable_cap = Default::default(); | ||
/// // This example cannot enable an arm/aarch64 capability since there | ||
/// // is no capability available for these architectures. | ||
/// if cfg!(target_arch = "x86") || cfg!(target_arch = "x86_64") { | ||
/// cap.cap = KVM_CAP_SPLIT_IRQCHIP; | ||
/// // As per the KVM documentation, KVM_CAP_SPLIT_IRQCHIP only emulates | ||
/// // the local APIC in kernel, expecting that a userspace IOAPIC will | ||
/// // be implemented by the VMM. | ||
/// // Along with this capability, the user needs to specify the number | ||
/// // of pins reserved for the userspace IOAPIC. This number needs to be | ||
/// // provided through the first argument of the capability structure, as | ||
/// // specified in KVM documentation: | ||
/// // args[0] - number of routes reserved for userspace IOAPICs | ||
/// // | ||
/// // Because an IOAPIC supports 24 pins, that's the reason why this test | ||
/// // picked this number as reference. | ||
/// cap.args[0] = 24; | ||
/// vm.enable_cap(&cap).unwrap(); | ||
/// } | ||
/// ``` | ||
/// | ||
#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] | ||
pub fn enable_cap(&self, cap: &kvm_enable_cap) -> Result<()> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What architectures is this available on? The documentation only mentions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The documentation states that all architectures support this ioctl:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh my bad! Talking with @andreeaflorescu I realized this snippet of the doc is not part of 4.14 or 4.20, it's only been introduced later in 5.x. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok I've updated the PR! |
||
// The ioctl is safe because we allocated the struct and we know the | ||
// kernel will write exactly the size of the struct. | ||
let ret = unsafe { ioctl_with_ref(self, KVM_ENABLE_CAP(), cap) }; | ||
if ret == 0 { | ||
Ok(()) | ||
} else { | ||
Err(io::Error::last_os_error()) | ||
} | ||
} | ||
|
||
/// Get the `kvm_run` size. | ||
pub fn run_size(&self) -> usize { | ||
self.run_size | ||
|
@@ -812,4 +868,37 @@ mod tests { | |
let msi = kvm_msi::default(); | ||
assert!(vm.signal_msi(msi).is_err()); | ||
} | ||
|
||
#[test] | ||
#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] | ||
fn test_enable_cap_failure() { | ||
let kvm = Kvm::new().unwrap(); | ||
let vm = kvm.create_vm().unwrap(); | ||
let cap: kvm_enable_cap = Default::default(); | ||
// Providing the `kvm_enable_cap` structure filled with default() should | ||
// always result in a failure as it is not a valid capability. | ||
assert!(vm.enable_cap(&cap).is_err()); | ||
} | ||
|
||
#[test] | ||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] | ||
fn test_enable_split_irqchip_cap() { | ||
sboeuf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let kvm = Kvm::new().unwrap(); | ||
let vm = kvm.create_vm().unwrap(); | ||
let mut cap: kvm_enable_cap = Default::default(); | ||
cap.cap = KVM_CAP_SPLIT_IRQCHIP; | ||
// As per the KVM documentation, KVM_CAP_SPLIT_IRQCHIP only emulates | ||
// the local APIC in kernel, expecting that a userspace IOAPIC will | ||
// be implemented by the VMM. | ||
// Along with this capability, the user needs to specify the number | ||
// of pins reserved for the userspace IOAPIC. This number needs to be | ||
// provided through the first argument of the capability structure, as | ||
// specified in KVM documentation: | ||
// args[0] - number of routes reserved for userspace IOAPICs | ||
// | ||
// Because an IOAPIC supports 24 pins, that's the reason why this test | ||
// picked this number as reference. | ||
cap.args[0] = 24; | ||
assert!(vm.enable_cap(&cap).is_ok()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
91.2 | ||
91.3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove his line (and the next one prefixed by
#
). They don't show up in the generated doc and the doctest passes without them.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed but those lines (prefixed by #) where there in every other doctest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't remove it, the CI complains: