public inbox for opensbi@lists.infradead.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/7] Extend the reserved PMP entries
@ 2025-08-15 10:01 Yu-Chien Peter Lin
  2025-08-15 10:01 ` [RFC PATCH 1/7] lib: utils: fdt_helper: add fdt_has_isa_extension() helper Yu-Chien Peter Lin
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Yu-Chien Peter Lin @ 2025-08-15 10:01 UTC (permalink / raw)
  To: opensbi; +Cc: greentime.hu, Yu-Chien Peter Lin, zong.li

This series extends the number of reserved PMP entry.
The capabilities of the reserved PMP entries include:
- Highest priority
- Allow TOR mode for platform-specific use cases
- Can be consistent across domain context switches
- Allow runtime PMP allocation

A potential use case for reserved PMP entries is parsing gaps in
memory ports marked as PMA_UNSAFE [1] in device-tree. These gaps
may not be able to exactly covered by 1 or 2 NAPOT entries, so TOR
mode PMP can be allocated to save PMP usage. Besides, they don't
need reconfiguration across domains.

This series depends on:
1) https://lore.kernel.org/all/20250815024434.14303-1-peter.lin@sifive.com/
2) https://lore.kernel.org/all/20250814110522.18809-1-peter.lin@sifive.com/

[1] https://patchwork.kernel.org/project/linux-riscv/patch/20241102000843.1301099-2-samuel.holland@sifive.com/

Yu-Chien Peter Lin (7):
  lib: utils: fdt_helper: add fdt_has_isa_extension() helper
  include: sbi: sbi_platform: add reserved_pmp_count field
  platform: generic: platform: introduce
    fw_platform_get_reserved_pmp_count()
  lib: sbi_init: print total and reserved PMP counts
  lib: sbi: riscv_asm: add reserved_pmp_alloc() to allocate a reserved
    PMP
  lib: sbi: sbi_hart: extend PMP handling to support multiple reserved
    entries
  docs: opensbi_config: add description for reserved-pmp-count

 docs/opensbi_config.md             |  4 +++
 include/sbi/riscv_asm.h            |  2 ++
 include/sbi/sbi_hart.h             | 15 --------
 include/sbi/sbi_platform.h         | 15 +++++---
 include/sbi_utils/fdt/fdt_helper.h |  2 ++
 lib/sbi/riscv_asm.c                | 25 +++++++++++++
 lib/sbi/sbi_domain_context.c       |  6 +++-
 lib/sbi/sbi_hart.c                 | 56 ++++++++++++++++++++++--------
 lib/sbi/sbi_init.c                 |  6 ++--
 lib/utils/fdt/fdt_helper.c         | 35 +++++++++++++++++++
 platform/generic/platform.c        | 34 ++++++++++++++++++
 11 files changed, 163 insertions(+), 37 deletions(-)

-- 
2.48.0


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [RFC PATCH 1/7] lib: utils: fdt_helper: add fdt_has_isa_extension() helper
  2025-08-15 10:01 [RFC PATCH 0/7] Extend the reserved PMP entries Yu-Chien Peter Lin
@ 2025-08-15 10:01 ` Yu-Chien Peter Lin
  2025-08-15 10:01 ` [RFC PATCH 2/7] include: sbi: sbi_platform: add reserved_pmp_count field Yu-Chien Peter Lin
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Yu-Chien Peter Lin @ 2025-08-15 10:01 UTC (permalink / raw)
  To: opensbi; +Cc: greentime.hu, Yu-Chien Peter Lin, zong.li

Add a helper function to search for a given ISA string in
`riscv,isa-extensions` or `riscv,isa` properties within
the FDT.

Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
 include/sbi_utils/fdt/fdt_helper.h |  2 ++
 lib/utils/fdt/fdt_helper.c         | 35 ++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index 24ad1a94..8aa216c7 100644
--- a/include/sbi_utils/fdt/fdt_helper.h
+++ b/include/sbi_utils/fdt/fdt_helper.h
@@ -56,6 +56,8 @@ int fdt_parse_timebase_frequency(const void *fdt, unsigned long *freq);
 
 int fdt_parse_isa_extensions(const void *fdt, unsigned long *hart_exts);
 
+bool fdt_has_isa_extension(const void *fdt, const char *ext);
+
 int fdt_parse_gaisler_uart_node(const void *fdt, int nodeoffset,
 				struct platform_uart_data *uart);
 
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index b0b18b1c..de72f34a 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -447,6 +447,41 @@ int fdt_parse_isa_extensions(const void *fdt, unsigned long *hart_exts)
 	return 0;
 }
 
+bool fdt_has_isa_extension(const void *fdt, const char *ext)
+{
+	const struct sbi_hart_ext_data *ext_data = NULL;
+	DECLARE_BITMAP(hart_exts, SBI_HART_EXT_MAX);
+	int rc, i;
+
+	if (!fdt || !ext)
+		return false;
+
+	for (i = 0; i < SBI_HART_EXT_MAX; i++) {
+		if (!sbi_strncmp(sbi_hart_ext[i].name, ext,
+	                         sbi_strlen(ext))) {
+			ext_data = &sbi_hart_ext[i];
+			break;
+		}
+	}
+
+	if (!ext_data) {
+		sbi_printf("%s: extension %s not found in sbi_hart_ext[]\n",
+			   __func__, ext);
+		return false;
+	}
+
+	bitmap_zero(hart_exts, SBI_HART_EXT_MAX);
+
+	rc = fdt_parse_isa_extensions(fdt, hart_exts);
+	if (rc) {
+		sbi_printf("%s: failed to parse isa extensions\n",
+			   __func__);
+		return false;
+	}
+
+	return bitmap_test(hart_exts, ext_data->id);
+}
+
 static int fdt_parse_uart_node_common(const void *fdt, int nodeoffset,
 				      struct platform_uart_data *uart,
 				      unsigned long default_freq,
-- 
2.48.0


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH 2/7] include: sbi: sbi_platform: add reserved_pmp_count field
  2025-08-15 10:01 [RFC PATCH 0/7] Extend the reserved PMP entries Yu-Chien Peter Lin
  2025-08-15 10:01 ` [RFC PATCH 1/7] lib: utils: fdt_helper: add fdt_has_isa_extension() helper Yu-Chien Peter Lin
