qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v1 1/1] riscv: pmp: Allow valid instruction fetches


From: Chris Williams
Subject: [Qemu-devel] [PATCH v1 1/1] riscv: pmp: Allow valid instruction fetches at the start of a PMP range
Date: Mon, 16 Sep 2019 11:08:23 +0200 (CEST)

Allow Qemu guest code to execute from the very start of a PMP range without 
faulting.

When an instruction is fetched from the first word of a PMP range, 
pmp_hart_has_privs()
is called with a size of zero. This causes pmp_is_in_range() to be called with 
an address
lower than addr, when obtaining a value for e, and a fault is incorrectly 
generated.

This fault was observed by creating a PMP range with RWX access, filling the 
range with
valid code from its base address, and then jumping to the first instruction at 
the base address.
Qemu generates an instruction access fault: the correct behavior is to allow 
the instruction fetch.

This patch checks a size is non-zero before applying a calculation operation 
that would bring it
below addr, and thus erroneously raise a fault.

Signed-off-by: Chris Williams <address@hidden <mailto:address@hidden>>
---
target/riscv/pmp.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 958c7502a0..06f2cd52f0 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -242,10 +242,12 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
     }

     /* 1.10 draft priv spec states there is an implicit order
-         from low to high */
+         from low to high. Also, catch attempts to check a request
+         size of zero, and ensure it does not accidentally fail by
+         checking for an address *below* addr */
     for (i = 0; i < MAX_RISCV_PMPS; i++) {
         s = pmp_is_in_range(env, i, addr);
-        e = pmp_is_in_range(env, i, addr + size - 1);
+        e = pmp_is_in_range(env, i, (size == 0) ? addr : addr + size - 1);

         /* partially inside */
         if ((s + e) == 1) {
--
2.20.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]