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

[PATCH v2 05/26] xen/riscv: introduce guest riscv,isa string



Introduce generation of the riscv,isa string passed to the guest via the
Device Tree riscv,isa property.

Introduce the per-domain isa string and guest isa bitmap, populated
during domain creation by calling init_guest_isa().

Introduce guest_unsupp to filter out ISA extensions that should not be
exposed to guests:

- f/d/q/v: FPU and vector context save/restore are not yet implemented
  for guests.
- h: Nested virtualisation is not supported.
- sstc: Xen owns the supervisor timer; guests must use SBI.
- svade: Xen manages hardware A/D bit updates in stage-2 page tables.
- svpbmt: Page-based memory types are not yet wired up in stage-2 code.

Drop __initconst for riscv_isa_ext() as it can be used after init stage
by init_guest_isa().

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
---
Changes in v2:
 - s/guest_unsupp_bmp/guest_unsupp.
 - Drop guest_isa_str.
 - Provide init_guest_isa() instead of polluting match_isa_ext().
 - Drop xlen.
 - Add the comment about guest_unsupp.
 - Update the way how guest_unsupp is init-ed.
 - Drop __initconst for riscv_isa_ext[] as it is used in init_guest_isa()
   which isn't marked as __init as it could be used after init stage.
---
---
 xen/arch/riscv/cpufeature.c             | 59 ++++++++++++++++++++++++-
 xen/arch/riscv/domain.c                 |  3 ++
 xen/arch/riscv/include/asm/cpufeature.h |  5 +++
 xen/arch/riscv/include/asm/domain.h     |  4 ++
 4 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/xen/arch/riscv/cpufeature.c b/xen/arch/riscv/cpufeature.c
index 92235fdfd5ab..618592e6096a 100644
--- a/xen/arch/riscv/cpufeature.c
+++ b/xen/arch/riscv/cpufeature.c
@@ -14,6 +14,7 @@
 #include <xen/errno.h>
 #include <xen/init.h>
 #include <xen/lib.h>
+#include <xen/sched.h>
 #include <xen/sections.h>
 
 #include <asm/cpufeature.h>
@@ -120,7 +121,7 @@ static int __init dt_get_cpuid_from_node(const struct 
dt_device_node *cpu,
  * and strncmp() is used in match_isa_ext() to compare extension names instead
  * of strncasecmp().
  */
-const struct riscv_isa_ext_data __initconst riscv_isa_ext[] = {
+const struct riscv_isa_ext_data riscv_isa_ext[] = {
     RISCV_ISA_EXT_DATA(i),
     RISCV_ISA_EXT_DATA(m),
     RISCV_ISA_EXT_DATA(a),
@@ -128,6 +129,7 @@ const struct riscv_isa_ext_data __initconst riscv_isa_ext[] 
= {
     RISCV_ISA_EXT_DATA(d),
     RISCV_ISA_EXT_DATA(q),
     RISCV_ISA_EXT_DATA(c),
+    RISCV_ISA_EXT_DATA(v),
     RISCV_ISA_EXT_DATA(h),
     RISCV_ISA_EXT_DATA(zicntr),
     RISCV_ISA_EXT_DATA(zicsr),
@@ -160,6 +162,12 @@ static const struct riscv_isa_ext_data __initconst 
required_extensions[] = {
     RISCV_ISA_EXT_DATA(svpbmt),
 };
 
+/*
+ * Everything in riscv_isa_ext[] which shouldn't be exposed to guests should
+ * appear here.
+ */
+static __ro_after_init DECLARE_BITMAP(guest_unsupp, RISCV_ISA_EXT_MAX);
+
 static bool __init is_lowercase_extension_name(const char *str)
 {
     /*
@@ -480,6 +488,53 @@ bool riscv_isa_extension_available(const unsigned long 
*isa_bitmap,
     return test_bit(id, isa_bitmap);
 }
 
+int init_guest_isa(struct domain *d)
+{
+    char *buf = d->arch.guest_isa_str;
+    size_t len = sizeof(d->arch.guest_isa_str);
+
+    bitmap_andnot(d->arch.guest_isa, riscv_isa, guest_unsupp,
+                  RISCV_ISA_EXT_MAX);
+
+#if defined(CONFIG_RISCV_32)
+    if ( snprintf(buf, len, "rv32") >= len )
+        return -ENOBUFS;
+#elif defined(CONFIG_RISCV_64)
+    if ( snprintf(buf, len, "rv64") >= len )
+        return -ENOBUFS;
+#else
+#   error "Unsupported RISC-V bitness"
+#endif
+
+    for ( unsigned int i = 0; i < ARRAY_SIZE(riscv_isa_ext); i++ )
+    {
+        const struct riscv_isa_ext_data *ext = &riscv_isa_ext[i];
+
+        if ( !riscv_isa_extension_available(d->arch.guest_isa, ext->id) )
+            continue;
+
+        if ( ext->id >= RISCV_ISA_EXT_BASE && strlcat(buf, "_", len) >= len )
+            return -ENOBUFS;
+
+        if ( strlcat(buf, ext->name, len) >= len )
+            return -ENOBUFS;
+    }
+
+    return 0;
+}
+
+static void __init init_guest_unsupp(void)
+{
+    set_bit(RISCV_ISA_EXT_f, guest_unsupp);
+    set_bit(RISCV_ISA_EXT_d, guest_unsupp);
+    set_bit(RISCV_ISA_EXT_q, guest_unsupp);
+    set_bit(RISCV_ISA_EXT_v, guest_unsupp);
+    set_bit(RISCV_ISA_EXT_h, guest_unsupp);
+    set_bit(RISCV_ISA_EXT_sstc, guest_unsupp);
+    set_bit(RISCV_ISA_EXT_svade, guest_unsupp);
+    set_bit(RISCV_ISA_EXT_svpbmt, guest_unsupp);
+}
+
 void __init riscv_fill_hwcap(void)
 {
     unsigned int i;
@@ -527,4 +582,6 @@ void __init riscv_fill_hwcap(void)
     if ( !all_extns_available )
         panic("Look why the extensions above are needed in "
               
"https://xenbits.xenproject.org/docs/unstable/misc/riscv/booting.txt\n";);
+
+    init_guest_unsupp();
 }
diff --git a/xen/arch/riscv/domain.c b/xen/arch/riscv/domain.c
index 669dd27d79a3..041aed176f32 100644
--- a/xen/arch/riscv/domain.c
+++ b/xen/arch/riscv/domain.c
@@ -303,6 +303,9 @@ int arch_domain_create(struct domain *d,
     if ( is_idle_domain(d) )
         return 0;
 
+    if ( (rc = init_guest_isa(d)) != 0 )
+        goto fail;
+
     if ( (rc = p2m_init(d, config)) != 0)
         goto fail;
 
diff --git a/xen/arch/riscv/include/asm/cpufeature.h 
b/xen/arch/riscv/include/asm/cpufeature.h
index 0c48d57a03bb..42d13d9dbdbe 100644
--- a/xen/arch/riscv/include/asm/cpufeature.h
+++ b/xen/arch/riscv/include/asm/cpufeature.h
@@ -17,6 +17,8 @@
  */
 #define RISCV_ISA_EXT_BASE  26
 
+#define RISCV_GUEST_ISA_STR_MAX 256
+
 enum riscv_isa_ext_id {
     RISCV_ISA_EXT_a,
     RISCV_ISA_EXT_c,
@@ -44,7 +46,10 @@ enum riscv_isa_ext_id {
     RISCV_ISA_EXT_MAX
 };
 
+struct domain;
+
 void riscv_fill_hwcap(void);
+int init_guest_isa(struct domain *d);
 
 bool riscv_isa_extension_available(const unsigned long *isa_bitmap,
                                    enum riscv_isa_ext_id id);
diff --git a/xen/arch/riscv/include/asm/domain.h 
b/xen/arch/riscv/include/asm/domain.h
index 6044ce0feee0..664b0b9f9129 100644
--- a/xen/arch/riscv/include/asm/domain.h
+++ b/xen/arch/riscv/include/asm/domain.h
@@ -7,6 +7,7 @@
 #include <xen/xmalloc.h>
 #include <public/hvm/params.h>
 
+#include <asm/cpufeature.h>
 #include <asm/guest-layout.h>
 #include <asm/p2m.h>
 #include <asm/vtimer.h>
@@ -94,6 +95,9 @@ struct arch_domain {
     struct p2m_domain p2m;
 
     struct paging_domain paging;
+
+    DECLARE_BITMAP(guest_isa, RISCV_ISA_EXT_MAX);
+    char guest_isa_str[RISCV_GUEST_ISA_STR_MAX];
 };
 
 #include <xen/sched.h>
-- 
2.54.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.