From patchwork Thu Jan 7 20:14:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 358254 Delivered-To: patch@linaro.org Received: by 2002:a02:85a7:0:0:0:0:0 with SMTP id d36csp781075jai; Thu, 7 Jan 2021 12:22:18 -0800 (PST) X-Google-Smtp-Source: ABdhPJwf3EEDX7bXLDKbwJPtot4QMKH4nUA3ZK0pZQwkjFRDBvnw1w6595z4f/1s7gxcW2maEQtw X-Received: by 2002:a25:2e05:: with SMTP id u5mr798139ybu.297.1610050938571; Thu, 07 Jan 2021 12:22:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1610050938; cv=none; d=google.com; s=arc-20160816; b=BkaRI+U+En/nY85R5wk4GOBdOpGojM/TLoBLz6sYkfYNf/HMiJoY8bmL5gw6ASiXIy hsm3cVBupPcl3ObOG6Ihh6J03mUo1ukB1Ehd4bw1peIu/pyQ3Hq3oirF4QkzAppXzNws ywDBxWd3OGWKFYrw2hxk60JmgLmWaiEDk3HcqFc5dZbSjGEeds5SVWi8b0azvwXrB3B6 6BvNToS9YNolCme2f1kbdYs1mEMs0irepxoytEwtlZisj2X1EzjTHre7cw/vmDINehC+ 4BkmraN1xGrxNZ7xUX1+PWeVIwIGeuw52TcLPwyl7vIZVV4Y9ZBNDKYNEcvG8JU9TdF8 TIjQ== 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 :dkim-signature; bh=48z+GqlaobtZlttO/+L7peMtbYaAP6yESc8MWoNMMuc=; b=oCEpXiaihHyyNxLLNbHq/VT8+8dCNCzFQEzme/tMQRIoeSpXbuyh8YZ8swPqRJwb4Z xeLdbMQP4yjVxPOk87sSdnYq9gT3x7GzWf1RaYlSb0wKgQ9AlG033W4XO35iWiVkDA4C Gba0XlgOtDu8y1LvqIIiTUIhlL2x5zAIR86eNNyoBYZdK0v+AHByMCHERpGlKVoO2ofp a8riE+W3Zi3lDY2AQxF4NkFzZi4eNURlE9mRgNVKR6B5xwpiEVHo/6dMA32MHSbdMjAa cI2MZmeIR3WGejsBb6M65VyX5ix/4vvdSdsPMBHF0hwT/NiXLA4IExzsfWj2eKXTO4U8 TCmQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=I78dbytR; 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"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id m68si7280683ybf.30.2021.01.07.12.22.18 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 07 Jan 2021 12:22:18 -0800 (PST) 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; dkim=fail header.i=@linaro.org header.s=google header.b=I78dbytR; 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"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:35378 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kxbnW-00089d-1K for patch@linaro.org; Thu, 07 Jan 2021 15:22:18 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:47968) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kxbga-0000sQ-Te for qemu-devel@nongnu.org; Thu, 07 Jan 2021 15:15:08 -0500 Received: from mail-pg1-x533.google.com ([2607:f8b0:4864:20::533]:35169) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kxbgY-0001Rp-QZ for qemu-devel@nongnu.org; Thu, 07 Jan 2021 15:15:08 -0500 Received: by mail-pg1-x533.google.com with SMTP id n7so5756993pgg.2 for ; Thu, 07 Jan 2021 12:15:06 -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=48z+GqlaobtZlttO/+L7peMtbYaAP6yESc8MWoNMMuc=; b=I78dbytRXYvJ6Njh94mxv/VfHQmkQCHMvNYIyFsDzi4Kt0BSwX67O7xavuiKVuC5ho vhG2bAQ+BaLr33xb9cHw3iv+C1O4nc9N1UEH/QC+7Cw1JLQlyaGNUuROTM9/sIx164mB 1A6cynxmq8p6hE+0CD/LCZjZm102tCSjAmW5wV/Jiw+C0KbBlr1EQM18ciz8NAP4AoHb jEKnYgnFK871JAj4UhbWXVX7dbCCMcwl9LHZ11YMQEPb5tcjdP7Sqcn3iaDZUX4Ddkpr n3CV/MA380r9R9v/dokah+dNwcW1VTZEojXRjkxN48yAvq0pgBSL2zRHbaIp9pEKtkbQ YHoA== 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=48z+GqlaobtZlttO/+L7peMtbYaAP6yESc8MWoNMMuc=; b=fbJGnIowKKMJgdrq3hiWUIcs+RuSC7PTRPi3kQthIyYxQUBUelakWRknJXQCm65hUI WdkUx6jmMJaUze3kfQHAiKysF/VtvLcoJhLaEReQ3VjR+wYIGXYh0uFINciWNQ9sQ8sl NjIYB+ZqSAXb5qZlgo+uz4OeK3sTuTfVpACURy4UdG9O222ydl/o/ZIXF/365vnS3t7i A3L0luEH3HKZu+BT699w0pkLc9ckybunGPc/NeZYG+SEtlhGhbL4PRgdJp/4khLJf6Xj QScUJ8Ex4StyYwNc5crMV2mJuyZRfWxS73taBYenPUF4FonZhlTjZp7ZP38m3EECpipL K/HQ== X-Gm-Message-State: AOAM5334t837hTaOLdG6xQ0V9beaycHZKdBvstUeCFbCahVtU+SNATrq y2mLBOsApTimUhCCVaxZkddrTnwqVCDF9A== X-Received: by 2002:aa7:8104:0:b029:1ae:684f:d140 with SMTP id b4-20020aa781040000b02901ae684fd140mr337939pfi.62.1610050505129; Thu, 07 Jan 2021 12:15:05 -0800 (PST) Received: from localhost.localdomain (rrcs-173-197-107-21.west.biz.rr.com. [173.197.107.21]) by smtp.gmail.com with ESMTPSA id v6sm6516265pfi.31.2021.01.07.12.15.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Jan 2021 12:15:04 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 07/47] util: Enhance flush_icache_range with separate data pointer Date: Thu, 7 Jan 2021 10:14:08 -1000 Message-Id: <20210107201448.1152301-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210107201448.1152301-1-richard.henderson@linaro.org> References: <20210107201448.1152301-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::533; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x533.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: peter.maydell@linaro.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Joelle van Dyne Errors-To: qemu-devel-bounces+patch=linaro.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: Joelle van Dyne 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(-) -- 2.25.1 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 8b9ffc41c2..6301f4f0a5 100644 --- a/softmmu/physmem.c +++ b/softmmu/physmem.c @@ -2946,7 +2946,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 9bdc450196..759a41d848 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. */ @@ -4328,7 +4329,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); }