qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Chris Williams <diodesign@tuta.io>
To: Palmer Dabbelt <palmer@sifive.com>,
	Alistair Francis <alistair.francis@wdc.com>,
	Sagar Karandikar <sagark@eecs.berkeley.edu>,
	Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: qemu-riscv@nongnu.org, qemu-devel@nongnu.org
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)	[thread overview]
Message-ID: <LotC_Mg--3-1@tuta.io> (raw)

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 <diodesign@tuta.io <mailto:diodesign@tuta.io>>
---
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	other threads:[~2019-09-16  9:10 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=LotC_Mg--3-1@tuta.io \
    --to=diodesign@tuta.io \
    --cc=alistair.francis@wdc.com \
    --cc=kbastian@mail.uni-paderborn.de \
    --cc=palmer@sifive.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --cc=sagark@eecs.berkeley.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).