Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp2838460pxb; Tue, 13 Apr 2021 11:21:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzL78nzLnp6qB7GJVduuguL5gxVjwL0QmlxkwJE+P7PjaOxhoeIuxsikkVAVfGX+rX5Eqiw X-Received: by 2002:a63:c60a:: with SMTP id w10mr32761022pgg.421.1618338085241; Tue, 13 Apr 2021 11:21:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618338085; cv=none; d=google.com; s=arc-20160816; b=bLZvnoiWjuHmWhuYdAPkdcdJ2janIBuZscxw0MBUuDVxK9CU0TpG4Fmd5YIBfRtvQa JRLRtM1OKJjFXl+ndbEErRXxpqSRYxk4+yxJzmu2NSh29IWqfmbIaG4YqMUPaBn2Z38k sn2fPlCwH0Jbaoix/GMOHfBUZY5atutZav92I6mbWR9XYr6y7qbdFqeO0ACfBcDKHNml 3zWJNm+Yz3+phiBSj/35wvDdPFI1a8PXPROgzx5pFcpmqUjcpfHysU0Lb27hMeidt9Wn NR3hdAUKuUzJjM+iPCZ5GwCgar4aufpaZz1kF5g+nD8KUGgFnJWxjE/lxuL/rUN+5FMh 7l0A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:references :in-reply-to:subject:cc:to:from:dkim-signature; bh=mREcwwWGmj3B0DJ2fOYeWh4cZJDHnQx9n5SuD7IiKiA=; b=K7Z8Ee0SXj/rL8EKRNs2K/SrXadAKfJ0EerKZ/Lmj5ENkLLMrlCWfxX7DqX1bIPX8N 6gT8sDITMOYEDW7GBRhLbXCyeBpFTez2B1fU8j3P/5gis08ML7zboNjiAApM6w2LaWXZ eBfJowoDAv1Ltv1grBq94C+U3FyZiZvz7jUdKw+yD2zL/7mON9ygVTH6LX2R+fVWG20x CIEQ7ZGUHLYR3PQUIXlfpY7i0Z/MlEoafG8jRzhwEesy3vSC2H8ZOk0VAoeGtzxoG8yV maHQAGdD+XMgdemFTt1BEav4tZ24JNlKvshLBdwHKqPBPM11z+emdcI66xGTg0LGsCuA QIKQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=b0EhbzCt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u6si18223057pga.266.2021.04.13.11.21.11; Tue, 13 Apr 2021 11:21:25 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=b0EhbzCt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346031AbhDMNlb (ORCPT + 99 others); Tue, 13 Apr 2021 09:41:31 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:23330 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346038AbhDMNlX (ORCPT ); Tue, 13 Apr 2021 09:41:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1618321261; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=mREcwwWGmj3B0DJ2fOYeWh4cZJDHnQx9n5SuD7IiKiA=; b=b0EhbzCtsIIP/WHVGrutjC/phB9HJ4193I7QPPbsqOTitLhrozsitFQeBj8Qabh5p8593R XIxwe8uFgZ61uQ62W4Ih2sAx+rKcW16rjOfx9pTHVt1/1ncZWfW/eSJKfTMF/5tzOQe/xX AKlX+40lDtXeMfv0SJ2Z5HiMzRtx7W8= Received: from mail-ej1-f70.google.com (mail-ej1-f70.google.com [209.85.218.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-594-pbqsN8xpP66altX8RXZEGA-1; Tue, 13 Apr 2021 09:40:59 -0400 X-MC-Unique: pbqsN8xpP66altX8RXZEGA-1 Received: by mail-ej1-f70.google.com with SMTP id di5so5064904ejc.1 for ; Tue, 13 Apr 2021 06:40:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references:date :message-id:mime-version; bh=mREcwwWGmj3B0DJ2fOYeWh4cZJDHnQx9n5SuD7IiKiA=; b=mE68H6Wj56kQl1arQvIAWxm5dZYk1jRmfDBUhpkFTpQrrMwm2WxItLQBSuXfhUAf3U luUkNuCoBom9uxJna4y7TgLpHtvqNEbWloYN+JtdI9dACHriF3lchYETT3ck46AxkDkA Wo3hPimR6iCQeskqUnHX3a2civ21YCYuqwKm5l4a3Ju7FK+Yszsc6WuwjplUBpBKHDd9 RP4PQe6y0pA+qMUAW7COHunMJDz+GrtN9tljhCnMPqoN/pz0PATfcATFnnw0yTPjn6Bj Ty69tilFbdhM+6RQtFvsBizBpfW2kpCcQnAva5S0cESCrwTxdqLn7r9wic1KpKk+For8 Ut7Q== X-Gm-Message-State: AOAM530pLoCqznPRjfpIazqYH+r9m0h2b6HWsOyudOV52jTJqRzXDW2D hSXf/aMaBdEifC5VQz4NbsYqCj00ziICX9/cDZlldUwSbmdLsLBVvQ7kYl51HjKFgoyos7HptdX 0scxZaoNVuh8g4PS5Iuv55cvG X-Received: by 2002:aa7:d3c8:: with SMTP id o8mr35394136edr.289.1618321258398; Tue, 13 Apr 2021 06:40:58 -0700 (PDT) X-Received: by 2002:aa7:d3c8:: with SMTP id o8mr35394101edr.289.1618321258114; Tue, 13 Apr 2021 06:40:58 -0700 (PDT) Received: from vitty.brq.redhat.com (g-server-2.ign.cz. [91.219.240.2]) by smtp.gmail.com with ESMTPSA id b18sm3115900eju.22.2021.04.13.06.40.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 06:40:57 -0700 (PDT) From: Vitaly Kuznetsov To: Siddharth Chandrasekaran Cc: Alexander Graf , Evgeny Iakovlev , Liran Alon , Ioannis Aslanidis , linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, "K. Y. Srinivasan" , Haiyang Zhang , Stephen Hemminger , Wei Liu , Thomas Gleixner , Ingo Molnar , Borislav Petkov , x86@kernel.org, "H. Peter Anvin" , Paolo Bonzini , Sean Christopherson , Wanpeng Li , Jim Mattson , Joerg Roedel Subject: Re: [PATCH v2 1/4] KVM: x86: Move FPU register accessors into fpu.h In-Reply-To: <5d2945df9dd807dca45ab256c88aeb4430ecf508.1618244920.git.sidcha@amazon.de> References: <5d2945df9dd807dca45ab256c88aeb4430ecf508.1618244920.git.sidcha@amazon.de> Date: Tue, 13 Apr 2021 15:40:56 +0200 Message-ID: <87y2dm5ml3.fsf@vitty.brq.redhat.com> MIME-Version: 1.0 Content-Type: text/plain Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Siddharth Chandrasekaran writes: > Hyper-v XMM fast hypercalls use XMM registers to pass input/output > parameters. To access these, hyperv.c can reuse some FPU register > accessors defined in emulator.c. Move them to a common location so both > can access them. > > While at it, reorder the parameters of these accessor methods to make > them more readable. > > Cc: Alexander Graf > Cc: Evgeny Iakovlev > Signed-off-by: Siddharth Chandrasekaran > --- > arch/x86/kvm/emulate.c | 138 ++++++---------------------------------- > arch/x86/kvm/fpu.h | 140 +++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 158 insertions(+), 120 deletions(-) > create mode 100644 arch/x86/kvm/fpu.h > > diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c > index f7970ba6219f..296f8f3ce988 100644 > --- a/arch/x86/kvm/emulate.c > +++ b/arch/x86/kvm/emulate.c > @@ -22,7 +22,6 @@ > #include "kvm_cache_regs.h" > #include "kvm_emulate.h" > #include > -#include > #include > #include > > @@ -30,6 +29,7 @@ > #include "tss.h" > #include "mmu.h" > #include "pmu.h" > +#include "fpu.h" > > /* > * Operand types > @@ -1081,116 +1081,14 @@ static void fetch_register_operand(struct operand *op) > } > } > > -static void emulator_get_fpu(void) > -{ > - fpregs_lock(); > - > - fpregs_assert_state_consistent(); > - if (test_thread_flag(TIF_NEED_FPU_LOAD)) > - switch_fpu_return(); > -} > - > -static void emulator_put_fpu(void) > -{ > - fpregs_unlock(); > -} > - > -static void read_sse_reg(sse128_t *data, int reg) > -{ > - emulator_get_fpu(); > - switch (reg) { > - case 0: asm("movdqa %%xmm0, %0" : "=m"(*data)); break; > - case 1: asm("movdqa %%xmm1, %0" : "=m"(*data)); break; > - case 2: asm("movdqa %%xmm2, %0" : "=m"(*data)); break; > - case 3: asm("movdqa %%xmm3, %0" : "=m"(*data)); break; > - case 4: asm("movdqa %%xmm4, %0" : "=m"(*data)); break; > - case 5: asm("movdqa %%xmm5, %0" : "=m"(*data)); break; > - case 6: asm("movdqa %%xmm6, %0" : "=m"(*data)); break; > - case 7: asm("movdqa %%xmm7, %0" : "=m"(*data)); break; > -#ifdef CONFIG_X86_64 > - case 8: asm("movdqa %%xmm8, %0" : "=m"(*data)); break; > - case 9: asm("movdqa %%xmm9, %0" : "=m"(*data)); break; > - case 10: asm("movdqa %%xmm10, %0" : "=m"(*data)); break; > - case 11: asm("movdqa %%xmm11, %0" : "=m"(*data)); break; > - case 12: asm("movdqa %%xmm12, %0" : "=m"(*data)); break; > - case 13: asm("movdqa %%xmm13, %0" : "=m"(*data)); break; > - case 14: asm("movdqa %%xmm14, %0" : "=m"(*data)); break; > - case 15: asm("movdqa %%xmm15, %0" : "=m"(*data)); break; > -#endif > - default: BUG(); > - } > - emulator_put_fpu(); > -} > - > -static void write_sse_reg(sse128_t *data, int reg) > -{ > - emulator_get_fpu(); > - switch (reg) { > - case 0: asm("movdqa %0, %%xmm0" : : "m"(*data)); break; > - case 1: asm("movdqa %0, %%xmm1" : : "m"(*data)); break; > - case 2: asm("movdqa %0, %%xmm2" : : "m"(*data)); break; > - case 3: asm("movdqa %0, %%xmm3" : : "m"(*data)); break; > - case 4: asm("movdqa %0, %%xmm4" : : "m"(*data)); break; > - case 5: asm("movdqa %0, %%xmm5" : : "m"(*data)); break; > - case 6: asm("movdqa %0, %%xmm6" : : "m"(*data)); break; > - case 7: asm("movdqa %0, %%xmm7" : : "m"(*data)); break; > -#ifdef CONFIG_X86_64 > - case 8: asm("movdqa %0, %%xmm8" : : "m"(*data)); break; > - case 9: asm("movdqa %0, %%xmm9" : : "m"(*data)); break; > - case 10: asm("movdqa %0, %%xmm10" : : "m"(*data)); break; > - case 11: asm("movdqa %0, %%xmm11" : : "m"(*data)); break; > - case 12: asm("movdqa %0, %%xmm12" : : "m"(*data)); break; > - case 13: asm("movdqa %0, %%xmm13" : : "m"(*data)); break; > - case 14: asm("movdqa %0, %%xmm14" : : "m"(*data)); break; > - case 15: asm("movdqa %0, %%xmm15" : : "m"(*data)); break; > -#endif > - default: BUG(); > - } > - emulator_put_fpu(); > -} > - > -static void read_mmx_reg(u64 *data, int reg) > -{ > - emulator_get_fpu(); > - switch (reg) { > - case 0: asm("movq %%mm0, %0" : "=m"(*data)); break; > - case 1: asm("movq %%mm1, %0" : "=m"(*data)); break; > - case 2: asm("movq %%mm2, %0" : "=m"(*data)); break; > - case 3: asm("movq %%mm3, %0" : "=m"(*data)); break; > - case 4: asm("movq %%mm4, %0" : "=m"(*data)); break; > - case 5: asm("movq %%mm5, %0" : "=m"(*data)); break; > - case 6: asm("movq %%mm6, %0" : "=m"(*data)); break; > - case 7: asm("movq %%mm7, %0" : "=m"(*data)); break; > - default: BUG(); > - } > - emulator_put_fpu(); > -} > - > -static void write_mmx_reg(u64 *data, int reg) > -{ > - emulator_get_fpu(); > - switch (reg) { > - case 0: asm("movq %0, %%mm0" : : "m"(*data)); break; > - case 1: asm("movq %0, %%mm1" : : "m"(*data)); break; > - case 2: asm("movq %0, %%mm2" : : "m"(*data)); break; > - case 3: asm("movq %0, %%mm3" : : "m"(*data)); break; > - case 4: asm("movq %0, %%mm4" : : "m"(*data)); break; > - case 5: asm("movq %0, %%mm5" : : "m"(*data)); break; > - case 6: asm("movq %0, %%mm6" : : "m"(*data)); break; > - case 7: asm("movq %0, %%mm7" : : "m"(*data)); break; > - default: BUG(); > - } > - emulator_put_fpu(); > -} > - > static int em_fninit(struct x86_emulate_ctxt *ctxt) > { > if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) > return emulate_nm(ctxt); > > - emulator_get_fpu(); > + kvm_fpu_get(); > asm volatile("fninit"); > - emulator_put_fpu(); > + kvm_fpu_put(); > return X86EMUL_CONTINUE; > } > > @@ -1201,9 +1099,9 @@ static int em_fnstcw(struct x86_emulate_ctxt *ctxt) > if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) > return emulate_nm(ctxt); > > - emulator_get_fpu(); > + kvm_fpu_get(); > asm volatile("fnstcw %0": "+m"(fcw)); > - emulator_put_fpu(); > + kvm_fpu_put(); > > ctxt->dst.val = fcw; > > @@ -1217,9 +1115,9 @@ static int em_fnstsw(struct x86_emulate_ctxt *ctxt) > if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) > return emulate_nm(ctxt); > > - emulator_get_fpu(); > + kvm_fpu_get(); > asm volatile("fnstsw %0": "+m"(fsw)); > - emulator_put_fpu(); > + kvm_fpu_put(); > > ctxt->dst.val = fsw; > > @@ -1238,7 +1136,7 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt, > op->type = OP_XMM; > op->bytes = 16; > op->addr.xmm = reg; > - read_sse_reg(&op->vec_val, reg); > + kvm_read_sse_reg(reg, &op->vec_val); > return; > } > if (ctxt->d & Mmx) { > @@ -1289,7 +1187,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, > op->type = OP_XMM; > op->bytes = 16; > op->addr.xmm = ctxt->modrm_rm; > - read_sse_reg(&op->vec_val, ctxt->modrm_rm); > + kvm_read_sse_reg(ctxt->modrm_rm, &op->vec_val); > return rc; > } > if (ctxt->d & Mmx) { > @@ -1866,10 +1764,10 @@ static int writeback(struct x86_emulate_ctxt *ctxt, struct operand *op) > op->bytes * op->count); > break; > case OP_XMM: > - write_sse_reg(&op->vec_val, op->addr.xmm); > + kvm_write_sse_reg(op->addr.xmm, &op->vec_val); > break; > case OP_MM: > - write_mmx_reg(&op->mm_val, op->addr.mm); > + kvm_write_mmx_reg(op->addr.mm, &op->mm_val); > break; > case OP_NONE: > /* no writeback */ > @@ -4124,11 +4022,11 @@ static int em_fxsave(struct x86_emulate_ctxt *ctxt) > if (rc != X86EMUL_CONTINUE) > return rc; > > - emulator_get_fpu(); > + kvm_fpu_get(); > > rc = asm_safe("fxsave %[fx]", , [fx] "+m"(fx_state)); > > - emulator_put_fpu(); > + kvm_fpu_put(); > > if (rc != X86EMUL_CONTINUE) > return rc; > @@ -4172,7 +4070,7 @@ static int em_fxrstor(struct x86_emulate_ctxt *ctxt) > if (rc != X86EMUL_CONTINUE) > return rc; > > - emulator_get_fpu(); > + kvm_fpu_get(); > > if (size < __fxstate_size(16)) { > rc = fxregs_fixup(&fx_state, size); > @@ -4189,7 +4087,7 @@ static int em_fxrstor(struct x86_emulate_ctxt *ctxt) > rc = asm_safe("fxrstor %[fx]", : [fx] "m"(fx_state)); > > out: > - emulator_put_fpu(); > + kvm_fpu_put(); > > return rc; > } > @@ -5510,9 +5408,9 @@ static int flush_pending_x87_faults(struct x86_emulate_ctxt *ctxt) > { > int rc; > > - emulator_get_fpu(); > + kvm_fpu_get(); > rc = asm_safe("fwait"); > - emulator_put_fpu(); > + kvm_fpu_put(); > > if (unlikely(rc != X86EMUL_CONTINUE)) > return emulate_exception(ctxt, MF_VECTOR, 0, false); > @@ -5523,7 +5421,7 @@ static int flush_pending_x87_faults(struct x86_emulate_ctxt *ctxt) > static void fetch_possible_mmx_operand(struct operand *op) > { > if (op->type == OP_MM) > - read_mmx_reg(&op->mm_val, op->addr.mm); > + kvm_read_mmx_reg(op->addr.mm, &op->mm_val); > } > > static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop) > diff --git a/arch/x86/kvm/fpu.h b/arch/x86/kvm/fpu.h > new file mode 100644 > index 000000000000..3ba12888bf66 > --- /dev/null > +++ b/arch/x86/kvm/fpu.h > @@ -0,0 +1,140 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > + > +#ifndef __KVM_FPU_H_ > +#define __KVM_FPU_H_ > + > +#include > + > +typedef u32 __attribute__((vector_size(16))) sse128_t; Post-patch we seem to have two definitions of 'sse128_t': $ git grep sse128_t HEAD~3:arch/x86/kvm/fpu.h:typedef u32 __attribute__((vector_size(16))) sse128_t; HEAD~3:arch/x86/kvm/fpu.h:#define __sse128_u union { sse128_t vec; u64 as_u64[2]; u32 as_u32[4]; } HEAD~3:arch/x86/kvm/fpu.h:static inline void _kvm_read_sse_reg(int reg, sse128_t *data) HEAD~3:arch/x86/kvm/fpu.h:static inline void _kvm_write_sse_reg(int reg, const sse128_t *data) HEAD~3:arch/x86/kvm/fpu.h:static inline void kvm_read_sse_reg(int reg, sse128_t *data) HEAD~3:arch/x86/kvm/fpu.h:static inline void kvm_write_sse_reg(int reg, const sse128_t *data) HEAD~3:arch/x86/kvm/kvm_emulate.h:typedef u32 __attribute__((vector_size(16))) sse128_t; HEAD~3:arch/x86/kvm/kvm_emulate.h: char valptr[sizeof(sse128_t)]; HEAD~3:arch/x86/kvm/kvm_emulate.h: sse128_t vec_val; Should the one from kvm_emulate.h go away? > +#define __sse128_u union { sse128_t vec; u64 as_u64[2]; u32 as_u32[4]; } > +#define sse128_lo(x) ({ __sse128_u t; t.vec = x; t.as_u64[0]; }) > +#define sse128_hi(x) ({ __sse128_u t; t.vec = x; t.as_u64[1]; }) > +#define sse128_l0(x) ({ __sse128_u t; t.vec = x; t.as_u32[0]; }) > +#define sse128_l1(x) ({ __sse128_u t; t.vec = x; t.as_u32[1]; }) > +#define sse128_l2(x) ({ __sse128_u t; t.vec = x; t.as_u32[2]; }) > +#define sse128_l3(x) ({ __sse128_u t; t.vec = x; t.as_u32[3]; }) > +#define sse128(lo, hi) ({ __sse128_u t; t.as_u64[0] = lo; t.as_u64[1] = hi; t.vec; }) > + > +static inline void _kvm_read_sse_reg(int reg, sse128_t *data) > +{ > + switch (reg) { > + case 0: asm("movdqa %%xmm0, %0" : "=m"(*data)); break; > + case 1: asm("movdqa %%xmm1, %0" : "=m"(*data)); break; > + case 2: asm("movdqa %%xmm2, %0" : "=m"(*data)); break; > + case 3: asm("movdqa %%xmm3, %0" : "=m"(*data)); break; > + case 4: asm("movdqa %%xmm4, %0" : "=m"(*data)); break; > + case 5: asm("movdqa %%xmm5, %0" : "=m"(*data)); break; > + case 6: asm("movdqa %%xmm6, %0" : "=m"(*data)); break; > + case 7: asm("movdqa %%xmm7, %0" : "=m"(*data)); break; > +#ifdef CONFIG_X86_64 > + case 8: asm("movdqa %%xmm8, %0" : "=m"(*data)); break; > + case 9: asm("movdqa %%xmm9, %0" : "=m"(*data)); break; > + case 10: asm("movdqa %%xmm10, %0" : "=m"(*data)); break; > + case 11: asm("movdqa %%xmm11, %0" : "=m"(*data)); break; > + case 12: asm("movdqa %%xmm12, %0" : "=m"(*data)); break; > + case 13: asm("movdqa %%xmm13, %0" : "=m"(*data)); break; > + case 14: asm("movdqa %%xmm14, %0" : "=m"(*data)); break; > + case 15: asm("movdqa %%xmm15, %0" : "=m"(*data)); break; > +#endif > + default: BUG(); > + } > +} > + > +static inline void _kvm_write_sse_reg(int reg, const sse128_t *data) > +{ > + switch (reg) { > + case 0: asm("movdqa %0, %%xmm0" : : "m"(*data)); break; > + case 1: asm("movdqa %0, %%xmm1" : : "m"(*data)); break; > + case 2: asm("movdqa %0, %%xmm2" : : "m"(*data)); break; > + case 3: asm("movdqa %0, %%xmm3" : : "m"(*data)); break; > + case 4: asm("movdqa %0, %%xmm4" : : "m"(*data)); break; > + case 5: asm("movdqa %0, %%xmm5" : : "m"(*data)); break; > + case 6: asm("movdqa %0, %%xmm6" : : "m"(*data)); break; > + case 7: asm("movdqa %0, %%xmm7" : : "m"(*data)); break; > +#ifdef CONFIG_X86_64 > + case 8: asm("movdqa %0, %%xmm8" : : "m"(*data)); break; > + case 9: asm("movdqa %0, %%xmm9" : : "m"(*data)); break; > + case 10: asm("movdqa %0, %%xmm10" : : "m"(*data)); break; > + case 11: asm("movdqa %0, %%xmm11" : : "m"(*data)); break; > + case 12: asm("movdqa %0, %%xmm12" : : "m"(*data)); break; > + case 13: asm("movdqa %0, %%xmm13" : : "m"(*data)); break; > + case 14: asm("movdqa %0, %%xmm14" : : "m"(*data)); break; > + case 15: asm("movdqa %0, %%xmm15" : : "m"(*data)); break; > +#endif > + default: BUG(); > + } > +} > + > +static inline void _kvm_read_mmx_reg(int reg, u64 *data) > +{ > + switch (reg) { > + case 0: asm("movq %%mm0, %0" : "=m"(*data)); break; > + case 1: asm("movq %%mm1, %0" : "=m"(*data)); break; > + case 2: asm("movq %%mm2, %0" : "=m"(*data)); break; > + case 3: asm("movq %%mm3, %0" : "=m"(*data)); break; > + case 4: asm("movq %%mm4, %0" : "=m"(*data)); break; > + case 5: asm("movq %%mm5, %0" : "=m"(*data)); break; > + case 6: asm("movq %%mm6, %0" : "=m"(*data)); break; > + case 7: asm("movq %%mm7, %0" : "=m"(*data)); break; > + default: BUG(); > + } > +} > + > +static inline void _kvm_write_mmx_reg(int reg, const u64 *data) > +{ > + switch (reg) { > + case 0: asm("movq %0, %%mm0" : : "m"(*data)); break; > + case 1: asm("movq %0, %%mm1" : : "m"(*data)); break; > + case 2: asm("movq %0, %%mm2" : : "m"(*data)); break; > + case 3: asm("movq %0, %%mm3" : : "m"(*data)); break; > + case 4: asm("movq %0, %%mm4" : : "m"(*data)); break; > + case 5: asm("movq %0, %%mm5" : : "m"(*data)); break; > + case 6: asm("movq %0, %%mm6" : : "m"(*data)); break; > + case 7: asm("movq %0, %%mm7" : : "m"(*data)); break; > + default: BUG(); > + } > +} > + > +static inline void kvm_fpu_get(void) > +{ > + fpregs_lock(); > + > + fpregs_assert_state_consistent(); > + if (test_thread_flag(TIF_NEED_FPU_LOAD)) > + switch_fpu_return(); > +} > + > +static inline void kvm_fpu_put(void) > +{ > + fpregs_unlock(); > +} > + > +static inline void kvm_read_sse_reg(int reg, sse128_t *data) > +{ > + kvm_fpu_get(); > + _kvm_read_sse_reg(reg, data); > + kvm_fpu_put(); > +} > + > +static inline void kvm_write_sse_reg(int reg, const sse128_t *data) > +{ > + kvm_fpu_get(); > + _kvm_write_sse_reg(reg, data); > + kvm_fpu_put(); > +} > + > +static inline void kvm_read_mmx_reg(int reg, u64 *data) > +{ > + kvm_fpu_get(); > + _kvm_read_mmx_reg(reg, data); > + kvm_fpu_put(); > +} > + > +static inline void kvm_write_mmx_reg(int reg, const u64 *data) > +{ > + kvm_fpu_get(); > + _kvm_write_mmx_reg(reg, data); > + kvm_fpu_put(); > +} > + > +#endif -- Vitaly