git: a7bf553d175a - main - riscv vmm: add SSTC extension check.

From: Ruslan Bukin <br_at_FreeBSD.org>
Date: Tue, 17 Dec 2024 11:20:13 UTC
The branch main has been updated by br:

URL: https://cgit.FreeBSD.org/src/commit/?id=a7bf553d175a27b03cbad7d0f94e40991df2958b

commit a7bf553d175a27b03cbad7d0f94e40991df2958b
Author:     Ruslan Bukin <br@FreeBSD.org>
AuthorDate: 2024-12-17 10:35:24 +0000
Commit:     Ruslan Bukin <br@FreeBSD.org>
CommitDate: 2024-12-17 10:35:44 +0000

    riscv vmm: add SSTC extension check.
    
    Check if RISC-V SSTC is available and advertise to the guest.
    
    This is needed for Eswin EIC7700 that does not include SSTC.
    
    As we don't have a mechanism for reporting extension presence
    from the kernel to userspace, then use vm_cap_type for now.
    
    Reviewed by: mhorne, markj
    Differential Revision: https://reviews.freebsd.org/D48058
---
 lib/libvmmapi/riscv/vmmapi_machdep.c    |  1 +
 sys/riscv/include/vmm.h                 |  1 +
 sys/riscv/vmm/vmm_riscv.c               |  4 ++++
 usr.sbin/bhyve/riscv/bhyverun_machdep.c |  9 ++++++++-
 usr.sbin/bhyve/riscv/fdt.c              | 17 +++++++++--------
 usr.sbin/bhyve/riscv/fdt.h              |  2 +-
 6 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/lib/libvmmapi/riscv/vmmapi_machdep.c b/lib/libvmmapi/riscv/vmmapi_machdep.c
index 9c70185942c9..4da2fb909f61 100644
--- a/lib/libvmmapi/riscv/vmmapi_machdep.c
+++ b/lib/libvmmapi/riscv/vmmapi_machdep.c
@@ -40,6 +40,7 @@
 #include "internal.h"
 
 const char *vm_capstrmap[] = {
+	[VM_CAP_SSTC] = "sstc",
 	[VM_CAP_MAX] = NULL,
 };
 
