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=-13.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT 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 4C20CC433E1 for ; Fri, 24 Jul 2020 09:10:23 +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 176E5206EB for ; Fri, 24 Jul 2020 09:10:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=sifive.com header.i=@sifive.com header.b="MX87ge4y" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 176E5206EB Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:57630 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jytig-0005v3-DH for qemu-devel@archiver.kernel.org; Fri, 24 Jul 2020 05:10:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45718) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jytgv-000394-FN for qemu-devel@nongnu.org; Fri, 24 Jul 2020 05:08:33 -0400 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:40462) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jytgt-0003si-5j for qemu-devel@nongnu.org; Fri, 24 Jul 2020 05:08:33 -0400 Received: by mail-pg1-x542.google.com with SMTP id n5so4880196pgf.7 for ; Fri, 24 Jul 2020 02:08:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Pc71QwKUTxcdbbb2mF5Hfr3ZbnXpr9ERBcMcGfZrI00=; b=MX87ge4yURs1x2t1f/TigdUPhHB7zTe3UYnWD/41nbnxwjYposVkmVN/kHLKDXbW2P ZC0H5oNIj0DxeWIsytaoyrPe9k8/J0FfVJUgjDZa+NOdO5KwgNU32BsODRfowBIw3ogJ Hs0lfcAU7rlCYy9c3Slw9rldES32TdCHZ/mQ46IzKu4Tss3k91WWwt1kH75TmRo/+FHC bK16Ixc+AHt4YageiaWueQSVf2WsRne0gzISSkacCQuCvxMe5u1i3ZxxtnVEdc51PkSC txhKUW78+0Q54WGP8lkA1MOmj3GdkxDkqUMraaaetUGwIPeb+uIyH0wh9gKREmlC8OWj AISA== 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=Pc71QwKUTxcdbbb2mF5Hfr3ZbnXpr9ERBcMcGfZrI00=; b=DZ5x41uZSFUqqs9NnUrne5m9ZgO9EHT79GEPTPZJ/tsY0MXX/AlOAy74jSHGIqMSJi GDzCXpkVbhWx/5N23tbtRLiSqlJpiytm1978AaRN0gedX6wAVlQ6Nme2wAfLgPTrSxgn 2LhxEVSD54oVSofgb+2sSYU4u7LuW3r8eAP2AuPEZuuQSfWgp6ypxyo1W2Qtbf4P38Em W4vIdgtjfQePZk+alpXlM1uzJ/QyP2QG4JBOZRgHtIbi+vvHlcOwZcBRkeY+G8k4evid 7/ziGpPLJ0JR8HvuMGxZZFo00o+ZcJRvs0AaJoSKtHlFClEP6WHzQSyFWICptqJIwuzD MsQg== X-Gm-Message-State: AOAM532Upe2VFYSeryeplBOux+JcbKaRpgii9imfIscC9kpPoxHa/986 H1/i+uXN8Q+xg3lQ38akOpOtNQ== X-Google-Smtp-Source: ABdhPJzE76Ie2N+kBXXB4nvSEW7/ZTwW4Gl7KZgvf5uDi1tJV5dVrc/8mhYPbyDH+tb8ze/eCZNzaQ== X-Received: by 2002:a62:b409:: with SMTP id h9mr7806369pfn.305.1595581709859; Fri, 24 Jul 2020 02:08:29 -0700 (PDT) Received: from hsinchu02.internal.sifive.com (114-34-229-221.HINET-IP.hinet.net. [114.34.229.221]) by smtp.gmail.com with ESMTPSA id z10sm5751282pfr.90.2020.07.24.02.08.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Jul 2020 02:08:29 -0700 (PDT) From: Zong Li To: palmer@dabbelt.com, Alistair.Francis@wdc.com, bmeng.cn@gmail.com, sagark@eecs.berkeley.edu, kbastian@mail.uni-paderborn.de, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v4 4/4] target/riscv: Change the TLB page size depends on PMP entries. Date: Fri, 24 Jul 2020 17:08:17 +0800 Message-Id: X-Mailer: git-send-email 2.27.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::542; envelope-from=zong.li@sifive.com; helo=mail-pg1-x542.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. 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, URIBL_BLOCKED=0.001 autolearn=unavailable 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: Zong Li Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The minimum granularity of PMP is 4 bytes, it is small than 4KB page size, therefore, the pmp checking would be ignored if its range doesn't start from the alignment of one page. This patch detects the pmp entries and sets the small page size to TLB if there is a PMP entry which cover the page size. Signed-off-by: Zong Li --- target/riscv/cpu_helper.c | 10 ++++++-- target/riscv/pmp.c | 52 +++++++++++++++++++++++++++++++++++++++ target/riscv/pmp.h | 2 ++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 08b069f0c9..b3013bc91e 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -693,6 +693,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool first_stage_error = true; int ret = TRANSLATE_FAIL; int mode = mmu_idx; + target_ulong tlb_size = 0; env->guest_phys_fault_addr = 0; @@ -784,8 +785,13 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } if (ret == TRANSLATE_SUCCESS) { - tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK, - prot, mmu_idx, TARGET_PAGE_SIZE); + if (pmp_is_range_in_tlb(env, pa & TARGET_PAGE_MASK, &tlb_size)) { + tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1), + prot, mmu_idx, tlb_size); + } else { + tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK, + prot, mmu_idx, TARGET_PAGE_SIZE); + } return true; } else if (probe) { return false; diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index e0161d6aab..a040cdd285 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -392,3 +392,55 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index) return val; } + +/* + * Calculate the TLB size if the start address or the end address of + * PMP entry is presented in thie TLB page. + */ +static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index, + target_ulong tlb_sa, target_ulong tlb_ea) +{ + target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa; + target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea; + + if (pmp_sa >= tlb_sa && pmp_ea <= tlb_ea) { + return pmp_ea - pmp_sa + 1; + } + + if (pmp_sa >= tlb_sa && pmp_sa <= tlb_ea && pmp_ea >= tlb_ea) { + return tlb_ea - pmp_sa + 1; + } + + if (pmp_ea <= tlb_ea && pmp_ea >= tlb_sa && pmp_sa <= tlb_sa) { + return pmp_ea - tlb_sa + 1; + } + + return 0; +} + +/* + * Check is there a PMP entry whcih range covers this page. If so, + * try to find the minimum granularity for the TLB size. + */ +bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa, + target_ulong *tlb_size) +{ + int i; + target_ulong val; + target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1); + + for (i = 0; i < MAX_RISCV_PMPS; i++) { + val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea); + if (val) { + if (*tlb_size == 0 || *tlb_size > val) { + *tlb_size = val; + } + } + } + + if (*tlb_size != 0) { + return true; + } + + return false; +} diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h index 8e19793132..c70f2ea4c4 100644 --- a/target/riscv/pmp.h +++ b/target/riscv/pmp.h @@ -60,5 +60,7 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index, target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index); bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, target_ulong size, pmp_priv_t priv, target_ulong mode); +bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa, + target_ulong *tlb_size); #endif -- 2.27.0