Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfixes for LPMP #1

Merged
merged 3 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 2 additions & 119 deletions overlays/keystone/patches/opensbi/opensbi-lpmp.patch
Original file line number Diff line number Diff line change
@@ -1,129 +1,12 @@
diff --git a/include/sbi/sbi_lpmp.h b/include/sbi/sbi_lpmp.h
new file mode 100644
index 0000000..d56ad96
--- /dev/null
+++ b/include/sbi/sbi_lpmp.h
@@ -0,0 +1,21 @@
+#ifndef __SBI_LPMP_H__
+#define __SBI_LPMP_H__
+
+#define PTE_V (1L << 0)
+#define PTE_R (1L << 1)
+#define PTE_W (1L << 2)
+#define PTE_X (1L << 3)
+
+#define PPNSHIFT 9
+#define PGSHIFT 12
+#define PTE2PA(pte) (((pte) >> 10) << 12)
+#define PXMASK 0x1FF // 9 bits
+#define PXSHIFT(level) (PGSHIFT + (9 * (level)))
+#define PX(level, va) ((((uint64_t)(va)) >> PXSHIFT(level)) & PXMASK)
+
+typedef uint64_t *pagetable_t;
+typedef uint64_t pte_t;
+
+int pmp_fault_handler(ulong mtval);
+
+#endif
diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk
index 1ed1983..9bdc555 100644
--- a/lib/sbi/objects.mk
+++ b/lib/sbi/objects.mk
@@ -44,3 +44,4 @@ libsbi-objs-y += sbi_tlb.o
libsbi-objs-y += sbi_trap.o
libsbi-objs-y += sbi_unpriv.o
libsbi-objs-y += sbi_expected_trap.o
+libsbi-objs-y += sbi_lpmp.o
diff --git a/lib/sbi/sbi_lpmp.c b/lib/sbi/sbi_lpmp.c
new file mode 100644
index 0000000..35837e3
--- /dev/null
+++ b/lib/sbi/sbi_lpmp.c
@@ -0,0 +1,75 @@
+#include "lpmp.h"
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_lpmp.h>
+
+static uint64_t get_pt_root(void) {
+ return ((csr_read(satp) & 0xFFFFFFFFFFF) << 12);
+}
+
+static uint64_t walkaddr(pagetable_t pagetable, uint64_t va) {
+ if (pagetable == 0)
+ return 0;
+ pte_t *pte;
+ uint64_t level;
+ uint64_t pa;
+
+ // make sure page tables in PMP.
+ host_hit_region((uint64_t)pagetable);
+ for (level = 4; level > 0; level--) {
+ pte = &pagetable[PX(level, va)];
+ if (*pte & (PTE_X | PTE_W | PTE_R)) {
+ goto found; // A leaf pte has been found.
+ } else if (*pte & PTE_V) {
+ pagetable = (pagetable_t)PTE2PA(*pte);
+ host_hit_region((uint64_t)pagetable);
+ } else {
+ sbi_panic("invalid va=0x%lx\n", va);
+ }
+ }
+ pte = &pagetable[PX(0, va)];
+
+found:
+ if (pte == 0)
+ return 0;
+ if ((*pte & PTE_V) == 0)
+ return 0;
+ uint64_t number_of_ones = PGSHIFT + level * PPNSHIFT;
+ uint64_t offset_mask = (1 << number_of_ones) - 1;
+ uint64_t offset = (va & offset_mask);
+ pa = PTE2PA(*pte) + offset;
+
+ return pa;
+}
+
+static inline void flush_tlb()
+{
+ asm volatile("sfence.vma");
+}
+
+int pmp_fault_handler(ulong mtval) {
+ if (!mtval) {
+ sbi_printf("mepc = 0x%lx\n", csr_read(CSR_MEPC));
+ sbi_printf("Null pointer!\n");
+ return -1;
+ }
+ pagetable_t pt_root = (pagetable_t)get_pt_root();
+ uintptr_t pa = pt_root ? walkaddr(pt_root, mtval) : mtval;
+
+ if (pa && host_hit_region(pa)) {
+ activate_host_lpmp();
+ // Option 1. enable TLB cached PMP.
+ asm volatile("sfence.vma %0, zero \n\t" : : "r"(mtval));
+
+ // Option 2. disable TLB cached PMP.
+ // flush_tlb();
+
+ return 0;
+ } else {
+ sbi_printf("Error: Host should not access this pa\n");
+ return -1;
+ }
+}
diff --git a/lib/sbi/sbi_trap.c b/lib/sbi/sbi_trap.c
index ee3e4e9..2a4fd44 100644
index ee3e4e9..0ac34f9 100644
--- a/lib/sbi/sbi_trap.c
+++ b/lib/sbi/sbi_trap.c
@@ -21,6 +21,7 @@
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_timer.h>
#include <sbi/sbi_trap.h>
+#include <sbi/sbi_lpmp.h>
+#include "lpmp.h"

static void __noreturn sbi_trap_error(const char *msg, int rc,
ulong mcause, ulong mtval, ulong mtval2,
Expand Down
2 changes: 1 addition & 1 deletion sm/src/ipi.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void sbi_flush_tlb_local(struct sbi_tlb_info *__info)
asm volatile("sfence.vma");
}

void send_flush_tlb_ipi()
void send_flush_tlb_ipi(void)
{
ulong mask = 0;
ulong source_hart = current_hartid();
Expand Down
2 changes: 1 addition & 1 deletion sm/src/ipi.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ void send_and_sync_pmp_ipi(int region_idx, int type, uint8_t perm);

void sbi_flush_tlb_local(struct sbi_tlb_info *__info);

void send_flush_tlb_ipi();
void send_flush_tlb_ipi(void);

#endif
Loading