From patchwork Thu Mar 24 08:20:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 553899 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4186819mag; Thu, 24 Mar 2022 01:26:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxGB55oK38Fawvu8PPtO66UhRFkkc1URYGVJ98fzD+L96q6ZJCifi2+iSymPLRbYdeb+B8t X-Received: by 2002:a05:6214:1c8a:b0:440:f52d:8bcf with SMTP id ib10-20020a0562141c8a00b00440f52d8bcfmr3198689qvb.60.1648110366849; Thu, 24 Mar 2022 01:26:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648110366; cv=none; d=google.com; s=arc-20160816; b=eYvfnaU/eKoE4hMKrBYgu8JhDdikKrfK8CzNUmXKJ9PG0HoOLf4oASOw1OJNM7FRy5 sfQSkUSIA7YIlox4rQBDSSrB+DE0R26Z+XD/eo0Kzowt9Efe0Vt9qwCXSK0zSgZ7qc8d PL+Es5XHgBH71mGWAkOupBgEIFeKIQx1BOLxzk4u+EyhPXNO8iBPHE7oyq2gDFxIhY/q DNxigbtU090ApjZJXmew1elQ4prmJxCTwe6qvpOQ8yDdf5mkKwTuey191hGQUUPYkOQO vs9R8udeAM+O5S+194i2kXEqFLnKAu4PBOOcF96cbjDtupFx9le1EWdyTqwhE88BPTPw FAVA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from; bh=ISlSDPYVJwE3vp7bU03ufj/JKJQgcZoujK//JoxLpG4=; b=uBwinvpWPFxdRM9JJA2dmN3QIDiqSpH4lAXezhXasGKq+Klw1NyqPLqB0um7sUxkNp rLPgrmwz1joNElAeOfQgwL+mlXCeHu+aCh6j0s2hvb2bhm5xnJUrfx4aP/sqx1/6OXao ZDAlGiWOboIWlSj+BOCSd/gK5aU8Psrydyah7Wvh5IMRfg7kQKN1MtFbFjKnErBZOVKC V4ZSvwR75TJwuRzQ+5IFt8JIxRjJwuVZQfVJSmI4QjD9e58rZZnlHGV518SfK4NVjSG7 8yHzbiGLTT7wQar+9Uz21e65D21RNNBTR1rG4oJafCx4lrlI75fZ7+y/BwHLK+hsipJc H6jQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id bn12-20020a05622a1dcc00b002e1fbf3c03bsi4931811qtb.556.2022.03.24.01.26.06 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 24 Mar 2022 01:26:06 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Received: from localhost ([::1]:33820 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nXInG-000195-EW for patch@linaro.org; Thu, 24 Mar 2022 04:26:06 -0400 Received: from eggs.gnu.org ([209.51.188.92]:52246) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nXIho-0005yJ-R7 for qemu-devel@nongnu.org; Thu, 24 Mar 2022 04:20:28 -0400 Received: from mout.kundenserver.de ([212.227.126.130]:34009) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nXIhm-0003QQ-Rm for qemu-devel@nongnu.org; Thu, 24 Mar 2022 04:20:28 -0400 Received: from quad ([82.142.12.150]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.167]) with ESMTPSA (Nemesis) id 1MirX2-1o19oa3STs-00eqz8; Thu, 24 Mar 2022 09:20:25 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Subject: [PULL 10/10] linux-user/arm: Implement __kernel_cmpxchg64 with host atomics Date: Thu, 24 Mar 2022 09:20:16 +0100 Message-Id: <20220324082016.3463521-11-laurent@vivier.eu> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220324082016.3463521-1-laurent@vivier.eu> References: <20220324082016.3463521-1-laurent@vivier.eu> MIME-Version: 1.0 X-Provags-ID: V03:K1:ua5RvGBo8oB2zsuxbQLVWRtT+OjtQ2Pfk3/fLBQl6+aovURTHLY PSrmwUgXtdmZdW42sVoWXWy9eMOj5CCglZj3aD+4YCo+O3OLjaOmsv6n8jhv42v9oI7rMZD RD/3uopGPmnJV7TJ2o0pLg5KpZZmvrR4/yJL9jzygi6Xlx0Jnu6IE40iEwWl6tz+Gj845N9 vNqpecH7qirhwhd599xrw== X-UI-Out-Filterresults: notjunk:1;V03:K0:nD2La7kckSI=:Y1Bp7ofW8gJmNW8Cw2FF4N jWsKOrOefLCgNyymmuA654IY+PdY6Q5q5HcQnwbW/p+YckffIED1LY9lwwVDkjBrNV7/CntTi lmNad9i5qbu4g06HLEAzofrLluuvmbaK/t3qvGOWIQt6IhtdcTsNEpkw/o/3kbEStrdZFaaUU tDcoCGztxWCmAqaKqBBJ794b2PQbyt1yxDEn3gUPjaUC1zc9dWeOWCr5AOUMVLwhzoQph+Vb0 AHhUzTIQ5yL78ps6112xtxm0C0uQUkYmpbDA6Wna38FHweqUttpLe7+ymNTXjRY1C4IPPnuME ykYrabz10xXw46jRbi7LnfEFnVnbHqpgNwQmrqxni64oGgGMkzD48v0eP43zmytflGn1+hghG RGkKecD0H9EvsioCiy7Xe/NOUhfUZMbGfyc1hq6jdvB1vaNIxX7NCY475GwMchTN/8jgHfvSo BgmKvE8Qe4z1Q+AKBLo/ksDpFBM/ygKkPelq53aTAe1jE0W3/x+xFibnJrjXhzofxhro7VFNx W8yXd9w3P3937Z2VkArvrBJbsLF1qGhtWzsEWGV0jdcP4rmKDgmDbNkNj7V2QY5wMnfEolovM /VYl1TsRo9ZlpGxjWQUmVg78XJR30OVp87gYzs/pkKGoylcL6OoGdRHEYJ3/AfhoYwcrgcxlJ UE4vjcWar8WQlXmldtYUsp6kRx2Q+PXe3ZgdkAx+gKUPc9PSlRtcjB9SUW1CYvXIvVNo= Received-SPF: none client-ip=212.227.126.130; envelope-from=laurent@vivier.eu; helo=mout.kundenserver.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Richard Henderson , Laurent Vivier Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson If CONFIG_ATOMIC64, we can use a host cmpxchg and provide atomicity across processes; otherwise we have no choice but to continue using start/end_exclusive. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-Id: <20220323005839.94327-4-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/arm/cpu_loop.c | 75 +++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c index aa2d777bf449..aae375d61792 100644 --- a/linux-user/arm/cpu_loop.c +++ b/linux-user/arm/cpu_loop.c @@ -138,7 +138,7 @@ static void arm_kernel_cmpxchg32_helper(CPUARMState *env) } /* - * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt + * See the Linux kernel's Documentation/arm/kernel_user_helpers.rst * Input: * r0 = pointer to oldval * r1 = pointer to newval @@ -155,57 +155,54 @@ static void arm_kernel_cmpxchg64_helper(CPUARMState *env) { uint64_t oldval, newval, val; uint32_t addr, cpsr; + uint64_t *host_addr; - /* Based on the 32 bit code in do_kernel_trap */ - - /* XXX: This only works between threads, not between processes. - It's probably possible to implement this with native host - operations. However things like ldrex/strex are much harder so - there's not much point trying. */ - start_exclusive(); - cpsr = cpsr_read(env); - addr = env->regs[2]; - - if (get_user_u64(oldval, env->regs[0])) { - env->exception.vaddress = env->regs[0]; + addr = env->regs[0]; + if (get_user_u64(oldval, addr)) { goto segv; - }; + } - if (get_user_u64(newval, env->regs[1])) { - env->exception.vaddress = env->regs[1]; + addr = env->regs[1]; + if (get_user_u64(newval, addr)) { goto segv; - }; + } - if (get_user_u64(val, addr)) { - env->exception.vaddress = addr; - goto segv; + mmap_lock(); + addr = env->regs[2]; + host_addr = atomic_mmu_lookup(env, addr, 8); + if (!host_addr) { + mmap_unlock(); + return; } +#ifdef CONFIG_ATOMIC64 + val = qatomic_cmpxchg__nocheck(host_addr, oldval, newval); + cpsr = (val == oldval) * CPSR_C; +#else + /* + * This only works between threads, not between processes, but since + * the host has no 64-bit cmpxchg, it is the best that we can do. + */ + start_exclusive(); + val = *host_addr; if (val == oldval) { - val = newval; - - if (put_user_u64(val, addr)) { - env->exception.vaddress = addr; - goto segv; - }; - - env->regs[0] = 0; - cpsr |= CPSR_C; + *host_addr = newval; + cpsr = CPSR_C; } else { - env->regs[0] = -1; - cpsr &= ~CPSR_C; + cpsr = 0; } - cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr); end_exclusive(); +#endif + mmap_unlock(); + + cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr); + env->regs[0] = cpsr ? 0 : -1; return; -segv: - end_exclusive(); - /* We get the PC of the entry address - which is as good as anything, - on a real kernel what you get depends on which mode it uses. */ - /* XXX: check env->error_code */ - force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, - env->exception.vaddress); + segv: + force_sig_fault(TARGET_SIGSEGV, + page_get_flags(addr) & PAGE_VALID ? + TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR, addr); } /* Handle a jump to the kernel code page. */