All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Clark <mjc@sifive.com>
To: QEMU Developers <qemu-devel@nongnu.org>
Cc: Michael Clark <mjc@sifive.com>,
	Palmer Dabbelt <palmer@sifive.com>,
	Sagar Karandikar <sagark@eecs.berkeley.edu>,
	Bastian Koppelmann <kbastian@mail.uni-paderborn.de>,
	RISC-V Patches <patches@groups.riscv.org>
Subject: Re: [Qemu-devel] [PATCH v1 11/22] RISC-V: Improve page table walker spec compliance
Date: Fri, 9 Mar 2018 16:54:33 +1300	[thread overview]
Message-ID: <CAHNT7NuwqMY9WVsBoWCcDbEZ3gNwo-nwuDZPXD+FwZ+5oBv6Qg@mail.gmail.com> (raw)
In-Reply-To: <1520369037-37977-12-git-send-email-mjc@sifive.com>

On Wed, Mar 7, 2018 at 9:43 AM, Michael Clark <mjc@sifive.com> wrote:

> - Inline PTE_TABLE check for better readability
> - Improve readibility of User page U mode and SUM test
> - Disallow non U mode from fetching from User pages
> - Add reserved PTE flag check: W or W|X
> - Add misaligned PPN check
> - Change access checks from ternary operator to if statements
> - Improves page walker comments
> - No measurable performance impact on dd test
>
> Signed-off-by: Michael Clark <mjc@sifive.com>
> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
> ---
>  target/riscv/cpu_bits.h |  2 --
>  target/riscv/helper.c   | 57 ++++++++++++++++++++++++++++++
> ++++---------------
>  2 files changed, 40 insertions(+), 19 deletions(-)
>
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index 64aa097..12b4757 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -407,5 +407,3 @@
>  #define PTE_SOFT  0x300 /* Reserved for Software */
>
>  #define PTE_PPN_SHIFT 10
> -
> -#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) ==
> PTE_V)
> diff --git a/target/riscv/helper.c b/target/riscv/helper.c
> index 228933c..2165ecb 100644
> --- a/target/riscv/helper.c
> +++ b/target/riscv/helper.c
> @@ -185,16 +185,36 @@ restart:
>  #endif
>          target_ulong ppn = pte >> PTE_PPN_SHIFT;
>
> -        if (PTE_TABLE(pte)) { /* next level of page table */
> +        if (!(pte & PTE_V)) {
> +            /* Invalid PTE */
> +            return TRANSLATE_FAIL;
> +        } else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
> +            /* Inner PTE, continue walking */
>              base = ppn << PGSHIFT;
> -        } else if ((pte & PTE_U) ? (mode == PRV_S) && !sum : !(mode ==
> PRV_S)) {
> -            break;
> -        } else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
> -            break;
> -        } else if (access_type == MMU_INST_FETCH ? !(pte & PTE_X) :
> -                  access_type == MMU_DATA_LOAD ?  !(pte & PTE_R) &&
> -                  !(mxr && (pte & PTE_X)) : !((pte & PTE_R) && (pte &
> PTE_W))) {
> -            break;
> +        } else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
> +            /* Reserved leaf PTE flags: PTE_W */
> +            return TRANSLATE_FAIL;
> +        } else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
> +            /* Reserved leaf PTE flags: PTE_W + PTE_X */
> +            return TRANSLATE_FAIL;
> +        } else if ((pte & PTE_U) && ((mode != PRV_U) &&
> +                   (!sum || access_type == MMU_INST_FETCH))) {
> +            /* User PTE flags when not U mode and mstats.SUM is not set,
> +               or the access type is an instruction fetch */
> +            return TRANSLATE_FAIL;
> +        } else if (ppn & ((1ULL << ptshift) - 1)) {
> +            /* Misasligned PPN */
> +            return TRANSLATE_FAIL;
> +        } else if (access_type == MMU_DATA_LOAD && !((pte & PTE_R) ||
> +                   ((pte & PTE_X) && mxr))) {
>

This should only honor the mstatus.MXR flags if mode != PRV_U

+            /* Read access check failed */
> +            return TRANSLATE_FAIL;
> +        } else if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
> +            /* Write access check failed */
> +            return TRANSLATE_FAIL;
> +        } else if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) {
> +            /* Fetch access check failed */
> +            return TRANSLATE_FAIL;
>          } else {
>              /* if necessary, set accessed and dirty bits. */
>              target_ulong updated_pte = pte | PTE_A |
> @@ -202,11 +222,14 @@ restart:
>
>              /* Page table updates need to be atomic with MTTCG enabled */
>              if (updated_pte != pte) {
> -                /* if accessed or dirty bits need updating, and the PTE is
> -                 * in RAM, then we do so atomically with a compare and
> swap.
> -                 * if the PTE is in IO space, then it can't be updated.
> -                 * if the PTE changed, then we must re-walk the page table
> -                   as the PTE is no longer valid */
> +                /*
> +                 * - if accessed or dirty bits need updating, and the PTE
> is
> +                 *   in RAM, then we do so atomically with a compare and
> swap.
> +                 * - if the PTE is in IO space or ROM, then it can't be
> updated
> +                 *   and we return TRANSLATE_FAIL.
> +                 * - if the PTE changed by the time we went to update it,
> then
> +                 *   it is no longer valid and we must re-walk the page
> table.
> +                 */
>                  MemoryRegion *mr;
>                  hwaddr l = sizeof(target_ulong), addr1;
>                  rcu_read_lock();
> @@ -243,15 +266,15 @@ restart:
>              target_ulong vpn = addr >> PGSHIFT;
>              *physical = (ppn | (vpn & ((1L << ptshift) - 1))) << PGSHIFT;
>
> +            /* set permissions on the TLB entry */
>              if ((pte & PTE_R)) {
>                  *prot |= PAGE_READ;
>              }
>

There is a logic bug here, but it is pre-existing. If mxr and mode is not
U, the X flag needs to make the page readable i.e. (MXR) Make eXecute
Readable.


>              if ((pte & PTE_X)) {
>                  *prot |= PAGE_EXEC;
>              }
> -           /* only add write permission on stores or if the page
> -              is already dirty, so that we don't miss further
> -              page table walks to update the dirty bit */
> +            /* add write permission on stores or if the page is already
> dirty,
> +               so that we TLB miss on later writes to update the dirty
> bit */
>              if ((pte & PTE_W) &&
>                      (access_type == MMU_DATA_STORE || (pte & PTE_D))) {
>                  *prot |= PAGE_WRITE;
> --
> 2.7.0
>
>

  reply	other threads:[~2018-03-09  3:54 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-06 20:43 [Qemu-devel] [PATCH v1 00/22] Spec conformance bug fixes and cleanups Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 01/22] RISC-V: Make virt create_fdt interface consistent Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 02/22] RISC-V: Replace hardcoded constants with enum values Michael Clark
2018-03-06 22:56   ` Philippe Mathieu-Daudé
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 03/22] RISC-V: Make virt board description match spike Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 04/22] RISC-V: Use ROM base address and size from memory Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 05/22] RISC-V: Remove redundant identity_translate from Michael Clark
2018-03-06 23:00   ` Philippe Mathieu-Daudé
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 06/22] RISC-V: Mark ROM read-only after copying in code and Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 07/22] RISC-V: Remove unused class definitions from Michael Clark
     [not found]   ` <8787c302-b90a-df1f-9eb3-3ee16022a92e@amsat.org>
2018-03-07  4:14     ` Michael Clark
2018-03-07  4:30       ` Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 08/22] RISC-V: Make sure the emulated rom has space for Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 09/22] RISC-V: Include hexidecimal instruction in Michael Clark
2018-03-06 23:09   ` Philippe Mathieu-Daudé
2018-03-07  4:17     ` Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 10/22] RISC-V: Hold rcu_read_lock when accessing memory Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 11/22] RISC-V: Improve page table walker spec compliance Michael Clark
2018-03-09  3:54   ` Michael Clark [this message]
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 12/22] RISC-V: Update E order and I extension order Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 13/22] RISC-V: Make spike and virt header guards more Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 14/22] RISC-V: Make virt header comment title consistent Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 15/22] RISC-V: Use memory_region_is_ram in atomic pte Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 16/22] RISC-V: Remove EM_RISCV ELF_MACHINE indirection from Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 17/22] RISC-V: Ingore satp writes and return 0 for reads Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 18/22] RISC-V: Remove braces from satp case statement with Michael Clark
2018-03-06 23:09   ` Philippe Mathieu-Daudé
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 19/22] RISC-V: riscv-qemu port supports sv39 and sv48 Michael Clark
2018-03-06 20:43 ` [Qemu-devel] [PATCH v1 20/22] RISC-V: vectored traps are optional Michael Clark
2018-03-06 23:07 ` [Qemu-devel] [PATCH v1 00/22] Spec conformance bug fixes and cleanups Michael Clark
2018-03-06 23:47   ` Emilio G. Cota
2018-03-07  0:00     ` Michael Clark
2018-03-07 17:40       ` Emilio G. Cota
2018-03-06 20:56 [Qemu-devel] [PATCH v1 02/22] RISC-V: Replace hardcoded constants with enum values Michael Clark
2018-03-06 20:56 ` [Qemu-devel] [PATCH v1 11/22] RISC-V: Improve page table walker spec compliance Michael Clark

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=CAHNT7NuwqMY9WVsBoWCcDbEZ3gNwo-nwuDZPXD+FwZ+5oBv6Qg@mail.gmail.com \
    --to=mjc@sifive.com \
    --cc=kbastian@mail.uni-paderborn.de \
    --cc=palmer@sifive.com \
    --cc=patches@groups.riscv.org \
    --cc=qemu-devel@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.