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=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham 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 6A9C3C4361B for ; Mon, 14 Dec 2020 14:09:02 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (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 EDB412074B for ; Mon, 14 Dec 2020 14:09:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EDB412074B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:54104 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kooX6-0006pD-Ry for qemu-devel@archiver.kernel.org; Mon, 14 Dec 2020 09:09:00 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36062) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kooRj-0001WU-1h for qemu-devel@nongnu.org; Mon, 14 Dec 2020 09:03:27 -0500 Received: from mail-oi1-x242.google.com ([2607:f8b0:4864:20::242]:37229) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kooRg-0003u2-5h for qemu-devel@nongnu.org; Mon, 14 Dec 2020 09:03:26 -0500 Received: by mail-oi1-x242.google.com with SMTP id l207so19265484oib.4 for ; Mon, 14 Dec 2020 06:03:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=VBf9QskYdrzmXlYiy5KttGIoXCdMUZjZXJOehNVqkno=; b=lcqXOG6k+74/YmSo+a7htLjauAERA2Ae/NZ61odZo+wPSnM/NSHt8/i81TXKzvXTpo lg47+6A5DiPEsPvSfEfAA7/tXNLrPmFdYB5PdbpsN6wJ7msuTtWC5YcaqRDtf5UtrKK1 byWrN4nQT569JVe6SWVt73o4x4208an1htXuCjI0b2ltYIUSlLND4H3MdWnUCRd8RHYH a56yAu0Ey2CS7MWRc+4EZj3O1qmOax1T+tEIw0YduByyZCwgoFsys7cpPhFHe2PtgHj1 NdELjIPoarm8pZ27GdCSH/+ptC0u/jyGFnUS9DJ1z4aM6O45UnTYIn5LfPGwbXXXXufl NCtQ== 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:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VBf9QskYdrzmXlYiy5KttGIoXCdMUZjZXJOehNVqkno=; b=VHVEPWh0n6w/wZ46uXkIseoHbYaPxZrV23fV4niOKcNlYvvN9zQsKmzlGJlWLRZXFN WurjKQT/NSDXgJ0lACPgdtjbQvFSOBcladj9Vuyh2t9xxctZY+J82Jo4a+g0/yzpCc2d o842NtIS2u7u2bgdEGW3DybroQdzhroQ8/Aq9+tfzxxdkW0wK3wSjuCKbgmi71/bfHQc WUjKSxuFlwGLgvUR3oDjDeV4OH7nM64E621qowm6svsfgnfq/JQ+3pc0BzbbPhpngvxp l3UUAes4jP/+8Yh7c4rGT9lHUr8Eqs5jguBcjm3uR+3V+azMJ3g2SHkWS4RT+MFaXLv+ szYA== X-Gm-Message-State: AOAM532yEDp4G+IUM/5LaOr5pd50LCnp+UzsEAvtUBnd/kag9QYD7aki mEeuJr5DGWtJxM1KYSAv9vn67WoYXmJuazER X-Google-Smtp-Source: ABdhPJw3R1SwWcw/E1dzNReb8T4HGhIdjgoiG6dlZzc9fy4fFMFrW6t66lJfnESRFoqhOUe/k4QtCw== X-Received: by 2002:aca:3885:: with SMTP id f127mr12001938oia.104.1607954602158; Mon, 14 Dec 2020 06:03:22 -0800 (PST) Received: from localhost.localdomain (fixed-187-189-51-144.totalplay.net. [187.189.51.144]) by smtp.gmail.com with ESMTPSA id t24sm3940146oou.4.2020.12.14.06.03.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Dec 2020 06:03:21 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v4 03/43] util: Enhance flush_icache_range with separate data pointer Date: Mon, 14 Dec 2020 08:02:34 -0600 Message-Id: <20201214140314.18544-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201214140314.18544-1-richard.henderson@linaro.org> References: <20201214140314.18544-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::242; envelope-from=richard.henderson@linaro.org; helo=mail-oi1-x242.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" We are shortly going to have a split rw/rx jit buffer. Depending on the host, we need to flush the dcache at the rw data pointer and flush the icache at the rx code pointer. For now, the two passed pointers are identical, so there is no effective change in behaviour. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- include/qemu/cacheflush.h | 15 ++++++++++++-- softmmu/physmem.c | 2 +- tcg/tcg.c | 6 ++++-- util/cacheflush.c | 38 +++++++++++++++++++++--------------- util/cacheinfo.c | 8 +++++--- tcg/aarch64/tcg-target.c.inc | 2 +- tcg/mips/tcg-target.c.inc | 2 +- tcg/ppc/tcg-target.c.inc | 4 ++-- tcg/sparc/tcg-target.c.inc | 4 ++-- 9 files changed, 51 insertions(+), 30 deletions(-) diff --git a/include/qemu/cacheflush.h b/include/qemu/cacheflush.h index 58ae488491..ae20bcda73 100644 --- a/include/qemu/cacheflush.h +++ b/include/qemu/cacheflush.h @@ -8,16 +8,27 @@ #ifndef QEMU_CACHEFLUSH_H #define QEMU_CACHEFLUSH_H +/** + * flush_idcache_range: + * @rx: instruction address + * @rw: data address + * @len: length to flush + * + * Flush @len bytes of the data cache at @rw and the icache at @rx + * to bring them in sync. The two addresses may be different virtual + * mappings of the same physical page(s). + */ + #if defined(__i386__) || defined(__x86_64__) || defined(__s390__) -static inline void flush_icache_range(uintptr_t start, uintptr_t stop) +static inline void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) { /* icache is coherent and does not require flushing. */ } #else -void flush_icache_range(uintptr_t start, uintptr_t stop); +void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len); #endif diff --git a/softmmu/physmem.c b/softmmu/physmem.c index 36854f0cd0..7aa706b1e3 100644 --- a/softmmu/physmem.c +++ b/softmmu/physmem.c @@ -2947,7 +2947,7 @@ static inline MemTxResult address_space_write_rom_internal(AddressSpace *as, invalidate_and_set_dirty(mr, addr1, l); break; case FLUSH_CACHE: - flush_icache_range((uintptr_t)ram_ptr, (uintptr_t)ram_ptr + l); + flush_idcache_range((uintptr_t)ram_ptr, (uintptr_t)ram_ptr, l); break; } } diff --git a/tcg/tcg.c b/tcg/tcg.c index 4b4cafe952..675334e844 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1079,7 +1079,8 @@ void tcg_prologue_init(TCGContext *s) buf1 = s->code_ptr; #ifndef CONFIG_TCG_INTERPRETER - flush_icache_range((uintptr_t)buf0, (uintptr_t)buf1); + flush_idcache_range((uintptr_t)buf0, (uintptr_t)buf0, + tcg_ptr_byte_diff(buf1, buf0)); #endif /* Deduct the prologue from the buffer. */ @@ -4324,7 +4325,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) #ifndef CONFIG_TCG_INTERPRETER /* flush instruction cache */ - flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr); + flush_idcache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_buf, + tcg_ptr_byte_diff(s->code_ptr, s->code_buf)); #endif return tcg_current_code_size(s); diff --git a/util/cacheflush.c b/util/cacheflush.c index 2881832a38..92805efe49 100644 --- a/util/cacheflush.c +++ b/util/cacheflush.c @@ -21,29 +21,32 @@ #include #endif -void flush_icache_range(uintptr_t start, uintptr_t stop) +void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) { - cacheflush((void *)start, stop - start, ICACHE); + if (rx != rw) { + cacheflush((void *)rw, len, DCACHE); + } + cacheflush((void *)rx, len, ICACHE); } #elif defined(__powerpc__) -void flush_icache_range(uintptr_t start, uintptr_t stop) +void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) { - uintptr_t p, start1, stop1; + uintptr_t p, b, e; size_t dsize = qemu_dcache_linesize; size_t isize = qemu_icache_linesize; - start1 = start & ~(dsize - 1); - stop1 = (stop + dsize - 1) & ~(dsize - 1); - for (p = start1; p < stop1; p += dsize) { + b = rw & ~(dsize - 1); + e = (rw + len + dsize - 1) & ~(dsize - 1); + for (p = b; p < e; p += dsize) { asm volatile ("dcbst 0,%0" : : "r"(p) : "memory"); } asm volatile ("sync" : : : "memory"); - start &= start & ~(isize - 1); - stop1 = (stop + isize - 1) & ~(isize - 1); - for (p = start1; p < stop1; p += isize) { + b = rx & ~(isize - 1); + e = (rx + len + isize - 1) & ~(isize - 1); + for (p = b; p < e; p += isize) { asm volatile ("icbi 0,%0" : : "r"(p) : "memory"); } asm volatile ("sync" : : : "memory"); @@ -52,20 +55,23 @@ void flush_icache_range(uintptr_t start, uintptr_t stop) #elif defined(__sparc__) -void flush_icache_range(uintptr_t start, uintptr_t stop) +void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) { - uintptr_t p; - - for (p = start & -8; p < ((stop + 7) & -8); p += 8) { + /* No additional data flush to the RW virtual address required. */ + uintptr_t p, end = (rx + len + 7) & -8; + for (p = rx & -8; p < end; p += 8) { __asm__ __volatile__("flush\t%0" : : "r" (p)); } } #else -void flush_icache_range(uintptr_t start, uintptr_t stop) +void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) { - __builtin___clear_cache((char *)start, (char *)stop); + if (rw != rx) { + __builtin___clear_cache((char *)rw, (char *)rw + len); + } + __builtin___clear_cache((char *)rx, (char *)rx + len); } #endif diff --git a/util/cacheinfo.c b/util/cacheinfo.c index 7804c186b6..b182f0b693 100644 --- a/util/cacheinfo.c +++ b/util/cacheinfo.c @@ -166,9 +166,11 @@ static void fallback_cache_info(int *isize, int *dsize) *isize = *dsize; } else { #if defined(_ARCH_PPC) - /* For PPC, we're going to use the icache size computed for - flush_icache_range. Which means that we must use the - architecture minimum. */ + /* + * For PPC, we're going to use the cache sizes computed for + * flush_idcache_range. Which means that we must use the + * architecture minimum. + */ *isize = *dsize = 16; #else /* Otherwise, 64 bytes is not uncommon. */ diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index 26f71cb599..83af3108a4 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1363,7 +1363,7 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, } pair = (uint64_t)i2 << 32 | i1; qatomic_set((uint64_t *)jmp_addr, pair); - flush_icache_range(jmp_addr, jmp_addr + 8); + flush_idcache_range(jmp_addr, jmp_addr, 8); } static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l) diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 41be574e89..c255ecb444 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -2660,7 +2660,7 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, uintptr_t addr) { qatomic_set((uint32_t *)jmp_addr, deposit32(OPC_J, 0, 26, addr >> 2)); - flush_icache_range(jmp_addr, jmp_addr + 4); + flush_idcache_range(jmp_addr, jmp_addr, 4); } typedef struct { diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index 0d068ec8ab..b756281042 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -1753,12 +1753,12 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, /* As per the enclosing if, this is ppc64. Avoid the _Static_assert within qatomic_set that would fail to build a ppc32 host. */ qatomic_set__nocheck((uint64_t *)jmp_addr, pair); - flush_icache_range(jmp_addr, jmp_addr + 8); + flush_idcache_range(jmp_addr, jmp_addr, 8); } else { intptr_t diff = addr - jmp_addr; tcg_debug_assert(in_range_b(diff)); qatomic_set((uint32_t *)jmp_addr, B | (diff & 0x3fffffc)); - flush_icache_range(jmp_addr, jmp_addr + 4); + flush_idcache_range(jmp_addr, jmp_addr, 4); } } diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc index 6775bd30fc..6e2d755f6a 100644 --- a/tcg/sparc/tcg-target.c.inc +++ b/tcg/sparc/tcg-target.c.inc @@ -1836,7 +1836,7 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, if (!USE_REG_TB) { qatomic_set((uint32_t *)jmp_addr, deposit32(CALL, 0, 30, br_disp >> 2)); - flush_icache_range(jmp_addr, jmp_addr + 4); + flush_idcache_range(jmp_addr, jmp_addr, 4); return; } @@ -1860,5 +1860,5 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, } qatomic_set((uint64_t *)jmp_addr, deposit64(i2, 32, 32, i1)); - flush_icache_range(jmp_addr, jmp_addr + 8); + flush_idcache_range(jmp_addr, jmp_addr, 8); } -- 2.25.1