diff --git a/sys/riscv/include/vmm.h b/sys/riscv/include/vmm.h
index 1093e1cd0096..6c027f50e97a 100644
--- a/sys/riscv/include/vmm.h
+++ b/sys/riscv/include/vmm.h
@@ -275,6 +275,7 @@ struct vre {
  */
 enum vm_cap_type {
 	VM_CAP_UNRESTRICTED_GUEST,
+	VM_CAP_SSTC,
 	VM_CAP_MAX
 };
 
diff --git a/sys/riscv/vmm/vmm_riscv.c b/sys/riscv/vmm/vmm_riscv.c
index 6a76f8cf4f26..e276f8583e37 100644
--- a/sys/riscv/vmm/vmm_riscv.c
+++ b/sys/riscv/vmm/vmm_riscv.c
@@ -903,6 +903,10 @@ vmmops_getcap(void *vcpui, int num, int *retval)
 	ret = ENOENT;
 
 	switch (num) {
+	case VM_CAP_SSTC:
+		*retval = has_sstc;
+		ret = 0;
+		break;
 	case VM_CAP_UNRESTRICTED_GUEST:
 		*retval = 1;
 		ret = 0;
diff --git a/usr.sbin/bhyve/riscv/bhyverun_machdep.c b/usr.sbin/bhyve/riscv/bhyverun_machdep.c
index 39d6a7cdf231..d06b517a6624 100644
--- a/usr.sbin/bhyve/riscv/bhyverun_machdep.c
+++ b/usr.sbin/bhyve/riscv/bhyverun_machdep.c
@@ -308,6 +308,8 @@ bhyve_init_platform(struct vmctx *ctx, struct vcpu *bsp)
 	int error;
 	int pcie_intrs[4] = {PCIE_INTA, PCIE_INTB, PCIE_INTC, PCIE_INTD};
 	vm_paddr_t fdt_gpa;
+	char isa[32];
+	int retval;
 
 	bootrom = get_config_value("bootrom");
 	if (bootrom == NULL) {
@@ -321,8 +323,13 @@ bhyve_init_platform(struct vmctx *ctx, struct vcpu *bsp)
 		return (error);
 	}
 
+	error = vm_get_capability(bsp, VM_CAP_SSTC, &retval);
+	assert(error == 0);
+	snprintf(isa, sizeof(isa), "%s%s", "rv64imafdc",
+	    retval == 1 ? "_sstc" : "");
+
 	fdt_gpa = vm_get_highmem_base(ctx) + roundup2(len, FDT_DTB_ALIGN);
-	error = fdt_init(ctx, guest_ncpus, fdt_gpa, FDT_SIZE);
+	error = fdt_init(ctx, guest_ncpus, fdt_gpa, FDT_SIZE, isa);
 	if (error != 0)
 		return (error);
 
diff --git a/usr.sbin/bhyve/riscv/fdt.c b/usr.sbin/bhyve/riscv/fdt.c
index 54b75c68ea76..bef3f64b0c64 100644
--- a/usr.sbin/bhyve/riscv/fdt.c
+++ b/usr.sbin/bhyve/riscv/fdt.c
@@ -84,7 +84,7 @@ set_single_reg(void *fdt, uint64_t start, uint64_t len)
 }
 
 static void
-add_cpu(void *fdt, int cpuid)
+add_cpu(void *fdt, int cpuid, const char *isa)
 {
 	char node_name[16];
 
@@ -94,7 +94,7 @@ add_cpu(void *fdt, int cpuid)
 	fdt_property_string(fdt, "device_type", "cpu");
 	fdt_property_string(fdt, "compatible", "riscv");
 	fdt_property_u32(fdt, "reg", cpuid);
-	fdt_property_string(fdt, "riscv,isa", "rv64imafdc_sstc");
+	fdt_property_string(fdt, "riscv,isa", isa);
 	fdt_property_string(fdt, "mmu-type", "riscv,sv39");
 	fdt_property_string(fdt, "clock-frequency", "1000000000");
 
@@ -110,7 +110,7 @@ add_cpu(void *fdt, int cpuid)
 }
 
 static void
-add_cpus(void *fdt, int ncpu)
+add_cpus(void *fdt, int ncpu, const char *isa)
 {
 	int cpuid;
 
@@ -120,14 +120,15 @@ add_cpus(void *fdt, int ncpu)
 	fdt_property_u32(fdt, "#size-cells", 0);
 	fdt_property_u32(fdt, "timebase-frequency", 10000000);
 
-	for (cpuid = 0; cpuid < ncpu; cpuid++) {
-		add_cpu(fdt, cpuid);
-	}
+	for (cpuid = 0; cpuid < ncpu; cpuid++)
+		add_cpu(fdt, cpuid, isa);
+
 	fdt_end_node(fdt);
 }
 
 int
-fdt_init(struct vmctx *ctx, int ncpu, vm_paddr_t fdtaddr, vm_size_t fdtsize)
+fdt_init(struct vmctx *ctx, int ncpu, vm_paddr_t fdtaddr, vm_size_t fdtsize,
+    const char *isa)
 {
 	void *fdt;
 	const char *bootargs;
@@ -162,7 +163,7 @@ fdt_init(struct vmctx *ctx, int ncpu, vm_paddr_t fdtaddr, vm_size_t fdtsize)
 	set_single_reg(fdt, vm_get_highmem_base(ctx), vm_get_highmem_size(ctx));
 	fdt_end_node(fdt);
 
-	add_cpus(fdt, ncpu);
+	add_cpus(fdt, ncpu, isa);
 
 	/* Finalized by fdt_finalized(). */
 	fdtroot = fdt;
diff --git a/usr.sbin/bhyve/riscv/fdt.h b/usr.sbin/bhyve/riscv/fdt.h
index 9bebe6ffa29d..60140a82a211 100644
--- a/usr.sbin/bhyve/riscv/fdt.h
+++ b/usr.sbin/bhyve/riscv/fdt.h
@@ -36,7 +36,7 @@
 struct vmctx;
 
 int	fdt_init(struct vmctx *ctx, int ncpu, vm_paddr_t addrp,
-	    vm_size_t size);
+	    vm_size_t size, const char *isa);
 void	fdt_add_aplic(uint64_t dist_base, uint64_t dist_size);
 void	fdt_add_pcie(int intrs[static 4]);
 void	fdt_add_uart(uint64_t uart_base, uint64_t uart_size, int intr);