@ 2025-08-15 10:01 ` Yu-Chien Peter Lin
  2025-08-15 10:01 ` [RFC PATCH 3/7] platform: generic: platform: introduce fw_platform_get_reserved_pmp_count() Yu-Chien Peter Lin
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Yu-Chien Peter Lin @ 2025-08-15 10:01 UTC (permalink / raw)
  To: opensbi; +Cc: greentime.hu, Yu-Chien Peter Lin, zong.li

Add reserved_pmp_count field to struct sbi_platform to specify the
configurable number of high-priority PMP entries reserved.

Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
 include/sbi/sbi_platform.h | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h
index c6d30080..e2bf9b77 100644
--- a/include/sbi/sbi_platform.h
+++ b/include/sbi/sbi_platform.h
@@ -31,16 +31,18 @@
 #define SBI_PLATFORM_HART_STACK_SIZE_OFFSET (0x54)
 /** Offset of heap_size in struct sbi_platform */
 #define SBI_PLATFORM_HEAP_SIZE_OFFSET (0x58)
+/** Offset of reserved PMP entry count in struct sbi_platform */
+#define SBI_PLATFORM_RESERVED_PMP_COUNT_OFFSET (0x5c)
 /** Offset of reserved in struct sbi_platform */
-#define SBI_PLATFORM_RESERVED_OFFSET (0x5c)
+#define SBI_PLATFORM_RESERVED_OFFSET (0x60)
 /** Offset of platform_ops_addr in struct sbi_platform */
-#define SBI_PLATFORM_OPS_OFFSET (0x60)
+#define SBI_PLATFORM_OPS_OFFSET (0x68)
 /** Offset of firmware_context in struct sbi_platform */
-#define SBI_PLATFORM_FIRMWARE_CONTEXT_OFFSET (0x60 + __SIZEOF_POINTER__)
+#define SBI_PLATFORM_FIRMWARE_CONTEXT_OFFSET (0x68 + __SIZEOF_POINTER__)
 /** Offset of hart_index2id in struct sbi_platform */
-#define SBI_PLATFORM_HART_INDEX2ID_OFFSET (0x60 + (__SIZEOF_POINTER__ * 2))
+#define SBI_PLATFORM_HART_INDEX2ID_OFFSET (0x68 + (__SIZEOF_POINTER__ * 2))
 /** Offset of cbom_block_size in struct sbi_platform */
-#define SBI_PLATFORM_CBOM_BLOCK_SIZE_OFFSET (0x60 + (__SIZEOF_POINTER__ * 3))
+#define SBI_PLATFORM_CBOM_BLOCK_SIZE_OFFSET (0x68 + (__SIZEOF_POINTER__ * 3))
 
 #define SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT		(1UL << 12)
 
