From patchwork Thu May 26 16:35:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: alvise rigo X-Patchwork-Id: 9137263 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 68FA16075A for ; Thu, 26 May 2016 16:41:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3EA7D2807E for ; Thu, 26 May 2016 16:41:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2DA1D282E2; Thu, 26 May 2016 16:41:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 77EBA2807E for ; Thu, 26 May 2016 16:41:14 +0000 (UTC) Received: from localhost ([::1]:39507 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5yLR-0002Sn-JR for patchwork-qemu-devel@patchwork.kernel.org; Thu, 26 May 2016 12:41:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58558) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5yGk-0006Z3-6E for qemu-devel@nongnu.org; Thu, 26 May 2016 12:36:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b5yGi-0003ml-F0 for qemu-devel@nongnu.org; Thu, 26 May 2016 12:36:21 -0400 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:33258) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5yGh-0003mM-4x for qemu-devel@nongnu.org; Thu, 26 May 2016 12:36:20 -0400 Received: by mail-wm0-x242.google.com with SMTP id a136so7015304wme.0 for ; Thu, 26 May 2016 09:36:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtualopensystems-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ZLw60oQQQX2AnfA2EG5R7t1Z++wy6g1VQFzLyr18BrE=; b=ZND7y2seQBgbKhYM+d2zZ/XAXJdrcEePQXLJ/d5AjOmTCKTQRJo5UZdpDZAnkwwDix zZhURUCiP8O9C3maS7D2pDTZWfwFYUlVhasSQftdTaDuhXVefkBw0WAQ2WCc8ozjBssJ cQIsDbHp385teQCcDGrYF6S/u5lb/U3xhHmakwaVKIHPym4NxyK8+sMxowiqJx9UZIEQ qEJlYKoNhhPZIevJA5izyy90UFSq4FcMozU1QQF+ww8QhAgsF+OdC2+gXo5EZfZOLS+O hoDtOqNGr9wJ/9k6Aj/3VTxVufD7kildVaGtEIVruiIJ+R4miW6psOhzCdDiFBNC15Tz 7rpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ZLw60oQQQX2AnfA2EG5R7t1Z++wy6g1VQFzLyr18BrE=; b=mXdkWbQ1AoC0dGeMPc6MCui65zi1D7SnW8pBfZ0RkkXf6mRwTiPYe2p2Cb9G4MXt5b n3q1OWZF8nSXlibte+I5+2Rfti7GjTtbLwhyWlbw6/rVtJIvZXocqHJURTwOLDRJX+i6 YR0dZcOCpqK+YjIw+3BvDCuRIekgADUW+OBe+4S0f5grG4CqbEBkf3bmjFLI4NjKBxQW 3jzmVq8Ha+8zDTW2K9JBUb7Zg1z6tSi//FSd3sl//dBqpyPaQ+XlsSmXkad9RqgkOB5C RK4f0GQ9lBzzGB09s6rp7wdbGX/gOZApX2H6YvSkhkEvowurnWWV4ERU37la+Jn8gddd 2rAA== X-Gm-Message-State: ALyK8tJZb5XZpINgb50JPJHgJgY9TFyQ+faVfZt7J0Nmzb23TUqjRujLqTv8D9s7yMcbrQ== X-Received: by 10.28.181.148 with SMTP id e142mr4446828wmf.38.1464280578452; Thu, 26 May 2016 09:36:18 -0700 (PDT) Received: from linarch.localdomain (LPuteaux-656-1-278-113.w80-15.abo.wanadoo.fr. [80.15.154.113]) by smtp.googlemail.com with ESMTPSA id lf9sm15133703wjc.44.2016.05.26.09.36.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 26 May 2016 09:36:17 -0700 (PDT) From: Alvise Rigo To: mttcg@listserver.greensocs.com, alex.bennee@linaro.org Date: Thu, 26 May 2016 18:35:46 +0200 Message-Id: <20160526163549.3276-8-a.rigo@virtualopensystems.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20160526163549.3276-1-a.rigo@virtualopensystems.com> References: <20160526163549.3276-1-a.rigo@virtualopensystems.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::242 Subject: [Qemu-devel] [RFC 07/10] cputlb: Query tlb_flush_by_mmuidx X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, rth@twiddle.net, claudio.fontana@huawei.com, qemu-devel@nongnu.org, Alvise Rigo , cota@braap.org, serge.fdrv@gmail.com, pbonzini@redhat.com, jani.kokkonen@huawei.com, tech@virtualopensystems.com, fred.konrad@greensocs.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Some architectures need to flush the TLB by MMU index. As per tlb_flush(), also these flushes have to be properly queried to the target VCPU. For the time being, this type of flush is used only in the ARM/aarch64 target architecture and is the result of guest instructions emulation. As a result, we can always get safely the CPUState of the current VCPU without relying on current_cpu. This however complicates a bit the function prototype by adding an argument pointing to the current VCPU's CPUState. Signed-off-by: Alvise Rigo --- cputlb.c | 49 +++++++++++++++++++++++++++++++++++++++---------- include/exec/exec-all.h | 4 ++-- target-arm/helper.c | 40 +++++++++++++++++++++------------------- 3 files changed, 62 insertions(+), 31 deletions(-) diff --git a/cputlb.c b/cputlb.c index 5bbbf1b..73624d6 100644 --- a/cputlb.c +++ b/cputlb.c @@ -59,6 +59,8 @@ /* We need a solution for stuffing 64 bit pointers in 32 bit ones if * we care about this combination */ QEMU_BUILD_BUG_ON(sizeof(target_ulong) > sizeof(void *)); +/* Size, in bytes, of the bitmap used by tlb_flush_by_mmuidx functions */ +#define MMUIDX_BITMAP_SIZE sizeof(unsigned long) * BITS_TO_LONGS(NB_MMU_MODES) /* statistics */ int tlb_flush_count; @@ -153,10 +155,41 @@ static inline void tlb_tables_flush_bitmap(CPUState *cpu, unsigned long *bitmap) memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache)); } -static inline void v_tlb_flush_by_mmuidx(CPUState *cpu, va_list argp) +struct TLBFlushByMMUIdxParams { + DECLARE_BITMAP(idx_to_flush, NB_MMU_MODES); +}; + +static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, void *opaque) +{ + struct TLBFlushByMMUIdxParams *params = opaque; + + tlb_tables_flush_bitmap(cpu, params->idx_to_flush); + + g_free(params); +} + +static inline void v_tlb_flush_by_mmuidx(CPUState *cpu, CPUState *target, + unsigned long *idxmap) { + if (!qemu_cpu_is_self(target)) { + struct TLBFlushByMMUIdxParams *params; + + params = g_malloc(sizeof(struct TLBFlushByMMUIdxParams)); + memcpy(params->idx_to_flush, idxmap, MMUIDX_BITMAP_SIZE); + async_wait_run_on_cpu(target, cpu, tlb_flush_by_mmuidx_async_work, + params); + } else { + tlb_tables_flush_bitmap(cpu, idxmap); + } +} + +void tlb_flush_by_mmuidx(CPUState *cpu, CPUState *target_cpu, ...) +{ + va_list argp; DECLARE_BITMAP(idxmap, NB_MMU_MODES) = { 0 }; + va_start(argp, target_cpu); + for (;;) { int mmu_idx = va_arg(argp, int); @@ -167,15 +200,9 @@ static inline void v_tlb_flush_by_mmuidx(CPUState *cpu, va_list argp) set_bit(mmu_idx, idxmap); } - tlb_tables_flush_bitmap(cpu, idxmap); -} - -void tlb_flush_by_mmuidx(CPUState *cpu, ...) -{ - va_list argp; - va_start(argp, cpu); - v_tlb_flush_by_mmuidx(cpu, argp); va_end(argp); + + v_tlb_flush_by_mmuidx(cpu, target_cpu, idxmap); } static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) @@ -244,7 +271,9 @@ void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...) TARGET_FMT_lx "/" TARGET_FMT_lx ")\n", env->tlb_flush_addr, env->tlb_flush_mask); - v_tlb_flush_by_mmuidx(cpu, argp); + /* Temporarily use current_cpu until tlb_flush_page_by_mmuidx + * is reworked */ + tlb_flush_by_mmuidx(current_cpu, cpu, argp); va_end(argp); return; } diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index bc97683..066870b 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -152,7 +152,7 @@ void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...); * Flush all entries from the TLB of the specified CPU, for the specified * MMU indexes. */ -void tlb_flush_by_mmuidx(CPUState *cpu, ...); +void tlb_flush_by_mmuidx(CPUState *cpu, CPUState *target, ...); /** * tlb_set_page_with_attrs: * @cpu: CPU to add this TLB entry for @@ -205,7 +205,7 @@ static inline void tlb_flush_page_by_mmuidx(CPUState *cpu, { } -static inline void tlb_flush_by_mmuidx(CPUState *cpu, ...) +static inline void tlb_flush_by_mmuidx(CPUState *cpu, CPUState *target ...) { } static inline void tlb_flush_page_all(target_ulong addr) diff --git a/target-arm/helper.c b/target-arm/helper.c index bc9fbda..3dcd910 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2388,7 +2388,7 @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, /* Accesses to VTTBR may change the VMID so we must flush the TLB. */ if (raw_read(env, ri) != value) { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, + tlb_flush_by_mmuidx(cs, cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, ARMMMUIdx_S2NS, -1); raw_write(env, ri, value); } @@ -2748,9 +2748,9 @@ static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri, CPUState *cs = CPU(cpu); if (arm_is_secure_below_el3(env)) { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); + tlb_flush_by_mmuidx(cs, cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); } else { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); + tlb_flush_by_mmuidx(cs, cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); } } @@ -2758,13 +2758,14 @@ static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { bool sec = arm_is_secure_below_el3(env); - CPUState *other_cs; + CPUState *other_cs, *this_cs = ENV_GET_CPU(env); CPU_FOREACH(other_cs) { if (sec) { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); + tlb_flush_by_mmuidx(this_cs, other_cs, ARMMMUIdx_S1SE1, + ARMMMUIdx_S1SE0, -1); } else { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, + tlb_flush_by_mmuidx(this_cs, other_cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); } } @@ -2781,13 +2782,13 @@ static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri, CPUState *cs = CPU(cpu); if (arm_is_secure_below_el3(env)) { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); + tlb_flush_by_mmuidx(cs, cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); } else { if (arm_feature(env, ARM_FEATURE_EL2)) { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, + tlb_flush_by_mmuidx(cs, cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, ARMMMUIdx_S2NS, -1); } else { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); + tlb_flush_by_mmuidx(cs, cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); } } } @@ -2798,7 +2799,7 @@ static void tlbi_aa64_alle2_write(CPUARMState *env, const ARMCPRegInfo *ri, ARMCPU *cpu = arm_env_get_cpu(env); CPUState *cs = CPU(cpu); - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1E2, -1); + tlb_flush_by_mmuidx(cs, cs, ARMMMUIdx_S1E2, -1); } static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -2807,7 +2808,7 @@ static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri, ARMCPU *cpu = arm_env_get_cpu(env); CPUState *cs = CPU(cpu); - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1E3, -1); + tlb_flush_by_mmuidx(cs, cs, ARMMMUIdx_S1E3, -1); } static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -2819,16 +2820,17 @@ static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri, */ bool sec = arm_is_secure_below_el3(env); bool has_el2 = arm_feature(env, ARM_FEATURE_EL2); - CPUState *other_cs; + CPUState *other_cs, *this_cs = ENV_GET_CPU(env); CPU_FOREACH(other_cs) { if (sec) { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); + tlb_flush_by_mmuidx(this_cs, other_cs, ARMMMUIdx_S1SE1, + ARMMMUIdx_S1SE0, -1); } else if (has_el2) { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, + tlb_flush_by_mmuidx(this_cs, other_cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, ARMMMUIdx_S2NS, -1); } else { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, + tlb_flush_by_mmuidx(this_cs, other_cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); } } @@ -2837,20 +2839,20 @@ static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri, static void tlbi_aa64_alle2is_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - CPUState *other_cs; + CPUState *other_cs, *this_cs = ENV_GET_CPU(env); CPU_FOREACH(other_cs) { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1E2, -1); + tlb_flush_by_mmuidx(this_cs, other_cs, ARMMMUIdx_S1E2, -1); } } static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - CPUState *other_cs; + CPUState *other_cs, *this_cs = ENV_GET_CPU(env); CPU_FOREACH(other_cs) { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1E3, -1); + tlb_flush_by_mmuidx(this_cs, other_cs, ARMMMUIdx_S1E3, -1); } }