x86: Reject CPU policies with vendors other than the host's

While in principle it's possible to have a vendor virtualising another,
this is fairly tricky in practice and comes with the world's supply of
security issues.

Reject any CPU policy with vendors not matching the host's.

Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> # CHANGELOG.md
This commit is contained in:
Alejandro Vallejo authored and Jan Beulich committed 2026-04-09 08:22:36 +02:00
1 parent af5495d7c6
commit c520286a53
3 files changed
+37 -1

No files matched your search

+6
View File
@@ -31,6 +31,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Xenoprofile support. Oprofile themselves removed support for Xen in 2014
prior to the version 1.0 release, and there has been no development since
before then in Xen.
- Cross-vendor support; guests can now only be configured as the same
vendor as the host CPU. When added back in 2009, with enough trickery
Intel and AMD CPUs could be made to be compatible enough to live migrate
a guest, but the vendors have been diverging since then in ways that Xen
cannot compensate for, and the advent of speculative security issues has
put to rest any possibility of this being a viable option.
- Removed xenpm tool on non-x86 platforms as it doesn't actually provide
anything useful outside of x86.
+27
View File
@@ -586,6 +586,19 @@ static void test_is_compatible_success(void)
.platform_info.cpuid_faulting = true,
},
},
{
.name = "Host CPU vendor == Guest CPU vendor (both unknown)",
.host = {
.basic.vendor_ebx = X86_VENDOR_AMD_EBX + 1,
.basic.vendor_ecx = X86_VENDOR_AMD_ECX,
.basic.vendor_edx = X86_VENDOR_AMD_EDX,
},
.guest = {
.basic.vendor_ebx = X86_VENDOR_AMD_EBX + 1,
.basic.vendor_ecx = X86_VENDOR_AMD_ECX,
.basic.vendor_edx = X86_VENDOR_AMD_EDX,
},
},
};
struct cpu_policy_errors no_errors = INIT_CPU_POLICY_ERRORS;
@@ -629,6 +642,20 @@ static void test_is_compatible_failure(void)
},
.e = { -1, -1, 0xce },
},
{
.name = "Host CPU vendor != Guest CPU vendor (both unknown)",
.host = {
.basic.vendor_ebx = X86_VENDOR_AMD_EBX + 1,
.basic.vendor_ecx = X86_VENDOR_AMD_ECX,
.basic.vendor_edx = X86_VENDOR_AMD_EDX,
},
.guest = {
.basic.vendor_ebx = X86_VENDOR_AMD_EBX + 2,
.basic.vendor_ecx = X86_VENDOR_AMD_ECX,
.basic.vendor_edx = X86_VENDOR_AMD_EDX,
},
.e = { 0, -1, -1 },
},
};
printf("Testing policy compatibility failure:\n");
+4 -1
View File
@@ -15,7 +15,10 @@ int x86_cpu_policies_are_compatible(const struct cpu_policy *host,
#define FAIL_MSR(m) \
do { e.msr = (m); goto out; } while ( 0 )
if ( guest->basic.max_leaf > host->basic.max_leaf )
if ( (guest->basic.vendor_ebx != host->basic.vendor_ebx) ||
(guest->basic.vendor_ecx != host->basic.vendor_ecx) ||
(guest->basic.vendor_edx != host->basic.vendor_edx) ||
(guest->basic.max_leaf > host->basic.max_leaf) )
FAIL_CPUID(0, NA);
if ( guest->feat.max_subleaf > host->feat.max_subleaf )
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.