From patchwork Tue Feb 9 17:43:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 8264501 Return-Path: X-Original-To: patchwork-qemu-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 B1BECBEEE5 for ; Tue, 9 Feb 2016 17:49:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D4D22201EF for ; Tue, 9 Feb 2016 17:49:57 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EB365201B4 for ; Tue, 9 Feb 2016 17:49:56 +0000 (UTC) Received: from localhost ([::1]:58883 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTCQG-0007IV-Ak for patchwork-qemu-devel@patchwork.kernel.org; Tue, 09 Feb 2016 12:49:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33688) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTCLI-000792-Eq for qemu-devel@nongnu.org; Tue, 09 Feb 2016 12:44:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aTCLH-0000lZ-83 for qemu-devel@nongnu.org; Tue, 09 Feb 2016 12:44:48 -0500 Received: from mail-pa0-x244.google.com ([2607:f8b0:400e:c03::244]:35814) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTCLG-0000lQ-UH for qemu-devel@nongnu.org; Tue, 09 Feb 2016 12:44:47 -0500 Received: by mail-pa0-x244.google.com with SMTP id fl4so296482pad.2 for ; Tue, 09 Feb 2016 09:44:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=0fnrul1w/v/sT9fJL5mvOAElChIVBK1BdehCMJ+/a/k=; b=cJNG8ilVBU6Yn75qVpg0idnPylyexHu7zstZdtc6ejMF6we5yUIEWiLhA27zRExWQJ pnkoHY0yw0MPtqyq2PENfOtK2Z3UPkznmvhSilVpzPd/+Hd/vd+pDiVAtThWLx3u6Z7s /a27AX0mC38C3BY7w140CwjAeJjvWQUe8/qYYvhJgbFHp7VliFbLLF/5zzB0XLj5kWK9 muHv14WKw5WlbvxMfiJ0LOVETwsTyqqj8bIVixt/Le+oh1TQwXzw3JQpFcUrMG0teFum wNoIkie5Km7EZrAUJizbYoPArvf1yqTCw1M/SyIaeNCEJ8oCe3vHtTFqHpQ3pf6K6FDP esFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=0fnrul1w/v/sT9fJL5mvOAElChIVBK1BdehCMJ+/a/k=; b=WMaHHptQcq662Kmdl60RGEDMIi7yMfVvaJGr12sLyRdu9FOWd0wTFxYjLuwdL32znO VP6Egh5PYbvY5zprqzA2qzNt+Jw/87yNrE/BIRjReCnXtWI9d0hthk28EpJO7cQrcGCm W39k8/dLtrr+iX2qNLZj5lbXA7BovC1mMICqcMmprIJT3SfY5pO0HOU5rzF+a/reprwN L96ZElonq623pGjD68/TXRyqBjSLpHN0A3fRTFKxmpuxGNYBQ2Wm5nbgPMr0JGIZV70c hOXQpaxYIDUReq3RDh6nhSKJGIACzHnYL7RQ66mhhh4TjfrYa55nEvBbFc36qxpmiN0l 2GjA== X-Gm-Message-State: AG10YOTM4+2l5I2yiOaZpKD3J0XNbkUSDh19iFdXdxM2f35N4iT+ZvtEMAvVuf4peV6itg== X-Received: by 10.66.101.36 with SMTP id fd4mr53063903pab.76.1455039886234; Tue, 09 Feb 2016 09:44:46 -0800 (PST) Received: from bigtime.com (alanje.lnk.telstra.net. [120.151.179.201]) by smtp.gmail.com with ESMTPSA id pu3sm52144740pac.9.2016.02.09.09.44.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Feb 2016 09:44:45 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Wed, 10 Feb 2016 04:43:41 +1100 Message-Id: <1455039832-9133-6-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1455039832-9133-1-git-send-email-rth@twiddle.net> References: <1455039832-9133-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c03::244 Cc: pbonzini@redhat.com Subject: [Qemu-devel] [PATCH 05/16] target-i386: Implement XSAVEOPT X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham 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 Signed-off-by: Richard Henderson --- target-i386/cpu.c | 6 ++++-- target-i386/fpu_helper.c | 29 +++++++++++++++++++++++------ target-i386/helper.h | 1 + target-i386/translate.c | 18 +++++++++++++++--- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index fb8a646..dcc6e9c 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -366,7 +366,9 @@ static const char *cpuid_6_feature_name[] = { #define TCG_7_0_ECX_FEATURES 0 #define TCG_APM_FEATURES 0 #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT - +#define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1) + /* missing: + CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */ typedef struct FeatureWordInfo { const char **feat_names; @@ -440,7 +442,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { .cpuid_eax = 0xd, .cpuid_needs_ecx = true, .cpuid_ecx = 1, .cpuid_reg = R_EAX, - .tcg_features = 0, + .tcg_features = TCG_XSAVE_FEATURES, }, [FEAT_6_EAX] = { .feat_names = cpuid_6_feature_name, diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c index 159e1df..9750cd2 100644 --- a/target-i386/fpu_helper.c +++ b/target-i386/fpu_helper.c @@ -1197,9 +1197,9 @@ static uint64_t get_xinuse(CPUX86State *env) return -1; } -void helper_xsave(CPUX86State *env, target_ulong ptr, uint64_t rfbm) +static void do_xsave(CPUX86State *env, target_ulong ptr, uint64_t rfbm, + uint64_t inuse, uint64_t opt, uintptr_t ra) { - uintptr_t ra = GETPC(); uint64_t old_bv, new_bv; /* The OS must have enabled XSAVE. */ @@ -1214,21 +1214,36 @@ void helper_xsave(CPUX86State *env, target_ulong ptr, uint64_t rfbm) /* Never save anything not enabled by XCR0. */ rfbm &= env->xcr0; + opt &= rfbm; - if (rfbm & XSTATE_FP) { + if (opt & XSTATE_FP) { do_xsave_fpu(env, ptr, ra); } if (rfbm & XSTATE_SSE) { + /* Note that saving MXCSR is not suppressed by XSAVEOPT. */ do_xsave_mxcsr(env, ptr, ra); + } + if (opt & XSTATE_SSE) { do_xsave_sse(env, ptr, ra); } /* Update the XSTATE_BV field. */ old_bv = cpu_ldq_data_ra(env, ptr + 512, ra); - new_bv = (old_bv & ~rfbm) | (get_xinuse(env) & rfbm); + new_bv = (old_bv & ~rfbm) | (inuse & rfbm); cpu_stq_data_ra(env, ptr + 512, new_bv, ra); } +void helper_xsave(CPUX86State *env, target_ulong ptr, uint64_t rfbm) +{ + do_xsave(env, ptr, rfbm, get_xinuse(env), -1, GETPC()); +} + +void helper_xsaveopt(CPUX86State *env, target_ulong ptr, uint64_t rfbm) +{ + uint64_t inuse = get_xinuse(env); + do_xsave(env, ptr, rfbm, inuse, inuse, GETPC()); +} + static void do_xrstor_fpu(CPUX86State *env, target_ulong ptr, uintptr_t ra) { int i, fpus, fptag; @@ -1369,8 +1384,10 @@ uint64_t helper_xgetbv(CPUX86State *env, uint32_t ecx) case 0: return env->xcr0; case 1: - /* FIXME: #GP if !CPUID.(EAX=0DH,ECX=1):EAX.XG1[bit 2]. */ - return env->xcr0 & get_xinuse(env); + if (env->features[FEAT_XSAVE] & CPUID_XSAVE_XGETBV1) { + return env->xcr0 & get_xinuse(env); + } + break; } raise_exception_ra(env, EXCP0D_GPF, GETPC()); } diff --git a/target-i386/helper.h b/target-i386/helper.h index 9dfc735..9a83955 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -188,6 +188,7 @@ DEF_HELPER_3(frstor, void, env, tl, int) DEF_HELPER_FLAGS_2(fxsave, TCG_CALL_NO_WG, void, env, tl) DEF_HELPER_FLAGS_2(fxrstor, TCG_CALL_NO_WG, void, env, tl) DEF_HELPER_FLAGS_3(xsave, TCG_CALL_NO_WG, void, env, tl, i64) +DEF_HELPER_FLAGS_3(xsaveopt, TCG_CALL_NO_WG, void, env, tl, i64) DEF_HELPER_FLAGS_3(xrstor, TCG_CALL_NO_WG, void, env, tl, i64) DEF_HELPER_FLAGS_2(xgetbv, TCG_CALL_NO_WG, i64, env, i32) DEF_HELPER_FLAGS_3(xsetbv, TCG_CALL_NO_WG, void, env, i32, i64) diff --git a/target-i386/translate.c b/target-i386/translate.c index f5233aa..47aca64 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -127,6 +127,7 @@ typedef struct DisasContext { int cpuid_ext2_features; int cpuid_ext3_features; int cpuid_7_0_ebx_features; + int cpuid_xsave_features; } DisasContext; static void gen_eob(DisasContext *s); @@ -7630,7 +7631,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_helper_xrstor(cpu_env, cpu_A0, cpu_tmp1_i64); break; - CASE_MEM_OP(6): /* clwb */ + CASE_MEM_OP(6): /* xsaveopt / clwb */ if (prefixes & PREFIX_LOCK) { goto illegal_op; } @@ -7640,9 +7641,19 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, goto illegal_op; } gen_nop_modrm(env, s, modrm); - break; + } else { + /* xsaveopt */ + if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0 + || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0 + || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) { + goto illegal_op; + } + gen_lea_modrm(env, s, modrm); + tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX], + cpu_regs[R_EDX]); + gen_helper_xsaveopt(cpu_env, cpu_A0, cpu_tmp1_i64); } - goto illegal_op; + break; CASE_MEM_OP(7): /* clflush / clflushopt */ if (prefixes & PREFIX_LOCK) { @@ -7864,6 +7875,7 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb) dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX]; dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX]; dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; + dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; #ifdef TARGET_X86_64 dc->lma = (flags >> HF_LMA_SHIFT) & 1; dc->code64 = (flags >> HF_CS64_SHIFT) & 1;