From patchwork Fri Feb 5 13:42:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 8234821 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7F9BE9FB33 for ; Fri, 5 Feb 2016 14:04:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8222020390 for ; Fri, 5 Feb 2016 14:04:43 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 989E720306 for ; Fri, 5 Feb 2016 14:04:41 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aRgxc-0000D2-Aa; Fri, 05 Feb 2016 14:02:08 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aRgxa-00007m-L6 for xen-devel@lists.xen.org; Fri, 05 Feb 2016 14:02:06 +0000 Received: from [193.109.254.147] by server-1.bemta-14.messagelabs.com id 7A/6E-28791-E5BA4B65; Fri, 05 Feb 2016 14:02:06 +0000 X-Env-Sender: prvs=8364524b4=Andrew.Cooper3@citrix.com X-Msg-Ref: server-6.tower-27.messagelabs.com!1454680920!21830103!5 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 51422 invoked from network); 5 Feb 2016 14:02:05 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-6.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 5 Feb 2016 14:02:05 -0000 X-IronPort-AV: E=Sophos;i="5.22,400,1449532800"; d="scan'208";a="329920311" From: Andrew Cooper To: Xen-devel Date: Fri, 5 Feb 2016 13:42:23 +0000 Message-ID: <1454679743-18133-31-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1454679743-18133-1-git-send-email-andrew.cooper3@citrix.com> References: <1454679743-18133-1-git-send-email-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-DLP: MIA2 Cc: Andrew Cooper , Ian Jackson , Ian Campbell , Wei Liu Subject: [Xen-devel] [PATCH v2 30/30] tools/libxc: Calculate xstate cpuid leaf from guest information X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org 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. Signed-off-by: Andrew Cooper --- CC: Ian Campbell CC: Ian Jackson CC: Wei Liu --- tools/libxc/xc_cpuid_x86.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c index 0e79812..810377c 100644 --- a/tools/libxc/xc_cpuid_x86.c +++ b/tools/libxc/xc_cpuid_x86.c @@ -380,6 +380,11 @@ static void intel_xc_cpuid_policy(xc_interface *xch, } } +#define X86_XCR0_X87 (1ULL << 0) +#define X86_XCR0_SSE (1ULL << 1) +#define X86_XCR0_AVX (1ULL << 2) +#define X86_XCR0_LWP (1ULL << 62) + #define XSAVEOPT (1 << 0) #define XSAVEC (1 << 1) #define XGETBV1 (1 << 2) @@ -389,34 +394,53 @@ 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_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 & 0xFFFFFFFF; /* EDX: high 32bits of xfeature_enabled_mask */ - regs[3] = (info->xfeature_mask >> 32) & 0xFFFFFFFF; + regs[3] = (guest_xfeature_mask >> 32) & 0xFFFFFFFF; /* 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 */ @@ -424,7 +448,7 @@ static void xc_cpuid_config_xsave(xc_interface *xch, regs[1] = regs[2] = regs[3] = 0; break; case 2 ... 63: /* sub-leaves */ - if ( !(info->xfeature_mask & (1ULL << input[1])) ) + if ( !(guest_xfeature_mask & (1ULL << input[1])) ) { regs[0] = regs[1] = regs[2] = regs[3] = 0; break;