[Top][All Lists]

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

[PATCH v2 15/18] target/riscv: make riscv_isa_string_ext() KVM compatibl

From: Daniel Henrique Barboza
Subject: [PATCH v2 15/18] target/riscv: make riscv_isa_string_ext() KVM compatible
Date: Tue, 13 Jun 2023 17:58:54 -0300

The isa_edata_arr[] is used by riscv_isa_string_ext() to create the
riscv,isa DT attribute. isa_edata_arr[] is kept in sync with the TCG
property vector riscv_cpu_extensions[], i.e. all TCG properties from
this vector that has a riscv,isa representation are included in

KVM doesn't implement all TCG properties, but allow them to be created
anyway to not force an API change between TCG and KVM guests. Some of
these TCG-only extensions are defaulted to 'true', and users are also
allowed to enable them. KVM doesn't care, but riscv_isa_string_ext()
does. The result is that these TCG-only enabled extensions will appear
in the riscv,isa DT string under KVM.

To avoid code repetition and re-use riscv_isa_string_ext() for KVM
guests we'll make a couple of tweaks:

- set env->priv_ver to 'LATEST' for the KVM 'host' CPU. This is needed
  because riscv_isa_string_ext() makes a priv check for each extension
  before including them in the ISA string. KVM doesn't care about
  env->priv_ver, since it's part of the TCG-only CPU validation, so this
  change is benign for KVM;

- add a new 'kvm_available' flag in isa_ext_data struct. This flag is
  set via a new ISA_EXT_DATA_ENTRY_KVM macro to report that, for a given
  extension, KVM also supports it. riscv_isa_string_ext() then can check
  if a given extension is known by KVM and skip it if it's not.

This will allow us to re-use riscv_isa_string_ext() for KVM guests.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
 target/riscv/cpu.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a4f3ed0c17..a773c09645 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -44,11 +44,15 @@ struct isa_ext_data {
     const char *name;
     int min_version;
     int ext_enable_offset;
+    bool kvm_available;
 #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
     {#_name, _min_ver, offsetof(struct RISCVCPUConfig, _prop)}
+#define ISA_EXT_DATA_ENTRY_KVM(_name, _min_ver, _prop) \
+    {#_name, _min_ver, offsetof(struct RISCVCPUConfig, _prop), true}
  * Here are the ordering rules of extension naming defined by RISC-V
  * specification :
@@ -68,14 +72,17 @@ struct isa_ext_data {
  * Single letter extensions are checked in riscv_cpu_validate_misa_priv()
  * instead.
+ *
+ * ISA_EXT_DATA_ENTRY_KVM() is used to indicate that the extension is
+ * also known by the KVM driver. If unsure, use ISA_EXT_DATA_ENTRY().
 static const struct isa_ext_data isa_edata_arr[] = {
-    ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_icbom),
-    ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_icboz),
+    ISA_EXT_DATA_ENTRY_KVM(zicbom, PRIV_VERSION_1_12_0, ext_icbom),
+    ISA_EXT_DATA_ENTRY_KVM(zicboz, PRIV_VERSION_1_12_0, ext_icboz),
     ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
     ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
     ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
-    ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
+    ISA_EXT_DATA_ENTRY_KVM(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
     ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
     ISA_EXT_DATA_ENTRY(zfh, PRIV_VERSION_1_11_0, ext_zfh),
     ISA_EXT_DATA_ENTRY(zfhmin, PRIV_VERSION_1_11_0, ext_zfhmin),
@@ -89,7 +96,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
     ISA_EXT_DATA_ENTRY(zcmp, PRIV_VERSION_1_12_0, ext_zcmp),
     ISA_EXT_DATA_ENTRY(zcmt, PRIV_VERSION_1_12_0, ext_zcmt),
     ISA_EXT_DATA_ENTRY(zba, PRIV_VERSION_1_12_0, ext_zba),
-    ISA_EXT_DATA_ENTRY(zbb, PRIV_VERSION_1_12_0, ext_zbb),
+    ISA_EXT_DATA_ENTRY_KVM(zbb, PRIV_VERSION_1_12_0, ext_zbb),
     ISA_EXT_DATA_ENTRY(zbc, PRIV_VERSION_1_12_0, ext_zbc),
     ISA_EXT_DATA_ENTRY(zbkb, PRIV_VERSION_1_12_0, ext_zbkb),
     ISA_EXT_DATA_ENTRY(zbkc, PRIV_VERSION_1_12_0, ext_zbkc),
@@ -114,13 +121,13 @@ static const struct isa_ext_data isa_edata_arr[] = {
     ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
     ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
     ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
-    ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
+    ISA_EXT_DATA_ENTRY_KVM(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
     ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
-    ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
+    ISA_EXT_DATA_ENTRY_KVM(sstc, PRIV_VERSION_1_12_0, ext_sstc),
     ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
-    ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
+    ISA_EXT_DATA_ENTRY_KVM(svinval, PRIV_VERSION_1_12_0, ext_svinval),
     ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
-    ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
+    ISA_EXT_DATA_ENTRY_KVM(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
     ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
     ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
     ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs),
@@ -586,6 +593,7 @@ static void riscv_host_cpu_init(Object *obj)
     set_misa(env, MXL_RV64, 0);
+    env->priv_ver = PRIV_VERSION_LATEST;
@@ -1981,6 +1989,10 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char 
     int i;
     for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
+        if (riscv_running_kvm() && !isa_edata_arr[i].kvm_available) {
+            continue;
+        }
         if (cpu->env.priv_ver >= isa_edata_arr[i].min_version &&
             isa_ext_is_enabled(cpu, &isa_edata_arr[i])) {
             new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);

reply via email to

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