From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xen.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
Jan Beulich <JBeulich@suse.com>
Subject: [PATCH 3/3] x86/levelling: Provide architectural OSXSAVE handling to masked native CPUID
Date: Tue, 23 Aug 2016 18:26:10 +0100 [thread overview]
Message-ID: <1471973170-21158-3-git-send-email-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <1471973170-21158-1-git-send-email-andrew.cooper3@citrix.com>
Contrary to c/s b2507fe7 "x86/domctl: Update PV domain cpumasks when setting
cpuid policy", Intel CPUID masks are applied after fast forwarding hardware
state, rather than before. (All behaviour in this regard appears completely
undocumented by both Intel and AMD).
Therefore, a set bit in the MSR causes hardware to be fast-forwarded, while a
clear bit forces the guests view to 0, even if CR4.OSXSAVE is actually set.
This allows Xen to provide an architectural view of a guest kernels
CR4.OSXSAVE setting to any CPUID instruction issused by guest kernel or
userspace.
The masking value defaults to 1 (if the guest has XSAVE available) to cause
fast-forwarding to occur for the HVM and idle vcpus.
When setting the MSRs, a PV guest kernel's choice of OXSAVE is taken into
account, and clobbered from the MSR if not set. This causes the
fast-forwarding of Xen's CR4 state not to happen.
As a side effect however, levelling may need updating on all PV CR4 changes.
Repored-by: Jan Beulich <JBeulich@suse.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
xen/arch/x86/cpu/amd.c | 19 ++++++++++++++++++-
xen/arch/x86/cpu/intel.c | 24 +++++++++++++++++++++++-
xen/arch/x86/domctl.c | 10 +++++++++-
xen/arch/x86/traps.c | 1 +
4 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index 784fa40..d1ef827 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -211,6 +211,24 @@ static void amd_ctxt_switch_levelling(const struct vcpu *next)
(nextd && is_pv_domain(nextd) && nextd->arch.pv_domain.cpuidmasks)
? nextd->arch.pv_domain.cpuidmasks : &cpuidmask_defaults;
+ if ((levelling_caps & LCAP_1cd) == LCAP_1cd) {
+ uint64_t val = masks->_1cd;
+
+ /*
+ * OSXSAVE defaults to 1, which causes fast-forwarding of
+ * Xen's real setting. Clobber it if disabled by the guest
+ * kernel.
+ */
+ if (next && is_pv_vcpu(next) &&
+ !(next->arch.pv_vcpu.ctrlreg[4] & X86_CR4_OSXSAVE))
+ val &= ~((uint64_t)cpufeat_mask(X86_FEATURE_OSXSAVE) << 32);
+
+ if (unlikely(these_masks->_1cd != val)) {
+ wrmsr_amd(MSR_K8_FEATURE_MASK, val);
+ these_masks->_1cd = val;
+ }
+ }
+
#define LAZY(cap, msr, field) \
({ \
if (unlikely(these_masks->field != masks->field) && \
@@ -221,7 +239,6 @@ static void amd_ctxt_switch_levelling(const struct vcpu *next)
} \
})
- LAZY(LCAP_1cd, MSR_K8_FEATURE_MASK, _1cd);
LAZY(LCAP_e1cd, MSR_K8_EXT_FEATURE_MASK, e1cd);
LAZY(LCAP_7ab0, MSR_AMD_L7S0_FEATURE_MASK, _7ab0);
LAZY(LCAP_6c, MSR_AMD_THRM_FEATURE_MASK, _6c);
diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c
index 3491638..bf4f15d 100644
--- a/xen/arch/x86/cpu/intel.c
+++ b/xen/arch/x86/cpu/intel.c
@@ -182,6 +182,24 @@ static void intel_ctxt_switch_levelling(const struct vcpu *next)
masks = (nextd && is_pv_domain(nextd) && nextd->arch.pv_domain.cpuidmasks)
? nextd->arch.pv_domain.cpuidmasks : &cpuidmask_defaults;
+ if (msr_basic) {
+ uint64_t val = masks->_1cd;
+
+ /*
+ * OSXSAVE defaults to 1, which causes fast-forwarding of
+ * Xen's real setting. Clobber it if disabled by the guest
+ * kernel.
+ */
+ if (next && is_pv_vcpu(next) &&
+ !(next->arch.pv_vcpu.ctrlreg[4] & X86_CR4_OSXSAVE))
+ val &= ~cpufeat_mask(X86_FEATURE_OSXSAVE);
+
+ if (unlikely(these_masks->_1cd != val)) {
+ wrmsrl(msr_basic, val);
+ these_masks->_1cd = val;
+ }
+ }
+
#define LAZY(msr, field) \
({ \
if (unlikely(these_masks->field != masks->field) && \
@@ -192,7 +210,6 @@ static void intel_ctxt_switch_levelling(const struct vcpu *next)
} \
})
- LAZY(msr_basic, _1cd);
LAZY(msr_ext, e1cd);
LAZY(msr_xsave, Da1);
@@ -218,6 +235,11 @@ static void __init noinline intel_init_levelling(void)
ecx &= opt_cpuid_mask_ecx;
edx &= opt_cpuid_mask_edx;
+ /* Fast-forward bits - Must be set. */
+ if (ecx & cpufeat_mask(X86_FEATURE_XSAVE))
+ ecx |= cpufeat_mask(X86_FEATURE_OSXSAVE);
+ edx |= cpufeat_mask(X86_FEATURE_APIC);
+
cpuidmask_defaults._1cd &= ((u64)edx << 32) | ecx;
}
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index bed70aa..a904fd6 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -110,10 +110,18 @@ static void update_domain_cpuid_info(struct domain *d,
case X86_VENDOR_INTEL:
/*
* Intel masking MSRs are documented as AND masks.
- * Experimentally, they are applied before OSXSAVE and APIC
+ * Experimentally, they are applied after OSXSAVE and APIC
* are fast-forwarded from real hardware state.
*/
mask &= ((uint64_t)edx << 32) | ecx;
+
+ if ( ecx & cpufeat_mask(X86_FEATURE_XSAVE) )
+ ecx = cpufeat_mask(X86_FEATURE_OSXSAVE);
+ else
+ ecx = 0;
+ edx = cpufeat_mask(X86_FEATURE_APIC);
+
+ mask |= ((uint64_t)edx << 32) | ecx;
break;
case X86_VENDOR_AMD:
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index c95fadb..b6e56b8 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -2739,6 +2739,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
case 4: /* Write CR4 */
v->arch.pv_vcpu.ctrlreg[4] = pv_guest_cr4_fixup(v, *reg);
write_cr4(pv_guest_cr4_to_real_cr4(v));
+ ctxt_switch_levelling(v);
break;
default:
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2016-08-23 17:26 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-23 17:26 [PATCH 1/3] x86/levelling: Restrict non-architectural OSXSAVE handling to emulated CPUID Andrew Cooper
2016-08-23 17:26 ` [PATCH 2/3] x86/levelling: Pass a vcpu rather than a domain to ctxt_switch_levelling() Andrew Cooper
2016-08-24 8:16 ` Jan Beulich
2016-08-23 17:26 ` Andrew Cooper [this message]
2016-08-24 8:41 ` [PATCH 3/3] x86/levelling: Provide architectural OSXSAVE handling to masked native CPUID Jan Beulich
2016-08-31 18:29 ` Andrew Cooper
2016-09-01 10:25 ` [PATCH v2 " Andrew Cooper
2016-09-01 10:34 ` Jan Beulich
2016-08-24 8:14 ` [PATCH 1/3] x86/levelling: Restrict non-architectural OSXSAVE handling to emulated CPUID Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1471973170-21158-3-git-send-email-andrew.cooper3@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=JBeulich@suse.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).