forked from cloud-hypervisor/cloud-hypervisor
-
Notifications
You must be signed in to change notification settings - Fork 4
RFC: CPU profiles #8
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
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| - Start Date: 2025-07-18 | ||
|
|
||
| # Summary | ||
|
|
||
| Add a `CpuProfile` parameter to restrict the set of CPU features a VM may utilize. | ||
|
|
||
| # Motiviation | ||
|
|
||
| ## More migration targets | ||
|
|
||
| A running VM can only be migrated to a different host if the target host supports every CPU feature that the | ||
| running VM may utilize. While cloud hypervisor already performs checks to ensure that this is indeed the case | ||
| (in order for the migration to be performed safely), there are few ways to restrict which CPU features a VM may | ||
| utilize at startup. This in turn limits the set of possible migration targets. | ||
|
|
||
| As an example a VM running on a host supporting the [x86-64-v4 microarchitecture level](https://en.wikipedia.org/w/index.php?title=X86-64&oldid=1301541626#Microarchitecture_levels) | ||
| cannot be migrated to one that only supports the x86-64-v3 level, even though the creator of the VM knows | ||
| all their workloads to also be compatible with the latter. | ||
|
|
||
| # Explanation | ||
|
|
||
| Recall the `CpusConfig` structure which is currently part of the `VmConfig` that users set when creating a new VM. | ||
| We propose extending it with an additional field `profile` of type `CpuProfile` which is an enum of the supported | ||
| profiles. It may look something like this and can be extended with more variants in the future: | ||
|
|
||
| ```rust | ||
| #[derive(Default, Serialize, Deserialize)] | ||
| pub enum CpuProfile { | ||
| /// The CPU features of the host are passed through to the virtual CPUs in the VM. | ||
| #[default] | ||
| Host, | ||
| /// The CPU features supported by the first generation of Intel's Skylake server CPUs. | ||
| SkylakeServerV1, | ||
| } | ||
| ``` | ||
| Note that the default is `Host` which corresponds to the current behaviour of passing as many of the | ||
| host's CPU features to guests as possible. | ||
|
|
||
| We propose that the initial implementation only focuses on the x86-64 arch, but may be extended to include | ||
| profiles of other architectures in the future. | ||
|
|
||
| Upon VM creation the `CpuProfile` is extracted (if set, otherwise the default `CpuProfile::Host` will be used) | ||
| and converted to an array of `CpuIdEntry` structs which are used internally to read and manipulate the available | ||
| CPU features/ feature flags. These entries will then in turn be combined with all other pre-existing cpu id entry | ||
| manipulations (such as `tdx` and `amx` configuration for instance) before they ultimately get passed to `KVM_SET_CPUID2` | ||
| thus restricting the CPU features the virtual CPUs may take advantage of. | ||
|
|
||
| The snapshot restoration and migration functionality will have to be adapted to also take the `CpuProfile` into account, | ||
| but note that they at least already do operate on the existing `VmConfig` hence this will not be a direct user facing change. | ||
|
|
||
| We re-emphasize that the addition proposed here does not bring any additional safety guarantees with regards to live migration | ||
| as the compatibility of CPU features is already checked. The main benefit of this addition is that one can increase the set | ||
| of compatible migration targets by restricting the virtual CPUs to only have access to common subsets of CPU features of the | ||
| known hosts. | ||
|
|
||
| ## Interaction with related CPU configurations | ||
|
|
||
| Cpu configuration with their own parameters are not affected by the choice of `CpuProfile`. We acknowledge that | ||
| this may confuse some users, but consider it a necessary evil to 1) Not overcomplicate the `CpuProfile` concept | ||
| with all kinds of complex extension points, and 2) keep this RFC as a backward compatible stritcly additive | ||
| change. | ||
|
|
||
| ### Interaction with `CpuFeatures` | ||
|
|
||
| The pre-existing [`CpuFeatues`](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/main/docs/cpu.md#features) | ||
| will always take precedence over `CpuProfile`. This means that any feature that is disabled by default may | ||
| only be enabled via explicitly placing it in `CpuFeatures` (if possible), regardless of whether said feature is | ||
| supported by the CPU generation or CPU feature set selected in `CpuProfile`. | ||
|
|
||
| ### Interaction with SGX and TDX | ||
|
|
||
| Similarly to the case with [`CpuFeatures`](#interaction-with-cpufeatures) the use of either SGX or TDX is | ||
| independent from whatever is set in the `CpuProfile` and continues to be enabled in exactly the same manner | ||
| as previously. | ||
|
|
||
| # Drawbacks | ||
|
|
||
| - Users are at risk of misunderstanding how this feature interacts with related features | ||
| such as for instance `CpuFeatures`, SGX and TDX support. | ||
| - This feature requires more code, with non-trivial interactions with existing code thus | ||
| making the code base more complex. | ||
|
|
||
| # Rationale and alternatives | ||
|
|
||
| ## Adapting the pre-existing `CpuFeatures` set | ||
|
|
||
| If users were to set the CPU features available for virtual CPUs via the [`CpuFeature set`](https://github.com/cloud-hypervisor/cloud-hypervisor/blob/main/docs/cpu.md#features) | ||
| then this would first of all inevitably be a breaking change. Indeed, recall that this is currently defined | ||
| as CPU features that are disabled by default. Hence if we are to add more possible features to this set then | ||
| they must all be disabled by default which is a breaking change (Recall that `amx` is the only feature that may | ||
| be specified in this set as of now). This approach will force users to write out a lot of features they might | ||
| want/need which is both unergonomic and also arguably error prone. | ||
|
|
||
| ### Redefining `CpuFeatures` | ||
|
|
||
| Alternatively the `CpuFeatures` set can be redefined to have a different default per CPU feature, rather than | ||
| only referring to features that are disabled for guests by default. Features that are enabled by default, but | ||
| not available on the host, are silently ignored unless explicitly set by the user. | ||
|
|
||
| This approach decreases the amount of CPU features one typically needs to manually set, but is still arguably | ||
| less ergonomic than simply declaring a CPU model/generation. An argument in favor of this approach is however | ||
| that one can then specify more precisely exactly which CPU features one wants the guest to have. | ||
|
|
||
| # Prior art | ||
|
|
||
| QEMU has the [CPU models concept](https://qemu-project.gitlab.io/qemu/system/qemu-cpu-models.html) | ||
| and permits more advanced specification in terms of [Libvirt guest XML](https://qemu-project.gitlab.io/qemu/system/qemu-cpu-models.html#libvirt-guest-xml). | ||
| This prior work is the main inspiration for this RFC. | ||
|
|
||
| # Future possibilities | ||
|
|
||
| - Excluding individual features via `CpuFeatures` (See [redefining CPU features](#redefining-cpufeatures)). This can be seen as a change that complements | ||
| `CpuProfiles`, by letting users ergonomically set a CPU profile and then letting them disable individual features that would otherwise be enabled. | ||
| - More CPU profiles by adding more variants to the `CpuProfile` enum. This may also include support for other architectures than x86-64. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
It's unfortunate that there are so many existing flags that interact with related options. Adding the profile to that list does not sound appealing. I would strongly favor if
CpuFeaturescould be changed/redefined just enough to accommodate the use case of making more known platforms compatible for migration. I see listing every single feature bit here is tedious, error-prone, and not future-proof. Maybe you could define a "meta feature" here instead that limits the features according to a "profile"/"generation"?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.
Or maybe you have a concrete set of incompatible feature flags in mind already that block your experiments, for which you could add a "disable" feature toggle instead (e.g.
-avx512) and see how far that gets you?