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=-12.8 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,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 20937C433DF for ; Wed, 12 Aug 2020 22:51:10 +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 E2E7D20771 for ; Wed, 12 Aug 2020 22:51:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="bt59q912" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E2E7D20771 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45522 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1k5zaP-0002WX-5E for qemu-devel@archiver.kernel.org; Wed, 12 Aug 2020 18:51:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39664) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k5zQb-0002Uv-Ur for qemu-devel@nongnu.org; Wed, 12 Aug 2020 18:41:01 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:64096) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k5zQZ-0005qL-On for qemu-devel@nongnu.org; Wed, 12 Aug 2020 18:41:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1597272059; x=1628808059; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fLfdAGVZEVydfLn7ls9NeU8+lR26vwCk/tcpTzXncLw=; b=bt59q912VChTP98umtQa7uMAWWqAkmSjMLbH2IfEOFFCsQlirmYroJ4a NLsuY4L6bdn3nZbzlv5KgCecJ5S9gTujaYzlXiJgA42Z7fpOnZ3M6iVEi 5hQOAp1ep7D13cHCYXfE5eAJMUi1+iXLIvsmdZNIBXWYOpBuxz22gEWUa sFVrDH3+LpDCe0yx6hxPeOnVMQjnSmtpG2jrsdXANeWyGaoleUqmDxmjf Mlyszsj/dSAQYAvdGyjEmdmfb5VFuDuadCBTC4XtbF/6YzN1wEDdhnAi4 opRWGqJJB4su02sntmu8p+4yx4CaJij2oRQms7+xdq2QilG1P3srtLbqb g==; IronPort-SDR: My93DNMqyk9zQMo7wArfDYSZPyRbUsmqaZhEY41zAlpNgA7XwYdtiI2l51SLnM8thRPmKC4T5h An47j5WGDRKSrY9BMZ7Y/z4ZNUlUQJViZmN0hc/beQCEPTDicotbJjQk1hgzDuGhckLMROddrL u1in8kYXS8orzxbN+m89MaCCJVI8Wf7JCO851LA9MP+r6jiUKochOaOMSGyFEjcugh28l9M75T RUQYUJ/Y+lBE9hlxe4IhzVgKhCHTGarytV6RY34Wf4bZfp9UrdEhzIRmk0+ceqwRQ72gF5JN07 DiM= X-IronPort-AV: E=Sophos;i="5.76,305,1592841600"; d="scan'208";a="144799066" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 13 Aug 2020 06:40:52 +0800 IronPort-SDR: +G6C3hzbPhw4Sg4xxbzb/gE0nIf5RVPR1us2645dYGmp5F58aiLyYGpsSy5F348nU/WBShzQ5m 7ApRE4UxYXFQ== Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2020 15:28:43 -0700 IronPort-SDR: VNHxcisuux5nLEu2nhgxjYKbn7am1ES35igccZ2Y7GriKDNKa4KshKZOdRCHO5uhKa47OYUzuY I39KES3AGbHw== WDCIronportException: Internal Received: from jbfyk72.ad.shared (HELO risc6-mainframe.hgst.com) ([10.86.59.14]) by uls-op-cesaip01.wdc.com with ESMTP; 12 Aug 2020 15:40:50 -0700 From: Alistair Francis To: qemu-devel@nongnu.org Subject: [PULL 17/20] target/riscv: Change the TLB page size depends on PMP entries. Date: Wed, 12 Aug 2020 15:30:42 -0700 Message-Id: <20200812223045.96803-18-alistair.francis@wdc.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200812223045.96803-1-alistair.francis@wdc.com> References: <20200812223045.96803-1-alistair.francis@wdc.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=216.71.154.42; envelope-from=prvs=486123ee4=alistair.francis@wdc.com; helo=esa4.hgst.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/12 18:40:52 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 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_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, URIBL_BLOCKED=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: Alistair Francis , Zong Li Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Zong Li 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 Reviewed-by: Alistair Francis Message-Id: <6b0bf48662ef26ab4c15381a08e78a74ebd7ca79.1595924470.git.zong.li@sifive.com> Signed-off-by: Alistair Francis --- target/riscv/pmp.h | 2 ++ target/riscv/cpu_helper.c | 10 ++++++-- target/riscv/pmp.c | 52 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h index 8e19793132..6a8f072871 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 diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 2f337e418c..fd1d373b6f 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 b14feeb7da..c394e867f8 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -383,3 +383,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 which 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; +} -- 2.27.0