Skip to content
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

Merged
merged 1 commit into from
Jun 12, 2019
Merged

Conversation

sboeuf
Copy link

@sboeuf sboeuf commented Jun 10, 2019

By adding the support for the ioctl KVM_ENABLE_CAP, this commit will
allow consumers of the kvm-ioctls crate to enable any KVM capability
they would be missing from their VMM implementation.

One example of capability that can be interesting to enable is the
newly added KVM_CAP_SPLIT_IRQCHIP, that allows the consumer to prevent
KVM from creating a virtual IOAPIC and PIC. This capability can let
a VMM provide its own userspace implementation of those components for
security purposes.

Signed-off-by: Sebastien Boeuf [email protected]

@sboeuf sboeuf requested a review from andreeaflorescu June 10, 2019 17:04
@sboeuf sboeuf force-pushed the enable_cap branch 4 times, most recently from 81dc6b7 to d209557 Compare June 10, 2019 17:35
src/ioctls/vm.rs Outdated Show resolved Hide resolved
src/ioctls/vm.rs Show resolved Hide resolved
src/ioctls/vm.rs Outdated
/// ```rust
/// # extern crate kvm_ioctls;
/// extern crate kvm_bindings;
/// #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a big fan of having x86_64 specific examples when the ioctl is available on other platforms as well. I would suggest to use KVM_CAP_ARM_USER_IRQ on aarch64 and KVM_CAP_SPLIT_IRQCHIP on x86_64. The only code that should be specific to the platform should be cap.cap = ... and cap.args[0] = 24. Also add a comment about what is 24.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you're right, it's actually good to show an example with two different architectures.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well let me take that back... The cap KVM_CAP_ARM_USER_IRQ that you suggested is only meant to be checked through check_extension(), but it cannot be set from the VMM.
And based on the KVM bindings 4.20, there is no arm/aarch64 capability that we could take as an example.
I reworked the structure of the documentation test though, let me know if it's okay with you.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I didn't look in depth. Is there really no other cap that we can enable for aarch64?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm reading KVM doc the wrong way (could be possible :p), I don't think there are some ARM caps that we can simply try to enable.
The only one could be KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but it's not part of our bindings because it's been introduced recently on the kernel.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is only available starting with 5.0 so it will fail anyway since we don't have that capability on the host kernel.

src/ioctls/vm.rs Outdated Show resolved Hide resolved
@sboeuf sboeuf force-pushed the enable_cap branch 7 times, most recently from 22e1d2e to cdac6a8 Compare June 12, 2019 08:48
src/cap.rs Outdated
@@ -23,6 +23,8 @@ use kvm_bindings::*;
#[allow(missing_docs)]
pub enum Cap {
Irqchip = KVM_CAP_IRQCHIP,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
SplitIrqchip = KVM_CAP_SPLIT_IRQCHIP,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The capabilities are sorted by value. Please move this lower (should be between KVM_CAP_S390_USER_SIGP and KVM_CAP_IMMEDIATE_EXIT).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

src/ioctls/vm.rs Outdated
/// cap.args[0] = 24;
/// vm.enable_cap(&cap).unwrap();
/// }
///
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove blank line

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

/// # Example
///
/// ```rust
/// # extern crate kvm_ioctls;
Copy link
Member

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.

Copy link
Author

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.

Copy link
Author

@sboeuf sboeuf Jun 12, 2019

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:


---- src/ioctls/vm.rs - ioctls::vm::VmFd::enable_cap (line 627) stdout ----
error[E0433]: failed to resolve: use of undeclared type or module `Kvm`
--> src/ioctls/vm.rs:632:11
 |
7 | let kvm = Kvm::new().unwrap();
 | ^^^ use of undeclared type or module `Kvm`

///
/// ```
///
pub fn enable_cap(&self, cap: &kvm_enable_cap) -> Result<()> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What architectures is this available on? The documentation only mentions mips, ppc, s390, I found patches for x86, but what about aarch64?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation states that all architectures support this ioctl:

4.37 KVM_ENABLE_CAP

Capability: KVM_CAP_ENABLE_CAP
Architectures: mips, ppc, s390
Type: vcpu ioctl
Parameters: struct kvm_enable_cap (in)
Returns: 0 on success; -1 on error

Capability: KVM_CAP_ENABLE_CAP_VM
Architectures: all
Type: vcpu ioctl
Parameters: struct kvm_enable_cap (in)
Returns: 0 on success; -1 on error

+Not all extensions are enabled by default. Using this ioctl the application
can enable an extension, making it available to the guest.

On systems that do not support this ioctl, it always fails. On systems that
do support it, it only works for extensions that are supported for enablement.

To check if a capability can be enabled, the KVM_CHECK_EXTENSION ioctl should
be used.

struct kvm_enable_cap {
       /* in */
       __u32 cap;

The capability that is supposed to get enabled.

       __u32 flags;

A bitfield indicating future enhancements. Has to be 0 for now.

       __u64 args[4];

Arguments for enabling a feature. If a feature needs initial values to
function properly, this is the place to put them.

       __u8  pad[64];
};

The vcpu ioctl should be used for vcpu-specific capabilities, the vm ioctl
for vm-wide capabilities.

Copy link
Author

Choose a reason for hiding this comment

The 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.
So I suggest that for now I can remove the arm/aarch64 target.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I've updated the PR!

@sboeuf
Copy link
Author

sboeuf commented Jun 12, 2019

@aghecenco comments addressed PTAL

By adding the support for the ioctl KVM_ENABLE_CAP, this commit will
allow consumers of the kvm-ioctls crate to enable any KVM capability
they would be missing from their VMM implementation.

One example of capability that can be interesting to enable is the
newly added KVM_CAP_SPLIT_IRQCHIP, that allows the consumer to prevent
KVM from creating a virtual IOAPIC and PIC. This capability can let
a VMM provide its own userspace implementation of those components for
security purposes.

Unfortunately, we couldn't test enabling a capability for arm/aarch64
since there is no capability available for these architectures.

Signed-off-by: Sebastien Boeuf <[email protected]>
@sboeuf
Copy link
Author

sboeuf commented Jun 12, 2019

@andreeaflorescu @sameo @acatangiu @aghecenco please take a look.
The PR is ready, and @andreeaflorescu approved it, but the approval went away because I had to rebase it on master and repush...

@andreeaflorescu
Copy link
Member

@sboeuf you don't need to do push forces for updating to master. You can use the update branch button. The merge commit is not kept when merging the PR.

@sboeuf
Copy link
Author

sboeuf commented Jun 12, 2019

@andreeaflorescu oh okay good to know!

@sameo sameo merged commit d48fdaa into rust-vmm:master Jun 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants