From: Anup Patel <apatel@ventanamicro.com>
To: Peter Maydell <peter.maydell@linaro.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Alistair Francis <Alistair.Francis@wdc.com>,
Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Atish Patra <atishp@atishpatra.org>,
Anup Patel <anup@brainfault.org>,
qemu-riscv@nongnu.org, qemu-devel@nongnu.org,
Anup Patel <apatel@ventanamicro.com>,
Alistair Francis <alistair.francis@wdc.com>,
Rahul Pathak <rpathak@ventanamicro.com>
Subject: [PATCH v8 4/4] target/riscv: Force disable extensions if priv spec version does not match
Date: Tue, 28 Jun 2022 15:47:37 +0530 [thread overview]
Message-ID: <20220628101737.786681-5-apatel@ventanamicro.com> (raw)
In-Reply-To: <20220628101737.786681-1-apatel@ventanamicro.com>
We should disable extensions in riscv_cpu_realize() if minimum required
priv spec version is not satisfied. This also ensures that machines with
priv spec v1.11 (or lower) cannot enable H, V, and various multi-letter
extensions.
Fixes: a775398be2e9 ("target/riscv: Add isa extenstion strings to the device tree")
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
---
target/riscv/cpu.c | 150 ++++++++++++++++++++++++++++-----------------
1 file changed, 94 insertions(+), 56 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4e7ca6cd4a..9bc4ef0685 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -43,9 +43,82 @@ static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
struct isa_ext_data {
const char *name;
- bool enabled;
+ bool multi_letter;
+ int min_version;
+ int ext_enable_offset;
};
+#define ISA_EXT_DATA_ENTRY(_name, _m_letter, _min_ver, _prop) \
+{#_name, _m_letter, _min_ver, offsetof(struct RISCVCPUConfig, _prop)}
+
+/**
+ * Here are the ordering rules of extension naming defined by RISC-V
+ * specification :
+ * 1. All extensions should be separated from other multi-letter extensions
+ * by an underscore.
+ * 2. The first letter following the 'Z' conventionally indicates the most
+ * closely related alphabetical extension category, IMAFDQLCBKJTPVH.
+ * If multiple 'Z' extensions are named, they should be ordered first
+ * by category, then alphabetically within a category.
+ * 3. Standard supervisor-level extensions (starts with 'S') should be
+ * listed after standard unprivileged extensions. If multiple
+ * supervisor-level extensions are listed, they should be ordered
+ * alphabetically.
+ * 4. Non-standard extensions (starts with 'X') must be listed after all
+ * standard extensions. They must be separated from other multi-letter
+ * extensions by an underscore.
+ */
+static const struct isa_ext_data isa_edata_arr[] = {
+ ISA_EXT_DATA_ENTRY(h, false, PRIV_VERSION_1_12_0, ext_h),
+ ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_12_0, ext_v),
+ ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
+ ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
+ ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
+ ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
+ ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
+ ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
+ ISA_EXT_DATA_ENTRY(zba, true, PRIV_VERSION_1_12_0, ext_zba),
+ ISA_EXT_DATA_ENTRY(zbb, true, PRIV_VERSION_1_12_0, ext_zbb),
+ ISA_EXT_DATA_ENTRY(zbc, true, PRIV_VERSION_1_12_0, ext_zbc),
+ ISA_EXT_DATA_ENTRY(zbkb, true, PRIV_VERSION_1_12_0, ext_zbkb),
+ ISA_EXT_DATA_ENTRY(zbkc, true, PRIV_VERSION_1_12_0, ext_zbkc),
+ ISA_EXT_DATA_ENTRY(zbkx, true, PRIV_VERSION_1_12_0, ext_zbkx),
+ ISA_EXT_DATA_ENTRY(zbs, true, PRIV_VERSION_1_12_0, ext_zbs),
+ ISA_EXT_DATA_ENTRY(zk, true, PRIV_VERSION_1_12_0, ext_zk),
+ ISA_EXT_DATA_ENTRY(zkn, true, PRIV_VERSION_1_12_0, ext_zkn),
+ ISA_EXT_DATA_ENTRY(zknd, true, PRIV_VERSION_1_12_0, ext_zknd),
+ ISA_EXT_DATA_ENTRY(zkne, true, PRIV_VERSION_1_12_0, ext_zkne),
+ ISA_EXT_DATA_ENTRY(zknh, true, PRIV_VERSION_1_12_0, ext_zknh),
+ ISA_EXT_DATA_ENTRY(zkr, true, PRIV_VERSION_1_12_0, ext_zkr),
+ ISA_EXT_DATA_ENTRY(zks, true, PRIV_VERSION_1_12_0, ext_zks),
+ ISA_EXT_DATA_ENTRY(zksed, true, PRIV_VERSION_1_12_0, ext_zksed),
+ ISA_EXT_DATA_ENTRY(zksh, true, PRIV_VERSION_1_12_0, ext_zksh),
+ ISA_EXT_DATA_ENTRY(zkt, true, PRIV_VERSION_1_12_0, ext_zkt),
+ ISA_EXT_DATA_ENTRY(zve32f, true, PRIV_VERSION_1_12_0, ext_zve32f),
+ ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f),
+ ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
+ ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
+ ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
+ ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
+ ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
+};
+
+static bool isa_ext_is_enabled(RISCVCPU *cpu,
+ const struct isa_ext_data *edata)
+{
+ bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset;
+
+ return *ext_enabled;
+}
+
+static void isa_ext_update_enabled(RISCVCPU *cpu,
+ const struct isa_ext_data *edata, bool en)
+{
+ bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset;
+
+ *ext_enabled = en;
+}
+
const char * const riscv_int_regnames[] = {
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
"x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
@@ -530,7 +603,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
CPURISCVState *env = &cpu->env;
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
CPUClass *cc = CPU_CLASS(mcc);
- int priv_version = -1;
+ int i, priv_version = -1;
Error *local_err = NULL;
cpu_exec_realizefn(cs, &local_err);
@@ -558,6 +631,23 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
set_priv_version(env, priv_version);
}
+ /* Force disable extensions if priv spec version does not match */
+ for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
+ if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
+ (env->priv_ver < isa_edata_arr[i].min_version)) {
+ isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
+#ifndef CONFIG_USER_ONLY
+ warn_report("disabling %s extension for hart 0x%lx because "
+ "privilege spec version does not match",
+ isa_edata_arr[i].name, (unsigned long)env->mhartid);
+#else
+ warn_report("disabling %s extension because "
+ "privilege spec version does not match",
+ isa_edata_arr[i].name);
+#endif
+ }
+ }
+
if (cpu->cfg.mmu) {
riscv_set_feature(env, RISCV_FEATURE_MMU);
}
@@ -1049,67 +1139,15 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
device_class_set_props(dc, riscv_cpu_properties);
}
-#define ISA_EDATA_ENTRY(name, prop) {#name, cpu->cfg.prop}
-
static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len)
{
char *old = *isa_str;
char *new = *isa_str;
int i;
- /**
- * Here are the ordering rules of extension naming defined by RISC-V
- * specification :
- * 1. All extensions should be separated from other multi-letter extensions
- * by an underscore.
- * 2. The first letter following the 'Z' conventionally indicates the most
- * closely related alphabetical extension category, IMAFDQLCBKJTPVH.
- * If multiple 'Z' extensions are named, they should be ordered first
- * by category, then alphabetically within a category.
- * 3. Standard supervisor-level extensions (starts with 'S') should be
- * listed after standard unprivileged extensions. If multiple
- * supervisor-level extensions are listed, they should be ordered
- * alphabetically.
- * 4. Non-standard extensions (starts with 'X') must be listed after all
- * standard extensions. They must be separated from other multi-letter
- * extensions by an underscore.
- */
- struct isa_ext_data isa_edata_arr[] = {
- ISA_EDATA_ENTRY(zicsr, ext_icsr),
- ISA_EDATA_ENTRY(zifencei, ext_ifencei),
- ISA_EDATA_ENTRY(zmmul, ext_zmmul),
- ISA_EDATA_ENTRY(zfh, ext_zfh),
- ISA_EDATA_ENTRY(zfhmin, ext_zfhmin),
- ISA_EDATA_ENTRY(zfinx, ext_zfinx),
- ISA_EDATA_ENTRY(zdinx, ext_zdinx),
- ISA_EDATA_ENTRY(zba, ext_zba),
- ISA_EDATA_ENTRY(zbb, ext_zbb),
- ISA_EDATA_ENTRY(zbc, ext_zbc),
- ISA_EDATA_ENTRY(zbkb, ext_zbkb),
- ISA_EDATA_ENTRY(zbkc, ext_zbkc),
- ISA_EDATA_ENTRY(zbkx, ext_zbkx),
- ISA_EDATA_ENTRY(zbs, ext_zbs),
- ISA_EDATA_ENTRY(zk, ext_zk),
- ISA_EDATA_ENTRY(zkn, ext_zkn),
- ISA_EDATA_ENTRY(zknd, ext_zknd),
- ISA_EDATA_ENTRY(zkne, ext_zkne),
- ISA_EDATA_ENTRY(zknh, ext_zknh),
- ISA_EDATA_ENTRY(zkr, ext_zkr),
- ISA_EDATA_ENTRY(zks, ext_zks),
- ISA_EDATA_ENTRY(zksed, ext_zksed),
- ISA_EDATA_ENTRY(zksh, ext_zksh),
- ISA_EDATA_ENTRY(zkt, ext_zkt),
- ISA_EDATA_ENTRY(zve32f, ext_zve32f),
- ISA_EDATA_ENTRY(zve64f, ext_zve64f),
- ISA_EDATA_ENTRY(zhinx, ext_zhinx),
- ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin),
- ISA_EDATA_ENTRY(svinval, ext_svinval),
- ISA_EDATA_ENTRY(svnapot, ext_svnapot),
- ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
- };
-
for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
- if (isa_edata_arr[i].enabled) {
+ if (isa_edata_arr[i].multi_letter &&
+ isa_ext_is_enabled(cpu, &isa_edata_arr[i])) {
new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
g_free(old);
old = new;
--
2.34.1
prev parent reply other threads:[~2022-06-28 10:18 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-28 10:17 [PATCH v8 0/4] QEMU RISC-V nested virtualization fixes Anup Patel
2022-06-28 10:17 ` [PATCH v8 1/4] Revert "target/riscv: Add dummy mcountinhibit CSR for priv spec v1.11 or higher" Anup Patel
2022-06-28 10:17 ` [PATCH v8 2/4] target/riscv: Set minumum priv spec version for mcountinhibit Anup Patel
2022-06-28 22:12 ` Alistair Francis
2022-06-28 10:17 ` [PATCH v8 3/4] target/riscv: Update [m|h]tinst CSR in riscv_cpu_do_interrupt() Anup Patel
2022-06-29 12:13 ` dramforever
2022-06-28 10:17 ` Anup Patel [this message]
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=20220628101737.786681-5-apatel@ventanamicro.com \
--to=apatel@ventanamicro.com \
--cc=Alistair.Francis@wdc.com \
--cc=anup@brainfault.org \
--cc=atishp@atishpatra.org \
--cc=palmer@dabbelt.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=rpathak@ventanamicro.com \
--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.