@@ -182,6 +184,8 @@ struct sbi_platform {
 	u32 hart_stack_size;
 	/** Size of heap shared by all HARTs */
 	u32 heap_size;
+	/** Reserved PMP entry count */
+	u8 reserved_pmp_count;
 	/** Reserved for future use */
 	u32 reserved;
 	/** Pointer to sbi platform operations */
@@ -214,6 +218,7 @@ assert_member_offset(struct sbi_platform, features, SBI_PLATFORM_FEATURES_OFFSET
 assert_member_offset(struct sbi_platform, hart_count, SBI_PLATFORM_HART_COUNT_OFFSET);
 assert_member_offset(struct sbi_platform, hart_stack_size, SBI_PLATFORM_HART_STACK_SIZE_OFFSET);
 assert_member_offset(struct sbi_platform, heap_size, SBI_PLATFORM_HEAP_SIZE_OFFSET);
+assert_member_offset(struct sbi_platform, reserved_pmp_count, SBI_PLATFORM_RESERVED_PMP_COUNT_OFFSET);
 assert_member_offset(struct sbi_platform, reserved, SBI_PLATFORM_RESERVED_OFFSET);
 assert_member_offset(struct sbi_platform, platform_ops_addr, SBI_PLATFORM_OPS_OFFSET);
 assert_member_offset(struct sbi_platform, firmware_context, SBI_PLATFORM_FIRMWARE_CONTEXT_OFFSET);
-- 
2.48.0


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH 3/7] platform: generic: platform: introduce fw_platform_get_reserved_pmp_count()
  2025-08-15 10:01 [RFC PATCH 0/7] Extend the reserved PMP entries Yu-Chien Peter Lin
  2025-08-15 10:01 ` [RFC PATCH 1/7] lib: utils: fdt_helper: add fdt_has_isa_extension() helper Yu-Chien Peter Lin
  2025-08-15 10:01 ` [RFC PATCH 2/7] include: sbi: sbi_platform: add reserved_pmp_count field Yu-Chien Peter Lin
@ 2025-08-15 10:01 ` Yu-Chien Peter Lin
  2025-08-15 10:01 ` [RFC PATCH 4/7] lib: sbi_init: print total and reserved PMP counts Yu-Chien Peter Lin
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Yu-Chien Peter Lin @ 2025-08-15 10:01 UTC (permalink / raw)
  To: opensbi; +Cc: greentime.hu, Yu-Chien Peter Lin, zong.li

Introduce fw_platform_get_reserved_pmp_count() to parse the
`reserved-pmp-count` property from the opensbi-config node.

Since mseccfg.{RLB,MMWP,MML} are sticky bits, we can't poll them
to detect the presence of Smempp. Therefore, the only way is to
parse it from FDT `riscv,isa-extensions` or `riscv,isa`.

Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
 platform/generic/platform.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/platform/generic/platform.c b/platform/generic/platform.c
index 2e8c6051..10bc3137 100644
--- a/platform/generic/platform.c
+++ b/platform/generic/platform.c
@@ -67,6 +67,39 @@ default_config:
 	return fw_platform_calculate_heap_size(hart_count);
 }
 
+static u32 fw_platform_get_reserved_pmp_count(const void *fdt)
+{
+	int chosen_offset, config_offset, len;
+	u32 reserved_pmp_count;
+	const fdt32_t *val;
+
+	/*
+	 * Reserve one default entry if smepmp is enabned.
+	 * This entry is required for sbi_hart_map_saddr().
+	 */
+	if (fdt_has_isa_extension(fdt, "smepmp"))
+		reserved_pmp_count = 1;
+	else
+		reserved_pmp_count = 0;
+
+
+	/* Get the heap size from device tree */
+	chosen_offset = fdt_path_offset(fdt, "/chosen");
+	if (chosen_offset < 0)
+		goto out;
+
+	config_offset = fdt_node_offset_by_compatible(fdt, chosen_offset, "opensbi,config");
+	if (config_offset < 0)
+		goto out;
+
+	val = (fdt32_t *)fdt_getprop(fdt, config_offset, "reserved-pmp-count", &len);
+	if (len > 0 && val)
+		return fdt32_to_cpu(*val) + reserved_pmp_count;
+
+out:
+	return reserved_pmp_count;
+}
+
 extern struct sbi_platform platform;
 static bool platform_has_mlevel_imsic = false;
 static u32 generic_hart_index2id[SBI_HARTMASK_MAX_BITS] = { 0 };
