From patchwork Mon Jan 6 16:36:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 11319667 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 13E1C6C1 for ; Mon, 6 Jan 2020 16:37:01 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EE75820848 for ; Mon, 6 Jan 2020 16:37:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EE75820848 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ioVMB-0000zK-5K; Mon, 06 Jan 2020 16:35:55 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ioVM9-0000zB-E1 for xen-devel@lists.xenproject.org; Mon, 06 Jan 2020 16:35:53 +0000 X-Inumbo-ID: 954e42ca-30a2-11ea-a914-bc764e2007e4 Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 954e42ca-30a2-11ea-a914-bc764e2007e4; Mon, 06 Jan 2020 16:35:44 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 5A526AD00; Mon, 6 Jan 2020 16:35:43 +0000 (UTC) From: Jan Beulich To: "xen-devel@lists.xenproject.org" References: <6f167053-38dc-19b5-a873-321d978e9a59@suse.com> Message-ID: <95425a27-717d-59c8-bcd6-ee8cfea4439c@suse.com> Date: Mon, 6 Jan 2020 17:36:29 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.9.1 MIME-Version: 1.0 In-Reply-To: <6f167053-38dc-19b5-a873-321d978e9a59@suse.com> Content-Language: en-US Subject: [Xen-devel] [PATCH RFC v3 4/8] x86emul: support MOVDIR64B insn X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Roger Pau Monne Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Note that SDM revision 070 doesn't specify exception behavior for ModRM.mod != 0b11; assuming #UD here. Signed-off-by: Jan Beulich --- RFC: Yet to be tested (once SDE supports it). --- v4: Split MOVDIRI and MOVDIR64B. Switch to using ->rmw(). Re-base. v3: Update description. --- a/tools/tests/x86_emulator/test_x86_emulator.c +++ b/tools/tests/x86_emulator/test_x86_emulator.c @@ -2208,6 +2208,29 @@ int main(int argc, char **argv) goto fail; printf("okay\n"); + printf("%-40s", "Testing movdir64b 144(%edx),%ecx..."); + if ( stack_exec && cpu_has_movdir64b ) + { + instr[0] = 0x66; instr[1] = 0x0f; instr[2] = 0x38; instr[3] = 0xf8; + instr[4] = 0x8a; instr[5] = 0x90; instr[8] = instr[7] = instr[6] = 0; + regs.eip = (unsigned long)&instr[0]; + for ( i = 0; i < 64; ++i ) + res[i] = i - 20; + regs.edx = (unsigned long)res; + regs.ecx = (unsigned long)(res + 16); + rc = x86_emulate(&ctxt, &emulops); + if ( (rc != X86EMUL_OKAY) || + (regs.eip != (unsigned long)&instr[9]) || + res[15] != -5 || res[32] != 12 ) + goto fail; + for ( i = 16; i < 32; ++i ) + if ( res[i] != i ) + goto fail; + printf("okay\n"); + } + else + printf("skipped\n"); + printf("%-40s", "Testing movq %mm3,(%ecx)..."); if ( stack_exec && cpu_has_mmx ) { --- a/tools/tests/x86_emulator/x86-emulate.h +++ b/tools/tests/x86_emulator/x86-emulate.h @@ -154,6 +154,7 @@ static inline bool xcr0_mask(uint64_t ma #define cpu_has_avx512_vnni (cp.feat.avx512_vnni && xcr0_mask(0xe6)) #define cpu_has_avx512_bitalg (cp.feat.avx512_bitalg && xcr0_mask(0xe6)) #define cpu_has_avx512_vpopcntdq (cp.feat.avx512_vpopcntdq && xcr0_mask(0xe6)) +#define cpu_has_movdir64b cp.feat.movdir64b #define cpu_has_avx512_4vnniw (cp.feat.avx512_4vnniw && xcr0_mask(0xe6)) #define cpu_has_avx512_4fmaps (cp.feat.avx512_4fmaps && xcr0_mask(0xe6)) --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -249,12 +249,13 @@ $(BASEDIR)/include/asm-x86/asm-macros.h: # sure we pick up changes when the compiler used has changed.) ifeq ($(MAKECMDGOALS),asm-offsets.s) -as-ISA-list := CLWB EPT FSGSBASE INVPCID RDRAND RDSEED SSE4_2 VMX XSAVEOPT +as-ISA-list := CLWB EPT FSGSBASE INVPCID MOVDIR64B RDRAND RDSEED SSE4_2 VMX XSAVEOPT CLWB-insn := clwb (%rax) EPT-insn := invept (%rax),%rax FSGSBASE-insn := rdfsbase %rax INVPCID-insn := invpcid (%rax),%rax +MOVDIR64B-insn := movdir64b (%rax),%rax RDRAND-insn := rdrand %eax RDSEED-insn := rdseed %eax SSE4_2-insn := crc32 %eax,%eax --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -548,6 +548,7 @@ static const struct ext0f38_table { [0xf1] = { .to_mem = 1, .two_op = 1 }, [0xf2 ... 0xf3] = {}, [0xf5 ... 0xf7] = {}, + [0xf8] = { .simd_size = simd_other }, [0xf9] = { .to_mem = 1 }, }; @@ -834,6 +835,7 @@ struct x86_emulate_state { rmw_bts, rmw_dec, rmw_inc, + rmw_movdir64b, rmw_neg, rmw_not, rmw_or, @@ -896,6 +898,7 @@ typedef union { uint64_t __attribute__ ((aligned(16))) xmm[2]; uint64_t __attribute__ ((aligned(32))) ymm[4]; uint64_t __attribute__ ((aligned(64))) zmm[8]; + uint32_t words[16]; } mmval_t; /* @@ -1904,6 +1907,7 @@ in_protmode( #define vcpu_has_avx512_vpopcntdq() (ctxt->cpuid->feat.avx512_vpopcntdq) #define vcpu_has_rdpid() (ctxt->cpuid->feat.rdpid) #define vcpu_has_movdiri() (ctxt->cpuid->feat.movdiri) +#define vcpu_has_movdir64b() (ctxt->cpuid->feat.movdir64b) #define vcpu_has_avx512_4vnniw() (ctxt->cpuid->feat.avx512_4vnniw) #define vcpu_has_avx512_4fmaps() (ctxt->cpuid->feat.avx512_4fmaps) @@ -9919,6 +9923,23 @@ x86_emulate( : "0" ((uint32_t)src.val), "rm" (_regs.edx) ); break; + case X86EMUL_OPC_66(0x0f38, 0xf8): /* movdir64b r,m512 */ + host_and_vcpu_must_have(movdir64b); + generate_exception_if(ea.type != OP_MEM, EXC_UD); + src.val = truncate_ea(*dst.reg); + generate_exception_if(!is_aligned(x86_seg_es, src.val, 64, ctxt, ops), + EXC_GP, 0); + fail_if(!ops->rmw); + BUILD_BUG_ON(sizeof(*mmvalp) < 64); + state->rmw = rmw_movdir64b; + if ( (rc = ops->read(ea.mem.seg, ea.mem.off, mmvalp, 64, + ctxt)) != X86EMUL_OKAY || + (rc = ops->rmw(x86_seg_es, src.val, 64, &mmvalp->words[0], + state, ctxt)) != X86EMUL_OKAY ) + goto done; + state->simd_size = simd_none; + break; + case X86EMUL_OPC(0x0f38, 0xf9): /* movdiri mem,r */ vcpu_must_have(movdiri); generate_exception_if(dst.type != OP_MEM, EXC_UD); @@ -11074,6 +11095,26 @@ int x86_emul_rmw( #undef BINOP #undef SHIFT + case rmw_movdir64b: + if ( ((unsigned long)dst & 0x3f) ) + { + ASSERT_UNREACHABLE(); + return X86EMUL_UNHANDLEABLE; + } + /* + * eflags points to source data in this case. Use a memory clobber + * to compensate that the other operands don't properly express the + * (full) memory ranges covered. + */ +#ifdef HAVE_AS_MOVDIR64B + asm ( "movdir64b %0, %1" :: "m" (*dst), "r" (eflags) : "memory" ); +#else + /* movdir64b (%rdi), %rdx */ + asm ( ".byte 0x66, 0x0f, 0x38, 0xf8, 0x17" + :: "D" (dst), "d" (eflags) : "memory" ); +#endif + break; + case rmw_not: switch ( state->op_bytes ) { --- a/xen/include/asm-x86/cpufeature.h +++ b/xen/include/asm-x86/cpufeature.h @@ -120,6 +120,7 @@ #define cpu_has_avx512_bitalg boot_cpu_has(X86_FEATURE_AVX512_BITALG) #define cpu_has_avx512_vpopcntdq boot_cpu_has(X86_FEATURE_AVX512_VPOPCNTDQ) #define cpu_has_rdpid boot_cpu_has(X86_FEATURE_RDPID) +#define cpu_has_movdir64b boot_cpu_has(X86_FEATURE_MOVDIR64B) /* CPUID level 0x80000007.edx */ #define cpu_has_itsc boot_cpu_has(X86_FEATURE_ITSC) --- a/xen/include/public/arch-x86/cpufeatureset.h +++ b/xen/include/public/arch-x86/cpufeatureset.h @@ -238,6 +238,7 @@ XEN_CPUFEATURE(AVX512_VPOPCNTDQ, 6*32+14 XEN_CPUFEATURE(RDPID, 6*32+22) /*A RDPID instruction */ XEN_CPUFEATURE(CLDEMOTE, 6*32+25) /*A CLDEMOTE instruction */ XEN_CPUFEATURE(MOVDIRI, 6*32+27) /*A MOVDIRI instruction */ +XEN_CPUFEATURE(MOVDIR64B, 6*32+28) /*A MOVDIR64B instruction */ /* AMD-defined CPU features, CPUID level 0x80000007.edx, word 7 */ XEN_CPUFEATURE(ITSC, 7*32+ 8) /* Invariant TSC */