Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP5:GA
xen.35285
xsa435-0-09.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa435-0-09.patch of Package xen.35285
From 817764ea33a44867f8b8a7bbd2fa4475ebe60de7 Mon Sep 17 00:00:00 2001 From: Andrew Cooper <andrew.cooper3@citrix.com> Date: Wed, 19 Jan 2022 19:55:02 +0000 Subject: x86/msr: Fix migration compatibility issue with MSR_SPEC_CTRL This bug existed in early in 2018 between MSR_SPEC_CTRL arriving in microcode, and SSBD arriving a few months later. It went unnoticed presumably because everyone was busy rebooting everything. The same bug will reappear when adding PSFD support. Clamp the guest MSR_SPEC_CTRL value to that permitted by CPUID on migrate. The guest is already playing with reserved bits at this point, and clamping the value will prevent a migration to a less capable host from failing. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> (cherry picked from commit 969a57f73f6b011b2ebf4c0ab1715efc65837335) --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -1341,6 +1341,7 @@ static const uint32_t msrs_to_send[] = { static int hvm_save_cpu_msrs(struct vcpu *v, hvm_domain_context_t *h) { + const struct domain *d = v->domain; struct hvm_save_descriptor *desc = _p(&h->data[h->cur]); struct hvm_msr *ctxt; unsigned int i; @@ -1356,7 +1357,8 @@ static int hvm_save_cpu_msrs(struct vcpu for ( i = 0; i < ARRAY_SIZE(msrs_to_send); ++i ) { uint64_t val; - int rc = guest_rdmsr(v, msrs_to_send[i], &val); + unsigned int msr = msrs_to_send[i]; + int rc = guest_rdmsr(v, msr, &val); /* * It is the programmers responsibility to ensure that @@ -1376,7 +1378,26 @@ static int hvm_save_cpu_msrs(struct vcpu if ( !val ) continue; /* Skip empty MSRs. */ - ctxt->msr[ctxt->count].index = msrs_to_send[i]; + /* + * Guests are given full access to certain MSRs for performance + * reasons. A consequence is that Xen is unable to enforce that all + * bits disallowed by the CPUID policy yield #GP, and an enterprising + * guest may be able to set and use a bit it ought to leave alone. + * + * When migrating from a more capable host to a less capable one, such + * bits may be rejected by the destination, and the migration failed. + * + * Discard such bits here on the source side. Such bits have reserved + * behaviour, and the guest has only itself to blame. + */ + switch ( msr ) + { + case MSR_SPEC_CTRL: + val &= msr_spec_ctrl_valid_bits(d->arch.cpuid); + break; + } + + ctxt->msr[ctxt->count].index = msr; ctxt->msr[ctxt->count++].val = val; } --- a/xen/arch/x86/msr.c +++ b/xen/arch/x86/msr.c @@ -213,7 +213,7 @@ int guest_rdmsr(struct vcpu *v, uint32_t break; case MSR_SPEC_CTRL: - if ( !cp->feat.ibrsb ) + if ( !cp->feat.ibrsb && !cp->extd.ibrs ) goto gp_fault; *val = msrs->spec_ctrl.raw; break; @@ -331,6 +331,24 @@ int guest_rdmsr(struct vcpu *v, uint32_t return X86EMUL_EXCEPTION; } +/* + * Caller to confirm that MSR_SPEC_CTRL is available. Intel and AMD have + * separate CPUID features for this functionality, but only set will be + * active. + */ +uint64_t msr_spec_ctrl_valid_bits(const struct cpuid_policy *cp) +{ + bool ssbd = cp->feat.ssbd || cp->extd.amd_ssbd; + + /* + * Note: SPEC_CTRL_STIBP is specified as safe to use (i.e. ignored) + * when STIBP isn't enumerated in hardware. + */ + return (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | + (ssbd ? SPEC_CTRL_SSBD : 0) | + 0); +} + int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) { const struct vcpu *curr = current; @@ -407,18 +425,9 @@ int guest_wrmsr(struct vcpu *v, uint32_t break; case MSR_SPEC_CTRL: - if ( !cp->feat.ibrsb ) - goto gp_fault; /* MSR available? */ - - /* - * Note: SPEC_CTRL_STIBP is specified as safe to use (i.e. ignored) - * when STIBP isn't enumerated in hardware. - */ - rsvd = ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | - (cp->feat.ssbd ? SPEC_CTRL_SSBD : 0)); - - if ( val & rsvd ) - goto gp_fault; /* Rsvd bit set? */ + if ( (!cp->feat.ibrsb && !cp->extd.ibrs) || + (val & ~msr_spec_ctrl_valid_bits(cp)) ) + goto gp_fault; msrs->spec_ctrl.raw = val; break; --- a/xen/include/asm-x86/msr.h +++ b/xen/include/asm-x86/msr.h @@ -267,6 +267,8 @@ static inline void wrmsr_tsc_aux(uint32_ } } +uint64_t msr_spec_ctrl_valid_bits(const struct cpuid_policy *cp); + extern struct msr_policy raw_msr_policy, host_msr_policy, hvm_max_msr_policy,
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor