qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alistair Francis <alistair.francis@opensource.wdc.com>
To: qemu-devel@nongnu.org
Cc: alistair23@gmail.com, LIU Zhiwei <zhiwei_liu@linux.alibaba.com>,
	Alistair Francis <alistair.francis@wdc.com>
Subject: [PULL v3 01/43] target/riscv: Fix PMP propagation for tlb
Date: Fri,  6 Jan 2023 13:13:15 +1000	[thread overview]
Message-ID: <20230106031357.777790-2-alistair.francis@opensource.wdc.com> (raw)
In-Reply-To: <20230106031357.777790-1-alistair.francis@opensource.wdc.com>

From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Only the pmp index that be checked by pmp_hart_has_privs can be used
by pmp_get_tlb_size to avoid an error pmp index.

Before modification, we may use an error pmp index. For example,
we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
will return true;

However, this checked pmp index is discarded as pmp_hart_has_privs
return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
rules. The tlb_sa will be 0x0, and tlb_ea will be 0xfff. If there is
a pmp rule [0x10, 0x14), it will be misused as it is legal in
pmp_get_tlb_size.

As we have already known the correct pmp index, just remove the
remove the pmp_is_range_in_tlb and get tlb size directly from
pmp_get_tlb_size.

Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20221012060016.30856-1-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/pmp.h        |  6 +--
 target/riscv/cpu_helper.c | 16 ++++---
 target/riscv/pmp.c        | 90 +++++++++++++--------------------------
 3 files changed, 42 insertions(+), 70 deletions(-)

diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index a8dd797476..da32c61c85 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -72,11 +72,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
 void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
     target_ulong val);
 target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
     target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
     target_ulong mode);
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
-                         target_ulong *tlb_size);
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
+                              target_ulong tlb_sa, target_ulong tlb_ea);
 void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
 void pmp_update_rule_nums(CPURISCVState *env);
 uint32_t pmp_get_num_rules(CPURISCVState *env);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 278d163803..5d66246c2c 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -706,24 +706,26 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
                                     int mode)
 {
     pmp_priv_t pmp_priv;
-    target_ulong tlb_size_pmp = 0;
+    int pmp_index = -1;
 
     if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
         *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
         return TRANSLATE_SUCCESS;
     }
 
-    if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
-                            mode)) {
+    pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
+                                   &pmp_priv, mode);
+    if (pmp_index < 0) {
         *prot = 0;
         return TRANSLATE_PMP_FAIL;
     }
 
     *prot = pmp_priv_to_page_prot(pmp_priv);
-    if (tlb_size != NULL) {
-        if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
-            *tlb_size = tlb_size_pmp;
-        }
+    if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
+        target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
+        target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
+
+        *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
     }
 
     return TRANSLATE_SUCCESS;
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 2b43e399b8..d1126a6066 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -292,8 +292,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
 
 /*
  * Check if the address has required RWX privs to complete desired operation
+ * Return PMP rule index if a pmp rule match
+ * Return MAX_RISCV_PMPS if default match
+ * Return negtive value if no match
  */
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
     target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
     target_ulong mode)
 {
@@ -305,8 +308,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
 
     /* Short cut if no rules */
     if (0 == pmp_get_num_rules(env)) {
-        return pmp_hart_has_privs_default(env, addr, size, privs,
-                                          allowed_privs, mode);
+        if (pmp_hart_has_privs_default(env, addr, size, privs,
+                                       allowed_privs, mode)) {
+            ret = MAX_RISCV_PMPS;
+        }
     }
 
     if (size == 0) {
@@ -333,7 +338,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
         if ((s + e) == 1) {
             qemu_log_mask(LOG_GUEST_ERROR,
                           "pmp violation - access is partially inside\n");
-            ret = 0;
+            ret = -1;
             break;
         }
 
@@ -436,18 +441,22 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
                 }
             }
 
-            ret = ((privs & *allowed_privs) == privs);
+            if ((privs & *allowed_privs) == privs) {
+                ret = i;
+            }
             break;
         }
     }
 
     /* No rule matched */
     if (ret == -1) {
-        return pmp_hart_has_privs_default(env, addr, size, privs,
-                                          allowed_privs, mode);
+        if (pmp_hart_has_privs_default(env, addr, size, privs,
+                                       allowed_privs, mode)) {
+            ret = MAX_RISCV_PMPS;
+        }
     }
 
-    return ret == 1 ? true : false;
+    return ret;
 }
 
 /*
@@ -586,64 +595,25 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
  * Calculate the TLB size if the start address or the end address of
  * PMP entry is presented in the TLB page.
  */
-static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
-                                     target_ulong tlb_sa, target_ulong tlb_ea)
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
+                              target_ulong tlb_sa, target_ulong tlb_ea)
 {
     target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
     target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
 
-    if (pmp_sa >= tlb_sa && pmp_ea <= tlb_ea) {
-        return pmp_ea - pmp_sa + 1;
-    }
-
-    if (pmp_sa >= tlb_sa && pmp_sa <= tlb_ea && pmp_ea >= tlb_ea) {
-        return tlb_ea - pmp_sa + 1;
-    }
-
-    if (pmp_ea <= tlb_ea && pmp_ea >= tlb_sa && pmp_sa <= tlb_sa) {
-        return pmp_ea - tlb_sa + 1;
-    }
-
-    return 0;
-}
-
-/*
- * Check is there a PMP entry which range covers this page. If so,
- * try to find the minimum granularity for the TLB size.
- */
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
-                         target_ulong *tlb_size)
-{
-    int i;
-    target_ulong val;
-    target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
-
-    for (i = 0; i < MAX_RISCV_PMPS; i++) {
-        val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
-        if (val) {
-            if (*tlb_size == 0 || *tlb_size > val) {
-                *tlb_size = val;
-            }
-        }
-    }
-
-    if (*tlb_size != 0) {
+    if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
+        return TARGET_PAGE_SIZE;
+    } else {
         /*
-         * At this point we have a tlb_size that is the smallest possible size
-         * That fits within a TARGET_PAGE_SIZE and the PMP region.
-         *
-         * If the size is less then TARGET_PAGE_SIZE we drop the size to 1.
-         * This means the result isn't cached in the TLB and is only used for
-         * a single translation.
-         */
-        if (*tlb_size < TARGET_PAGE_SIZE) {
-            *tlb_size = 1;
-        }
-
-        return true;
+        * At this point we have a tlb_size that is the smallest possible size
+        * That fits within a TARGET_PAGE_SIZE and the PMP region.
+        *
+        * If the size is less then TARGET_PAGE_SIZE we drop the size to 1.
+        * This means the result isn't cached in the TLB and is only used for
+        * a single translation.
+        */
+        return 1;
     }
-
-    return false;
 }
 
 /*
-- 
2.39.0



  reply	other threads:[~2023-01-06  3:22 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-06  3:13 [PULL v3 00/43] riscv-to-apply queue Alistair Francis
2023-01-06  3:13 ` Alistair Francis [this message]
2023-01-06  3:13 ` [PULL v3 02/43] tcg/riscv: Fix range matched by TCG_CT_CONST_M12 Alistair Francis
2023-01-06  3:13 ` [PULL v3 03/43] tcg/riscv: Fix reg overlap case in tcg_out_addsub2 Alistair Francis
2023-01-06  3:13 ` [PULL v3 04/43] tcg/riscv: Fix base register for user-only qemu_ld/st Alistair Francis
2023-01-06  3:13 ` [PULL v3 05/43] hw/riscv/opentitan: bump opentitan Alistair Francis
2023-01-06  3:13 ` [PULL v3 06/43] hw/riscv/opentitan: add aon_timer base unimpl Alistair Francis
2023-01-06  3:13 ` [PULL v3 07/43] target/riscv: Add smstateen support Alistair Francis
2023-01-06  3:13 ` [PULL v3 08/43] target/riscv: smstateen check for h/s/envcfg Alistair Francis
2023-01-06  3:13 ` [PULL v3 09/43] target/riscv: generate virtual instruction exception Alistair Francis
2023-01-06  3:13 ` [PULL v3 10/43] target/riscv: Add itrigger support when icount is not enabled Alistair Francis
2023-01-06  3:13 ` [PULL v3 11/43] target/riscv: Add itrigger support when icount is enabled Alistair Francis
2023-01-06  3:13 ` [PULL v3 12/43] target/riscv: Enable native debug itrigger Alistair Francis
2023-01-06  3:13 ` [PULL v3 13/43] target/riscv: Add itrigger_enabled field to CPURISCVState Alistair Francis
2023-01-06  3:13 ` [PULL v3 14/43] hw/intc: sifive_plic: Renumber the S irqs for numa support Alistair Francis
2023-01-06  3:13 ` [PULL v3 15/43] target/riscv: Typo fix in sstc() predicate Alistair Francis
2023-01-06  3:13 ` [PULL v3 16/43] hw/riscv: virt: Remove the redundant ipi-id property Alistair Francis
2023-01-06  3:13 ` [PULL v3 17/43] target/riscv: support cache-related PMU events in virtual mode Alistair Francis
2023-01-06  3:13 ` [PULL v3 18/43] target/riscv: Add some comments for sstatus CSR in riscv_cpu_dump_state() Alistair Francis
2023-01-06  3:13 ` [PULL v3 19/43] hw/misc: pfsoc: add fabric clocks to ioscb Alistair Francis
2023-01-06  3:13 ` [PULL v3 20/43] hw/riscv: pfsoc: add missing FICs as unimplemented Alistair Francis
2023-01-06  3:13 ` [PULL v3 21/43] hw/{misc, riscv}: pfsoc: add system controller " Alistair Francis
2023-01-06  3:13 ` [PULL v3 22/43] hw/intc: sifive_plic: fix out-of-bound access of source_priority array Alistair Francis
2023-01-06  3:13 ` [PULL v3 23/43] target/riscv: Fix mret exception cause when no pmp rule is configured Alistair Francis
2023-01-06  3:13 ` [PULL v3 24/43] target/riscv: Set pc_succ_insn for !rvc illegal insn Alistair Francis
2023-01-06  3:13 ` [PULL v3 25/43] target/riscv: Simplify helper_sret() a little bit Alistair Francis
2023-01-06  3:13 ` [PULL v3 26/43] target/riscv: Clear mstatus.MPRV when leaving M-mode for priv spec 1.12+ Alistair Francis
2023-01-06  3:13 ` [PULL v3 27/43] RISC-V: Add Zawrs ISA extension support Alistair Francis
2023-01-06  3:13 ` [PULL v3 28/43] hw/riscv: Select MSI_NONBROKEN in SIFIVE_PLIC Alistair Francis
2023-01-06  3:13 ` [PULL v3 29/43] hw/intc: Select MSI_NONBROKEN in RISC-V AIA interrupt controllers Alistair Francis
2023-01-06  3:13 ` [PULL v3 30/43] hw/riscv: Fix opentitan dependency to SIFIVE_PLIC Alistair Francis
2023-01-06  3:13 ` [PULL v3 31/43] hw/riscv: Sort machines Kconfig options in alphabetical order Alistair Francis
2023-01-06  3:13 ` [PULL v3 32/43] hw/riscv: spike: Remove misleading comments Alistair Francis
2023-01-06  3:13 ` [PULL v3 33/43] hw/intc: sifive_plic: Drop PLICMode_H Alistair Francis
2023-01-06  3:13 ` [PULL v3 34/43] hw/intc: sifive_plic: Improve robustness of the PLIC config parser Alistair Francis
2023-01-06  3:13 ` [PULL v3 35/43] hw/intc: sifive_plic: Use error_setg() to propagate the error up via errp in sifive_plic_realize() Alistair Francis
2023-01-06  3:13 ` [PULL v3 36/43] hw/intc: sifive_plic: Update "num-sources" property default value Alistair Francis
2023-01-06  3:13 ` [PULL v3 37/43] hw/riscv: microchip_pfsoc: Fix the number of interrupt sources of PLIC Alistair Francis
2023-01-06  3:13 ` [PULL v3 38/43] hw/riscv: sifive_e: " Alistair Francis
2023-01-06  3:13 ` [PULL v3 39/43] hw/riscv: sifive_u: Avoid using magic number for "riscv, ndev" Alistair Francis
2023-01-06  3:13 ` [PULL v3 40/43] hw/riscv: virt: Fix the value of "riscv, ndev" in the dtb Alistair Francis
2023-01-06  3:13 ` [PULL v3 41/43] hw/intc: sifive_plic: Change "priority-base" to start from interrupt source 0 Alistair Francis
2023-01-06  3:13 ` [PULL v3 42/43] hw/riscv: opentitan: Drop "hartid-base" and "priority-base" initialization Alistair Francis
2023-01-06  3:13 ` [PULL v3 43/43] hw/intc: sifive_plic: Fix the pending register range check Alistair Francis
2023-01-07 13:07 ` [PULL v3 00/43] riscv-to-apply queue Peter Maydell

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=20230106031357.777790-2-alistair.francis@opensource.wdc.com \
    --to=alistair.francis@opensource.wdc.com \
    --cc=alistair.francis@wdc.com \
    --cc=alistair23@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=zhiwei_liu@linux.alibaba.com \
    /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).