Skip to content

Commit e094982

Browse files
committed
[debug] Set PMP to create bad address
1 parent fa2f65c commit e094982

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

debug/gdbserver.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,9 @@ def test(self):
278278
class MemTestReadInvalid(SimpleMemoryTest):
279279
def test(self):
280280
bad_address = self.hart.bad_address
281+
if self.target.support_set_pmp_deny:
282+
self.set_pmp_deny(bad_address)
283+
self.gdb.command("monitor riscv set_mem_access progbuf abstract")
281284
good_address = self.hart.ram + 0x80
282285

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

297304
#class MemTestWriteInvalid(SimpleMemoryTest):
298305
# def test(self):
@@ -2182,6 +2189,9 @@ def test(self):
21822189
# Set fox to a bad pointer so we'll get a load access exception later.
21832190
# Use NULL if a known-bad address is not provided.
21842191
bad_address = self.hart.bad_address or 0
2192+
if self.target.support_set_pmp_deny:
2193+
self.set_pmp_deny(bad_address)
2194+
self.gdb.command("monitor riscv set_mem_access progbuf abstract")
21852195
self.gdb.p(f"fox=(char*)0x{bad_address:08x}")
21862196
output = self.gdb.c()
21872197
# We should not be at handle_trap
@@ -2190,6 +2200,10 @@ def test(self):
21902200
# actual exception handler.
21912201
assertIn("breakpoint", output)
21922202
assertIn("trap_entry", self.gdb.where())
2203+
if self.target.support_set_pmp_deny:
2204+
self.reset_pmp_deny()
2205+
self.gdb.command("monitor riscv set_mem_access progbuf sysbus "
2206+
"abstract")
21932207

21942208
class IcountTest(DebugTest):
21952209
compile_args = ("programs/infinite_loop.S", )

debug/targets.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ class Target:
141141
# Instruction count limit
142142
icount_limit = 4
143143

144+
# Support set_pmp_deny to create invalid addresses.
145+
support_set_pmp_deny = False
146+
144147
# Internal variables:
145148
directory = None
146149
temporary_files = []

debug/testlib.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,22 @@ def parkOtherHarts(self, symbol=None):
14851485
self.gdb.select_hart(self.hart)
14861486
self.gdb.command(f"monitor targets {self.hart.id}")
14871487

1488+
def set_pmp_deny(self, address, size=4 * 1024):
1489+
# Enable physical memory protection, no permission to access specific
1490+
# address range (default 4KB).
1491+
self.gdb.p("$mseccfg=0x4") # RLB
1492+
self.gdb.p("$pmpcfg0=0x98") # L, NAPOT, !R, !W, !X
1493+
self.gdb.p("$pmpaddr0="
1494+
f"0x{((address >> 2) | ((size - 1) >> 3)):x}")
1495+
# PMP changes require an sfence.vma, 0x12000073 is sfence.vma
1496+
self.gdb.command("monitor riscv exec_progbuf 0x12000073")
1497+
1498+
def reset_pmp_deny(self):
1499+
self.gdb.p("$pmpcfg0=0")
1500+
self.gdb.p("$pmpaddr0=0")
1501+
# PMP changes require an sfence.vma, 0x12000073 is sfence.vma
1502+
self.gdb.command("monitor riscv exec_progbuf 0x12000073")
1503+
14881504
def disable_pmp(self):
14891505
# Disable physical memory protection by allowing U mode access to all
14901506
# memory.

0 commit comments

Comments
 (0)