From patchwork Wed Mar 23 16:36:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 8652301 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 108B7C0553 for ; Wed, 23 Mar 2016 17:02:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1D8AB2009C for ; Wed, 23 Mar 2016 17:02:38 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4ED37203AB for ; Wed, 23 Mar 2016 17:02:36 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1aim8n-0005jK-I8; Wed, 23 Mar 2016 17:00:17 +0000 Received: from mail6.bemta6.messagelabs.com ([85.158.143.247]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1aim8m-0005gq-RA for xen-devel@lists.xen.org; Wed, 23 Mar 2016 17:00:16 +0000 Received: from [85.158.143.35] by server-2.bemta-6.messagelabs.com id AB/6D-09532-0ABC2F65; Wed, 23 Mar 2016 17:00:16 +0000 X-Env-Sender: prvs=883e14dc5=Andrew.Cooper3@citrix.com X-Msg-Ref: server-9.tower-21.messagelabs.com!1458752414!5526954!1 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 8.11; banners=-,-,- X-VirusChecked: Checked Received: (qmail 13841 invoked from network); 23 Mar 2016 17:00:15 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-9.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 23 Mar 2016 17:00:15 -0000 X-IronPort-AV: E=Sophos;i="5.24,383,1454976000"; d="scan'208";a="348181813" From: Andrew Cooper To: Xen-devel Date: Wed, 23 Mar 2016 16:36:29 +0000 Message-ID: <1458750989-28967-27-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1458750989-28967-1-git-send-email-andrew.cooper3@citrix.com> References: <1458750989-28967-1-git-send-email-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-DLP: MIA2 Cc: Andrew Cooper , Wei Liu , Ian Jackson , Jan Beulich Subject: [Xen-devel] [PATCH v4 26/26] tools/libxc: Calculate xstate cpuid leaf from guest information X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP It is unsafe to generate the guests xstate leaves from host information, as it prevents the differences between hosts from being hidden. In addition, some further improvements and corrections: - don't discard the known flags in sub-leaves 2..63 ECX - zap sub-leaves beyond 62 - zap all bits in leaf 1, EBX/ECX. No XSS features are currently supported. Signed-off-by: Andrew Cooper Signed-off-by: Jan Beulich Acked-by: Wei Liu --- CC: Wei Liu CC: Ian Jackson v3: * Reintroduce MPX adjustment (this series has been in development since before the introduction of MPX upstream, and it got lost in a rebase) v4: * Fold further improvements from Jan --- tools/libxc/xc_cpuid_x86.c | 71 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c index fc7e20a..cf1f6b7 100644 --- a/tools/libxc/xc_cpuid_x86.c +++ b/tools/libxc/xc_cpuid_x86.c @@ -398,54 +398,97 @@ static void intel_xc_cpuid_policy(xc_interface *xch, } } +/* XSTATE bits in XCR0. */ +#define X86_XCR0_X87 (1ULL << 0) +#define X86_XCR0_SSE (1ULL << 1) +#define X86_XCR0_AVX (1ULL << 2) +#define X86_XCR0_BNDREG (1ULL << 3) +#define X86_XCR0_BNDCSR (1ULL << 4) +#define X86_XCR0_LWP (1ULL << 62) + +#define X86_XSS_MASK (0) /* No XSS states supported yet. */ + +/* Per-component subleaf flags. */ +#define XSTATE_XSS (1ULL << 0) +#define XSTATE_ALIGN64 (1ULL << 1) + /* Configure extended state enumeration leaves (0x0000000D for xsave) */ static void xc_cpuid_config_xsave(xc_interface *xch, const struct cpuid_domain_info *info, const unsigned int *input, unsigned int *regs) { - if ( info->xfeature_mask == 0 ) + uint64_t guest_xfeature_mask; + + if ( info->xfeature_mask == 0 || + !test_bit(X86_FEATURE_XSAVE, info->featureset) ) { regs[0] = regs[1] = regs[2] = regs[3] = 0; return; } + guest_xfeature_mask = X86_XCR0_SSE | X86_XCR0_X87; + + if ( test_bit(X86_FEATURE_AVX, info->featureset) ) + guest_xfeature_mask |= X86_XCR0_AVX; + + if ( test_bit(X86_FEATURE_MPX, info->featureset) ) + guest_xfeature_mask |= X86_XCR0_BNDREG | X86_XCR0_BNDCSR; + + if ( test_bit(X86_FEATURE_LWP, info->featureset) ) + guest_xfeature_mask |= X86_XCR0_LWP; + + /* + * Clamp to host mask. Should be no-op, as guest_xfeature_mask should not + * be able to be calculated as larger than info->xfeature_mask. + * + * TODO - see about making this a harder error. + */ + guest_xfeature_mask &= info->xfeature_mask; + switch ( input[1] ) { - case 0: + case 0: /* EAX: low 32bits of xfeature_enabled_mask */ - regs[0] = info->xfeature_mask & 0xFFFFFFFF; + regs[0] = guest_xfeature_mask; /* EDX: high 32bits of xfeature_enabled_mask */ - regs[3] = (info->xfeature_mask >> 32) & 0xFFFFFFFF; + regs[3] = guest_xfeature_mask >> 32; /* ECX: max size required by all HW features */ { unsigned int _input[2] = {0xd, 0x0}, _regs[4]; regs[2] = 0; - for ( _input[1] = 2; _input[1] < 64; _input[1]++ ) + for ( _input[1] = 2; _input[1] <= 62; _input[1]++ ) { cpuid(_input, _regs); if ( (_regs[0] + _regs[1]) > regs[2] ) regs[2] = _regs[0] + _regs[1]; } } - /* EBX: max size required by enabled features. - * This register contains a dynamic value, which varies when a guest - * enables or disables XSTATE features (via xsetbv). The default size - * after reset is 576. */ + /* EBX: max size required by enabled features. + * This register contains a dynamic value, which varies when a guest + * enables or disables XSTATE features (via xsetbv). The default size + * after reset is 576. */ regs[1] = 512 + 64; /* FP/SSE + XSAVE.HEADER */ break; + case 1: /* leaf 1 */ regs[0] = info->featureset[featureword_of(X86_FEATURE_XSAVEOPT)]; - regs[2] &= info->xfeature_mask; - regs[3] = 0; + regs[2] = guest_xfeature_mask & X86_XSS_MASK; + regs[3] = (guest_xfeature_mask >> 32) & X86_XSS_MASK; break; - case 2 ... 63: /* sub-leaves */ - if ( !(info->xfeature_mask & (1ULL << input[1])) ) + + case 2 ... 62: /* per-component sub-leaves */ + if ( !(guest_xfeature_mask & (1ULL << input[1])) ) { regs[0] = regs[1] = regs[2] = regs[3] = 0; break; } /* Don't touch EAX, EBX. Also cleanup ECX and EDX */ - regs[2] = regs[3] = 0; + regs[2] &= XSTATE_XSS | XSTATE_ALIGN64; + regs[3] = 0; + break; + + default: + regs[0] = regs[1] = regs[2] = regs[3] = 0; break; } }