@@ -185,6 +218,7 @@ unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,
 
 	platform.hart_count = hart_count;
 	platform.heap_size = fw_platform_get_heap_size(fdt, hart_count);
+	platform.reserved_pmp_count = fw_platform_get_reserved_pmp_count(fdt);
 	platform_has_mlevel_imsic = fdt_check_imsic_mlevel(fdt);
 	platform.cbom_block_size = cbom_block_size;
 
-- 
2.48.0


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH 4/7] lib: sbi_init: print total and reserved PMP counts
  2025-08-15 10:01 [RFC PATCH 0/7] Extend the reserved PMP entries Yu-Chien Peter Lin
                   ` (2 preceding siblings ...)
  2025-08-15 10:01 ` [RFC PATCH 3/7] platform: generic: platform: introduce fw_platform_get_reserved_pmp_count() Yu-Chien Peter Lin
@ 2025-08-15 10:01 ` Yu-Chien Peter Lin
  2025-08-15 10:01 ` [RFC PATCH 5/7] lib: sbi: riscv_asm: add reserved_pmp_alloc() to allocate a reserved PMP Yu-Chien Peter Lin
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Yu-Chien Peter Lin @ 2025-08-15 10:01 UTC (permalink / raw)
  To: opensbi; +Cc: greentime.hu, Yu-Chien Peter Lin, zong.li

Show both total and reserved PMP counts in boot log.

Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
 lib/sbi/sbi_init.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index 84a63748..367476f0 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -163,6 +163,7 @@ static void sbi_boot_print_hart(struct sbi_scratch *scratch, u32 hartid)
 	int xlen;
 	char str[256];
 	const struct sbi_domain *dom = sbi_domain_thishart_ptr();
+	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
 
 	if (scratch->options & SBI_SCRATCH_NO_BOOT_PRINTS)
 		return;
@@ -183,8 +184,9 @@ static void sbi_boot_print_hart(struct sbi_scratch *scratch, u32 hartid)
 	sbi_printf("Boot HART Base ISA          : %s\n", str);
 	sbi_hart_get_extensions_str(scratch, str, sizeof(str));
 	sbi_printf("Boot HART ISA Extensions    : %s\n", str);
-	sbi_printf("Boot HART PMP Count         : %d\n",
-		   sbi_hart_pmp_count(scratch));
+	sbi_printf("Boot HART PMP Count         : "
+		   "%d (total), %d (reserved)\n",
+		   sbi_hart_pmp_count(scratch), plat->reserved_pmp_count);
 	sbi_printf("Boot HART PMP Granularity   : %u bits\n",
 		   sbi_hart_pmp_log2gran(scratch));
 	sbi_printf("Boot HART PMP Address Bits  : %d\n",
-- 
2.48.0


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH 5/7] lib: sbi: riscv_asm: add reserved_pmp_alloc() to allocate a reserved PMP
  2025-08-15 10:01 [RFC PATCH 0/7] Extend the reserved PMP entries Yu-Chien Peter Lin
                   ` (3 preceding siblings ...)
  2025-08-15 10:01 ` [RFC PATCH 4/7] lib: sbi_init: print total and reserved PMP counts Yu-Chien Peter Lin
@ 2025-08-15 10:01 ` Yu-Chien Peter Lin
  2025-08-15 10:01 ` [RFC PATCH 6/7] lib: sbi: sbi_hart: extend PMP handling to support multiple reserved entries Yu-Chien Peter Lin
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Yu-Chien Peter Lin @ 2025-08-15 10:01 UTC (permalink / raw)
  To: opensbi; +Cc: greentime.hu, Yu-Chien Peter Lin, zong.li

Add a function that allocates unused PMP entries from the high-priority
reserved pool.

Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
 include/sbi/riscv_asm.h |  2 ++
 lib/sbi/riscv_asm.c     | 25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h
index ef48dc89..5fff2196 100644
--- a/include/sbi/riscv_asm.h
+++ b/include/sbi/riscv_asm.h
@@ -221,6 +221,8 @@ int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
 int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out,
 	    unsigned long *log2len);
 
+int reserved_pmp_alloc(unsigned int *pmp_id);
+
 #endif /* !__ASSEMBLER__ */
 
 #endif
diff --git a/lib/sbi/riscv_asm.c b/lib/sbi/riscv_asm.c
index c7d75ac0..daa5087a 100644
--- a/lib/sbi/riscv_asm.c
+++ b/lib/sbi/riscv_asm.c
@@ -403,3 +403,28 @@ int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out,
 
 	return 0;
 }
+
+/**
+ * reserved_pmp_alloc() - Allocate an unused reserved PMP entry
+ * @pmp_id: Pointer to store the allocated PMP entry ID
+ *
+ * Returns: 0 on success, negative error code on failure
+ *
+ * The caller is responsible for configuring the allocated entry
+ * using pmp_set() and pmp_disable().
+ */
+int reserved_pmp_alloc(unsigned int *pmp_id)
+{
+	const struct sbi_platform *plat = sbi_platform_thishart_ptr();
+
+	for (int n = 0; n < plat->reserved_pmp_count; n++) {
+		if (is_pmp_entry_mapped(n))
+			continue;
+		*pmp_id = n;
+		return SBI_SUCCESS;
+	}
+
+	sbi_printf("%s: Failed to allocate PMP entry. "
+		   "Please increase reserved-pmp-count\n", __func__);
+	return SBI_EFAIL;
+}
-- 
2.48.0


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH 6/7] lib: sbi: sbi_hart: extend PMP handling to support multiple reserved entries
  2025-08-15 10:01 [RFC PATCH 0/7] Extend the reserved PMP entries Yu-Chien Peter Lin
                   ` (4 preceding siblings ...)
  2025-08-15 10:01 ` [RFC PATCH 5/7] lib: sbi: riscv_asm: add reserved_pmp_alloc() to allocate a reserved PMP Yu-Chien Peter Lin
@ 2025-08-15 10:01 ` Yu-Chien Peter Lin
  2025-08-15 10:01 ` [RFC PATCH 7/7] docs: opensbi_config: add description for reserved-pmp-count Yu-Chien Peter Lin
  2025-10-06  5:21 ` [RFC PATCH 0/7] Extend the reserved PMP entries Anup Patel
  7 siblings, 0 replies; 9+ messages in thread
From: Yu-Chien Peter Lin @ 2025-08-15 10:01 UTC (permalink / raw)
  To: opensbi; +Cc: greentime.hu, Yu-Chien Peter Lin, zong.li

Previously, OpenSBI supported only a single reserved PMP entry. This
change adds support for multiple reserved PMP entries, configurable
via the `reserved-pmp-count` DT property in the opensbi-config.

Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
 include/sbi/sbi_hart.h       | 15 ----------
 lib/sbi/sbi_domain_context.c |  6 +++-
 lib/sbi/sbi_hart.c           | 56 +++++++++++++++++++++++++++---------
 3 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index 82b19dcf..86c2675b 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -101,21 +101,6 @@ enum sbi_hart_csrs {
 	SBI_HART_CSR_MAX,
 };
 
-/*
- * Smepmp enforces access boundaries between M-mode and
- * S/U-mode. When it is enabled, the PMPs are programmed
- * such that M-mode doesn't have access to S/U-mode memory.
- *
- * To give M-mode R/W access to the shared memory between M and
- * S/U-mode, first entry is reserved. It is disabled at boot.
- * When shared memory access is required, the physical address
- * should be programmed into the first PMP entry with R/W
- * permissions to the M-mode. Once the work is done, it should be
- * unmapped. sbi_hart_map_saddr/sbi_hart_unmap_saddr function
- * pair should be used to map/unmap the shared memory.
- */
-#define SBI_SMEPMP_RESV_ENTRY		0
-
 struct sbi_hart_features {
 	bool detected;
 	int priv_version;
diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
index fb04d81d..a78bd28c 100644
--- a/lib/sbi/sbi_domain_context.c
+++ b/lib/sbi/sbi_domain_context.c
@@ -101,6 +101,7 @@ static void switch_to_next_domain_context(struct hart_context *ctx,
 	struct sbi_domain *current_dom = ctx->dom;
 	struct sbi_domain *target_dom = dom_ctx->dom;
 	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+	const struct sbi_platform *plat = sbi_platform_thishart_ptr();
 	unsigned int pmp_count = sbi_hart_pmp_count(scratch);
 
 	/* Assign current hart to target domain */
@@ -115,7 +116,10 @@ static void switch_to_next_domain_context(struct hart_context *ctx,
 	spin_unlock(&target_dom->assigned_harts_lock);
 
 	/* Reconfigure PMP settings for the new domain */
-	for (int i = 0; i < pmp_count; i++) {
+	for (int i = plat->reserved_pmp_count; i < pmp_count; i++) {
+		if (pmp_is_fw_region(i, current_dom))
+			continue;
+
 		sbi_platform_pmp_disable(sbi_platform_thishart_ptr(), i);
 		pmp_disable(i);
 	}
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 6a2d7d6f..e8762084 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -17,6 +17,7 @@
 #include <sbi/sbi_csr_detect.h>
 #include <sbi/sbi_error.h>
 #include <sbi/sbi_hart.h>
+#include <sbi/sbi_init.h>
 #include <sbi/sbi_math.h>
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_pmu.h>
@@ -30,6 +31,7 @@ extern void __sbi_expected_trap_hext(void);
 void (*sbi_hart_expected_trap)(void) = &__sbi_expected_trap;
 
 static unsigned long hart_features_offset;
+static unsigned int saddr_pmp_id;
 
 static void mstatus_init(struct sbi_scratch *scratch)
 {
@@ -393,6 +395,7 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch,
 				     unsigned long pmp_addr_max)
 {
 	struct sbi_domain_memregion *reg;
+	const struct sbi_platform *plat = sbi_platform_thishart_ptr();
 	struct sbi_domain *dom = sbi_domain_thishart_ptr();
 	unsigned int pmp_idx, pmp_flags;
 
@@ -402,16 +405,19 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch,
 	 */
 	csr_set(CSR_MSECCFG, MSECCFG_RLB);
 
-	/* Disable the reserved entry */
-	pmp_disable(SBI_SMEPMP_RESV_ENTRY);
+	/* Disable the reserved entries */
+	for (int i = 0; i < plat->reserved_pmp_count; i++)
+		pmp_disable(i);
 
 	/* Program M-only regions when MML is not set. */
 	pmp_idx = 0;
 	sbi_domain_for_each_memregion(dom, reg) {
 		/* Skip reserved entry */
-		if (pmp_idx == SBI_SMEPMP_RESV_ENTRY)
-			pmp_idx++;
-		if (pmp_count <= pmp_idx)
+		if (pmp_idx < plat->reserved_pmp_count)
+			pmp_idx += plat->reserved_pmp_count;
+		if (pmp_count <= pmp_idx) {
+			sbi_printf("%s: ERR: region %#lx cannot be protected - "
+				   "insufficient PMP entries\n", __func__, reg->base);
 			break;
 
 		/* Skip shared and SU-only regions */
@@ -435,9 +441,11 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch,
 	pmp_idx = 0;
 	sbi_domain_for_each_memregion(dom, reg) {
 		/* Skip reserved entry */
-		if (pmp_idx == SBI_SMEPMP_RESV_ENTRY)
-			pmp_idx++;
-		if (pmp_count <= pmp_idx)
+		if (pmp_idx < plat->reserved_pmp_count)
+			pmp_idx += plat->reserved_pmp_count;
+		if (pmp_count <= pmp_idx) {
+			sbi_printf("%s: ERR: region %#lx cannot be protected - "
+				   "insufficient PMP entries\n", __func__, reg->base);
 			break;
 
 		/* Skip M-only regions */
@@ -468,13 +476,19 @@ static int sbi_hart_oldpmp_configure(struct sbi_scratch *scratch,
 				     unsigned long pmp_addr_max)
 {
 	struct sbi_domain_memregion *reg;
+	const struct sbi_platform *plat = sbi_platform_thishart_ptr();
 	struct sbi_domain *dom = sbi_domain_thishart_ptr();
 	unsigned int pmp_idx = 0;
 	unsigned int pmp_flags;
 	unsigned long pmp_addr;
 
 	sbi_domain_for_each_memregion(dom, reg) {
-		if (pmp_count <= pmp_idx)
+		/* Skip reserved entry */
+		if (pmp_idx < plat->reserved_pmp_count)
+			pmp_idx += plat->reserved_pmp_count;
+		if (pmp_count <= pmp_idx) {
+			sbi_printf("%s: ERR: region %#lx cannot be protected - "
+				   "insufficient PMP entries\n", __func__, reg->base);
 			break;
 
 		pmp_flags = 0;
@@ -510,6 +524,19 @@ static int sbi_hart_oldpmp_configure(struct sbi_scratch *scratch,
 	return 0;
 }
 
+/*
+ * Smepmp enforces access boundaries between M-mode and
+ * S/U-mode. When it is enabled, the PMPs are programmed
+ * such that M-mode doesn't have access to S/U-mode memory.
+ *
+ * To give M-mode R/W access to the shared memory between M and
+ * S/U-mode, high-priority entry is reserved. It is disabled at boot.
+ * When shared memory access is required, the physical address
+ * should be programmed into the reserved PMP entry with R/W
+ * permissions to the M-mode. Once the work is done, it should be
+ * unmapped. sbi_hart_map_saddr/sbi_hart_unmap_saddr function
+ * pair should be used to map/unmap the shared memory.
+ */
 int sbi_hart_map_saddr(unsigned long addr, unsigned long size)
 {
 	/* shared R/W access for M and S/U mode */
@@ -521,8 +548,9 @@ int sbi_hart_map_saddr(unsigned long addr, unsigned long size)
 	if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMEPMP))
 		return SBI_OK;
 
-	if (is_pmp_entry_mapped(SBI_SMEPMP_RESV_ENTRY))
+	if (reserved_pmp_alloc(&saddr_pmp_id)) {
 		return SBI_ENOSPC;
+	}
 
 	for (order = MAX(sbi_hart_pmp_log2gran(scratch), log2roundup(size));
 	     order <= __riscv_xlen; order++) {
@@ -538,10 +566,10 @@ int sbi_hart_map_saddr(unsigned long addr, unsigned long size)
 		}
 	}
 
-	sbi_platform_pmp_set(sbi_platform_ptr(scratch), SBI_SMEPMP_RESV_ENTRY,
+	sbi_platform_pmp_set(sbi_platform_ptr(scratch), saddr_pmp_id,
 			     SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW,
 			     pmp_flags, base, order);
-	pmp_set(SBI_SMEPMP_RESV_ENTRY, pmp_flags, base, order);
+	pmp_set(saddr_pmp_id, pmp_flags, base, order);
 
 	return SBI_OK;
 }
@@ -553,8 +581,8 @@ int sbi_hart_unmap_saddr(void)
 	if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMEPMP))
 		return SBI_OK;
 
-	sbi_platform_pmp_disable(sbi_platform_ptr(scratch), SBI_SMEPMP_RESV_ENTRY);
-	return pmp_disable(SBI_SMEPMP_RESV_ENTRY);
+	sbi_platform_pmp_disable(sbi_platform_ptr(scratch), saddr_pmp_id);
+	return pmp_disable(saddr_pmp_id);
 }
 
 int sbi_hart_pmp_configure(struct sbi_scratch *scratch)
-- 
2.48.0


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH 7/7] docs: opensbi_config: add description for reserved-pmp-count
  2025-08-15 10:01 [RFC PATCH 0/7] Extend the reserved PMP entries Yu-Chien Peter Lin
                   ` (5 preceding siblings ...)
  2025-08-15 10:01 ` [RFC PATCH 6/7] lib: sbi: sbi_hart: extend PMP handling to support multiple reserved entries Yu-Chien Peter Lin
@ 2025-08-15 10:01 ` Yu-Chien Peter Lin
  2025-10-06  5:21 ` [RFC PATCH 0/7] Extend the reserved PMP entries Anup Patel
  7 siblings, 0 replies; 9+ messages in thread
From: Yu-Chien Peter Lin @ 2025-08-15 10:01 UTC (permalink / raw)
  To: opensbi; +Cc: greentime.hu, Yu-Chien Peter Lin, zong.li

Add documentation for the reserved-pmp-count property, which
specifies the number of additional high-priority PMP entries.

Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
 docs/opensbi_config.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/docs/opensbi_config.md b/docs/opensbi_config.md
index 104d82c9..02481800 100644
--- a/docs/opensbi_config.md
+++ b/docs/opensbi_config.md
@@ -26,6 +26,9 @@ The DT properties of a domain configuration DT node are as follows:
 * **heap-size** (Optional) - When present, the specified value is used
   as the size of the heap in bytes.
 
+* **reserved-pmp-count** (Optional) - When present, the specified value
+  is used as the additional number of reserved high-priority PMP entries.
+
 * **system-suspend-test** (Optional) - When present, enable a system
   suspend test implementation which simply waits five seconds and issues a WFI.
 
@@ -40,6 +43,7 @@ The OpenSBI Configuration Node will be deleted at the end of cold boot
             compatible = "opensbi,config";
             cold-boot-harts = <&cpu1 &cpu2 &cpu3 &cpu4>;
             heap-size = <0x400000>;
+            reserved-pmp-count = <2>;
             system-suspend-test;
         };
     };
-- 
2.48.0


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 0/7] Extend the reserved PMP entries
  2025-08-15 10:01 [RFC PATCH 0/7] Extend the reserved PMP entries Yu-Chien Peter Lin
                   ` (6 preceding siblings ...)
  2025-08-15 10:01 ` [RFC PATCH 7/7] docs: opensbi_config: add description for reserved-pmp-count Yu-Chien Peter Lin
@ 2025-10-06  5:21 ` Anup Patel
  7 siblings, 0 replies; 9+ messages in thread
From: Anup Patel @ 2025-10-06  5:21 UTC (permalink / raw)
  To: Yu-Chien Peter Lin; +Cc: opensbi, greentime.hu, zong.li

On Fri, Aug 15, 2025 at 6:44 PM Yu-Chien Peter Lin <peter.lin@sifive.com> wrote:
>
> This series extends the number of reserved PMP entry.
> The capabilities of the reserved PMP entries include:
> - Highest priority
> - Allow TOR mode for platform-specific use cases
> - Can be consistent across domain context switches
> - Allow runtime PMP allocation
>
> A potential use case for reserved PMP entries is parsing gaps in
> memory ports marked as PMA_UNSAFE [1] in device-tree. These gaps
> may not be able to exactly covered by 1 or 2 NAPOT entries, so TOR
> mode PMP can be allocated to save PMP usage. Besides, they don't
> need reconfiguration across domains.
>
> This series depends on:
> 1) https://lore.kernel.org/all/20250815024434.14303-1-peter.lin@sifive.com/
> 2) https://lore.kernel.org/all/20250814110522.18809-1-peter.lin@sifive.com/
>
> [1] https://patchwork.kernel.org/project/linux-riscv/patch/20241102000843.1301099-2-samuel.holland@sifive.com/
>
> Yu-Chien Peter Lin (7):
>   lib: utils: fdt_helper: add fdt_has_isa_extension() helper
>   include: sbi: sbi_platform: add reserved_pmp_count field
>   platform: generic: platform: introduce
>     fw_platform_get_reserved_pmp_count()
>   lib: sbi_init: print total and reserved PMP counts
>   lib: sbi: riscv_asm: add reserved_pmp_alloc() to allocate a reserved
>     PMP
>   lib: sbi: sbi_hart: extend PMP handling to support multiple reserved
>     entries
>   docs: opensbi_config: add description for reserved-pmp-count

