|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v1 1/3] xen/riscv: introduce vSBI extension framework
This commit introduces support for handling virtual SBI extensions in Xen.
The changes include:
- Added new vsbi.c and vsbi.h files to implement virtual SBI extension
handling.
- Modified traps.c to handle CAUSE_VIRTUAL_SUPERVISOR_ECALL by calling
vsbi_handle_ecall() when the trap originates from VS-mode.
- Updated xen.lds.S to include a new .vsbi.exts section for virtual SBI
extension data.
- Updated Makefile to include the new vsbi/ directory in the build.
- Add hstatus register to struct cpu_user_regs as it is needed for
a check that CAUSE_VIRTUAL_SUPERVISOR_ECALL happens from VS-mode.
The implementation allows for registration and handling of SBI
extensions via a new vsbi_ext structure and ".vsbi.exts" section,
enabling extensible virtual SBI support for RISC-V guests.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
---
xen/arch/riscv/Makefile | 1 +
xen/arch/riscv/include/asm/processor.h | 1 +
xen/arch/riscv/include/asm/vsbi.h | 31 +++++++++++++++++
xen/arch/riscv/traps.c | 8 +++++
xen/arch/riscv/vsbi/Makefile | 1 +
xen/arch/riscv/vsbi/vsbi.c | 46 ++++++++++++++++++++++++++
xen/arch/riscv/xen.lds.S | 7 ++++
7 files changed, 95 insertions(+)
create mode 100644 xen/arch/riscv/include/asm/vsbi.h
create mode 100644 xen/arch/riscv/vsbi/Makefile
create mode 100644 xen/arch/riscv/vsbi/vsbi.c
diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index e2b8aa42c8..7bfe7024ef 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -17,6 +17,7 @@ obj-y += stubs.o
obj-y += time.o
obj-y += traps.o
obj-y += vm_event.o
+obj-y += vsbi/
$(TARGET): $(TARGET)-syms
$(OBJCOPY) -O binary -S $< $@
diff --git a/xen/arch/riscv/include/asm/processor.h
b/xen/arch/riscv/include/asm/processor.h
index 39696fb58d..79d02c3dd2 100644
--- a/xen/arch/riscv/include/asm/processor.h
+++ b/xen/arch/riscv/include/asm/processor.h
@@ -49,6 +49,7 @@ struct cpu_user_regs
unsigned long t6;
unsigned long sepc;
unsigned long sstatus;
+ unsigned long hstatus;
/* pointer to previous stack_cpu_regs */
unsigned long pregs;
};
diff --git a/xen/arch/riscv/include/asm/vsbi.h
b/xen/arch/riscv/include/asm/vsbi.h
new file mode 100644
index 0000000000..984e7acf7b
--- /dev/null
+++ b/xen/arch/riscv/include/asm/vsbi.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef ASM_RISCV_VSBI_H
+#define ASM_RISCV_VSBI_H
+
+struct regs;
+struct vcpu;
+
+struct vsbi_ext {
+ const char *name;
+ unsigned long eid_start;
+ unsigned long eid_end;
+ int (*handle)(struct vcpu *vcpu, unsigned long eid,
+ unsigned long fid, struct cpu_user_regs *regs);
+};
+
+#define VSBI_EXT_START(ext, extid_start, extid_end, extid_handle) \
+static const struct vsbi_ext vsbi_ext_##ext __used \
+__section(".vsbi.exts") = { \
+ .name = #ext, \
+ .eid_start = extid_start, \
+ .eid_end = extid_end, \
+ .handle = extid_handle,
+
+#define VSBI_EXT_END \
+};
+
+void vsbi_handle_ecall(struct vcpu *vcpu, struct cpu_user_regs *regs);
+const struct vsbi_ext *vsbi_find_extension(unsigned long ext_id);
+
+#endif
diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
index f061004d83..dfe1a5a112 100644
--- a/xen/arch/riscv/traps.c
+++ b/xen/arch/riscv/traps.c
@@ -15,6 +15,7 @@
#include <asm/processor.h>
#include <asm/riscv_encoding.h>
#include <asm/traps.h>
+#include <asm/vsbi.h>
/*
* Initialize the trap handling.
@@ -114,6 +115,13 @@ void do_trap(struct cpu_user_regs *cpu_regs)
switch ( cause )
{
+ case CAUSE_VIRTUAL_SUPERVISOR_ECALL:
+ if ( !(cpu_regs->hstatus & HSTATUS_SPV) )
+ panic("CAUSE_VIRTUAL_SUPERVISOR_ECALL came not from VS-mode\n");
+
+ vsbi_handle_ecall(current, cpu_regs);
+ break;
+
case CAUSE_ILLEGAL_INSTRUCTION:
if ( do_bug_frame(cpu_regs, pc) >= 0 )
{
diff --git a/xen/arch/riscv/vsbi/Makefile b/xen/arch/riscv/vsbi/Makefile
new file mode 100644
index 0000000000..574c8ff78d
--- /dev/null
+++ b/xen/arch/riscv/vsbi/Makefile
@@ -0,0 +1 @@
+obj-y += vsbi.o
diff --git a/xen/arch/riscv/vsbi/vsbi.c b/xen/arch/riscv/vsbi/vsbi.c
new file mode 100644
index 0000000000..cd119ce0d6
--- /dev/null
+++ b/xen/arch/riscv/vsbi/vsbi.c
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <xen/sched.h>
+
+#include <asm/processor.h>
+#include <asm/sbi.h>
+#include <asm/vsbi.h>
+
+extern const struct vsbi_ext _svsbi_exts[], _evsbi_exts[];
+
+const struct vsbi_ext *vsbi_find_extension(unsigned long ext_id)
+{
+ const struct vsbi_ext *vsbi_ext;
+
+ for ( vsbi_ext = _svsbi_exts; vsbi_ext != _evsbi_exts; vsbi_ext++ )
+ if ( ext_id >= vsbi_ext->eid_start &&
+ ext_id <= vsbi_ext->eid_end )
+ return vsbi_ext;
+
+ return NULL;
+}
+
+void vsbi_handle_ecall(struct vcpu *vcpu, struct cpu_user_regs *regs)
+{
+ const unsigned long eid = regs->a7;
+ const unsigned long fid = regs->a6;
+ const struct vsbi_ext *ext = vsbi_find_extension(eid);
+ int ret;
+
+ if ( ext && ext->handle )
+ ret = ext->handle(vcpu, eid, fid, regs);
+ else
+ {
+ printk("Unsupported Guest SBI EID #%#lx, FID #%lu\n", eid, regs->a1);
+ ret = SBI_ERR_NOT_SUPPORTED;
+ }
+
+ /*
+ * The ecall instruction is not part of the RISC-V C extension (compressed
+ * instructions), so it is always 4 bytes long. Therefore, it is safe to
+ * use a fixed length of 4 bytes instead of reading guest memory to
+ * determine the instruction length.
+ */
+ regs->sepc += 4;
+ regs->a0 = ret;
+}
diff --git a/xen/arch/riscv/xen.lds.S b/xen/arch/riscv/xen.lds.S
index edcadff90b..2967f00ac5 100644
--- a/xen/arch/riscv/xen.lds.S
+++ b/xen/arch/riscv/xen.lds.S
@@ -91,6 +91,13 @@ SECTIONS
DT_DEV_INFO /* Devicetree based device info */
+ . = ALIGN(POINTER_ALIGN);
+ DECL_SECTION(.vsbi.exts) {
+ _svsbi_exts = .;
+ *(.vsbi.exts)
+ _evsbi_exts = .;
+ } :text
+
. = ALIGN(PAGE_SIZE); /* Init code and data */
__init_begin = .;
.init.text : {
--
2.52.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |