[RFC PATCH v7 2/6] lib: sbi: Introduce memory class for memory type hart protection
Rahul Pathak
rahul.pathak at oss.qualcomm.com
Sun Nov 1 20:33:53 PST 2026
In TYPE_MEMORY type mechanisms, some of the hart protection
mechanisms can be exclusive and other can work as an addon
with the other TYPE_MEMORY type mechanisms. For example, in
PMP, SMEPMP and SMSD which are currently the TYPE_MEMORY
type protection mechanisms, the PMP and SMEPMP are exclusive
to each other and the SMSD if present will work together with
PMP or SMEPMP. So it will be either PMP+SMSD or SMEPMP+SMSD.
For such configurations selection, add memory class in which
types within same memory class are exclusive but other types
in different memory class selected will work together.
Signed-off-by: Rahul Pathak <rahul.pathak at oss.qualcomm.com>
---
include/sbi/sbi_hart_protection.h | 20 ++++++++
lib/sbi/sbi_hart_pmp.c | 2 +
lib/sbi/sbi_hart_protection.c | 84 ++++++++++++-------------------
3 files changed, 53 insertions(+), 53 deletions(-)
diff --git a/include/sbi/sbi_hart_protection.h b/include/sbi/sbi_hart_protection.h
index bdcad0080baf..fee5063ca167 100644
--- a/include/sbi/sbi_hart_protection.h
+++ b/include/sbi/sbi_hart_protection.h
@@ -20,6 +20,23 @@ enum sbi_hart_protection_type {
SBI_HART_PROTECTION_TYPE_MAX
};
+/**
+ * Hart protection class for memory protection.
+ *
+ * Memory protection mechanisms of the same class use the same
+ * hardware for memory access which makes them mutually exclusive and
+ * among those the rating will choose which one is active.
+ * Mechanisms of different classes can work together so a hart can have
+ * PMP + MPT or ePMP + MPT.
+ */
+enum sbi_hart_protection_memory_class {
+ /** PMP CSRs: pmp, epmp */
+ SBI_HART_PROTECTION_MEMORY_CLASS_PMP = 0,
+ /** mmpt CSR: MPT (Smsd) */
+ SBI_HART_PROTECTION_MEMORY_CLASS_MPT,
+ SBI_HART_PROTECTION_MEMORY_CLASS_MAX
+};
+
/** Representation of hart protection mechanism */
struct sbi_hart_protection {
/** List head */
@@ -31,6 +48,9 @@ struct sbi_hart_protection {
/** Type of the hart protection mechanism */
enum sbi_hart_protection_type type;
+ /** Hardware programmed by the mechanism */
+ enum sbi_hart_protection_memory_class memory_class;
+
/** Ratings of the hart protection mechanism (higher is better) */
unsigned long rating;
diff --git a/lib/sbi/sbi_hart_pmp.c b/lib/sbi/sbi_hart_pmp.c
index c530739f8c46..e60dbdcfca0a 100644
--- a/lib/sbi/sbi_hart_pmp.c
+++ b/lib/sbi/sbi_hart_pmp.c
@@ -426,6 +426,7 @@ static struct sbi_hart_protection pmp_protection = {
.name = "pmp",
.rating = 100,
.type = SBI_HART_PROTECTION_TYPE_MEMORY,
+ .memory_class = SBI_HART_PROTECTION_MEMORY_CLASS_PMP,
.configure = sbi_hart_oldpmp_configure,
.unconfigure = sbi_hart_pmp_unconfigure,
};
@@ -434,6 +435,7 @@ static struct sbi_hart_protection epmp_protection = {
.name = "epmp",
.rating = 200,
.type = SBI_HART_PROTECTION_TYPE_MEMORY,
+ .memory_class = SBI_HART_PROTECTION_MEMORY_CLASS_PMP,
.configure = sbi_hart_smepmp_configure,
.unconfigure = sbi_hart_pmp_unconfigure,
.temp_map_range = sbi_hart_smepmp_temp_map_range,
diff --git a/lib/sbi/sbi_hart_protection.c b/lib/sbi/sbi_hart_protection.c
index ee4d4beb9087..72ce4e9899cc 100644
--- a/lib/sbi/sbi_hart_protection.c
+++ b/lib/sbi/sbi_hart_protection.c
@@ -12,21 +12,37 @@
static SBI_LIST_HEAD(hart_protection_list);
-static struct sbi_hart_protection *__hart_memory_protection_best(void)
+static struct sbi_hart_protection *
+__hart_memory_protection_best(enum sbi_hart_protection_memory_class memclass)
{
struct sbi_hart_protection *pos;
sbi_list_for_each_entry(pos, &hart_protection_list, head) {
- if (pos->type == SBI_HART_PROTECTION_TYPE_MEMORY)
+ if (pos->type == SBI_HART_PROTECTION_TYPE_MEMORY &&
+ pos->memory_class == memclass)
return pos;
}
return NULL;
}
+/*
+ * Select the highest rating protection mechanism from each class
+ */
+static bool __hart_protection_selected(struct sbi_hart_protection *hprot)
+{
+ switch (hprot->type) {
+ case SBI_HART_PROTECTION_TYPE_MEMORY:
+ return hprot == __hart_memory_protection_best(hprot->memory_class);
+ case SBI_HART_PROTECTION_TYPE_ID:
+ return true;
+ default:
+ return false;
+ }
+}
+
void sbi_hart_protection_get_str(char *out_str, int out_str_size)
{
- bool memory_protect_done = false;
struct sbi_hart_protection *pos;
int offset = 0;
@@ -35,11 +51,8 @@ void sbi_hart_protection_get_str(char *out_str, int out_str_size)
sbi_memset(out_str, 0, out_str_size);
sbi_list_for_each_entry(pos, &hart_protection_list, head) {
- if (pos->type == SBI_HART_PROTECTION_TYPE_MEMORY) {
- if (memory_protect_done)
- continue;
- memory_protect_done = true;
- }
+ if (!__hart_protection_selected(pos))
+ continue;
sbi_snprintf(out_str + offset, out_str_size - offset, "%s,", pos->name);
offset = offset + sbi_strlen(pos->name) + 1;
}
@@ -59,6 +72,9 @@ int sbi_hart_protection_register(struct sbi_hart_protection *hprot)
return SBI_EINVAL;
if (hprot->type >= SBI_HART_PROTECTION_TYPE_MAX)
return SBI_EINVAL;
+ if (hprot->type == SBI_HART_PROTECTION_TYPE_MEMORY &&
+ hprot->memory_class >= SBI_HART_PROTECTION_MEMORY_CLASS_MAX)
+ return SBI_EINVAL;
sbi_list_for_each_entry(pos, &hart_protection_list, head) {
if (hprot->rating > pos->rating) {
@@ -108,24 +124,11 @@ static void __hart_protection_unconfigure(struct sbi_scratch *scratch,
int sbi_hart_protection_configure(struct sbi_scratch *scratch,
struct sbi_domain *dom)
{
- bool do_configure, memory_protect_done = false;
struct sbi_hart_protection *hprot;
int ret;
sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
- do_configure = false;
- switch (hprot->type) {
- case SBI_HART_PROTECTION_TYPE_MEMORY:
- do_configure = !memory_protect_done;
- memory_protect_done = true;
- break;
- case SBI_HART_PROTECTION_TYPE_ID:
- do_configure = true;
- break;
- default:
- break;
- }
- if (!do_configure)
+ if (!__hart_protection_selected(hprot))
continue;
ret = __hart_protection_configure(scratch, hprot, dom);
@@ -139,24 +142,10 @@ int sbi_hart_protection_configure(struct sbi_scratch *scratch,
void sbi_hart_protection_unconfigure(struct sbi_scratch *scratch,
struct sbi_domain *dom)
{
-
- bool do_unconfigure, memory_protect_done = false;
struct sbi_hart_protection *hprot;
sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
- do_unconfigure = false;
- switch (hprot->type) {
- case SBI_HART_PROTECTION_TYPE_MEMORY:
- do_unconfigure = !memory_protect_done;
- memory_protect_done = true;
- break;
- case SBI_HART_PROTECTION_TYPE_ID:
- do_unconfigure = true;
- break;
- default:
- break;
- }
- if (!do_unconfigure)
+ if (!__hart_protection_selected(hprot))
continue;
__hart_protection_unconfigure(scratch, hprot, dom);
@@ -167,24 +156,11 @@ int sbi_hart_protection_reconfigure(struct sbi_scratch *scratch,
struct sbi_domain *current_dom,
struct sbi_domain *next_dom)
{
- bool do_reconfigure, memory_protect_done = false;
struct sbi_hart_protection *hprot;
int ret;
sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
- do_reconfigure = false;
- switch (hprot->type) {
- case SBI_HART_PROTECTION_TYPE_MEMORY:
- do_reconfigure = !memory_protect_done;
- memory_protect_done = true;
- break;
- case SBI_HART_PROTECTION_TYPE_ID:
- do_reconfigure = true;
- break;
- default:
- break;
- }
- if (!do_reconfigure)
+ if (!__hart_protection_selected(hprot))
continue;
__hart_protection_unconfigure(scratch, hprot, current_dom);
@@ -198,7 +174,8 @@ int sbi_hart_protection_reconfigure(struct sbi_scratch *scratch,
int sbi_hart_protection_temp_map_range(unsigned long base, unsigned long size)
{
- struct sbi_hart_protection *hprot = __hart_memory_protection_best();
+ struct sbi_hart_protection *hprot =
+ __hart_memory_protection_best(SBI_HART_PROTECTION_MEMORY_CLASS_PMP);
if (!hprot || !hprot->temp_map_range)
return 0;
@@ -208,7 +185,8 @@ int sbi_hart_protection_temp_map_range(unsigned long base, unsigned long size)
int sbi_hart_protection_temp_unmap_range(unsigned long base, unsigned long size)
{
- struct sbi_hart_protection *hprot = __hart_memory_protection_best();
+ struct sbi_hart_protection *hprot =
+ __hart_memory_protection_best(SBI_HART_PROTECTION_MEMORY_CLASS_PMP);
if (!hprot || !hprot->temp_unmap_range)
return 0;
--
2.53.0
More information about the opensbi
mailing list