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

Set PMP to create invalid address #535

Merged
merged 1 commit into from
Nov 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
14 changes: 14 additions & 0 deletions debug/gdbserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@ def test(self):
class MemTestReadInvalid(SimpleMemoryTest):
def test(self):
bad_address = self.hart.bad_address
if self.target.support_set_pmp_deny:
self.set_pmp_deny(bad_address)
self.gdb.command("monitor riscv set_mem_access progbuf abstract")
good_address = self.hart.ram + 0x80

self.write_nop_program(2)
Expand All @@ -293,6 +296,10 @@ def test(self):
self.gdb.stepi() # Don't let gdb cache register read
assertEqual(self.gdb.p(f"*((int*)0x{good_address:x})"), 0xabcdef)
assertEqual(self.gdb.p("$s0"), 0x12345678)
if self.target.support_set_pmp_deny:
self.reset_pmp_deny()
self.gdb.command("monitor riscv set_mem_access progbuf sysbus "
"abstract")

#class MemTestWriteInvalid(SimpleMemoryTest):
# def test(self):
Expand Down Expand Up @@ -2182,6 +2189,9 @@ def test(self):
# Set fox to a bad pointer so we'll get a load access exception later.
# Use NULL if a known-bad address is not provided.
bad_address = self.hart.bad_address or 0
if self.target.support_set_pmp_deny:
self.set_pmp_deny(bad_address)
self.gdb.command("monitor riscv set_mem_access progbuf abstract")
self.gdb.p(f"fox=(char*)0x{bad_address:08x}")
output = self.gdb.c()
# We should not be at handle_trap
Expand All @@ -2190,6 +2200,10 @@ def test(self):
# actual exception handler.
assertIn("breakpoint", output)
assertIn("trap_entry", self.gdb.where())
if self.target.support_set_pmp_deny:
self.reset_pmp_deny()
self.gdb.command("monitor riscv set_mem_access progbuf sysbus "
"abstract")

class IcountTest(DebugTest):
compile_args = ("programs/infinite_loop.S", )
Expand Down
3 changes: 3 additions & 0 deletions debug/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ class Target:
# Instruction count limit
icount_limit = 4

# Support set_pmp_deny to create invalid addresses.
support_set_pmp_deny = False

# Internal variables:
directory = None
temporary_files = []
Expand Down
16 changes: 16 additions & 0 deletions debug/testlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,22 @@ def parkOtherHarts(self, symbol=None):
self.gdb.select_hart(self.hart)
self.gdb.command(f"monitor targets {self.hart.id}")

def set_pmp_deny(self, address, size=4 * 1024):
# Enable physical memory protection, no permission to access specific
# address range (default 4KB).
self.gdb.p("$mseccfg=0x4") # RLB
self.gdb.p("$pmpcfg0=0x98") # L, NAPOT, !R, !W, !X
self.gdb.p("$pmpaddr0="
f"0x{((address >> 2) | ((size - 1) >> 3)):x}")
# PMP changes require an sfence.vma, 0x12000073 is sfence.vma
self.gdb.command("monitor riscv exec_progbuf 0x12000073")

def reset_pmp_deny(self):
self.gdb.p("$pmpcfg0=0")
self.gdb.p("$pmpaddr0=0")
# PMP changes require an sfence.vma, 0x12000073 is sfence.vma
self.gdb.command("monitor riscv exec_progbuf 0x12000073")

def disable_pmp(self):
# Disable physical memory protection by allowing U mode access to all
# memory.
Expand Down
Loading