From patchwork Wed Jun 26 17:48:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiang W X-Patchwork-Id: 1952743 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=JDkbVNGb; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=126.com header.i=@126.com header.a=rsa-sha256 header.s=s110527 header.b=iqvNfcJS; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4W8Tjb3Db0z214l for ; Thu, 27 Jun 2024 03:49:37 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=pb3OAc9NwyKv8BmFfoDn1kUQPo8pvqa633GKUsF91oE=; b=JDkbVNGbosNntM ucXpWnMhE1N62z+dP7DeYymO8oNSpAng56hkyswx7Z1tqcCCkwiyn7rEDMgTqa3Ytaz5ccvNBcQTC FqOUkx/e72PzzKus5A9xTcfJTYZl7q/m94QMCfk15BkuXciySwA3egyxRNOTxpL1zqErT+EBeLxhB qqSh4IxMzXVCI8nuKyiBPGccD91y9t+I4szc3r75bH/lbsSlSceJcQKzJYJweI1QbFb1r9hQutRz+ Vr7EJxb2ejCbB8KT0d0UYkziymt38/aHBzOcRAcV6pj3YGeySKWr7QqjgZfkbhJqxOCkgSg8WWsqQ odpXg3pIl6sIKZobE0fg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMWlq-00000007oZK-24Km; Wed, 26 Jun 2024 17:49:26 +0000 Received: from m16.mail.126.com ([117.135.210.8]) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMWlk-00000007oX4-2Dyp for opensbi@lists.infradead.org; Wed, 26 Jun 2024 17:49:23 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=6Z9XT JciO6WfMg20V/YiEgONhr6SIDF3hGyMnNDLDmA=; b=iqvNfcJSOfxXk8tbTMv5T hGTPlax4zdD9N2Bb02DtOfKQ6iBFnksZ0qFjSDVnyuH2TKfLljMxTGG8Z1OkomYC 5ADO/1OIqkCGvKSVAh0NqiT1jFYZhjq7QKfr9vn4amcS504PCzeasvV3T/dX7127 hdyHlmqwAOd8kMHdMWaPY8= Received: from T490.lan (unknown [112.83.183.192]) by gzga-smtp-mta-g0-1 (Coremail) with SMTP id _____wD3Hz5iVHxmnCGXAA--.57783S4; Thu, 27 Jun 2024 01:48:19 +0800 (CST) From: Xiang W To: opensbi@lists.infradead.org Cc: Xiang W , anup@brainfault.org Subject: [PATCH 2/3] lib: sbi: Introduce size to sbi_domain_memregion Date: Thu, 27 Jun 2024 01:48:13 +0800 Message-ID: <20240626174816.2837278-3-wxjstz@126.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240626174816.2837278-1-wxjstz@126.com> References: <20240626174816.2837278-1-wxjstz@126.com> MIME-Version: 1.0 X-CM-TRANSID: _____wD3Hz5iVHxmnCGXAA--.57783S4 X-Coremail-Antispam: 1Uf129KBjvJXoW3AFyfXw18GryDCF4xKFWDXFb_yoWfCr1fp3 W8tFy3Gr4Iqr4FqwnrGa1UW390kry0yF4Ykay2kw10kw18Arn8CF48Zwn09r13AFyxZa1U ur4jvrsruFsxtaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0ziHUDJUUUUU= X-Originating-IP: [112.83.183.192] X-CM-SenderInfo: pz0m23b26rjloofrz/1tbi5BUKOmVLaGIaoAAAsf X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240626_104920_943171_B548CDED X-CRM114-Status: GOOD ( 20.36 ) X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: In order to support tor type pmp, introduce size to sbi_domain_memregion. Signed-off-by: Xiang W --- include/sbi/sbi_domain.h | 37 ++++++++++++++++++ lib/sbi/sbi_domain.c | 82 ++++++++++++++++++++ lib/sbi/sbi_hart.c | 15 ++++---- 3 files changed, 85 in [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [wxjstz(at)126.com] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [117.135.210.8 listed in list.dnswl.org] 0.0 RCVD_IN_MSPIKE_L3 RBL: Low reputation (-3) [117.135.210.8 listed in bl.mailspike.net] 0.0 RCVD_IN_MSPIKE_BL Mailspike blocklisted X-BeenThere: opensbi@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "opensbi" Errors-To: opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org In order to support tor type pmp, introduce size to sbi_domain_memregion. Signed-off-by: Xiang W --- include/sbi/sbi_domain.h | 37 ++++++++++++++++++ lib/sbi/sbi_domain.c | 82 ++++++++++++++++++++-------------------- lib/sbi/sbi_hart.c | 15 ++++---- 3 files changed, 85 insertions(+), 49 deletions(-) diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h index a6e99c6..f97f62e 100644 --- a/include/sbi/sbi_domain.h +++ b/include/sbi/sbi_domain.h @@ -32,6 +32,14 @@ struct sbi_domain_memregion { * It has to be minimum 3 and maximum __riscv_xlen */ unsigned long order; + + /** + * when size is not equal to 0, order is invalid + * When the size of the memory region is not a power of 2, + * it is represented by size. + */ + unsigned long size; + /** * Base address of memory region * It must be 2^order aligned address @@ -227,6 +235,35 @@ extern struct sbi_domain *domidx_to_domain_table[]; /** Iterate over each memory region of a domain */ #define sbi_domain_for_each_memregion(__d, __r) \ for ((__r) = (__d)->regions; (__r)->order; (__r)++) +/** + * Calculate the start address of the memory region + * @param r pointer to memory region + * @return start address of the memory region + */ +static inline unsigned long memregion_start(const struct sbi_domain_memregion *r) +{ + if (r->size) + return r->base; + if (r->order < __riscv_xlen) + return r->base; + else + return 0; +} + +/** + * Calculate the end addresses of the memory region + * @param r pointer to memory region + * @return end addresses of the memory region + */ +static inline unsigned long memregion_end(const struct sbi_domain_memregion *r) +{ + if (r->size) + return r->base + r->size - 1; + if (r->order < __riscv_xlen) + return r->base + BIT(r->order) - 1; + else + return -1UL; +} /** * Check whether given HART is assigned to specified domain diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c index 374ac36..9a9fce1 100644 --- a/lib/sbi/sbi_domain.c +++ b/lib/sbi/sbi_domain.c @@ -40,6 +40,10 @@ struct sbi_domain root = { static unsigned long domain_hart_ptr_offset; +static const struct sbi_domain_memregion *find_region( + const struct sbi_domain *dom, + unsigned long addr); + struct sbi_domain *sbi_hartindex_to_domain(u32 hartindex) { struct sbi_scratch *scratch; @@ -96,6 +100,12 @@ ulong sbi_domain_get_assigned_hartmask(const struct sbi_domain *dom, return ret; } +static inline bool +in_memregion(const struct sbi_domain_memregion *r, unsigned long addr) +{ + return memregion_start(r) <= addr && addr <= memregion_end(r); +} + void sbi_domain_memregion_init(unsigned long addr, unsigned long size, unsigned long flags, @@ -120,6 +130,7 @@ void sbi_domain_memregion_init(unsigned long addr, if (reg) { reg->base = base; + reg->size = 0; reg->order = order; reg->flags = flags; } @@ -130,8 +141,8 @@ bool sbi_domain_check_addr(const struct sbi_domain *dom, unsigned long access_flags) { bool rmmio, mmio = false; - struct sbi_domain_memregion *reg; - unsigned long rstart, rend, rflags, rwx = 0, rrwx = 0; + const struct sbi_domain_memregion *reg; + unsigned long rflags, rwx = 0, rrwx = 0; if (!dom) return false; @@ -153,22 +164,18 @@ bool sbi_domain_check_addr(const struct sbi_domain *dom, if (access_flags & SBI_DOMAIN_MMIO) mmio = true; - sbi_domain_for_each_memregion(dom, reg) { + reg = find_region(dom, addr); + if (reg) { rflags = reg->flags; rrwx = (mode == PRV_M ? (rflags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK) : (rflags & SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK) >> SBI_DOMAIN_MEMREGION_SU_ACCESS_SHIFT); - rstart = reg->base; - rend = (reg->order < __riscv_xlen) ? - rstart + ((1UL << reg->order) - 1) : -1UL; - if (rstart <= addr && addr <= rend) { - rmmio = (rflags & SBI_DOMAIN_MEMREGION_MMIO) ? true : false; - if (mmio != rmmio) - return false; - return ((rrwx & rwx) == rwx) ? true : false; - } + rmmio = (rflags & SBI_DOMAIN_MEMREGION_MMIO) ? true : false; + if (mmio != rmmio) + return false; + return ((rrwx & rwx) == rwx) ? true : false; } return (mode == PRV_M) ? true : false; @@ -177,6 +184,9 @@ bool sbi_domain_check_addr(const struct sbi_domain *dom, /* Check if region complies with constraints */ static bool is_region_valid(const struct sbi_domain_memregion *reg) { + if (reg->size) + return sbi_popcount(reg->size) > 2 ? true : false; + if (reg->order < 3 || __riscv_xlen < reg->order) return false; @@ -193,18 +203,9 @@ static bool is_region_valid(const struct sbi_domain_memregion *reg) static bool is_region_subset(const struct sbi_domain_memregion *regA, const struct sbi_domain_memregion *regB) { - ulong regA_start = regA->base; - ulong regA_end = regA->base + (BIT(regA->order) - 1); - ulong regB_start = regB->base; - ulong regB_end = regB->base + (BIT(regB->order) - 1); - - if ((regB_start <= regA_start) && - (regA_start < regB_end) && - (regB_start < regA_end) && - (regA_end <= regB_end)) - return true; - - return false; + ulong regA_start = memregion_start(regA); + ulong regA_end = memregion_end(regA); + return in_memregion(regB, regA_start) && in_memregion(regB, regA_end); } /** Check if regionA can be replaced by regionB */ @@ -221,10 +222,12 @@ static bool is_region_compatible(const struct sbi_domain_memregion *regA, static bool is_region_before(const struct sbi_domain_memregion *regA, const struct sbi_domain_memregion *regB) { - if (regA->order < regB->order) + unsigned long regA_s = memregion_end(regA) - memregion_start(regA); + unsigned long regB_s = memregion_end(regB) - memregion_start(regB); + if (regA_s < regB_s) return true; - if ((regA->order == regB->order) && + if ((regA_s == regB_s) && (regA->base < regB->base)) return true; @@ -235,14 +238,10 @@ static const struct sbi_domain_memregion *find_region( const struct sbi_domain *dom, unsigned long addr) { - unsigned long rstart, rend; struct sbi_domain_memregion *reg; sbi_domain_for_each_memregion(dom, reg) { - rstart = reg->base; - rend = (reg->order < __riscv_xlen) ? - rstart + ((1UL << reg->order) - 1) : -1UL; - if (rstart <= addr && addr <= rend) + if (in_memregion(reg, addr)) return reg; } @@ -262,7 +261,8 @@ static const struct sbi_domain_memregion *find_next_subset_region( continue; if (!ret || (sreg->base < ret->base) || - ((sreg->base == ret->base) && (sreg->order < ret->order))) + ((sreg->base == ret->base) && + (memregion_end(sreg) < memregion_end(ret)))) ret = sreg; } @@ -314,8 +314,8 @@ static int sanitize_domain(struct sbi_domain *dom) sbi_domain_for_each_memregion(dom, reg) { if (!is_region_valid(reg)) { sbi_printf("%s: %s has invalid region base=0x%lx " - "order=%lu flags=0x%lx\n", __func__, - dom->name, reg->base, reg->order, + "order=%lu size=%lu flags=0x%lx\n", __func__, + dom->name, reg->base, reg->order, reg->size, reg->flags); return SBI_EINVAL; } @@ -423,10 +423,11 @@ bool sbi_domain_check_addr_range(const struct sbi_domain *dom, sreg = find_next_subset_region(dom, reg, addr); if (sreg) addr = sreg->base; - else if (reg->order < __riscv_xlen) - addr = reg->base + (1UL << reg->order); - else - break; + else { + addr = memregion_end(reg) + 1; + if (addr == 0) + break; + } } return true; @@ -455,9 +456,8 @@ void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix) i = 0; sbi_domain_for_each_memregion(dom, reg) { - rstart = reg->base; - rend = (reg->order < __riscv_xlen) ? - rstart + ((1UL << reg->order) - 1) : -1UL; + rstart = memregion_start(reg); + rend = memregion_end(reg); sbi_printf("Domain%d Region%02d %s: 0x%" PRILX "-0x%" PRILX " ", dom->index, i, suffix, rstart, rend); diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index acf0926..982e77a 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -355,10 +355,9 @@ static void sbi_hart_smepmp_set(struct sbi_scratch *scratch, unsigned long pmp_addr_max) { unsigned long pmp_addr = reg->base >> PMP_SHIFT; - unsigned long start = reg->base; - unsigned long end = reg->order < __riscv_xlen ? - start + BIT(reg->order) - 1: -1UL; - if (pmp_log2gran <= reg->order && pmp_addr < pmp_addr_max) + unsigned long start = memregion_start(reg); + unsigned long end = memregion_end(reg); + if ((1 << pmp_log2gran) - 1 <= end - start && pmp_addr < pmp_addr_max) pmp_set(pmp_idx, pmp_flags, start, end); else { sbi_printf("Can not configure pmp for domain %s because" @@ -475,10 +474,10 @@ static int sbi_hart_oldpmp_configure(struct sbi_scratch *scratch, pmp_flags |= PMP_X; pmp_addr = reg->base >> PMP_SHIFT; - start = reg->base; - end = reg->order < __riscv_xlen ? - start + BIT(reg->order) - 1 : -1UL; - if (pmp_log2gran <= reg->order && pmp_addr < pmp_addr_max) { + start = memregion_start(reg); + end = memregion_end(reg); + if ((1 << pmp_log2gran) - 1 <= end - start && + pmp_addr < pmp_addr_max) { pmp_set(&pmp_idx, pmp_flags, start, end); } else { sbi_printf("Can not configure pmp for domain %s because"