Same issue as the other series, it is not showing up in OpenSBI
patchwork (https://patchwork.ozlabs.org/project/opensbi/list/).

Can you please rebase and resend this series ?

Regards,
Anup

>
>  docs/opensbi_config.md             |  4 +++
>  include/sbi/riscv_asm.h            |  2 ++
>  include/sbi/sbi_hart.h             | 15 --------
>  include/sbi/sbi_platform.h         | 15 +++++---
>  include/sbi_utils/fdt/fdt_helper.h |  2 ++
>  lib/sbi/riscv_asm.c                | 25 +++++++++++++
>  lib/sbi/sbi_domain_context.c       |  6 +++-
>  lib/sbi/sbi_hart.c                 | 56 ++++++++++++++++++++++--------
>  lib/sbi/sbi_init.c                 |  6 ++--
>  lib/utils/fdt/fdt_helper.c         | 35 +++++++++++++++++++
>  platform/generic/platform.c        | 34 ++++++++++++++++++
>  11 files changed, 163 insertions(+), 37 deletions(-)
>
> --
> 2.48.0
>
>
> --
> opensbi mailing list
> opensbi@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi

-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-10-06  5:22 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-15 10:01 [RFC PATCH 0/7] Extend the reserved PMP entries Yu-Chien Peter Lin
2025-08-15 10:01 ` [RFC PATCH 1/7] lib: utils: fdt_helper: add fdt_has_isa_extension() helper Yu-Chien Peter Lin
2025-08-15 10:01 ` [RFC PATCH 2/7] include: sbi: sbi_platform: add reserved_pmp_count field Yu-Chien Peter Lin
2025-08-15 10:01 ` [RFC PATCH 3/7] platform: generic: platform: introduce fw_platform_get_reserved_pmp_count() Yu-Chien Peter Lin
2025-08-15 10:01 ` [RFC PATCH 4/7] lib: sbi_init: print total and reserved PMP counts Yu-Chien Peter Lin
2025-08-15 10:01 ` [RFC PATCH 5/7] lib: sbi: riscv_asm: add reserved_pmp_alloc() to allocate a reserved PMP Yu-Chien Peter Lin
2025-08-15 10:01 ` [RFC PATCH 6/7] lib: sbi: sbi_hart: extend PMP handling to support multiple reserved entries Yu-Chien Peter Lin
2025-08-15 10:01 ` [RFC PATCH 7/7] docs: opensbi_config: add description for reserved-pmp-count Yu-Chien Peter Lin
2025-10-06  5:21 ` [RFC PATCH 0/7] Extend the reserved PMP entries Anup Patel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox