From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 279CBC433FF for ; Fri, 9 Aug 2019 16:15:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CC1272086A for ; Fri, 9 Aug 2019 16:15:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437091AbfHIQPB (ORCPT ); Fri, 9 Aug 2019 12:15:01 -0400 Received: from mx01.bbu.dsd.mx.bitdefender.com ([91.199.104.161]:52918 "EHLO mx01.bbu.dsd.mx.bitdefender.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437061AbfHIQPA (ORCPT ); Fri, 9 Aug 2019 12:15:00 -0400 Received: from smtp.bitdefender.com (smtp02.buh.bitdefender.net [10.17.80.76]) by mx01.bbu.dsd.mx.bitdefender.com (Postfix) with ESMTPS id 59BC2305D369; Fri, 9 Aug 2019 19:01:44 +0300 (EEST) Received: from localhost.localdomain (unknown [89.136.169.210]) by smtp.bitdefender.com (Postfix) with ESMTPSA id C8C39305B7A1; Fri, 9 Aug 2019 19:01:43 +0300 (EEST) From: =?UTF-8?q?Adalbert=20Laz=C4=83r?= To: kvm@vger.kernel.org Cc: linux-mm@kvack.org, virtualization@lists.linux-foundation.org, Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Konrad Rzeszutek Wilk , Tamas K Lengyel , Mathieu Tarral , =?UTF-8?q?Samuel=20Laur=C3=A9n?= , Patrick Colp , Jan Kiszka , Stefan Hajnoczi , Weijiang Yang , Zhang@vger.kernel.org, Yu C , =?UTF-8?q?Mihai=20Don=C8=9Bu?= , =?UTF-8?q?Adalbert=20Laz=C4=83r?= Subject: [RFC PATCH v6 90/92] kvm: x86: emulate lock cmpxchg8b atomically Date: Fri, 9 Aug 2019 19:00:45 +0300 Message-Id: <20190809160047.8319-91-alazar@bitdefender.com> In-Reply-To: <20190809160047.8319-1-alazar@bitdefender.com> References: <20190809160047.8319-1-alazar@bitdefender.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Mihai Donțu As it was the case for lock cmpxchg, lock cmpxchg8b was emulated in two steps the first one setting/clearing the zero flag and the last one making the actual atomic operation. This patch fixes that by combining the two, ie. the writeback step is no longer necessary as the first step made the changes directly in memory. Signed-off-by: Mihai Donțu Signed-off-by: Adalbert Lazăr --- arch/x86/kvm/emulate.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index dac4c0ca1ee3..2038e42c1eae 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2320,7 +2320,47 @@ static int em_call_near_abs(struct x86_emulate_ctxt *ctxt) static int em_cmpxchg8b(struct x86_emulate_ctxt *ctxt) { - u64 old = ctxt->dst.orig_val64; + u64 old; + + if (ctxt->lock_prefix) { + int rc; + ulong linear; + u64 new = (reg_read(ctxt, VCPU_REGS_RBX) & (u32)-1) | + ((reg_read(ctxt, VCPU_REGS_RCX) & (u32)-1) << 32); + + old = (reg_read(ctxt, VCPU_REGS_RAX) & (u32)-1) | + ((reg_read(ctxt, VCPU_REGS_RDX) & (u32)-1) << 32); + + /* disable writeback altogether */ + ctxt->d &= ~SrcWrite; + ctxt->d |= NoWrite; + + rc = linearize(ctxt, ctxt->dst.addr.mem, 8, true, &linear); + if (rc != X86EMUL_CONTINUE) + return rc; + + rc = ctxt->ops->cmpxchg_emulated(ctxt, linear, &old, &new, + ctxt->dst.bytes, + &ctxt->exception); + + switch (rc) { + case X86EMUL_CONTINUE: + ctxt->eflags |= X86_EFLAGS_ZF; + break; + case X86EMUL_CMPXCHG_FAILED: + *reg_write(ctxt, VCPU_REGS_RAX) = old & (u32)-1; + *reg_write(ctxt, VCPU_REGS_RDX) = (old >> 32) & (u32)-1; + + ctxt->eflags &= ~X86_EFLAGS_ZF; + + rc = X86EMUL_CONTINUE; + break; + } + + return rc; + } + + old = ctxt->dst.orig_val64; if (ctxt->dst.bytes == 16) return X86EMUL_UNHANDLEABLE;