From patchwork Mon Aug 24 02:09:49 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Pathak X-Patchwork-Id: 2290630 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=HenpiWQD; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=juduqZFM; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.a=rsa-sha256 header.s=google header.b=VfF2YUkV; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) 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 4hSvWj3Cf0z1xwG for ; Mon, 24 Aug 2026 12:10:25 +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=07Bfm63Y7qvc1jT/VwItRm39URia7ym2os98eYZXcTA=; b=HenpiWQDKEWKZq 6YbgaEfOcLSKzYDzW8Mw+Yj6T54Tusuf3aOCLJOCwqqreCR5mfTPVc61NYmWSHFo/PSo48/82rUDR aC30sw8U8oIu2UX8N0rITk7svyUxl3HLgsuSR34dnA+mXiublH9K9OvYXkb+tttT0bI9khAGhhaW1 KUYnW3wTLEPpcwdBTbWbIO058nhz8kU/H/VxdfqYNtjOuuwzTQE7pDQtFE9euyvlejq3ObnJ5JBBK xFKSfOzcdEXS3ED58p8ElHIKVku3/vg7tbJ7GWHlQqrxRn7YhGq0WTN6C/xM32MXwGTHQ0jV+LzBw baYnEbEZj/80aWZfvppw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wyK8b-0000000Fkwx-0fEg; Mon, 24 Aug 2026 02:10:13 +0000 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wyK8X-0000000Fkvx-3Ibs for opensbi@lists.infradead.org; Mon, 24 Aug 2026 02:10:11 +0000 Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67O0kg9p1461855 for ; Mon, 24 Aug 2026 02:10:08 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=YYxqXZNsDxb e9ha5BCrzluYoDjgRy8xJ59jC3amvL4M=; b=juduqZFM1R8Gb26k26+O7xTs7DK kVBHz8YRIW+Xx09Zg3dfOFHtqnEksl+SWkb/9JWSkjMbxwAtSMu1yoVDUhqdKVvV 9gzmBoGSWF8D+N2ldErc7CrIpV+nLWkCWLsAJiCHIWQiO10kA5zCgn1VmWHzNPux JGcrUDvHA8POVJ3UEvyRFklNyuTYoowzw9cyR9GtT5UH1xjMru21Tx8NF2iqw+A8 rwJFZff/EvvlRhw9uFA/JyLzpn1xYr9tWgGMD9vhIJj4+twp9d2oTJbnOvFVu3Be 4VECC2BaRcX/0Xy6CugrJqtGCIrP9mS/EmhlEr9DciHt/2kWeQsCNlatw8A== Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g8bdr06jj-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 24 Aug 2026 02:10:08 +0000 (GMT) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-2d04908139bso40603875ad.2 for ; Sun, 23 Aug 2026 19:10:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787537408; x=1788142208; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=YYxqXZNsDxbe9ha5BCrzluYoDjgRy8xJ59jC3amvL4M=; b=VfF2YUkVgbEpfRJo8Tz2EdtPAFtSEs792eXKWZxbBCOVJ43yB/4iTc1KJGH6N9Qn1b bOIMStmV+aMFtmQ5njYed9gMIhrAsXikN5Kb6t0zkE0s+2PWTItAcFxhFVBtVKwki81K j/spTz08SA5KVw7xbAdHoF/5gIY5Z9Wwh5flywOlq1OIjnS05SEenk6gBUU5pll08Fxr J1a4iJxH9fmcrBpP4Ea8YGIWDqAUgPbB83KWFBHAmGHIUfniiCqvp2BaHIpIjNJ6Udcj kqO4XES0GYU8kErJIdl25+xnb4A23k+lf1FnP3WAZgcX0TCM66fNAks5hBr73c2Xa0uk de0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787537408; x=1788142208; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=YYxqXZNsDxbe9ha5BCrzluYoDjgRy8xJ59jC3amvL4M=; b=oau1SieldEiqnx4EXrSywgLy+6W3R4SR8vAI5nu4YHHpg0RBrXICGnCmYOgJ6T9Ubv 7ySTM6RBkdh27jZsvQOk7+HBVtrFoS3BNW2Guc2VZnMSiiLudCy3L7ROKNzE+wMGZ/rI N/OZU7CSyyJeKh+kfIVeXiKn61t7nOVe6Hl6gOEbgxlS/LuIw0/UxyKWx5w49jegPyOC Gt+vN75BjUADt15aP6FZWjI0UK49k0fSDNAqPI6V8BCarmH14dhI48DtfERqjrA06ofS Fd3JvL6gp7Kb/Id9ZtzB4xjhuxeWLxT+dSuSTHwqWvgPzyQZkmblzcJkimJTHoOtXs/t d0xA== X-Gm-Message-State: AFuF++m9WKZrYK3rJFQaQ3a9XsC+LIemO2NW4BSuZah34sLyDEIx7Nfw qzODu+wfr4QhM8ClndACd0CuVppawt6b2jNlL2hP08wfUqMdzmI/rJ36gOHcAJtlO1HGExGPKH3 U1U4hnMCdIwKRvTe8wdS2im7/O+zZdptDIwgQHZyN9X7RftoxpFXswc+FtX/7wH6r0nke4ugmrQ == X-Gm-Gg: AR+sD12I9Zxf5ZTjhkj9cASEJ1jMBv1axYPXrjJujPKqK+sDSL6q1tiAXGnMwtMkyUo w6x73iMIonzZZTqpO+XOwja1dOqScWKEqPov8S+4MV/XORZJ0IYFHjc7p6o6juL+xKi2cVDeY/y xVidV9E6JEZRjUzZFllDY2XJxb49/zbs1YZ98yyYvKgTfzw3SRFSKh0VhhEJZCxr9r3wQiR6dxC +T5dvBDyIPkOSnNaNTQG56jtGgwiQSoY8niGN/obLnU+UPZb+VPBEPJCT1BkUMWe9FDqy5YjR9O W6tV5papR74JJU8eb6jOaJC9YgzspIdl7h9oXicEmS7Y5BbKeJICWu8YF/ZXmA3EmwzBXB9Me1+ SezY+PSqCchdY/ueSOZekqTHOj0fsCB6vat/QkXtFVirOhnkvwbbWoTh6h7XremhrHPvg7h6EBi HHDR8uw+WeRAZ0HWnnCAZ7 X-Received: by 2002:a17:902:f78f:b0:2c9:9a2e:dab0 with SMTP id d9443c01a7336-2d64ad92e17mr421640715ad.3.1787537407661; Sun, 23 Aug 2026 19:10:07 -0700 (PDT) X-Received: by 2002:a17:902:f78f:b0:2c9:9a2e:dab0 with SMTP id d9443c01a7336-2d64ad92e17mr421639585ad.3.1787537407154; Sun, 23 Aug 2026 19:10:07 -0700 (PDT) Received: from hu-rahupath-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-327f92359c9sm20487634eec.27.2026.08.23.19.10.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2026 19:10:06 -0700 (PDT) From: Rahul Pathak To: opensbi@lists.infradead.org Cc: rahul.pathak@oss.qualcomm, rahul@summations.net, Rahul Pathak Subject: [RFC PATCH v4 1/4] lib: sbi_domain: Add finalize callback for per-domain state Date: Mon, 24 Aug 2026 07:39:49 +0530 Message-ID: <20260824020953.2438946-2-rahul.pathak@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260824020953.2438946-1-rahul.pathak@oss.qualcomm.com> References: <20260824020953.2438946-1-rahul.pathak@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI0MDAxNyBTYWx0ZWRfXxBgnWuasKfPl 5vun3mumxe3Q+1NihD7fj20F9JvuKgYXsoXBs4vjB9GLGXmJyXe7jPeR1QvMZKS4Fi9TVD579qU Fb2YW0pPPqobVtf2dXI9p0qM/Otzh4RszCBk8Mmf1Kbd8OHxrQ26+jQThEJwJvuoRgJMpzSgeSm 3lIAfcbn44tUY3/gJlUXb7bAiULhHOWx2oDUUWMbLke8Ew+VgEbzFkS62CNPopYdARYvFfAMObR 5tp5a3VjwfB6q99kfD9lupyC9OTEoHB+HpxYZ7/2nKXT+aPjtynrInEuN7rRBv8RdALf7XS4mcf sLASn9sR4zCU4ahOnw6JnV+Z2/Q5nsrI6APg+Q1Fu8grbEjoTg3Z0RggSDGwTBJSLiBplQm3P+X jqMKbxxWEi9qSBx6YEdwVVkeV+rE8yS1o3HpEpcWVfaXR7LzDPiZ/foEjRUv6Jo4aeknKQ0Azum Vt2eY6qzINmLxqKzpzg== X-Proofpoint-GUID: TmHmHXRpQ6Io_GBbVXkSEnK1yASQD_a- X-Proofpoint-ORIG-GUID: TmHmHXRpQ6Io_GBbVXkSEnK1yASQD_a- X-Proofpoint-Spam-Info: AW1haW4tMjYwODI0MDAxNyBTYWx0ZWRfX12zERfmo0VwA y4QMlk8NwmptfuJxxDwp00vVP6dLzg5vV0FRvhPw07OlIGF6tGMN8QGqbW9RaXh8ioaKGQIs68C 0G0bdFp0WR6iGsbaZIDUdvONqytvwE0= X-Authority-Analysis: v=2.4 cv=W8cIkxWk c=1 sm=1 tr=0 ts=6a8ba800 cx=c_pps a=IZJwPbhc+fLeJZngyXXI0A==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=A3s7GLJBcYfuUOYuCAAA:9 a=uG9DUKGECoFWVXl0Dc02:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-24_01,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 suspectscore=0 lowpriorityscore=0 spamscore=0 priorityscore=1501 clxscore=1015 bulkscore=0 malwarescore=0 adultscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608240017 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260823_191009_968691_71E43030 X-CRM114-Status: GOOD ( 18.45 ) X-Spam-Score: -2.8 (--) 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: Per-domain state is registered via sbi_domain_state in state_setup() but during that time the domain memory regions are not final. Add optional state_finalize() callback which is called from sbi_domai [...] Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, low trust [205.220.180.131 listed in list.dnswl.org] -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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -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 -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.0 DMARC_PASS DMARC pass policy 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 Per-domain state is registered via sbi_domain_state in state_setup() but during that time the domain memory regions are not final. Add optional state_finalize() callback which is called from sbi_domain_finalize for each domain after all domains are registered and their memory regions are final. Signed-off-by: Rahul Pathak --- include/sbi/sbi_domain_state.h | 22 ++++++++++++++++++++++ lib/sbi/sbi_domain.c | 16 ++++++++++++++++ lib/sbi/sbi_domain_state.c | 25 +++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/include/sbi/sbi_domain_state.h b/include/sbi/sbi_domain_state.h index 72030380..6528a95b 100644 --- a/include/sbi/sbi_domain_state.h +++ b/include/sbi/sbi_domain_state.h @@ -40,6 +40,18 @@ struct sbi_domain_state { /** Optional callback to setup domain state */ int (*state_setup)(struct sbi_domain *dom, struct sbi_domain_state *state, void *state_ptr); + /** + * Optional callback to finalize domain state + * + * Called for each domain from sbi_domain_finalize() after all + * domains are registered and memory regions are final. + * + * State from the domain memory regions must be setup here instead + * of state_setup() + */ + int (*state_finalize)(struct sbi_domain *dom, + struct sbi_domain_state *state, void *state_ptr); + /** Optional callback to cleanup domain state */ void (*state_cleanup)(struct sbi_domain *dom, struct sbi_domain_state *state, void *state_ptr); @@ -64,6 +76,16 @@ void *sbi_domain_state_ptr(struct sbi_domain *dom, struct sbi_domain_state *stat */ int sbi_domain_setup_state(struct sbi_domain *dom); +/** + * Finalize all domain state for a domain + * @param dom pointer to domain + * + * @return 0 on success and negative error code on failure + * + * Note: This function is used internally within domain framework. + */ +int sbi_domain_finalize_state(struct sbi_domain *dom); + /** * Cleanup all domain state for a domain * @param dom pointer to domain diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c index 79d61c54..aa85d736 100644 --- a/lib/sbi/sbi_domain.c +++ b/lib/sbi/sbi_domain.c @@ -845,6 +845,7 @@ int sbi_domain_startup(struct sbi_scratch *scratch, u32 cold_hartid) int sbi_domain_finalize(struct sbi_scratch *scratch) { int rc; + struct sbi_domain *dom; const struct sbi_platform *plat = sbi_platform_ptr(scratch); /* Sanity checks */ @@ -865,6 +866,21 @@ int sbi_domain_finalize(struct sbi_scratch *scratch) */ domain_finalized = true; + /* + * Finalize per-domain state of each domain. Now all domains + * are finalized already and their memory regions are final. + * State which is derived from the domain memory regions is + * set up below. + */ + sbi_domain_for_each(dom) { + rc = sbi_domain_finalize_state(dom); + if (rc) { + sbi_printf("%s: domain state finalize failed for %s" + " (error %d)\n", __func__, dom->name, rc); + return rc; + } + } + return 0; } diff --git a/lib/sbi/sbi_domain_state.c b/lib/sbi/sbi_domain_state.c index 2d1f30e3..f8ccab69 100644 --- a/lib/sbi/sbi_domain_state.c +++ b/lib/sbi/sbi_domain_state.c @@ -84,6 +84,31 @@ int sbi_domain_setup_state(struct sbi_domain *dom) return 0; } +int sbi_domain_finalize_state(struct sbi_domain *dom) +{ + struct sbi_domain_state *state; + void *state_ptr; + int rc; + + if (!dom) + return SBI_EINVAL; + + sbi_list_for_each_entry(state, &state_list, head) { + if (!state->state_finalize) + continue; + + state_ptr = sbi_domain_state_ptr(dom, state); + if (!state_ptr) + continue; + + rc = state->state_finalize(dom, state, state_ptr); + if (rc) + return rc; + } + + return 0; +} + void sbi_domain_cleanup_state(struct sbi_domain *dom) { struct sbi_domain_state *state; From patchwork Mon Aug 24 02:09:50 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Pathak X-Patchwork-Id: 2290632 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=YmpJGGz6; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=pVRqzg1t; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.a=rsa-sha256 header.s=google header.b=dITMfYsp; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) 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 4hSvWl0Zkhz1xwG for ; Mon, 24 Aug 2026 12:10:27 +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=Ui5RjWTUK5CMvRsBH41oE02T07EFzc71wdPZcqQwJwk=; b=YmpJGGz6DdXEly hjwMc1MRVBDJ8EWn2k6zRVsPleu04ZazUDXCaEAWluVSrup4FMQrtzqeVTRVv5uacsyQE9h1fJ54Q rlcR8+ZeNDHtMZP4UeId73kgYVNn8XbiIy+u1Gl4m9bFiQQxYyavBXwIK/R5dTyBKla14/OaG6Di0 aCVhHq2BOR4Q18KV8yhn2l5iJLSimv1H6h0h8IIpTGG8VYdsirN99HKKHGLvePFVVBVz1Lso14Y53 zugqF+Hw56TAfcpCgssjBORuJ1MeDmF86+qZ6/SbnHmQBrWkOonUeXYn7Ro8Qz9KkZyNuPe7OeBdc 844IEkPbN9lwSXrI/G6A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wyK8c-0000000FkxG-1ZVM; Mon, 24 Aug 2026 02:10:14 +0000 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wyK8a-0000000Fkwi-2cTP for opensbi@lists.infradead.org; Mon, 24 Aug 2026 02:10:13 +0000 Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67O0lApX982804 for ; Mon, 24 Aug 2026 02:10:11 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=YfwoPexlS52 rGZ9wcU+VHbQeAUjVL1bmhsl4MVGqwv0=; b=pVRqzg1t5jw4MkuHBuU8XM4SOjP TTC4/h+U4bIc4JJ3uqbskwcK9sv3XIYdgc/kvjvsxYnwWuJB+t2MDqgEGs6IeKrI h5tRn0NW5OtNN34lyqsQpswSrup2jvv4JBriFA+XJ9TvA8FrViVxZumWLwr2X79O z00fg/6SdbBTIhsDDBpgVIa5gBYDl2FVWwmnsbqunKc/Wd97CsC+H7kOoCg5mAfx Ok6CKJtFz0DsTp2ikYHFAu/2otdAkx0oxspoSF1NQOA/OcdhTgCUlzYv64Our20U WEXCAGO98+SZAZPpmB2vOhNEObzZ1M4l+8mHPocv3wf9Aam+IeP9V+3kffA== Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g7456w2dx-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 24 Aug 2026 02:10:11 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-38f97b3f853so4569306a91.3 for ; Sun, 23 Aug 2026 19:10:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787537411; x=1788142211; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=YfwoPexlS52rGZ9wcU+VHbQeAUjVL1bmhsl4MVGqwv0=; b=dITMfYspcnyQWkeg0eZsaMLcKDH97HB8VzM4E1GU7cKZ7JlVjo7WauUm9b48xZ7yPE Mi3qgTHrkR9d3aeWeGBNdtwhQ5+L7z6/khdg7Dn5H/9gZRoLaoIa9/rAxu7XTSYrcv6r ei5HNjcWYWelIwr9vQtP5ZsAMDDi1oXxZZVOI0TldHcIcavM17qfwXud37Ea0Vufkjgr /7Qt4l1PBfm52uKOylKgovwz47EEjhpgDAlw4J3pRJEmwFuRpynoh4qtOZ+4dDhBSGmf pi7ntxYuj9jcm0sK7JfFXZNmpHDoCnuHVRZGYY4ZCbuj64aYRiIq0c6V4RJVo3gQtys2 V0RQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787537411; x=1788142211; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=YfwoPexlS52rGZ9wcU+VHbQeAUjVL1bmhsl4MVGqwv0=; b=BNWI92AorHXCqoDqBZIJOhQ+4nDNmRets4y3ZY0AkTXVTRof9PUR/B5nqz5cAhZSks 8AoRtLYEQbHfG3HqmWgk/MPFzGk6I4+qTogTk3wK44pEmGDEjyb3ZzxNeMHoRvETl8VF /pJejdRjat9i7AIwUFdRzSx1EMjuuWoQxwMUJaNibo8HQLSw8ziM5gBpfZOtwOHLUYyp HTPWS3sE+r47vK6xlph+i3Z/l5QUeE85c/Jb9BE9rvV9VChvPsCUHoJMonNVpv1pIlaU rT1UdWFRVsuOjZGKZj7kghegR36oLQFwDxW0xUmUdvmHMM6VSULjTkXfyzcdv/f3+8Y/ cUYg== X-Gm-Message-State: AFuF++muWrXBWKlD0C/Y8T4cyc1JPWINj+UPyrEkg9z+MCroGs78RK8a FzFwt1Y8cOJu1ZU13g4O7tUnSw6sNGOGWmSbDobacdgUsJNbm4A3x9OqaYEaXmT3D5MrHGmOpUc mbYbWukjF54WTW6chqS3KiarWnh+Eu4YsRrOd3AmTxt3ymYbyc8w+6O41r1K/vhWMjqo1PLUwig == X-Gm-Gg: AR+sD12u0Y+6yUrXZ6rzv0wnabG0VPGr+fyIUAIpc0OsEoyxNrb5xbi4/1E0X8/fdxJ PmLK7TgisvdFLjI0E4PzoJmFKAmuaThsv893qCeCCJZgu5TSO6f5vVzjFrNyznN5XDkxWmK8KHF vGBN1wLM3+2cKqIlXQDTDxeNXlYuUvuHyblC2VPZs9zM6Lpdb7s/yTt0BEIUo+717pdyXEmk51x gFQgUtqDWm5WZv5Lfudp96mDFSxNG6tRWFsw4y2/Mk36UO7LcqAAMr921AAidGHvlYq5G2nTWKE R6Ou535NMchlcgLu7KrhXiOGNrNT7w7hVRa2Sn/AzPNl+iLEtT4V6k33+sMFmoTwFT8++bUSnEN T88QKE7BtV2Fdyp9w3ydCA+mKNJjRyMgRs3I5UToaeUgVuVMNYGskhkVhGXcK2JcXnyzufN8zQA cv36UZGTXVDEIiE7cKS1RT X-Received: by 2002:a17:90b:58cf:b0:37f:eafd:3505 with SMTP id 98e67ed59e1d1-395deec0e5amr28463579a91.6.1787537410667; Sun, 23 Aug 2026 19:10:10 -0700 (PDT) X-Received: by 2002:a17:90b:58cf:b0:37f:eafd:3505 with SMTP id 98e67ed59e1d1-395deec0e5amr28463472a91.6.1787537410193; Sun, 23 Aug 2026 19:10:10 -0700 (PDT) Received: from hu-rahupath-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-327f92359c9sm20487634eec.27.2026.08.23.19.10.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2026 19:10:09 -0700 (PDT) From: Rahul Pathak To: opensbi@lists.infradead.org Cc: rahul.pathak@oss.qualcomm, rahul@summations.net, Rahul Pathak , Pawandeep Oza , Ranbir Singh Subject: [RFC PATCH v4 2/4] riscv: Add Smsdid and Smmpt hart extensions Date: Mon, 24 Aug 2026 07:39:50 +0530 Message-ID: <20260824020953.2438946-3-rahul.pathak@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260824020953.2438946-1-rahul.pathak@oss.qualcomm.com> References: <20260824020953.2438946-1-rahul.pathak@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-Spam-Info: AW1haW4tMjYwODI0MDAxNyBTYWx0ZWRfX6CzjS/1EO4oU S+pbWSpUh+CIM7tm2C9WY4xeXlhr+jpoFmHISde1bjxOxdGdLjclby+Udtv0hfookiY80AkGz1H Tqk9YcIa5liilTs+S3cyl4JY6sWAb1s= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI0MDAxNyBTYWx0ZWRfXz8Gr+nnwUB6k lDiD1hTjraCOZUOT+7+QO0Zupx8qJOj4D5pXHBfQNW2SJB0q0Ud0lFFNIaRgC8nYNb3YPzAHyVZ Xye4TAc7lPEXt5qrl1R30zbjGHgAJC9CIrbWy/TLeCDCbJcu79mFDFTVbwR8u3Ulus6144dgywn AOMyLPCvs19xGmYGBySNwGQaVsHvxnDasnCQGDtzA8iszMIGXKCtBId865xYaxb0rFRpKziyZSq BgB+SigsldEgIavsIA56NA60Vj+zY9f4wyfTaVHh7Y7193Ni0FvxmoPdf8J/ge2eqBw89f2UvuY V3jgr+irkVgiQMCAQgCvtwQ6ePz/5hF7cICc24W3fYpDP3sc988PqJvzN8zrf3UVljQ3AC9BQMp OojJf+TPzcWX+bwfRPWQ0YXH9/BGlD8mrTyOiQ3zEedXUcIJlaBUbZosw0Nmn+o9PmcsRqU2hlj JbsO7BRiffa/+nxbzDQ== X-Authority-Analysis: v=2.4 cv=RtL16imK c=1 sm=1 tr=0 ts=6a8ba803 cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yx91gb_oNiZeI1HMLzn7:22 a=EUspDBNiAAAA:8 a=F7PIS_qpXq7oc_onYicA:9 a=mQ_c8vxmzFEMiUWkPHU9:22 X-Proofpoint-ORIG-GUID: XVO1hluMxAiKR1A-eiq2ICsYfAj1cTMe X-Proofpoint-GUID: XVO1hluMxAiKR1A-eiq2ICsYfAj1cTMe X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-24_01,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 adultscore=0 malwarescore=0 phishscore=0 impostorscore=0 priorityscore=1501 suspectscore=0 bulkscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608240017 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260823_191012_787469_458AA049 X-CRM114-Status: GOOD ( 11.12 ) X-Spam-Score: -2.8 (--) 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: Add hart extension identifiers for the RISC-V Smsdid (supervisor domain ID) and Smmpt (supervisor domain memory protection) extensions. Signed-off-by: Rahul Pathak Reviewed-by: Pawandeep Oza Reviewed-by: Ranbir Singh --- include/sbi/sbi_ha [...] Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, low trust [205.220.180.131 listed in list.dnswl.org] -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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -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 -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.0 DMARC_PASS DMARC pass policy 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 Add hart extension identifiers for the RISC-V Smsdid (supervisor domain ID) and Smmpt (supervisor domain memory protection) extensions. Signed-off-by: Rahul Pathak Reviewed-by: Pawandeep Oza Reviewed-by: Ranbir Singh --- include/sbi/sbi_hart.h | 4 ++++ lib/sbi/sbi_hart.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h index 543393bb..cbad94d4 100644 --- a/include/sbi/sbi_hart.h +++ b/include/sbi/sbi_hart.h @@ -95,6 +95,10 @@ enum sbi_hart_extensions { SBI_HART_EXT_F, /** Hart has D extension */ SBI_HART_EXT_D, + /** Hart has SMMTT - SMSDID extension */ + SBI_HART_EXT_SMSDID, + /** Hart has SMMTT - SMMPT extension */ + SBI_HART_EXT_SMMPT, /** Maximum index of Hart extension */ SBI_HART_EXT_MAX, diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index bee88557..4261fea8 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -360,6 +360,8 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = { __SBI_HART_EXT_DATA(v, SBI_HART_EXT_V), __SBI_HART_EXT_DATA(f, SBI_HART_EXT_F), __SBI_HART_EXT_DATA(d, SBI_HART_EXT_D), + __SBI_HART_EXT_DATA(smsdid, SBI_HART_EXT_SMSDID), + __SBI_HART_EXT_DATA(smmpt, SBI_HART_EXT_SMMPT), }; _Static_assert(SBI_HART_EXT_MAX == array_size(sbi_hart_ext), From patchwork Mon Aug 24 02:09:51 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Rahul Pathak X-Patchwork-Id: 2290633 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=0Sk1B4ZN; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=c47mKYwp; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.a=rsa-sha256 header.s=google header.b=L8u9wHx3; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) 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 4hSvWt4DS1z1xwG for ; Mon, 24 Aug 2026 12:10:34 +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=JT/rJ8GvEH51W9WamOEJB4GM5fGjS/clv3c9Hs3TA8s=; b=0Sk1B4ZN6gU4O6 Q2aZa6zuQ4ext7Eo0yniVM94fEDXiscxLWlK5lW6lC9YjOFYDsfRVrNzfm/zbBpJI+5mBjaOCrylK f2m4DFeghJLkVIz3PMYzIW3IwZ5hZ/RRm/nF4nv29SDVm3nPmpOVJpeGRvmPJ7yT6ZoNP8EGz1vsL t/IhVaZ72nPqA8vwqriEr+2SVJOuSWKIUgNyHrvs5o/EHkXKmTosmzmGHY5d0KceTuy+pQFS1O7Hl c6GzF+rnhLJHthWO6y/ZbNB08/3fGlOXgt7WN9tuZPAiID1DQfyJk18u1xQjkfOk6RsccxfR6zwhQ 1EpKBlz5SglupN5P567Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wyK8n-0000000Fkza-2G1S; Mon, 24 Aug 2026 02:10:25 +0000 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wyK8f-0000000Fky9-2dH1 for opensbi@lists.infradead.org; Mon, 24 Aug 2026 02:10:24 +0000 Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67O0ki5d2471624 for ; Mon, 24 Aug 2026 02:10:17 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= BmeVuLp6hf/2uHNVOOHynsP+FoOMkjJis6bibtQ/53M=; b=c47mKYwpBCKHIg82 MjdBhtK7GDWeGNso5vd32s5PEk8INxsx04EcETrfUKYLVjmIxLmbm/0J1B4pD60j FFCBx7fl+MmZAwca8AUXCYzYPZMfmYlF4jmtky7KfnSF//GKtHDRp1dGbDzIdUG1 hn2siiVRBQmIhDmEqA84RCtxHn5bYI6epveYGl/a+6kkuW/M0UYDoGhL2FNlHMIn 77Qg0yg8JhanJm6UuhRCJJNccjfuZbfjr/6F5u1YLQ8ms+21rh5ii1BKKX3a8tbt A+piwTIlGhU0Iit3foB9CRh7BRCon7XVnSarUh15Jupck5ZTT99+pPoeCoHkA6+f EEh4gA== Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g88jpgesu-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 24 Aug 2026 02:10:16 +0000 (GMT) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-38e6d253330so3064883a91.1 for ; Sun, 23 Aug 2026 19:10:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787537416; x=1788142216; darn=lists.infradead.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=BmeVuLp6hf/2uHNVOOHynsP+FoOMkjJis6bibtQ/53M=; b=L8u9wHx3MB2V2s3txvIW7j5hbFQktGSLHqqlVVAREipv60rxDXPqePOouHPjOBqRL+ wKxjh0G0WctN9v8Rm8a4oNlWiapPVtQbU1SXN3AHZu9dTdF1O0aM674hLqkJ6+WMjHU6 UmNnIMcIKGq/F4+9zoc/MiMaZM91ujRprl/fa5rDt1Kd4/dbuCsM9HdwSDWHCRUY6fli JeHXTdrSLIQa4kclHYGu4OwL2kXO9NRwcMsYm0mqtW8BW2tGqlRgPoDeXq2UnRgOQFpi Yet9QyvOFsXJHCSOz/k2aALPSPaeJI6Mfaarw+JbW1mxtrTGJ1lbCNrl1uH+Z1M20mNp BGjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787537416; x=1788142216; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=BmeVuLp6hf/2uHNVOOHynsP+FoOMkjJis6bibtQ/53M=; b=CpQ8tTFbGFDV+CTfbXVciIPdqwhNbPdWg2i8n9EwEWzR1zoMOFkI352V9ebJp9DTn+ KUUTHYmpI5/P/x5b2KAV93CCzMGLmk7spxXkWgUUvMTIEP0qvltV11b1cw3mK+aPrqk0 +fzX3/KjIRqA3mcbwJRbUvRL9jyOv4+MxuFrWbyj0P4yVIWWKocPbFyrY88E4jhwxQso htTCy1M0Hu1Q62Ijqeoy0vf1tfIcyuwIzZI5iMKlW6eD025mQYLzhamkVrSZs8/2EmO4 uljqKqJqvwKZhc6+zGX7WkhnvUyu2PGnIbKjUsqxwfFFED4zQNbeWtXYSsGZc3l1nRTJ bseQ== X-Gm-Message-State: AFuF++kpu1jRyQpNXqpoBAMwIUlwiOKGNbwCOAy7gpHiJROuYJMBB9TL feOhyQQpJ20bGPOpIzFoMq+QpPD9SGn7rW+iAvLZn3MOEQ4obllpk8XND3slzrzOIi0q2JSns6H YRalanfZrMPEWj+i8DfCRRzyTfC5O3kTAPlEeOHEwO2brJqMJFQTiOpm9jnN9j2EqaiH2JJPJog == X-Gm-Gg: AR+sD121Ru/s3l9W7SmTn13+HtfAM69DnWuCT4bbMZm3YRXMsfMYvkise0NypPENtaF SoUvhnCLUg3yk4NvEwkqTbacTfJxIRt9k8yp70/e1HkiUB5+8/Rewx9JD1LgeVJ5uZbtJlpi1H4 n6o36spe8AfLBC4bB/tK9r5zQpYsrY1vZCw2PRWoT0Sr74FDdsCgxqFtUN1ANXc32aEqUJquqqj 1i3bvFmSmO5bMkpPY7ZkasOG+kydH1j/81ULwEB6eOnZvL2sRW7eAwKzPql35MxZ3I0DRwxED7A sRB9BZ4n1kVm0Gj5LtbKRngT63D8aTmK5hD7AfxNAE+cZiNKZWN4WskyjSrF+IwSyoRkamRYrag hNLAXk5VI9CWj+DBX9e5H4QYsnB8lmzFTm98Y/5wveOUhNh0i5nRu+6pY76i7a5X0NUd0/dtoY6 sWd51veHILhDtfnJ2cysFN X-Received: by 2002:a17:90b:388d:b0:387:d9cc:7dc3 with SMTP id 98e67ed59e1d1-395a074a348mr38506215a91.21.1787537414883; Sun, 23 Aug 2026 19:10:14 -0700 (PDT) X-Received: by 2002:a17:90b:388d:b0:387:d9cc:7dc3 with SMTP id 98e67ed59e1d1-395a074a348mr38506087a91.21.1787537413464; Sun, 23 Aug 2026 19:10:13 -0700 (PDT) Received: from hu-rahupath-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-327f92359c9sm20487634eec.27.2026.08.23.19.10.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2026 19:10:12 -0700 (PDT) From: Rahul Pathak To: opensbi@lists.infradead.org Cc: rahul.pathak@oss.qualcomm, rahul@summations.net, Rahul Pathak , Pawandeep Oza Subject: [RFC PATCH v4 3/4] mpt: Add Smsdid and Smmpt supervisor domain core Date: Mon, 24 Aug 2026 07:39:51 +0530 Message-ID: <20260824020953.2438946-4-rahul.pathak@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260824020953.2438946-1-rahul.pathak@oss.qualcomm.com> References: <20260824020953.2438946-1-rahul.pathak@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI0MDAxNyBTYWx0ZWRfX14l1LMDy5Sc2 u0yx8X/iwQL5G0YBeB4y6POY+lLyEswqYaMEpNq1c+yOwQaNkAJfGprSt72fHTV57c1IZdWgW5C fC+TW0aCY1YVyhPLdRvcuqb9jxEwrovP83DHUICHNK8ek89AnKaH8srh9jzNMIMPa0ZnAD5kQhC 2+8Qh5nhji37o88bDiF0oY8+D26S7BkqboBRTKlyW4yX2GnbSD4N4+Kdv86PgTit0WDZBqG8pEk 4A1bQV8VJ51T3k4r2ygNv+RUbX44wnH8ijmB+FjswCs1J8ILds6b5gbib4pfFQ5TF78rETsjPIy BFrW4/CL4m1X5pJVw9jylpYkOLVqZc6twMgS2dtH+tFei/gS9jxl6DJP87S3eG4LEzd5MnN+fO3 vvM0h25MblwjIa9jZDo4wwlR1rruIsV5riZTIpUkmjt/90AAmVstFvcA+xjvh7wQY6NA/xPWF/k eKt3eDNL79rEAahHYIA== X-Proofpoint-GUID: 0IHU8c-2NgguAJ1hYrlDsOrjs_8jY5Jq X-Proofpoint-Spam-Info: AW1haW4tMjYwODI0MDAxNyBTYWx0ZWRfX2CDKPp7QLtA5 26vBkvSFKsie86bLrXzWoNjSBrenJBDDyA2S9yleSDF8j961tswhenITnztnaUQ5nNTd7DqD6YW 41E+QgA0M8jLWql9pYjRF2sLHPj5WAI= X-Authority-Analysis: v=2.4 cv=Xey5Co55 c=1 sm=1 tr=0 ts=6a8ba808 cx=c_pps a=RP+M6JBNLl+fLTcSJhASfg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=9zIJ9XPVV8g2lhebKi4A:9 a=bo10ewcgooylpS98:21 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=iS9zxrgQBfv6-_F4QbHw:22 X-Proofpoint-ORIG-GUID: 0IHU8c-2NgguAJ1hYrlDsOrjs_8jY5Jq X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-24_01,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 adultscore=0 impostorscore=0 spamscore=0 lowpriorityscore=0 malwarescore=0 phishscore=0 clxscore=1015 bulkscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608240017 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260823_191018_479324_B43DEFD9 X-CRM114-Status: GOOD ( 20.01 ) X-Spam-Score: -2.8 (--) 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: Introduce the supervisor domain memory-protection (Smmpt) table management core. This adds the mode agnostic core layer and the per mode table walkers/builder. Add defines for the mmpt CSR encoding, MPTE bit layout, permission flags, structures, fence helpers and the public interfaces. Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, low trust [205.220.168.131 listed in list.dnswl.org] -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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -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 -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.0 DMARC_PASS DMARC pass policy 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 Introduce the supervisor domain memory-protection (Smmpt) table management core. This adds the mode agnostic core layer and the per mode table walkers/builder. Add defines for the mmpt CSR encoding, MPTE bit layout, permission flags, structures, fence helpers and the public interfaces. It implements the RV64 supported modes (Smmpt43/52/64) and the RV32 mode (Smmpt34), its MPT table support. Also implements mpt core which integrates Smmpt with SBI domains and other core layers. Signed-off-by: Rahul Pathak Reviewed-by: Pawandeep Oza --- include/sbi/sbi_hart_mpt.h | 312 +++++++++++ lib/sbi/objects.mk | 2 + lib/sbi/sbi_hart_mpt.c | 993 +++++++++++++++++++++++++++++++++++ lib/sbi/sbi_mpt.c | 1000 ++++++++++++++++++++++++++++++++++++ 4 files changed, 2307 insertions(+) create mode 100644 include/sbi/sbi_hart_mpt.h create mode 100644 lib/sbi/sbi_hart_mpt.c create mode 100644 lib/sbi/sbi_mpt.c diff --git a/include/sbi/sbi_hart_mpt.h b/include/sbi/sbi_hart_mpt.h new file mode 100644 index 00000000..c60b42bf --- /dev/null +++ b/include/sbi/sbi_hart_mpt.h @@ -0,0 +1,312 @@ +/* SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Authors: Rahul Pathak + */ + +#ifndef __SBI_HART_MPT_H__ +#define __SBI_HART_MPT_H__ + +#include +#include +#include +#include +#include + +struct sbi_domain; +struct sbi_mpt_domain; +struct sbi_mpt_ctrl; +struct sbi_domain_memregion; + +/* CSR addresses */ +#define SBI_CSR_MMPT 0x382 +#define SBI_CSR_MSDCFG 0x74E + +/* mmpt register field definitions */ +#if __riscv_xlen == 64 +# define SBI_MMPT_MODE_SHIFT 60UL +# define SBI_MMPT_MODE_MASK (UL(0xF) << SBI_MMPT_MODE_SHIFT) +# define SBI_MMPT_SDID_SHIFT 52UL +# define SBI_MMPT_SDID_MASK (UL(0x3F) << SBI_MMPT_SDID_SHIFT) +# define SBI_MMPT_PPN_MASK UL(0x00000FFFFFFFFFFF) +#else +# define SBI_MMPT_MODE_SHIFT 30UL +# define SBI_MMPT_MODE_MASK (UL(0x3) << SBI_MMPT_MODE_SHIFT) +# define SBI_MMPT_SDID_SHIFT 22UL +# define SBI_MMPT_SDID_MASK (UL(0x3F) << SBI_MMPT_SDID_SHIFT) +# define SBI_MMPT_PPN_MASK UL(0x3FFFFF) +#endif + +#define SBI_MMPT_MODE_BARE 0UL +#if __riscv_xlen == 64 +# define SBI_MMPT_MODE_SMMPT43 1UL +# define SBI_MMPT_MODE_SMMPT52 2UL +# define SBI_MMPT_MODE_SMMPT64 3UL +#else +# define SBI_MMPT_MODE_SMMPT34 1UL +#endif + +/* + * sbi_mmpt_encode() — assemble the full mmpt CSR value. + */ +static inline unsigned long sbi_mmpt_encode(u32 mode, u32 sdid, + unsigned long ppn) +{ + return (((unsigned long)mode << SBI_MMPT_MODE_SHIFT) & SBI_MMPT_MODE_MASK) | + (((unsigned long)sdid << SBI_MMPT_SDID_SHIFT) & SBI_MMPT_SDID_MASK) | + (ppn & SBI_MMPT_PPN_MASK); +} + +/* + * MPTE bit definitions + */ +#define SBI_MPTE_V (1UL << 0) +#define SBI_MPTE_L (1UL << 1) +#define SBI_MPTE_N (1UL << 2) +#define SBI_MPTE_PPN_SHIFT 10U +#define SBI_MPT_PAGE_SHIFT 12U +#define SBI_MPT_PAGE_SIZE 4096UL +#define SBI_MPT_PAGE_MASK (SBI_MPT_PAGE_SIZE - 1UL) +#define SBI_MPTE_XWR_BASE 8U +#define SBI_MPTE_XWR_WIDTH 3U +#define SBI_MPTE_XWR_MASK 7UL + +static inline u32 sbi_mpte_xwr_shift(u32 n) +{ + return (SBI_MPTE_XWR_BASE + n * SBI_MPTE_XWR_WIDTH); +} + +static inline unsigned long sbi_mpte_leaf_set_xwr(unsigned long mpte, + u32 n, u8 xwr) +{ + u32 sh = sbi_mpte_xwr_shift(n); + + mpte &= ~(SBI_MPTE_XWR_MASK << sh); + mpte |= (xwr & SBI_MPTE_XWR_MASK) << sh; + return mpte; +} + +static inline unsigned long sbi_mpte_nonleaf(unsigned long table_pa) +{ + return (((table_pa >> SBI_MPT_PAGE_SHIFT) << SBI_MPTE_PPN_SHIFT) + | SBI_MPTE_V); +} + +static inline unsigned long sbi_mpte_nonleaf_table_pa(unsigned long mpte) +{ + return ((mpte >> SBI_MPTE_PPN_SHIFT) << SBI_MPT_PAGE_SHIFT); +} + +/* + * XWR permission constants (XWR=000 means no access) + */ +#define SBI_MPT_PERM_NONE 0U +#define SBI_MPT_PERM_R 1U +#define SBI_MPT_PERM_W 2U +#define SBI_MPT_PERM_X 4U +#define SBI_MPT_PERM_RW (SBI_MPT_PERM_R | SBI_MPT_PERM_W) +#define SBI_MPT_PERM_RX (SBI_MPT_PERM_R | SBI_MPT_PERM_X) +#define SBI_MPT_PERM_RWX (SBI_MPT_PERM_R | SBI_MPT_PERM_W | SBI_MPT_PERM_X) + +/* + * SDID constants + */ +#define SBI_MPT_SDIDMAX 6U +#define SBI_MPT_MAX_DOMAINS (1UL << SBI_MPT_SDIDMAX) +#define SBI_MPT_SDID_INVALID SBI_MPT_MAX_DOMAINS + +/* + * SBI_MPT_MAX_REGIONS_DOMAIN: Number of regions a domain may have + * Used for tracking of regions + */ +#define SBI_MPT_MAX_REGIONS_DOMAIN 32U + +/* + * SMSDID mfence and minval raw encodings + * + * R-type, opcode=SYSTEM(0x73), funct3=0, rd=x0, rs1=PADDR, rs2=SDID + * mfence.pa funct7=0x19 -> 0x32000073 where rs1=rs2=x0 + * minval.pa funct7=0x1b -> 0x36000073 where rs1=rs2=x0 + * + * .insn r opcode, func3, func7, rd, rs1, rs2 + */ +#define SBI_MPT_MFENCE_PA(rs1, rs2) ".insn r 0x73, 0, 0x19, x0, " rs1 ", " rs2 + +#define SBI_MPT_MINVAL_PA(rs1, rs2) ".insn r 0x73, 0, 0x1b, x0, " rs1 ", " rs2 + +/* + * Fence and invalidation helpers + */ +static inline void sbi_mpt_fence_all(void) +{ + __asm__ volatile(SBI_MPT_MFENCE_PA("x0", "x0") ::: "memory"); +} + +static inline void sbi_mpt_fence_sdid(u32 sdid) +{ + unsigned long s = (unsigned long)sdid & (SBI_MPT_MAX_DOMAINS - 1UL); + + __asm__ volatile(SBI_MPT_MFENCE_PA("x0", "%0") :: "r"(s) : "memory"); +} + +/* + * rs1=paddr and rs2=x0 + */ +static inline void sbi_mpt_mfence_addr(unsigned long paddr) +{ + __asm__ volatile(SBI_MPT_MFENCE_PA("%0", "x0") :: "r"(paddr) : "memory"); +} + +/* + * rs1=paddr and rs2=sdid + */ +static inline void sbi_mpt_mfence_pa(unsigned long paddr, u32 sdid) +{ + unsigned long s = (unsigned long)sdid & (SBI_MPT_MAX_DOMAINS - 1UL); + + __asm__ volatile(SBI_MPT_MFENCE_PA("%0", "%1") + :: "r"(paddr), "r"(s) : "memory"); +} + +/* + * rs1=0 and rs2=0 + */ +static inline void sbi_mpt_minval_all(void) +{ + /* Prior stores globally visible before invalidation */ + __asm__ volatile("sfence.w.inval" ::: "memory"); + __asm__ volatile(SBI_MPT_MINVAL_PA("x0", "x0") ::: "memory"); + /* Invalidation completes before subsequent implicit accesses */ + __asm__ volatile("sfence.inval.ir" ::: "memory"); +} + +/* + * rs1=paddr and rs2=sdid + */ +static inline void sbi_mpt_minval_sdid(unsigned long pa, u32 sdid) +{ + unsigned long s = (unsigned long)sdid & (SBI_MPT_MAX_DOMAINS - 1UL); + + __asm__ volatile("sfence.w.inval" ::: "memory"); + __asm__ volatile(SBI_MPT_MINVAL_PA("%0", "%1") + :: "r"(pa), "r"(s) : "memory"); + __asm__ volatile("sfence.inval.ir" ::: "memory"); +} + +/* + * Core data structures + */ +struct sbi_mpt_region { + unsigned long pa; + unsigned long size; + u8 xwr; + /* region is locked and deny modification via add/remove_region */ + bool locked; + /* mapped into more than one domain */ + bool shared; +}; + +/* + * struct sbi_mpt_mode — SMMPT mode description. + */ +struct sbi_mpt_mode { + const char *name; + u32 mode_val; + + /* Assemble the MMPT CSR value */ + unsigned long (*encode_mmpt)(unsigned long ppn, u32 sdid); + + /* map a range in MPT table */ + int (*map_range)(struct sbi_mpt_domain *dom, + unsigned long pa, unsigned long size, u8 xwr); + + /* number bytes for root table allocation */ + unsigned long (*root_table_size)(void); + + /* required root table physical address alignment */ + unsigned long (*root_table_align)(void); + + /* check if [pa,pa+size] fits in smmpt mode supported address space */ + bool (*pa_in_range)(unsigned long pa, unsigned long size); + + /* map full range of address space which is supported by the mode */ + int (*map_full_range)(struct sbi_mpt_domain *dom, u8 xwr); + + /* read the xwr for a PA */ + u8 (*get_xwr)(struct sbi_mpt_domain *dom, unsigned long pa); +}; + +struct sbi_mpt_domain { + u32 sdid; + bool valid; + unsigned long root_pa; + struct sbi_mpt_mode *mode; + struct sbi_domain *sbi_dom; + unsigned int nregions; + struct sbi_mpt_region regions[SBI_MPT_MAX_REGIONS_DOMAIN]; + spinlock_t lock; +}; + +/* + * struct sbi_mpt_ctrl — RDSM MPT state + */ +struct sbi_mpt_ctrl { + bool ready; + struct sbi_mpt_mode *mode; + /* detected sdidlen from mmpt probe */ + u32 sdid_len; + /* 2^sdid_len — runtime limit for all domain operations */ + u32 max_domains; + unsigned long fw_pa; + unsigned long fw_size; + /* Per domain state */ + struct sbi_mpt_domain *domains[SBI_MPT_MAX_DOMAINS]; + u32 ndomain; + /* sdid offset in scratch */ + unsigned long sdid_offset; + /* bitmap to track assigned/free SDID (bit N set = SDID N free) */ + DECLARE_BITMAP(sdid_bitmap, SBI_MPT_MAX_DOMAINS); +}; + +struct sbi_mpt_ctrl *sbi_mpt_ctrl_get(void); + +static inline u32 sbi_mpt_thishart_sdid(void) +{ + struct sbi_mpt_ctrl *ctrl = sbi_mpt_ctrl_get(); + u32 *p; + + if (!ctrl->ready || !ctrl->sdid_offset) + return (u32)SBI_MPT_SDID_INVALID; + p = sbi_scratch_offset_ptr(sbi_scratch_thishart_ptr(), + ctrl->sdid_offset); + return *p; +} + +int sbi_mpt_init(void); + +int sbi_mpt_domain_add_region(u32 sdid, unsigned long pa, unsigned long size, u8 xwr); + +int sbi_mpt_domain_remove_region(u32 sdid, unsigned long pa, unsigned long size); + +int sbi_mpt_share_region(u32 src_sdid, u32 dst_sdid, unsigned long pa, unsigned long size, u8 dst_xwr); + +int sbi_mpt_unshare_region(u32 sdid, unsigned long pa, unsigned long size); + +int sbi_mpt_hart_activate(u32 sdid); + +void sbi_mpt_hart_deactivate(void); + +int sbi_mpt_hart_activate_for_domain(struct sbi_domain *sbi_dom); + +struct sbi_mpt_domain *sbi_mpt_domain_get(u32 sdid); + +unsigned long sbi_mpt_pool_alloc(unsigned long size, unsigned long align); + +void sbi_mpt_sdid_free(u32 sdid); + +int sbi_mpt_query_access(u32 sdid, unsigned long pa, u8 *out_xwr); + +void sbi_mpt_dump(void); + +#endif /* __SBI_HART_MPT_H__ */ diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk index ae27d0c5..ea69a6f2 100644 --- a/lib/sbi/objects.mk +++ b/lib/sbi/objects.mk @@ -108,3 +108,5 @@ libsbi-objs-y += sbi_expected_trap.o libsbi-objs-y += sbi_cppc.o libsbi-objs-$(CC_SUPPORT_VECTOR) += sbi_vector.o libsbi-objs-y += sbi_fp.o +libsbi-objs-y += sbi_hart_mpt.o +libsbi-objs-y += sbi_mpt.o diff --git a/lib/sbi/sbi_hart_mpt.c b/lib/sbi/sbi_hart_mpt.c new file mode 100644 index 00000000..7a027be0 --- /dev/null +++ b/lib/sbi/sbi_hart_mpt.c @@ -0,0 +1,993 @@ +/* SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Authors: Rahul Pathak + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct sbi_mpt_ctrl mpt_ctrl; + +struct sbi_mpt_ctrl *sbi_mpt_ctrl_get(void) +{ + return &mpt_ctrl; +} + +struct sbi_mpt_domain *sbi_mpt_domain_get(u32 sdid) +{ + struct sbi_mpt_domain *sd; + + if (sdid >= mpt_ctrl.max_domains) + return NULL; + + sd = mpt_ctrl.domains[sdid]; + if (!sd || !sd->valid) + return NULL; + + return sd; +} + +/* Memory allocator for MPT tables from heap */ +unsigned long sbi_mpt_pool_alloc(unsigned long size, unsigned long align) +{ + unsigned long ptr = (unsigned long)sbi_aligned_alloc(align, size); + + if (!ptr) { + sbi_printf("sbi_mpt: alloc failed (size=0x%lx align=0x%lx)\n", + size, align); + return 0; + } + + /* MPT tables must be zeroed to mark them invalid (mpte.V = 0) */ + sbi_memset((void *)ptr, 0, size); + + return ptr; +} + +/* Check if two regions overlap */ +static bool regions_overlap(unsigned long pa1, unsigned long size1, + unsigned long pa2, unsigned long size2) +{ + return (pa1 < pa2 + size2) && (pa2 < pa1 + size1); +} + +/* Check if a region is completely contained inside another region */ +static bool region_contained(unsigned long child_pa, unsigned long child_size, + unsigned long parent_pa, unsigned long parent_size) +{ + return (child_pa >= parent_pa) && + (child_pa + child_size <= parent_pa + parent_size); +} + +/* + * Check if a region [pa, pa+size] overlaps with any mapped + * region which is locked + */ +static bool region_overlaps_locked(const struct sbi_mpt_domain *dom, + unsigned long pa, unsigned long size) +{ + unsigned int i; + + for (i = 0; i < dom->nregions; i++) + if (dom->regions[i].locked && + regions_overlap(pa, size, dom->regions[i].pa, dom->regions[i].size)) + return true; + return false; +} + +/* Probe SDIDLEN from the mmpt CSR. */ +static u32 probe_sdidlen(u32 mode_val) +{ + unsigned long saved, sdid_val; + u32 sdidlen = 0; + + saved = csr_read(SBI_CSR_MMPT); + + /* Program a legal non-Bare MODE with all-ones in the SDID field */ + csr_write(SBI_CSR_MMPT, + (((unsigned long)mode_val << SBI_MMPT_MODE_SHIFT) & SBI_MMPT_MODE_MASK) | + SBI_MMPT_SDID_MASK); + + sdid_val = (csr_read(SBI_CSR_MMPT) & SBI_MMPT_SDID_MASK) >> SBI_MMPT_SDID_SHIFT; + + while (sdid_val) { + sdidlen += 1; + sdid_val >>= 1; + } + + if (sdidlen > SBI_MPT_SDIDMAX) + sdidlen = SBI_MPT_SDIDMAX; + + csr_write(SBI_CSR_MMPT, saved); + + return sdidlen; +} + +#if __riscv_xlen == 64 +extern struct sbi_mpt_mode smmpt43_mode; +extern struct sbi_mpt_mode smmpt52_mode; +extern struct sbi_mpt_mode smmpt64_mode; +#else +extern struct sbi_mpt_mode smmpt34_mode; +#endif + +static bool probe_mode(u32 mode_val) +{ + u32 m; + csr_write(SBI_CSR_MMPT, + ((unsigned long)mode_val << SBI_MMPT_MODE_SHIFT) & SBI_MMPT_MODE_MASK); + + m = (csr_read(SBI_CSR_MMPT) & SBI_MMPT_MODE_MASK) >> SBI_MMPT_MODE_SHIFT; + + return (m == mode_val); +} + + +/* + * Probe SMMPT mode and initialize the related mode ops + * + * Deliberately prefer coverage over latency, because latency can be + * improved by the MPT cache which hardware may implement but the + * coverage is not. So pick the widest mode which is supported by the + * hardware. + */ +static struct sbi_mpt_mode *init_mpt_mode(u32 *out_mode_val) +{ + unsigned long saved = csr_read(SBI_CSR_MMPT); + struct sbi_mpt_mode *s = NULL; + u32 mode_val = 0; + +#if __riscv_xlen == 64 + if (probe_mode(SBI_MMPT_MODE_SMMPT64)) { + s = &smmpt64_mode; + mode_val = SBI_MMPT_MODE_SMMPT64; + } else if (probe_mode(SBI_MMPT_MODE_SMMPT52)) { + s = &smmpt52_mode; + mode_val = SBI_MMPT_MODE_SMMPT52; + } else if (probe_mode(SBI_MMPT_MODE_SMMPT43)) { + s = &smmpt43_mode; + mode_val = SBI_MMPT_MODE_SMMPT43; + } +#else + if (probe_mode(SBI_MMPT_MODE_SMMPT34)) { + s = &smmpt34_mode; + mode_val = SBI_MMPT_MODE_SMMPT34; + } +#endif + + csr_write(SBI_CSR_MMPT, saved); + + if (out_mode_val) + *out_mode_val = mode_val; + + return s; +} + +/* + * mpt_map_range_perm(): Maps [pa, pa+size] region into supervisor domain MPT table + * with its access permissions(xwr). + * + * locked=true: means entry is immutable and it cannot be modified. Used for + * firmware deny-all and other such regions for permanenet access policy. + * + * locked=false: region entry is modifiable at runtime via add/remove_region. + * Used for S/U-mode accessible domain regions. + */ + +static int mpt_map_range_perm(struct sbi_mpt_domain *dom, struct sbi_mpt_mode *sch, + unsigned long pa, unsigned long size, u8 xwr, bool locked) +{ + int rc; + bool first_in_range; + + if (!size) { + sbi_printf("sbi_mpt: invalid size for range 0x%lx\n", pa); + return SBI_EINVAL; + } + + if ((pa & SBI_MPT_PAGE_MASK) || (size & SBI_MPT_PAGE_MASK)) { + sbi_printf("sbi_mpt: unaligned range 0x%lx+0x%lx\n", pa, size); + return SBI_EINVAL; + } + + if (!sch->pa_in_range(pa, size)) { + /* + * A region that pa_in_range() returns false falls into one of two + * different cases - PA which is out of range from the mappable + * range of that mode and second is PA is in range but the end + * (pa + size) is crossing the mappable range. + * + * Distinguish the two by probing pa_in_range() for just + * the first page in that big range and if even the first page + * is out of range it is the first case and if the base is in + * range but the whole region is not, it is case later. + */ + first_in_range = sch->pa_in_range(pa, SBI_MPT_PAGE_SIZE); + + if (locked) { + sbi_printf("sbi_mpt: locked region 0x%lx+0x%lx out of mode range\n", + pa, size); + return SBI_EINVAL; + } + + /* Region with PA which partially crossover the mappable space */ + if (first_in_range) { + sbi_printf("sbi_mpt: fatal region 0x%lx+0x%lx crossover" + " mode '%s' ceiling; high part may alias" + " with low MPTE entries — not mapping this region\n", + pa, size, sch->name); + return SBI_EINVAL; + } + + /* Region which is entirely above the ceiling — unreachable */ + sbi_printf("sbi_mpt: skip out-of-range 0x%lx+0x%lx" + " (entirely above '%s' ceiling; no MPT entry,\n", + pa, size, sch->name); + return 0; + } + + rc = sch->map_range(dom, pa, size, xwr); + if (rc) + return rc; + + if (dom->nregions >= SBI_MPT_MAX_REGIONS_DOMAIN) + return SBI_ENOMEM; + + dom->regions[dom->nregions].pa = pa; + dom->regions[dom->nregions].size = size; + dom->regions[dom->nregions].xwr = xwr; + dom->regions[dom->nregions].locked = locked; + dom->regions[dom->nregions].shared = false; + dom->nregions++; + + return 0; +} + +/* + * mpt_xwr_from_memregion(): derive an MPTE XWR encoding from a SBI domain + * memregion's S/U access flags, clamped by cap. + * + * cap is an upper bound the caller may impose. A region from SBI domain + * may have more permissive access permissions which an supervisor domain + * may want to restict and cap them. + */ +static u8 mpt_xwr_from_memregion(const struct sbi_domain_memregion *mr, + u8 cap) +{ + u8 xwr = SBI_MPT_PERM_NONE; + + if (mr->flags & SBI_DOMAIN_MEMREGION_SU_READABLE) + xwr |= SBI_MPT_PERM_R; + if (mr->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE) + xwr |= SBI_MPT_PERM_W; + if (mr->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE) + xwr |= SBI_MPT_PERM_X; + + xwr &= cap; + + /* XWR encodings 0b010 (W) and 0b110 (WX) are reserved */ + if ((xwr & SBI_MPT_PERM_W) && !(xwr & SBI_MPT_PERM_R)) { + sbi_printf("sbi_mpt: region 0x%lx: W without R is a reserved" + " XWR encoding — denying region\n", mr->base); + return SBI_MPT_PERM_NONE; + } + + return xwr; +} + +static int smmpt_hart_configure(struct sbi_scratch *scratch, + struct sbi_domain *dom) +{ + return sbi_mpt_hart_activate_for_domain(dom); +} + +static void smmpt_hart_unconfigure(struct sbi_scratch *scratch, + struct sbi_domain *dom) +{ + sbi_mpt_hart_deactivate(); +} + +static struct sbi_hart_protection smmpt_protection = { + .name = "smmpt", + .type = SBI_HART_PROTECTION_TYPE_ID, + .rating = 100, + .configure = smmpt_hart_configure, + .unconfigure = smmpt_hart_unconfigure, +}; + +/* + * Setup the MPT state for each domain + * + * The state of a supervisor domain is stored in the sbi_domain_state intance + * of the SBI domain it belongs to so that it is created and destroyed with + * that domain. + */ +static int mpt_state_setup(struct sbi_domain *dom, struct sbi_domain_state *state, + void *state_ptr) +{ + u32 sdid; + struct sbi_mpt_domain *sd = state_ptr; + struct sbi_mpt_ctrl *ctrl = &mpt_ctrl; + + if (!ctrl->ready) + return 0; + + for (sdid = 0; sdid < ctrl->max_domains; sdid++) + if (bitmap_test(ctrl->sdid_bitmap, sdid)) + break; + + if (sdid >= ctrl->max_domains) { + sbi_printf("sbi_mpt: no free SDID for domain %s\n", dom->name); + return SBI_ENOSPC; + } + + bitmap_clear(ctrl->sdid_bitmap, sdid, 1); + + SPIN_LOCK_INIT(sd->lock); + sd->sdid = sdid; + sd->valid = false; + sd->root_pa = 0; + sd->mode = ctrl->mode; + sd->sbi_dom = dom; + sd->nregions = 0; + + ctrl->domains[sdid] = sd; + + return 0; +} + +/* + * mpt_state_finalize(): Build the MPT table of a supervisor domain. + * + * This function called once all domains are registered and their memory regions + * are final. General strategy for mapping the memory regions is to create a + * baseline mapping of the whole mappable address space supported by that mode + * then the respective regions are overlay on top of it with the permissions flags + * from the sbi domain. The firmware region is denied to S-mode in the root domain. + */ +static int mpt_state_finalize(struct sbi_domain *dom, + struct sbi_domain_state *state, void *state_ptr) +{ + int rc; + u8 base_xwr; + unsigned long root_pa; + struct sbi_mpt_region *r; + struct sbi_mpt_mode *sch; + const struct sbi_domain_memregion *mr; + struct sbi_mpt_domain *sd = state_ptr; + struct sbi_mpt_ctrl *ctrl = &mpt_ctrl; + + if (!ctrl->ready) + return 0; + + sch = ctrl->mode; + + root_pa = sbi_mpt_pool_alloc(sch->root_table_size(), + sch->root_table_align()); + if (!root_pa) { + sbi_printf("sbi_mpt: OOM root table for domain %s\n", dom->name); + return SBI_ENOMEM; + } + sd->root_pa = root_pa; + + /* + * Similar to SBI domain, create a baseline which maps whole + * mappable address space by a mode and mark it with XWR + * permissions. Later selectively restrict the permissions in + * another pass. + */ + sbi_domain_for_each_memregion(dom, mr) { + if (mr->order < sizeof(unsigned long) * 8) + continue; + + if (!(mr->flags & SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK)) + continue; + + base_xwr = mpt_xwr_from_memregion(mr, SBI_MPT_PERM_RWX); + rc = sch->map_full_range(sd, base_xwr); + if (rc) + return rc; + + if (sd->nregions < SBI_MPT_MAX_REGIONS_DOMAIN) { + r = &sd->regions[sd->nregions++]; + r->pa = 0; + r->size = ~0UL & ~SBI_MPT_PAGE_MASK; + r->xwr = base_xwr; + r->locked = false; + r->shared = false; + } + + break; + } + + /* + * Another pass to map every other region which has its own + * permissions derived from the memregion's S/U flags. + */ + sbi_domain_for_each_memregion(dom, mr) { + if (mr->order >= sizeof(unsigned long) * 8) + continue; + + rc = mpt_map_range_perm(sd, sch, mr->base, BIT(mr->order), + mpt_xwr_from_memregion(mr, SBI_MPT_PERM_RWX), + false); + if (rc) + return rc; + } + + /* + * Explicitly map the firmware region to S-mode with no permissions + * and locked. + */ + if (dom->index == 0) { + rc = mpt_map_range_perm(sd, sch, ctrl->fw_pa, ctrl->fw_size, + SBI_MPT_PERM_NONE, true); + if (rc) { + sbi_printf("sbi_mpt: cannot protect firmware rc=%d\n", rc); + return rc; + } + } + + sd->valid = true; + ctrl->ndomain++; + + sbi_mpt_fence_sdid(sd->sdid); + + return 0; +} + +/* + * mpt_state_cleanup(): Release the MPT state of a supervisor domain. + */ +static void mpt_state_cleanup(struct sbi_domain *dom, + struct sbi_domain_state *state, void *state_ptr) +{ + struct sbi_mpt_domain *sd = state_ptr; + struct sbi_mpt_ctrl *ctrl = &mpt_ctrl; + + if (!ctrl->ready || !sd->valid) + return; + + /* + * TODO: free the MPT table tree (root, inner and leaf tables) + * allocated by mpt_state_finalize(). A recursive free is not + * implemented yet so the tables and it will be important when + * runtime regions changes will be there. + */ + + sd->valid = false; + ctrl->ndomain--; + + sbi_mpt_fence_sdid(sd->sdid); + sbi_mpt_sdid_free(sd->sdid); +} + +static struct sbi_domain_state mpt_domain_state = { + .state_size = sizeof(struct sbi_mpt_domain), + .state_setup = mpt_state_setup, + .state_finalize = mpt_state_finalize, + .state_cleanup = mpt_state_cleanup, +}; + +/* + * sbi_mpt_domain_add_region(): Map a region in a MPT table + */ +int sbi_mpt_domain_add_region(u32 sdid, unsigned long pa, + unsigned long size, u8 xwr) +{ + struct sbi_mpt_domain *dom; + struct sbi_mpt_region *r; + int rc; + + if (!mpt_ctrl.ready) + return SBI_ENODEV; + if (!size || (pa & SBI_MPT_PAGE_MASK) || (size & SBI_MPT_PAGE_MASK)) + return SBI_EINVAL; + + dom = sbi_mpt_domain_get(sdid); + if (!dom) + return SBI_EINVAL; + + if (region_overlaps_locked(dom, pa, size)) { + sbi_printf("sbi_mpt: 0x%lx+0x%lx overlaps locked" + " (SDID %u)\n", pa, size, sdid); + return SBI_EINVAL; + } + + if (!dom->mode->pa_in_range(pa, size)) { + /* + * A region that pa_in_range() rejects falls into one of two + * different cases - PA which is out of range from the mappable + * range of that mode and second is PA is in range but the end + * (PA + SIZE) is crossing the mappable range. + * + * Distinguish the two by probing pa_in_range() for just + * the base page and if even the base is out of range it is + * the first case and if the base is in range but the whole + * region is not, it is case later. + */ + if (dom->mode->pa_in_range(pa, SBI_MPT_PAGE_SIZE)) + sbi_printf("sbi_mpt: 0x%lx+0x%lx crossover mode '%s'" + " ceiling (SDID %u) — high part would alias;" + " rejected\n", + pa, size, dom->mode->name, sdid); + else + sbi_printf("sbi_mpt: 0x%lx+0x%lx out of range" + " (SDID %u)\n", pa, size, sdid); + return SBI_EINVAL; + } + + spin_lock(&dom->lock); + rc = dom->mode->map_range(dom, pa, size, xwr); + spin_unlock(&dom->lock); + + if (!rc) { + if (dom->nregions < SBI_MPT_MAX_REGIONS_DOMAIN) { + r = &dom->regions[dom->nregions++]; + r->pa = pa; + r->size = size; + r->xwr = xwr; + r->locked = false; + r->shared = false; + } + + sbi_mpt_fence_sdid(sdid); + } + + return rc; +} + +/* + * sbi_mpt_domain_remove_region(): Unmap a region from the MPT table + */ +int sbi_mpt_domain_remove_region(u32 sdid, unsigned long pa, + unsigned long size) +{ + int rc; + unsigned int i; + struct sbi_mpt_domain *dom; + struct sbi_mpt_region *r; + + if (!mpt_ctrl.ready) + return SBI_ENODEV; + + if (!size || (pa & SBI_MPT_PAGE_MASK) || (size & SBI_MPT_PAGE_MASK)) + return SBI_EINVAL; + + dom = sbi_mpt_domain_get(sdid); + if (!dom) + return SBI_EINVAL; + + for (i = 0; i < dom->nregions; i++) { + r = &dom->regions[i]; + + if (r->locked && region_contained(pa, size, r->pa, r->size)) + return SBI_EDENIED; + /* + * Shared regions must be removed via sbi_mpt_unshare_region() + * because that function prevents one domain revoking a region + * that another domain still has mapped. + */ + if (r->shared && r->pa == pa && r->size == size) + return SBI_EDENIED; + } + + spin_lock(&dom->lock); + rc = dom->mode->map_range(dom, pa, size, SBI_MPT_PERM_NONE); + spin_unlock(&dom->lock); + + if (!rc) + sbi_mpt_fence_sdid(sdid); + + return rc; +} + +/* + * Shared memory regions + * + * sbi_mpt_share_region() — map a region into a second domain. + * + * Both domains MPT tables are updated independently — each has its + * own root/inner/leaf table tree. The same PA range can have different + * XWR permissions in different domains. + * + */ + +int sbi_mpt_share_region(u32 src_sdid, u32 dst_sdid, + unsigned long pa, unsigned long size, + u8 dst_xwr) +{ + unsigned int i; + int rc; + struct sbi_mpt_domain *src_dom, *dst_dom; + + if (!mpt_ctrl.ready) + return SBI_ENODEV; + + if (!size || (pa & SBI_MPT_PAGE_MASK) || (size & SBI_MPT_PAGE_MASK)) + return SBI_EINVAL; + + if (src_sdid == dst_sdid) + return SBI_EINVAL; + + src_dom = sbi_mpt_domain_get(src_sdid); + dst_dom = sbi_mpt_domain_get(dst_sdid); + if (!src_dom || !dst_dom) + return SBI_EINVAL; + + if (region_overlaps_locked(dst_dom, pa, size)) { + sbi_printf("sbi_mpt: share 0x%lx+0x%lx overlaps locked region in SDID %u\n", + pa, size, dst_sdid); + return SBI_EINVAL; + } + + /* Reject reserved xwr permissions: 0b010 and 0b110 (W without R) */ + if ((dst_xwr & SBI_MPT_PERM_W) && !(dst_xwr & SBI_MPT_PERM_R)) { + sbi_printf("sbi_mpt: share 0x%lx+0x%lx: W without R is a reserved XWR encoding\n", + pa, size); + return SBI_EINVAL; + } + + if (dst_dom->nregions >= SBI_MPT_MAX_REGIONS_DOMAIN) { + sbi_printf("sbi_mpt: share: SDID %u region table full\n", dst_sdid); + return SBI_ENOMEM; + } + + spin_lock(&dst_dom->lock); + rc = dst_dom->mode->map_range(dst_dom, pa, size, dst_xwr); + spin_unlock(&dst_dom->lock); + if (rc) + return rc; + + dst_dom->regions[dst_dom->nregions].pa = pa; + dst_dom->regions[dst_dom->nregions].size = size; + dst_dom->regions[dst_dom->nregions].xwr = dst_xwr; + dst_dom->regions[dst_dom->nregions].locked = false; + dst_dom->regions[dst_dom->nregions].shared = true; + dst_dom->nregions++; + + for (i = 0; i < src_dom->nregions; i++) { + if (src_dom->regions[i].pa == pa && + src_dom->regions[i].size == size) { + src_dom->regions[i].shared = true; + break; + } + } + + sbi_mpt_fence_sdid(src_sdid); + sbi_mpt_fence_sdid(dst_sdid); + + sbi_printf("sbi_mpt: shared 0x%lx+0x%lx SDID %u → SDID %u xwr=%u\n", + pa, size, src_sdid, dst_sdid, dst_xwr); + + return 0; +} + +/* + * sbi_mpt_unshare_region() — Unmap a shared region from a domain. + * + * The other domain remains unaffected just the shared flag gets removed + * for that region from both the domains. + */ +int sbi_mpt_unshare_region(u32 sdid, unsigned long pa, unsigned long size) +{ + u32 s; + int rc; + unsigned int i, j; + struct sbi_mpt_domain *dom, *peer; + + if (!mpt_ctrl.ready) + return SBI_ENODEV; + + if (!size || (pa & SBI_MPT_PAGE_MASK) || (size & SBI_MPT_PAGE_MASK)) + return SBI_EINVAL; + + dom = sbi_mpt_domain_get(sdid); + if (!dom) + return SBI_EINVAL; + + for (i = 0; i < dom->nregions; i++) { + if (dom->regions[i].pa == pa && + dom->regions[i].size == size && + dom->regions[i].shared) + break; + } + if (i == dom->nregions) { + sbi_printf("sbi_mpt: unshare 0x%lx+0x%lx not found in SDID %u\n", + pa, size, sdid); + return SBI_EINVAL; + } + + spin_lock(&dom->lock); + rc = dom->mode->map_range(dom, pa, size, SBI_MPT_PERM_NONE); + spin_unlock(&dom->lock); + + if (rc) + return rc; + + dom->nregions -= 1; + dom->regions[i] = dom->regions[dom->nregions]; + + /* Clear the shared flag on any other domain that has this PA region shared.*/ + for (s = 0; s < mpt_ctrl.max_domains; s++) { + peer = sbi_mpt_domain_get(s); + if (!peer || peer == dom) + continue; + + for (j = 0; j < peer->nregions; j++) + if (peer->regions[j].pa == pa && peer->regions[j].size == size) + peer->regions[j].shared = false; + } + + sbi_mpt_fence_sdid(sdid); + + return 0; +} + +/* + * Disable SMMPT on hart + */ +void sbi_mpt_hart_deactivate(void) +{ + /* + * mmpt is inactive in M-mode per spec, so no CSR write + * is needed. + */ +} + +/* + * Enable SMMPT on hart on a supervisor domain(sdid) + */ +int sbi_mpt_hart_activate(u32 sdid) +{ + u32 *p; + unsigned long ppn; + struct sbi_mpt_domain *dom; + + if (!mpt_ctrl.ready) + return SBI_ENODEV; + + dom = sbi_mpt_domain_get(sdid); + if (!dom) + return SBI_EINVAL; + + ppn = dom->root_pa >> SBI_MPT_PAGE_SHIFT; + csr_write(SBI_CSR_MMPT, dom->mode->encode_mmpt(ppn, sdid)); + sbi_mpt_fence_sdid(sdid); + + if (mpt_ctrl.sdid_offset) { + p = sbi_scratch_offset_ptr(sbi_scratch_thishart_ptr(), mpt_ctrl.sdid_offset); + *p = sdid; + } + + return 0; +} + +/* + * Activate SMMPT for all harts which are associated with an linked + * SBI domain in an supervisor domain. + */ +int sbi_mpt_hart_activate_for_domain(struct sbi_domain *sbi_dom) +{ + struct sbi_mpt_domain *sd; + + if (!mpt_ctrl.ready) + return SBI_ENODEV; + if (!sbi_dom) + return SBI_EINVAL; + + sd = sbi_domain_state_ptr(sbi_dom, &mpt_domain_state); + if (!sd || !sd->valid) + return 0; + + return sbi_mpt_hart_activate(sd->sdid); +} + +/* + * sbi_mpt_sdid_free(): Returns SDID to the free pool after domain destroy. + */ +void sbi_mpt_sdid_free(u32 sdid) +{ + if (!mpt_ctrl.ready || sdid >= mpt_ctrl.max_domains) + return; + + bitmap_set(mpt_ctrl.sdid_bitmap, (int)sdid, 1); + + mpt_ctrl.domains[sdid] = NULL; +} + +/* + * sbi_mpt_query_access(): Returns the XWR for a PA in supervisor domain(sdid). + */ +int sbi_mpt_query_access(u32 sdid, unsigned long pa, u8 *out_xwr) +{ + struct sbi_mpt_domain *dom; + + if (!mpt_ctrl.ready) + return SBI_ENODEV; + + if (!out_xwr) + return SBI_EINVAL; + + dom = sbi_mpt_domain_get(sdid); + if (!dom) + return SBI_EINVAL; + + if (!dom->mode->pa_in_range(pa, SBI_MPT_PAGE_SIZE)) { + *out_xwr = SBI_MPT_PERM_NONE; + return 0; + } + + spin_lock(&dom->lock); + *out_xwr = dom->mode->get_xwr(dom, pa); + spin_unlock(&dom->lock); + + return 0; +} + +/* + * sbi_mpt_init(): Initialize MPT structures + */ +int sbi_mpt_init(void) +{ + int rc; + u32 *p; + u32 mode_val; + unsigned long fw_end; + struct sbi_scratch *s; + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); + unsigned long fw_pa = scratch->fw_start; + unsigned long fw_size = scratch->fw_size; + + if (mpt_ctrl.ready) + return 0; + + if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMSDID)) { + sbi_printf("sbi_mpt: Smsdid extension absent\n"); + return SBI_ENODEV; + } + + if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMMPT)) { + sbi_printf("sbi_mpt: Smmpt extension absent\n"); + return SBI_ENODEV; + } + + mpt_ctrl.mode = init_mpt_mode(&mode_val); + if (!mpt_ctrl.mode) { + sbi_printf("sbi_mpt: WARL probe found no mode\n"); + return SBI_ENODEV; + } + + /* + * SDIDLEN must be probed with a legal non-Bare MODE programmed, + * probe sdidlen must be done only after the probing the mode. + */ + mpt_ctrl.sdid_len = probe_sdidlen(mode_val); + if (!mpt_ctrl.sdid_len) { + sbi_printf("sbi_mpt: SDIDLEN=0 — SDID field not implemented\n"); + return SBI_ENODEV; + } + + mpt_ctrl.max_domains = 1UL << mpt_ctrl.sdid_len; + + /* + * Initialise SDID bitmap + * set bits 0..(max_domains-1) as 1 marking those SDIDs free. + */ + bitmap_fill(mpt_ctrl.sdid_bitmap, mpt_ctrl.max_domains); + + /* Round fw_pa and fw_size to page boundaries before storing. */ + fw_end = (fw_pa + fw_size + SBI_MPT_PAGE_SIZE - 1UL) & ~SBI_MPT_PAGE_MASK; + mpt_ctrl.fw_pa = fw_pa & ~SBI_MPT_PAGE_MASK; + mpt_ctrl.fw_size = fw_end - mpt_ctrl.fw_pa; + + + /* Per-hart SDID scratch slot — initialise all harts to INVALID */ + mpt_ctrl.sdid_offset = sbi_scratch_alloc_offset(sizeof(u32)); + if (!mpt_ctrl.sdid_offset) { + sbi_printf("sbi_mpt: scratch alloc for SDID failed\n"); + } + else { + sbi_for_each_hartindex(i) { + s = sbi_hartindex_to_scratch(i); + if (s) { + p = sbi_scratch_offset_ptr(s, mpt_ctrl.sdid_offset); + *p = SBI_MPT_SDID_INVALID; + } + } + } + + mpt_ctrl.ready = true; + + rc = sbi_hart_protection_register(&smmpt_protection); + if (rc) { + sbi_printf("sbi_mpt: hart protection register failed rc=%d\n", rc); + mpt_ctrl.ready = false; + return rc; + } + + rc = sbi_domain_register_state(&mpt_domain_state); + if (rc) { + sbi_printf("sbi_mpt: domain data register failed rc=%d\n", rc); + mpt_ctrl.ready = false; + return rc; + } + + return 0; +} + +/* + * Debug dump + */ +void sbi_mpt_dump(void) +{ + u32 s; + unsigned int r; + const struct sbi_mpt_domain *d; + const unsigned long catchall_size = ~0UL & ~SBI_MPT_PAGE_MASK; + + if (!mpt_ctrl.ready) { + sbi_printf("sbi_mpt: not initialised\n"); + return; + } + + sbi_printf("sbi_mpt: mode=%-10s SDIDLEN=%u max_domains=%u\n", mpt_ctrl.mode->name, + mpt_ctrl.sdid_len, mpt_ctrl.max_domains); + sbi_printf("root_size=0x%lx root_align=0x%lx\n", + mpt_ctrl.mode->root_table_size(), mpt_ctrl.mode->root_table_align()); + sbi_printf("fw 0x%016lx+0x%lx pool=global heap\n", + mpt_ctrl.fw_pa, mpt_ctrl.fw_size); + for (s = 0; s < mpt_ctrl.max_domains; s++) { + bool has_baseline = false; + u8 baseline_xwr = SBI_MPT_PERM_NONE; + + d = mpt_ctrl.domains[s]; + if (!d || !d->valid) + continue; + sbi_printf("SDID %2u root=0x%016lx regions=%u dom=%s\n", + d->sdid, d->root_pa, d->nregions, d->sbi_dom ? d->sbi_dom->name : "(none)"); + for (r = 0; r < d->nregions; r++) { + + if (d->regions[r].pa == 0 && + d->regions[r].size == catchall_size) { + has_baseline = true; + baseline_xwr = d->regions[r].xwr; + continue; + } + + sbi_printf("S-Domain%u Region%02u : 0x%016lx+0x%-16lx: xwr=%u (%c%c%c)%s%s\n", + d->sdid, r, d->regions[r].pa, + d->regions[r].size, + d->regions[r].xwr, + (d->regions[r].xwr & SBI_MPT_PERM_R) ? 'R' : '-', + (d->regions[r].xwr & SBI_MPT_PERM_W) ? 'W' : '-', + (d->regions[r].xwr & SBI_MPT_PERM_X) ? 'X' : '-', + d->regions[r].locked ? " [LOCKED]" : "", + d->regions[r].shared ? " [SHARED]" : ""); + } + + if (has_baseline) { + sbi_printf("S-Domain%u Default : %-37s: xwr=%u (%c%c%c) [baseline, overlay by regions above]\n", + d->sdid, "Rest of the address space", + baseline_xwr, + (baseline_xwr & SBI_MPT_PERM_R) ? 'R' : '-', + (baseline_xwr & SBI_MPT_PERM_W) ? 'W' : '-', + (baseline_xwr & SBI_MPT_PERM_X) ? 'X' : '-'); + } + else { + sbi_printf("S-Domain%u : xwr=0 (---) [no baseline — unmapped PAs denied]\n", + d->sdid); + } + } +} diff --git a/lib/sbi/sbi_mpt.c b/lib/sbi/sbi_mpt.c new file mode 100644 index 00000000..cb1ce937 --- /dev/null +++ b/lib/sbi/sbi_mpt.c @@ -0,0 +1,1000 @@ +/* SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Authors: Rahul Pathak + */ + +#include +#include +#include +#include + +#if __riscv_xlen == 64 + +/* + * Smmpt43 — 43-bit supervisor physical address (SPA) + * +---------+---------+---------+---------+--------+ + * | pn[2] | pn[1] | pn[0] | pi | offset | + * | [42:34] | [33:25] | [24:16] | [15:12] | [11:0] | + * | 9b | 9b | 9b | 4b | 12b | + * +---------+---------+---------+---------+--------+ + * + * Smmpt52 — 52-bit supervisor physical address (SPA) + * +---------+---------+---------+---------+---------+--------+ + * | pn[3] | pn[2] | pn[1] | pn[0] | pi | offset | + * | [51:43] | [42:34] | [33:25] | [24:16] | [15:12] | [11:0] | + * | 9b | 9b | 9b | 9b | 4b | 12b | + * +---------+---------+---------+---------+---------+--------+ + * + * Smmpt64 — 64-bit supervisor physical address (SPA) + * +---------+---------+---------+---------+---------+---------+--------+ + * | pn[4] | pn[3] | pn[2] | pn[1] | pn[0] | pi | offset | + * | [63:52] | [51:43] | [42:34] | [33:25] | [24:16] | [15:12] | [11:0] | + * | 12b | 9b | 9b | 9b | 9b | 4b | 12b | + * +---------+---------+---------+---------+---------+---------+--------+ + * + */ + +/* Innter entries are MPTEs not in root MPT page */ +#define RV64_INNER_ENTRIES 512U +#define RV64_MPTE_SIZE 8UL +#define RV64_TABLE_SIZE (RV64_INNER_ENTRIES * RV64_MPTE_SIZE) + +/* Smmpt64 root: 4096 entries × 8B = 32KB, 32KB aligned */ +#define RV64_ROOT_SMMPT64_ENTRIES 4096U +#define RV64_ROOT_SMMPT64_SIZE (RV64_ROOT_SMMPT64_ENTRIES * RV64_MPTE_SIZE) + +#define RV64_NUMPGINRANGE 4U +#define RV64_PAGES_PER_MPTE (1U << RV64_NUMPGINRANGE) +#define RV64_PAGES_PER_MPTE_MASK (RV64_PAGES_PER_MPTE - 1U) +#define RV64_INNER_PN_BITS 9U + +/* Bytes covered by one complete leaf table = pages_per_leaf × PAGE_SIZE */ +#define RV64_LEAF_RANGE (RV64_PAGES_PER_MPTE * SBI_MPT_PAGE_SIZE) + +/* Shift required to get tuple from sub MPT index (non-root inner table)*/ +#define RV64_SPLIT_TUPLE_SHIFT (RV64_INNER_PN_BITS - RV64_NUMPGINRANGE) + +/* + * NAPOT G=4 for Smmpt43, Smmpt52 and Smmpt64 + * + * G=4 means 2^(G+1)=32 contiguous leaf mpte which form a NAPOT group. + * Each RV64 leaf MPTE covers 64KiB so one NAPOT group covers 2MiB. + * + * All other G values apart from 4 are reserved. + */ +#define RV64_NAPOT_G 4U +#define RV64_NAPOT_G_SHIFT 12U +#define RV64_NAPOT_MPTE_COUNT (1U << (RV64_NAPOT_G + 1)) +#define RV64_NAPOT_SIZE ((unsigned long)RV64_NAPOT_MPTE_COUNT * RV64_LEAF_RANGE) +#define RV64_NAPOT_PN0_ALIGN RV64_NAPOT_MPTE_COUNT + +/* + * Swith to disable NAPOT compaction of MPTE entries while writing. + */ +#define RV64_NAPOT_DISABLE 0 + +/* + * Supervisor Physucal address fields extraction + */ + +/* + * rv64_table_idx() — extract pn[level] from a SPA. + */ +static inline u32 rv64_table_idx(unsigned long pa, u32 level, + const struct sbi_mpt_mode *sch) +{ + u32 shift = 16 + level * 9; + u32 mask = (sch->mode_val == SBI_MMPT_MODE_SMMPT64 && level == 4) ? 0xFFF : 0x1FF; + + return ((pa >> shift) & mask); +} + +/* + * rv64_tuple_idx_shift() — XWR tuple index shift at level i. + */ +static inline u32 rv64_tuple_idx_shift(u32 level) +{ + return (SBI_MPT_PAGE_SHIFT + level * RV64_INNER_PN_BITS); +} + +static inline u32 rv64_tuple_idx(unsigned long pa, u32 level) +{ + return ((pa >> rv64_tuple_idx_shift(level)) & RV64_PAGES_PER_MPTE_MASK); +} + +/* + * rv64_mpte_range() — bytes covered by one MPTE at level L. + */ +static inline unsigned long rv64_mpte_range(u32 level) +{ + return RV64_LEAF_RANGE << (level * RV64_INNER_PN_BITS); +} + +/* + * RV64 MPTE Read/Write functions + */ + +static inline u64 rv64_read_mpte(unsigned long pa) +{ + return *(volatile u64 *)pa; +} + +static inline void rv64_write_mpte(unsigned long pa, u64 v) +{ + *(volatile u64 *)pa = v; +} + +static inline unsigned long rv64_mpte_pa(unsigned long table_pa, u32 idx) +{ + return (table_pa + idx * RV64_MPTE_SIZE); +} + +static inline unsigned long rv64_next_table_pa(u64 mpte) +{ + return (unsigned long)((u64)(mpte >> SBI_MPTE_PPN_SHIFT) << SBI_MPT_PAGE_SHIFT); +} + +/* + * Generate Napot Leaf MPTE + * + * Constructs one MPTE value used for all + * RV64_NAPOT_MPTE_COUNT entries in a NAPOT group. + * + * All MPTEs in the group are identical + */ +static inline u64 rv64_napot_leaf_mpte(u8 xwr) +{ + u64 mpte = SBI_MPTE_V | SBI_MPTE_L | SBI_MPTE_N; + + mpte = sbi_mpte_leaf_set_xwr(mpte, 0, xwr); + mpte |= ((u64)RV64_NAPOT_G << RV64_NAPOT_G_SHIFT); + + return mpte; +} + +/* + * rv64_napot_leaf_xwr() — recover the uniform XWR from a NAPOT leaf. + */ +static inline u8 rv64_napot_leaf_xwr(u64 mpte) +{ + return ((mpte >> SBI_MPTE_XWR_BASE) & SBI_MPTE_XWR_MASK); +} + +/* + * rv64_napot_demote() — Convert a Napot MPTE group into RV64_NAPOT_MPTE_COUNT + * normal(Non-Napot) MPTE carrying the SAME permission. + * + * leaf_mpte_pa is any leaf mpte pa from the Napot group + */ +static void rv64_napot_demote(struct sbi_mpt_domain *dom, + unsigned long leaf_mpte_pa, unsigned long pa) +{ + u8 xwr; + u32 pn0, pg, i; + u64 leaf; + unsigned long grp_base; + + xwr = rv64_napot_leaf_xwr(rv64_read_mpte(leaf_mpte_pa)); + pn0 = rv64_table_idx(pa, 0, dom->mode); + grp_base = leaf_mpte_pa - (pn0 & (RV64_NAPOT_MPTE_COUNT - 1)) * RV64_MPTE_SIZE; + leaf = SBI_MPTE_V | SBI_MPTE_L; + + for (pg = 0; pg < RV64_PAGES_PER_MPTE; pg++) + leaf = sbi_mpte_leaf_set_xwr(leaf, pg, xwr); + + for (i = 0; i < RV64_NAPOT_MPTE_COUNT; i++) + rv64_write_mpte(grp_base + i * RV64_MPTE_SIZE, leaf); +} + +/* + * MPT table best-level selection + * + * Returns the highest level at which the range [pa, pa+size] can be + * covered by a single leaf MPTE. Level 0 is always valid because thats + * the last resort. + */ +static u32 rv64_best_level(unsigned long pa, unsigned long size, + u32 top_level) +{ + u32 lvl; + unsigned long range; + + for (lvl = top_level; lvl >= 1; lvl--) { + range = rv64_mpte_range(lvl); + + if (size >= range && (pa & (range - 1)) == 0) + return lvl; + } + return 0; +} + +/* + * Generic N-level walk with lazy table allocation + */ +static unsigned long rv64_split_leaf(unsigned long parent_ep) +{ + u64 parent = rv64_read_mpte(parent_ep); + unsigned long sub; + u32 j, pg, sh; + u8 xwr; + u64 child; + + sub = sbi_mpt_pool_alloc(RV64_TABLE_SIZE, SBI_MPT_PAGE_SIZE); + if (!sub) + return 0; + + for (j = 0; j < RV64_INNER_ENTRIES; j++) { + sh = sbi_mpte_xwr_shift(j >> RV64_SPLIT_TUPLE_SHIFT); + xwr = (((unsigned long)parent >> sh) & SBI_MPTE_XWR_MASK); + child = SBI_MPTE_V | SBI_MPTE_L; /* N=0 uniform leaf */ + + for (pg = 0; pg < RV64_PAGES_PER_MPTE; pg++) + child = sbi_mpte_leaf_set_xwr(child, pg, xwr); + + rv64_write_mpte(sub + j * RV64_MPTE_SIZE, child); + } + + /* parent leaf -> non-leaf pointer to MPT sub table. */ + rv64_write_mpte(parent_ep, sbi_mpte_nonleaf(sub)); + + return sub; +} + +/* + * Walk a MPT table and return MPTE PA and its suitable level + */ +static unsigned long rv64_walk_alloc(struct sbi_mpt_domain *dom, + unsigned long pa, + unsigned long size, + u32 *out_level, + u32 top_level) +{ + u32 lvl, idx; + u64 mpte; + unsigned long ep, sub, new_pa; + const struct sbi_mpt_mode *sch = dom->mode; + unsigned long table_pa = dom->root_pa; + u32 best_lvl = rv64_best_level(pa, size, top_level); + + + for (lvl = top_level; lvl >= 1; lvl--) { + idx = rv64_table_idx(pa, lvl, sch); + ep = rv64_mpte_pa(table_pa, idx); + mpte = rv64_read_mpte(ep); + + if (mpte & SBI_MPTE_L) { + if (lvl > best_lvl) { + sub = rv64_split_leaf(ep); + if (!sub) + return 0; + + table_pa = sub; + continue; + } + + *out_level = lvl; + return ep; + } + + if (!(mpte & SBI_MPTE_V)) { + if (lvl <= best_lvl) { + *out_level = lvl; + return ep; + } + /* Allocate inner table (always 4KiB, all levels, all modes) */ + new_pa = sbi_mpt_pool_alloc(RV64_TABLE_SIZE, + SBI_MPT_PAGE_SIZE); + if (!new_pa) + return 0; + + rv64_write_mpte(ep, (u64)sbi_mpte_nonleaf(new_pa)); + table_pa = new_pa; + } + else { + table_pa = rv64_next_table_pa(mpte); + } + } + + *out_level = 0; + + return rv64_mpte_pa(table_pa, rv64_table_idx(pa, 0, sch)); +} + +/* + * Generic map_range — shared by Smmpt43, Smmpt52, Smmpt64 + * + * Maps a range [pa, pa+size] in the MPT table + */ +static int __rv64_map_range(struct sbi_mpt_domain *dom, + unsigned long pa, unsigned long size, + u8 xwr, u32 top_level) +{ + unsigned long cur = pa; + unsigned long end = pa + size; + unsigned long leaf_mpte_pa, mpte_range, mpte_base, mpte_end, batch_end; + u32 level, pn0, i, pg_first, pg_last, pg; + u64 napot, mpte; + + while (cur < end) { + /* + * Check if the region qualifies for NAPOT range and the + * region is contained + */ + if ((cur & (RV64_NAPOT_SIZE - 1)) == 0 && + cur + RV64_NAPOT_SIZE > cur && + cur + RV64_NAPOT_SIZE <= end) { + leaf_mpte_pa = rv64_walk_alloc(dom, cur, end - cur, &level, top_level); + if (!leaf_mpte_pa) + return SBI_ENOMEM; + + pn0 = rv64_table_idx(cur, 0, dom->mode); + + if (!RV64_NAPOT_DISABLE && level == 0 && (pn0 & (RV64_NAPOT_PN0_ALIGN - 1)) == 0) { + napot = rv64_napot_leaf_mpte(xwr); + + for (i = 0; i < RV64_NAPOT_MPTE_COUNT; i++) + rv64_write_mpte(leaf_mpte_pa + i * RV64_MPTE_SIZE, napot); + + cur += RV64_NAPOT_SIZE; + continue; + } + } + else { + leaf_mpte_pa = rv64_walk_alloc(dom, cur, end - cur, &level, top_level); + if (!leaf_mpte_pa) + return SBI_ENOMEM; + } + + /* Normal path */ + mpte_range = rv64_mpte_range(level); + pg_first = rv64_tuple_idx(cur, level); + mpte_base = cur & ~(mpte_range - 1); + + mpte_end = mpte_base + mpte_range; + if (mpte_end < mpte_base) + mpte_end = ~0UL; + + batch_end = (end < mpte_end) ? end : mpte_end; + pg_last = rv64_tuple_idx(batch_end - SBI_MPT_PAGE_SIZE, level); + + /* + * If this level-0 MPTE is a Napot member, expand the + * whole naturally-aligned group to plain leaves and write same + * permissions xwr + */ + mpte = rv64_read_mpte(leaf_mpte_pa); + if (level == 0 && (mpte & (u64)SBI_MPTE_N)) { + rv64_napot_demote(dom, leaf_mpte_pa, cur); + sbi_mpt_fence_sdid(dom->sdid); + mpte = rv64_read_mpte(leaf_mpte_pa); + } + + if (!(mpte & (u64)(SBI_MPTE_V | SBI_MPTE_L))) + mpte = (u64)(SBI_MPTE_V | SBI_MPTE_L); + + for (pg = pg_first; pg <= pg_last; pg++) + mpte = sbi_mpte_leaf_set_xwr(mpte, pg, xwr); + + rv64_write_mpte(leaf_mpte_pa, mpte); + + cur = batch_end; + } + + return 0; +} + +/* + * Per-mode mmpt encoding + */ + +static unsigned long smmpt43_encode_mmpt(unsigned long ppn, u32 sdid) +{ + return sbi_mmpt_encode(SBI_MMPT_MODE_SMMPT43, sdid, ppn); +} + +static unsigned long smmpt52_encode_mmpt(unsigned long ppn, u32 sdid) +{ + return sbi_mmpt_encode(SBI_MMPT_MODE_SMMPT52, sdid, ppn); +} + +static unsigned long smmpt64_encode_mmpt(unsigned long ppn, u32 sdid) +{ + return sbi_mmpt_encode(SBI_MMPT_MODE_SMMPT64, sdid, ppn); +} + +static unsigned long smmpt43_root_table_size(void) +{ + return RV64_TABLE_SIZE; +} + +static unsigned long smmpt43_root_table_align(void) +{ + return SBI_MPT_PAGE_SIZE; +} + +static bool smmpt43_pa_in_range(unsigned long pa, unsigned long size) +{ + unsigned long pa_max = 1UL << 43; + + return (pa < pa_max && size <= pa_max - pa); +} + +static unsigned long smmpt52_root_table_size(void) +{ + return RV64_TABLE_SIZE; +} + +static unsigned long smmpt52_root_table_align(void) +{ + return SBI_MPT_PAGE_SIZE; +} + +static bool smmpt52_pa_in_range(unsigned long pa, unsigned long size) +{ + unsigned long pa_max = 1UL << 52; + + return (pa < pa_max && size <= pa_max - pa); +} + +static unsigned long smmpt64_root_table_size(void) +{ + return RV64_ROOT_SMMPT64_SIZE; +} + +static unsigned long smmpt64_root_table_align(void) +{ + return RV64_ROOT_SMMPT64_SIZE; +} + +static bool smmpt64_pa_in_range(unsigned long pa, + unsigned long size) +{ + /* + * Smmpt64 covers the full 64-bit PA space. + */ + return true; +} + +/* + * Per-mode map_range wrappers + * + * Smmpt43: + * Root level 2, 9-bit, 512 entries, 4KiB root MPT size + * + * Smmpt52: + * Root level 3, 9-bit, 512 entries, 4KiB root MPT size + * + * Smmpt64: + * Root level 4, 12-bit, 4096 entries, 32KiB root MPT size + */ + +static int smmpt43_map_range(struct sbi_mpt_domain *dom, + unsigned long pa, unsigned long size, u8 xwr) +{ + return __rv64_map_range(dom, pa, size, xwr, 2); +} + +static int smmpt52_map_range(struct sbi_mpt_domain *dom, + unsigned long pa, unsigned long size, u8 xwr) +{ + return __rv64_map_range(dom, pa, size, xwr, 3); +} + +static int smmpt64_map_range(struct sbi_mpt_domain *dom, + unsigned long pa, unsigned long size, u8 xwr) +{ + return __rv64_map_range(dom, pa, size, xwr, 4); +} + +/* + * __rv64_map_full_range() — Write every MPTE at Root MPT + * + * Writes xwr into every root table MPTE directly as a leaf + * superpage covering the mode entire addressable PA range. + * No intermidiate MPT tables allocated just all leaf MPTEs at + * root level. + */ + +static int __rv64_map_full_range(struct sbi_mpt_domain *dom, u8 xwr, + unsigned long root_entries) +{ + u32 pg; + unsigned long i; + u64 mpte = SBI_MPTE_V | SBI_MPTE_L; + + for (pg = 0; pg < RV64_PAGES_PER_MPTE; pg++) + mpte = sbi_mpte_leaf_set_xwr(mpte, pg, xwr); + + for (i = 0; i < root_entries; i++) + rv64_write_mpte(rv64_mpte_pa(dom->root_pa, i), mpte); + + return 0; +} + +static int smmpt43_map_full_range(struct sbi_mpt_domain *dom, u8 xwr) +{ + return __rv64_map_full_range(dom, xwr, RV64_INNER_ENTRIES); +} + +static int smmpt52_map_full_range(struct sbi_mpt_domain *dom, u8 xwr) +{ + return __rv64_map_full_range(dom, xwr, RV64_INNER_ENTRIES); +} + +static int smmpt64_map_full_range(struct sbi_mpt_domain *dom, u8 xwr) +{ + return __rv64_map_full_range(dom, xwr, RV64_ROOT_SMMPT64_ENTRIES); +} + +/* + * Get the access permissions(xwr) of a PA + */ +static u8 __rv64_get_xwr(struct sbi_mpt_domain *dom, unsigned long pa, + u32 top_level) +{ + const struct sbi_mpt_mode *sch = dom->mode; + unsigned long table_pa = dom->root_pa; + u32 level, idx, pi; + u64 mpte; + + for (level = top_level; ; level--) { + idx = rv64_table_idx(pa, level, sch); + mpte = rv64_read_mpte(rv64_mpte_pa(table_pa, idx)); + + if (!(mpte & SBI_MPTE_V)) + return SBI_MPT_PERM_NONE; + + if (!(mpte & SBI_MPTE_L) && (mpte & SBI_MPTE_N)) + return SBI_MPT_PERM_NONE; + + if (mpte & SBI_MPTE_L) { + if (mpte & SBI_MPTE_N) + return rv64_napot_leaf_xwr(mpte); + + pi = rv64_tuple_idx(pa, level); + + return (mpte >> sbi_mpte_xwr_shift(pi)) & SBI_MPTE_XWR_MASK; + } + + if (level == 0) + return SBI_MPT_PERM_NONE; + + table_pa = rv64_next_table_pa(mpte); + } + + return SBI_MPT_PERM_NONE; +} + +static u8 smmpt43_get_xwr(struct sbi_mpt_domain *dom, unsigned long pa) +{ + return __rv64_get_xwr(dom, pa, 2); +} + +static u8 smmpt52_get_xwr(struct sbi_mpt_domain *dom, unsigned long pa) +{ + return __rv64_get_xwr(dom, pa, 3); +} + +static u8 smmpt64_get_xwr(struct sbi_mpt_domain *dom, unsigned long pa) +{ + return __rv64_get_xwr(dom, pa, 4); +} + +struct sbi_mpt_mode smmpt43_mode = { + .name = "Smmpt43", + .mode_val = SBI_MMPT_MODE_SMMPT43, + .encode_mmpt = smmpt43_encode_mmpt, + .map_range = smmpt43_map_range, + .root_table_size = smmpt43_root_table_size, + .root_table_align = smmpt43_root_table_align, + .pa_in_range = smmpt43_pa_in_range, + .map_full_range = smmpt43_map_full_range, + .get_xwr = smmpt43_get_xwr, +}; + +struct sbi_mpt_mode smmpt52_mode = { + .name = "Smmpt52", + .mode_val = SBI_MMPT_MODE_SMMPT52, + .encode_mmpt = smmpt52_encode_mmpt, + .map_range = smmpt52_map_range, + .root_table_size = smmpt52_root_table_size, + .root_table_align = smmpt52_root_table_align, + .pa_in_range = smmpt52_pa_in_range, + .map_full_range = smmpt52_map_full_range, + .get_xwr = smmpt52_get_xwr, +}; + +struct sbi_mpt_mode smmpt64_mode = { + .name = "Smmpt64", + .mode_val = SBI_MMPT_MODE_SMMPT64, + .encode_mmpt = smmpt64_encode_mmpt, + .map_range = smmpt64_map_range, + .root_table_size = smmpt64_root_table_size, + .root_table_align = smmpt64_root_table_align, + .pa_in_range = smmpt64_pa_in_range, + .map_full_range = smmpt64_map_full_range, + .get_xwr = smmpt64_get_xwr, +}; + +#else /* __riscv_xlen == 64 */ + +/* + * Smmpt34 (RV32) — 34-bit supervisor physical address (SPA) + * + * +---------+---------+---------+--------+ + * | pn[1] | pn[0] | pi | offset | + * | [33:25] | [24:15] | [14:12] | [11:0] | + * | 9b | 10b | 3b | 12b | + * +---------+---------+---------+--------+ + * + */ + +#define RV32_MPTE_SIZE 4UL +#define RV32_ROOT_ENTRIES 512U +#define RV32_LEAF_ENTRIES 1024U +#define RV32_ROOT_SIZE (RV32_ROOT_ENTRIES * RV32_MPTE_SIZE) +#define RV32_LEAF_SIZE (RV32_LEAF_ENTRIES * RV32_MPTE_SIZE) + +/* pn field widths */ +#define RV32_PN1_BITS 9U +#define RV32_PN0_BITS 10U + +#define RV32_NUMPGINRANGE 3U +#define RV32_PAGES_PER_MPTE (1U << RV32_NUMPGINRANGE) +#define RV32_PAGES_PER_MPTE_MASK (RV32_PAGES_PER_MPTE - 1) + +/* Range covered by one MPTE at each level */ +#define RV32_LEAF_RANGE (RV32_PAGES_PER_MPTE * SBI_MPT_PAGE_SIZE) +#define RV32_ROOT_RANGE (RV32_LEAF_RANGE << RV32_PN0_BITS) + +/* NAPOT constants (G=6) */ +#define RV32_NAPOT_G 6U +#define RV32_NAPOT_G_SHIFT 12U +#define RV32_NAPOT_COUNT (1U << (RV32_NAPOT_G + 1)) +#define RV32_NAPOT_SIZE (RV32_NAPOT_COUNT * RV32_LEAF_RANGE) +#define RV32_NAPOT_PN0_ALIGN RV32_NAPOT_COUNT + +/* + * Swith to disable NAPOT compaction of MPTE entries while writing. + */ +#define RV32_NAPOT_DISABLE 0 + +/* + * rv32_pn1_table_idx() — extract pn[1] from a SPA. + */ +static inline u32 rv32_pn1_table_idx(unsigned long pa) +{ + return ((pa >> 25) & 0x1FFU); +} + +/* + * rv32_pn0_table_idx() — extract pn[0] from a SPA. + */ +static inline u32 rv32_pn0_table_idx(unsigned long pa) +{ + return ((pa >> 15) & 0x3FFU); +} + +static inline u32 rv32_tuple_idx_shift(u32 level) +{ + return (level == 0) ? SBI_MPT_PAGE_SHIFT : SBI_MPT_PAGE_SHIFT + RV32_PN0_BITS; +} + +static inline u32 rv32_tuple_idx(unsigned long pa, u32 level) +{ + return ((pa >> rv32_tuple_idx_shift(level)) & RV32_PAGES_PER_MPTE_MASK); +} + +/* + * Bytes covered by one MPTE at the given level + */ +static inline unsigned long rv32_mpte_range(u32 level) +{ + return (level == 0) ? RV32_LEAF_RANGE : RV32_ROOT_RANGE; +} + +/* + * RV32 MPTE Read/Write functions + */ +static inline u32 rv32_read_mpte(unsigned long pa) +{ + return *(volatile u32 *)pa; +} + +static inline void rv32_write_mpte(unsigned long pa, u32 v) +{ + *(volatile u32 *)pa = v; +} + +static inline unsigned long rv32_mpte_pa(unsigned long table_pa, u32 idx) +{ + return (table_pa + idx * RV32_MPTE_SIZE); +} + +static inline unsigned long rv32_next_table_pa(u32 mpte) +{ + return ((mpte >> SBI_MPTE_PPN_SHIFT) << SBI_MPT_PAGE_SHIFT); +} + +/* + * Generate Napot Leaf MPTE + * + * Constructs one MPTE value used for all RV32_NAPOT_COUNT entries + * in a NAPOT group. + * + * All MPTEs in the group are identical + */ +static inline u32 rv32_napot_leaf(u8 xwr) +{ + u32 mpte = SBI_MPTE_V | SBI_MPTE_L | SBI_MPTE_N; + + mpte = sbi_mpte_leaf_set_xwr(mpte, 0, xwr); + mpte |= ((u32)RV32_NAPOT_G << RV32_NAPOT_G_SHIFT); + + return mpte; +} + +/* + * Get the xwr from a Napot leaf. + */ +static inline u8 rv32_napot_xwr(u32 mpte) +{ + return ((mpte >> SBI_MPTE_XWR_BASE) & SBI_MPTE_XWR_MASK); +} + +/* + * rv32_napot_demote() — Convert a Napot MPTE group into RV64_NAPOT_MPTE_COUNT + * normal(Non-Napot) MPTE carrying the SAME permission. + * + * leaf_mpte_pa is any of the group MPTE PA + */ +static void rv32_napot_demote(struct sbi_mpt_domain *dom, + unsigned long leaf_mpte_pa, unsigned long pa) +{ + u32 pg, leaf, i; + unsigned long grp_base; + u8 xwr = rv32_napot_xwr(rv32_read_mpte(leaf_mpte_pa)); + u32 pn0 = rv32_pn0_table_idx(pa); + + grp_base = leaf_mpte_pa - (pn0 & (RV32_NAPOT_COUNT - 1)) * RV32_MPTE_SIZE; + + leaf = (SBI_MPTE_V | SBI_MPTE_L); /* N=0 */ + + for (pg = 0; pg < RV32_PAGES_PER_MPTE; pg++) + leaf = sbi_mpte_leaf_set_xwr(leaf, pg, xwr); + + for (i = 0; i < RV32_NAPOT_COUNT; i++) + rv32_write_mpte(grp_base + i * RV32_MPTE_SIZE, leaf); +} + +static inline u32 rv32_best_level(unsigned long pa, unsigned long size) +{ + if (size >= RV32_ROOT_RANGE && (pa & (RV32_ROOT_RANGE - 1)) == 0) + return 1; + + return 0; +} + +/* + * MPT Walk for RV32 Smmpt43 + * + * Returns the PA of the MPTE covering pa + */ +static unsigned long rv32_walk_alloc(struct sbi_mpt_domain *dom, + unsigned long pa, + unsigned long size, + u32 *out_level) +{ + unsigned long root_ep = rv32_mpte_pa(dom->root_pa, rv32_pn1_table_idx(pa)); + u32 root_mpte = rv32_read_mpte(root_ep); + u32 best = rv32_best_level(pa, size); + unsigned long leaf_pa; + + if (root_mpte & (u32)SBI_MPTE_L) { + /* Existing root-level leaf */ + *out_level = 1; + return root_ep; + } + + if (!(root_mpte & (u32)SBI_MPTE_V) && best == 1) { + /* new entry, range fits at root level so skip leaf allocation */ + *out_level = 1; + return root_ep; + } + + if (!(root_mpte & (u32)SBI_MPTE_V)) { + /* Allocate leaf table from global heap */ + leaf_pa = sbi_mpt_pool_alloc(RV32_LEAF_SIZE, + SBI_MPT_PAGE_SIZE); + if (!leaf_pa) + return 0; + + rv32_write_mpte(root_ep, sbi_mpte_nonleaf(leaf_pa)); + *out_level = 0; + + return rv32_mpte_pa(leaf_pa, rv32_pn0_table_idx(pa)); + } + + /* Valid non-leaf: follow PPN to existing leaf table */ + *out_level = 0; + + return rv32_mpte_pa(rv32_next_table_pa(rv32_read_mpte(root_ep)), rv32_pn0_table_idx(pa)); +} + +/* + * smmpt34_map_range(): Maps a range [pa, pa+size] in the MPT table + */ + +static int smmpt34_map_range(struct sbi_mpt_domain *dom, + unsigned long pa, unsigned long size, u8 xwr) +{ + unsigned long cur = pa; + unsigned long end = pa + size; + unsigned long leaf_mpte_pa; + unsigned long mpte_range, mpte_base, mpte_end, batch_end; + u32 level, pg_first, pg_last, pg, i; + u32 mpte, napot; + + while (cur < end) { + /* + * Check if the region qualifies for NAPOT range and the + * region is contained + */ + if ((cur & (RV32_NAPOT_SIZE - 1)) == 0 && + cur + RV32_NAPOT_SIZE > cur && + cur + RV32_NAPOT_SIZE <= end) { + leaf_mpte_pa = rv32_walk_alloc(dom, cur, end - cur, &level); + if (!leaf_mpte_pa) + return SBI_ENOMEM; + + if (!RV32_NAPOT_DISABLE && level == 0 && (rv32_pn0_table_idx(cur) & (RV32_NAPOT_PN0_ALIGN - 1)) == 0) { + napot = rv32_napot_leaf(xwr); + + for (i = 0; i < RV32_NAPOT_COUNT; i++) + rv32_write_mpte(leaf_mpte_pa + i * RV32_MPTE_SIZE, napot); + + cur += RV32_NAPOT_SIZE; + + continue; + } + } else { + leaf_mpte_pa = rv32_walk_alloc(dom, cur, end - cur, &level); + if (!leaf_mpte_pa) + return SBI_ENOMEM; + } + + /* Normal path */ + mpte_range = rv32_mpte_range(level); + pg_first = rv32_tuple_idx(cur, level); + mpte_base = cur & ~(mpte_range - 1UL); + mpte_end = mpte_base + mpte_range; + batch_end = (end < mpte_end) ? end : mpte_end; + pg_last = rv32_tuple_idx(batch_end - SBI_MPT_PAGE_SIZE, level); + + /* + * If this level-0 MPTE is a Napot member, expand the + * whole naturally-aligned group to plain leaves and write same + * permissions xwr + */ + mpte = rv32_read_mpte(leaf_mpte_pa); + if (level == 0 && (mpte & (u32)SBI_MPTE_N)) { + rv32_napot_demote(dom, leaf_mpte_pa, cur); + sbi_mpt_fence_sdid(dom->sdid); + mpte = rv32_read_mpte(leaf_mpte_pa); + } + if (!(mpte & (u32)(SBI_MPTE_V | SBI_MPTE_L))) + mpte = SBI_MPTE_V | SBI_MPTE_L; + + for (pg = pg_first; pg <= pg_last; pg++) + mpte = sbi_mpte_leaf_set_xwr(mpte, pg, xwr); + + rv32_write_mpte(leaf_mpte_pa, mpte); + cur = batch_end; + } + + return 0; +} + +/* + * mmpt encoding + */ +static unsigned long smmpt34_encode_mmpt(unsigned long ppn, u32 sdid) +{ + return sbi_mmpt_encode(SBI_MMPT_MODE_SMMPT34, sdid, ppn); +} + +static unsigned long smmpt34_root_table_size(void) +{ + return RV32_ROOT_SIZE; +} + +static unsigned long smmpt34_root_table_align(void) +{ + return SBI_MPT_PAGE_SIZE; +} + +static bool smmpt34_pa_in_range(unsigned long pa, unsigned long size) +{ + /* + * Return true since 1 << 34 wil be UB + * in RV32 case and anyways variables are limited by RV32 + * architectural width + */ + + return true; +} + +/* + * smmpt34_map_full_range() — Write every MPTE at Root MPT + * + * Writes xwr into every root table MPTE directly as a leaf + * superpage covering the mode entire addressable PA range. + * No intermidiate MPT tables allocated just all leaf MPTEs at + * root level. + */ + +static int smmpt34_map_full_range(struct sbi_mpt_domain *dom, u8 xwr) +{ + u32 mpte = SBI_MPTE_V | SBI_MPTE_L; + u32 pg, i; + + for (pg = 0; pg < RV32_PAGES_PER_MPTE; pg++) + mpte = sbi_mpte_leaf_set_xwr(mpte, pg, xwr); + + for (i = 0; i < RV32_ROOT_ENTRIES; i++) + rv32_write_mpte(rv32_mpte_pa(dom->root_pa, i), mpte); + + return 0; +} + +/* Get the access permissions(xwr) of a PA */ +static u8 smmpt34_get_xwr(struct sbi_mpt_domain *dom, unsigned long pa) +{ + u32 mpte, pi; + unsigned long table_pa = dom->root_pa; + + mpte = rv32_read_mpte(rv32_mpte_pa(table_pa, rv32_pn1_table_idx(pa))); + + if (!(mpte & SBI_MPTE_V)) + return SBI_MPT_PERM_NONE; + + if (!(mpte & SBI_MPTE_L) && (mpte & SBI_MPTE_N)) + return SBI_MPT_PERM_NONE; + + if (mpte & SBI_MPTE_L) { + if (mpte & SBI_MPTE_N) + return rv32_napot_xwr(mpte); + + pi = rv32_tuple_idx(pa, 1); + return (mpte >> sbi_mpte_xwr_shift(pi)) & SBI_MPTE_XWR_MASK; + } + + table_pa = rv32_next_table_pa(mpte); + mpte = rv32_read_mpte(rv32_mpte_pa(table_pa, rv32_pn0_table_idx(pa))); + + if (!(mpte & SBI_MPTE_V) || !(mpte & SBI_MPTE_L)) + return SBI_MPT_PERM_NONE; + + if (mpte & SBI_MPTE_N) + return rv32_napot_xwr(mpte); + + pi = rv32_tuple_idx(pa, 0); + + return ((mpte >> sbi_mpte_xwr_shift(pi)) & SBI_MPTE_XWR_MASK); +} + +struct sbi_mpt_mode smmpt34_mode = { + .name = "Smmpt34", + .mode_val = SBI_MMPT_MODE_SMMPT34, + .encode_mmpt = smmpt34_encode_mmpt, + .map_range = smmpt34_map_range, + .root_table_size = smmpt34_root_table_size, + .root_table_align = smmpt34_root_table_align, + .pa_in_range = smmpt34_pa_in_range, + .map_full_range = smmpt34_map_full_range, + .get_xwr = smmpt34_get_xwr, +}; + +#endif /* __riscv_xlen == 32 */ From patchwork Mon Aug 24 02:09:52 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Pathak X-Patchwork-Id: 2290634 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=GL5Hk9N+; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=cZUsO53d; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.a=rsa-sha256 header.s=google header.b=JUoOF0EG; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) 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 4hSvX01npxz1xwG for ; Mon, 24 Aug 2026 12:10:40 +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=nRo5CoooKPlgQBmM41JHbN2P2NBk1bX7U8TXtOGMMEs=; b=GL5Hk9N+ZOTHKt kILzGmRJnyd4avJoxpLtH/7lpi16puNLIDGlt/lfgF6zMPLNfGTa7Zndv9pES6TFZBHqZ9XcI15EI 9zJH0jAv99zjklwTCFzRj2sydCMYCj168eC0UT0q6HrMrJZDxwKXzufSEE9pL10o5mI3aDYy8OtnY Ks/j47ZIZjya11ywKzzD10HasI89ydAUIBTXI79mbefgXGrbdaU8sXy96W2VLfneNpooZJl7dddK4 bVn6cK/OJRSiFSRVVYg7yxJ2k/gDFwoBF6j6hTRx1Bt7jEANz/aVC3+XHpxdCm6Y+4uKRZbJUXsUt WA4KgioRq6yvWzEdbVeA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wyK8u-0000000Fl2Y-3Ifj; Mon, 24 Aug 2026 02:10:32 +0000 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wyK8r-0000000Fl0f-2HFR for opensbi@lists.infradead.org; Mon, 24 Aug 2026 02:10:31 +0000 Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67O0lfWl983217 for ; Mon, 24 Aug 2026 02:10:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=P+fnBYZnpAM vzlvirkb8jUt1h2rexRwJtAHpGC9p5FQ=; b=cZUsO53dXB7pc5R9/X60zFogAUo xx39gujF6zUAJ+N1ujI6uzHQFv/CCtYaOmO6xLBzsUlGZFES54ijrCdWtQ8Us1hi NdzcWllMNCjzrFCGY2oRwnEpyFafO1kRBneG9VgIy3BGfeGO39NIzTm95hW/9XyK CQSfw7/5ganOyrvIn1djSb1wbqvQY5EXGPci+0aLBLZacHoC/yfX4v3ZzLoZhMgn Ok7hMNTaWiOAaLOgyEH+SHJN4++QN2pwsKpB8qsZVVBgvjFnuAG5aaiVWILFPWWZ x765a9KVJ5Yn8Tr9f1WRtl1N852gCnYj1wPZ5HomPWCURuOeOg7yjGBcZ8g== Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g7456w2er-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 24 Aug 2026 02:10:28 +0000 (GMT) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2d63c48886bso52721065ad.0 for ; Sun, 23 Aug 2026 19:10:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787537427; x=1788142227; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=P+fnBYZnpAMvzlvirkb8jUt1h2rexRwJtAHpGC9p5FQ=; b=JUoOF0EGud2sLY79/nHIa+cgdAO1lft4EQxv0RxwqTfUIAwOa9yWVtNLS+5MCV6x++ jMu5HrifgN3wehZVLQLmAfomKFtP5w4gf4ZaAmjrURVzZuMVJHSSzXZUbKLdBekzAWvZ 6xLCbRiLrLio9qW2QUO66TBraZ2b4G0G5CRTp0013U0Y7qOsAeHe1zvl4Aj2MrzDY4/F KFiX0ceEuxzmKxmxzYSKqnkHmhY83sZCSaLfRkVD15EEMgMb+ZlMYw7IlfxxFfxbu5p/ kbCxAFn8AYvBqRA72i52qKIPcbup/LEZmQF+o2f93fjnug6agra0IBKrzn8N2MFRgbHh EmYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787537427; x=1788142227; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=P+fnBYZnpAMvzlvirkb8jUt1h2rexRwJtAHpGC9p5FQ=; b=neCaaaK5dAIyNGfpLCbbTgB62Yp+VuJnyNNIv21v5T16lp1egI1onWRJYMHybrfH0H fGwmqsy6dEzsUPoinqJsmaREi/nv6uJ9ldhibXxvbQVpaHN60kVxeoHsWgOGVCGMSaKe VCHxP1eoVLx9xyNWQqOcU1Fs/8jSckFdcK0Q98Q+wuhLYtqhuw2rbz6GGsOBgerhLuNC J8JI2fkbp9+hXW7+7pnVV+ijKEGkdb9ws/qA8c+nHVtgF3mOgV0xUdWtfBXV8fqFot6h ayHa5hg8SFnNV7/SWl2/3HeCKTSMdmtqCBZntERdcFxLIjx21ReqNzkWqPiF7Jw6AWCK oRiQ== X-Gm-Message-State: AFuF++l0T+wVcMaqvaEluZRTA+LdTYIetbZ0FahoTqpwfElwBHnEkXSH OpN0aqjXGMaR6GU4sVnu6pgSmpsfrRFaYUAm/Irbl26WuU8YviPL6AvK/IhgngIRgMaczOnLuZ0 VEKsPfMduvfC1VNMIajjgnHiinUNw8E7Xbu9HYSYW/db75xIy62sh4wb4eJnB6TH+ulJLg8Kg6w == X-Gm-Gg: AR+sD12BqiiWKWCOaCFgzPlDLm/bEcgz6edijWbT3WUnw7f4Mjs5NwgJW61/5rE3qT2 oesiWa22Ae4/lP35Vpj6CJ/FvYZcTszDH5BMd7d88R90d8Ku10/boRwuwPHxVTZHAt8u+UZ1v5L m98MvKkFlpgE3nb+oo1KgtWDeZSri9wgjtwiDXMelmpwTGmpMjCDtyauTsGqkaN9SA7sXlYFLLv yLC9Cn7fbC1MTL4j3DNwoFxHVNffzyTg1yLwNGzf5ZuPXseh6E/knNtIQwXLEQgz/cKUYc9wAvY zPCLd94oivhH4wMCbpEZhzYcIaoKn1KQaVU285Mewb3Af4jsf5pgkemQfwyMtRXiEQ34obVjlxG 0w2aW0IHb7bAp/r9ReoT3YU9/eoPVzBMc2Rvkmpup8fkPNWAtEqs9eAu9PDBtmg+Uty85of1gEz CT4O8M2sN1Sdmo8BmIHfVN X-Received: by 2002:a17:902:d4c5:b0:2d3:104b:1acf with SMTP id d9443c01a7336-2d64afe8b7dmr383429445ad.8.1787537423589; Sun, 23 Aug 2026 19:10:23 -0700 (PDT) X-Received: by 2002:a17:902:d4c5:b0:2d3:104b:1acf with SMTP id d9443c01a7336-2d64afe8b7dmr383418755ad.8.1787537415971; Sun, 23 Aug 2026 19:10:15 -0700 (PDT) Received: from hu-rahupath-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-327f92359c9sm20487634eec.27.2026.08.23.19.10.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2026 19:10:15 -0700 (PDT) From: Rahul Pathak To: opensbi@lists.infradead.org Cc: rahul.pathak@oss.qualcomm, rahul@summations.net, Rahul Pathak Subject: [RFC PATCH v4 4/4] lib: sbi: Initialize SMMPT during coldboot Date: Mon, 24 Aug 2026 07:39:52 +0530 Message-ID: <20260824020953.2438946-5-rahul.pathak@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260824020953.2438946-1-rahul.pathak@oss.qualcomm.com> References: <20260824020953.2438946-1-rahul.pathak@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-Spam-Info: AW1haW4tMjYwODI0MDAxNyBTYWx0ZWRfX/OBtZzBCVDpi E0qvc/3at3eICNmU8DLXgQqIwKJ0p/cwgCsQAWRkjXMJBs81o/Vw97d45js4+j9kv5d2JjrhUsZ R3qWZ9LUIo4E3oL1by2u7QruKAHANzA= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI0MDAxNyBTYWx0ZWRfX8cJS0Vf85h9n dtE1dqVnF2U2X2B0JRa70547k/PT5nH/m5G3w6ar2FF5iZgfRcmhsS7FI80w0genImGJSy62gB6 Sv7Ej+rQB5nC4WowAY8pQLqatvAM2IS5cNryH7zViZb30gxhNwm7cWn79jSF67U4RrMCw0QhjhJ kwVfOIyoXbk7NViPDEiy+UT5Jjtbjp+Hb/zK3F8VV8+r/7ydqmjvcyrEvSstlFQMhis4j5/cneR BeTqGitTQqcXtlcsxj+r2cdYu5qFI2ytjBJDagzJkQP12kOTnm1yu6ylCJ03HVb3Mu+KIvsk4Ye cHepxdmTjGVeV+kgaF0EMKi3tZFKhNKawoWG8inDqZfOgoHmjxwabGMkGuu5bAN1Ii8sSCj2BAz d7vZAhSMwbd9eAA53xiGv7mPLiDdz4oQnb0RqP5b9Ll/tU3G2cSHV72+/RAoC2rNIcnS3VnSJB0 AGZJiXeOzAcQZbvp2lA== X-Authority-Analysis: v=2.4 cv=RtL16imK c=1 sm=1 tr=0 ts=6a8ba814 cx=c_pps a=cmESyDAEBpBGqyK7t0alAg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yx91gb_oNiZeI1HMLzn7:22 a=EUspDBNiAAAA:8 a=rd1Op-0AFHWMy0GXr_EA:9 a=1OuFwYUASf3TG4hYMiVC:22 X-Proofpoint-ORIG-GUID: hfqZet3GV42YlTSa5LfGDZLDQaFPKGlP X-Proofpoint-GUID: hfqZet3GV42YlTSa5LfGDZLDQaFPKGlP X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-24_01,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 adultscore=0 malwarescore=0 phishscore=0 impostorscore=0 priorityscore=1501 suspectscore=0 bulkscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608240017 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260823_191030_222476_E76AD926 X-CRM114-Status: GOOD ( 15.39 ) X-Spam-Score: -2.8 (--) 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: Call sbi_mpt_init() function from coldboot path of sbi_hart_init() to initialize the SMMPT core. It will create and the MPT tables for each SBI domain and maps its memregions with appropriate permissi [...] Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, low trust [205.220.180.131 listed in list.dnswl.org] -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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -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 -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.0 DMARC_PASS DMARC pass policy 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 Call sbi_mpt_init() function from coldboot path of sbi_hart_init() to initialize the SMMPT core. It will create and the MPT tables for each SBI domain and maps its memregions with appropriate permissions in MPT tables. Also each MPT table requires to memory to install tables so reserve more space in heap for MPT tables Signed-off-by: Rahul Pathak --- lib/sbi/sbi_hart.c | 8 +++++++- platform/generic/platform.c | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index 4261fea8..cc18b2c5 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -1,4 +1,4 @@ -/* +/*sbi_hart. * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Western Digital Corporation or its affiliates. @@ -21,6 +21,7 @@ #include #include #include +#include extern void __sbi_expected_trap(void); extern void __sbi_expected_trap_hext(void); @@ -731,6 +732,11 @@ int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot) rc = sbi_hart_pmp_init(scratch); if (rc) return rc; + + /* Smmpt is optional. Continue if the Smmpt is not present. */ + rc = sbi_mpt_init(); + if (rc && rc != SBI_ENODEV) + return rc; } return sbi_hart_reinit(scratch); diff --git a/platform/generic/platform.c b/platform/generic/platform.c index 1df0280d..ccf6f756 100644 --- a/platform/generic/platform.c +++ b/platform/generic/platform.c @@ -42,6 +42,15 @@ static u32 fw_platform_calculate_heap_size(u32 hart_count) /* For TLB fifo */ heap_size += SBI_TLB_INFO_SIZE * (hart_count) * (hart_count); + /* + * MPT table budget + * 1 MiB memory for MPT allocated currently. + * + * TODO: Need better way to get the memory budget based on active + * SMMPT mode. + */ + heap_size += 1024 * 1024; + return BIT_ALIGN(heap_size, HEAP_BASE_ALIGN); }