:p
atchew
Login
Introduce the vSBI framework to handle extension ecall instruction calls from a guest. In this patch series, support is added for only a few extensions and FIDs, just enough to boot the first guest domains and obtain logs from them. This keeps the patch series independent from other ongoing work. It was decided to start with support for the Legacy Extension, as it is still supported by Linux (so we may need it anyway), and because some of its FIDs require less functionality to implement at this stage compared to the more modern extensions. Oleksii Kurochko (3): xen/riscv: introduce vSBI extension framework xen/riscv: add RISC-V legacy SBI extension support for guests xen/riscv: add RISC-V virtual SBI base extension support for guests xen/arch/riscv/Makefile | 1 + xen/arch/riscv/include/asm/processor.h | 1 + xen/arch/riscv/include/asm/sbi.h | 14 +++++- xen/arch/riscv/include/asm/vsbi.h | 31 ++++++++++++ xen/arch/riscv/sbi.c | 8 ++-- xen/arch/riscv/traps.c | 8 ++++ xen/arch/riscv/vsbi/Makefile | 3 ++ xen/arch/riscv/vsbi/vsbi-base-extension.c | 52 +++++++++++++++++++++ xen/arch/riscv/vsbi/vsbi-legacy-extension.c | 37 +++++++++++++++ xen/arch/riscv/vsbi/vsbi.c | 46 ++++++++++++++++++ xen/arch/riscv/xen.lds.S | 7 +++ 11 files changed, 203 insertions(+), 5 deletions(-) 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-base-extension.c create mode 100644 xen/arch/riscv/vsbi/vsbi-legacy-extension.c create mode 100644 xen/arch/riscv/vsbi/vsbi.c -- 2.52.0
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@gmail.com> --- 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 XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/Makefile +++ b/xen/arch/riscv/Makefile @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/include/asm/processor.h +++ b/xen/arch/riscv/include/asm/processor.h @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/riscv/include/asm/vsbi.h @@ -XXX,XX +XXX,XX @@ +/* 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 XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/traps.c +++ b/xen/arch/riscv/traps.c @@ -XXX,XX +XXX,XX @@ #include <asm/processor.h> #include <asm/riscv_encoding.h> #include <asm/traps.h> +#include <asm/vsbi.h> /* * Initialize the trap handling. @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX --- /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 XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/riscv/vsbi/vsbi.c @@ -XXX,XX +XXX,XX @@ +/* 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 XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/xen.lds.S +++ b/xen/arch/riscv/xen.lds.S @@ -XXX,XX +XXX,XX @@ 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
This commit adds support for legacy SBI extensions (version 0.1) in Xen for guest domains. The changes include: 1. Define all legacy SBI extension IDs (0x0 to 0x8) for better clarity and completeness. 2. Implement handling of legacy SBI extensions, starting with support for SBI_EXT_0_1_CONSOLE_{PUT,GET}CHAR. The implementation uses the existing virtual SBI framework to handle legacy SBI ecalls, ensuring compatibility with older SBI specifications in RISC-V guests. Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> --- xen/arch/riscv/include/asm/sbi.h | 11 ++++-- xen/arch/riscv/vsbi/Makefile | 1 + xen/arch/riscv/vsbi/vsbi-legacy-extension.c | 37 +++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 xen/arch/riscv/vsbi/vsbi-legacy-extension.c diff --git a/xen/arch/riscv/include/asm/sbi.h b/xen/arch/riscv/include/asm/sbi.h index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/include/asm/sbi.h +++ b/xen/arch/riscv/include/asm/sbi.h @@ -XXX,XX +XXX,XX @@ #include <xen/cpumask.h> -#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1 -#define SBI_EXT_0_1_SHUTDOWN 0x8 +#define SBI_EXT_0_1_SET_TIMER 0x0 +#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1 +#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2 +#define SBI_EXT_0_1_CLEAR_IPI 0x3 +#define SBI_EXT_0_1_SEND_IPI 0x4 +#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5 +#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6 +#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7 +#define SBI_EXT_0_1_SHUTDOWN 0x8 #define SBI_EXT_BASE 0x10 #define SBI_EXT_RFENCE 0x52464E43 diff --git a/xen/arch/riscv/vsbi/Makefile b/xen/arch/riscv/vsbi/Makefile index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/vsbi/Makefile +++ b/xen/arch/riscv/vsbi/Makefile @@ -1 +1,2 @@ obj-y += vsbi.o +obj-y += vsbi-legacy-extension.o diff --git a/xen/arch/riscv/vsbi/vsbi-legacy-extension.c b/xen/arch/riscv/vsbi/vsbi-legacy-extension.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/riscv/vsbi/vsbi-legacy-extension.c @@ -XXX,XX +XXX,XX @@ + +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <xen/lib.h> +#include <xen/sched.h> + +#include <asm/processor.h> +#include <asm/vsbi.h> + +static int vsbi_legacy_ecall_handler(struct vcpu *vcpu, unsigned long eid, + unsigned long fid, + struct cpu_user_regs *regs) +{ + int ret = 0; + + switch ( eid ) + { + case SBI_EXT_0_1_CONSOLE_PUTCHAR: + printk("%c", (char)regs->a0); + break; + + case SBI_EXT_0_1_CONSOLE_GETCHAR: + regs->a0 = SBI_ERR_NOT_SUPPORTED; + break; + + default: + panic("%s: Unsupported ecall: FID: #%lx, EID: #%lx\n", + __func__, fid, eid); + break; + } + + return ret; +} + +VSBI_EXT_START(legacy, SBI_EXT_0_1_SET_TIMER, SBI_EXT_0_1_SHUTDOWN, + vsbi_legacy_ecall_handler) +VSBI_EXT_END -- 2.52.0
Add support of virtual SBI base extension calls for RISC-V guests, delegating hardware-specific queries to the underlying SBI and handling version and firmware ID queries directly. The changes include: 1. Define new SBI base extension function IDs (SBI_EXT_BASE_GET_MVENDORID, SBI_EXT_BASE_GET_MARCHID, SBI_EXT_BASE_GET_MIMPID). 2. Make sbi_spec_version, sbi_fw_id, and sbi_fw_version global variables for use in virtual SBI handling, removing redundant local declarations in sbi_init. 3. Implement handling of SBI base extension functions, including version, firmware ID, and machine-specific queries. Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> --- xen/arch/riscv/include/asm/sbi.h | 3 ++ xen/arch/riscv/sbi.c | 8 ++-- xen/arch/riscv/vsbi/Makefile | 1 + xen/arch/riscv/vsbi/vsbi-base-extension.c | 52 +++++++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 xen/arch/riscv/vsbi/vsbi-base-extension.c diff --git a/xen/arch/riscv/include/asm/sbi.h b/xen/arch/riscv/include/asm/sbi.h index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/include/asm/sbi.h +++ b/xen/arch/riscv/include/asm/sbi.h @@ -XXX,XX +XXX,XX @@ #define SBI_EXT_BASE_GET_IMP_ID 0x1 #define SBI_EXT_BASE_GET_IMP_VERSION 0x2 #define SBI_EXT_BASE_PROBE_EXT 0x3 +#define SBI_EXT_BASE_GET_MVENDORID 0x4 +#define SBI_EXT_BASE_GET_MARCHID 0x5 +#define SBI_EXT_BASE_GET_MIMPID 0x6 /* SBI function IDs for RFENCE extension */ #define SBI_EXT_RFENCE_REMOTE_FENCE_I 0x0 diff --git a/xen/arch/riscv/sbi.c b/xen/arch/riscv/sbi.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/sbi.c +++ b/xen/arch/riscv/sbi.c @@ -XXX,XX +XXX,XX @@ #include <asm/processor.h> #include <asm/sbi.h> -static unsigned long __ro_after_init sbi_spec_version = SBI_SPEC_VERSION_DEFAULT; +unsigned long __ro_after_init sbi_spec_version = SBI_SPEC_VERSION_DEFAULT; +long __ro_after_init sbi_fw_id; +long __ro_after_init sbi_fw_version; struct sbiret sbi_ecall(unsigned long ext, unsigned long fid, unsigned long arg0, unsigned long arg1, @@ -XXX,XX +XXX,XX @@ int __init sbi_init(void) if ( !sbi_spec_is_0_1() ) { - long sbi_fw_id = sbi_get_firmware_id(); - long sbi_fw_version = sbi_get_firmware_version(); + sbi_fw_id = sbi_get_firmware_id(); + sbi_fw_version = sbi_get_firmware_version(); BUG_ON((sbi_fw_id < 0) || (sbi_fw_version < 0)); diff --git a/xen/arch/riscv/vsbi/Makefile b/xen/arch/riscv/vsbi/Makefile index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/vsbi/Makefile +++ b/xen/arch/riscv/vsbi/Makefile @@ -XXX,XX +XXX,XX @@ obj-y += vsbi.o +obj-y += vsbi-base-extension.o obj-y += vsbi-legacy-extension.o diff --git a/xen/arch/riscv/vsbi/vsbi-base-extension.c b/xen/arch/riscv/vsbi/vsbi-base-extension.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/riscv/vsbi/vsbi-base-extension.c @@ -XXX,XX +XXX,XX @@ + +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <xen/lib.h> +#include <xen/sched.h> + +#include <asm/processor.h> +#include <asm/sbi.h> +#include <asm/vsbi.h> + +extern unsigned long __ro_after_init sbi_spec_version; +extern long __ro_after_init sbi_fw_id; +extern long __ro_after_init sbi_fw_version; + +static int vsbi_base_ecall_handler(struct vcpu *vcpu, unsigned long eid, + unsigned long fid, + struct cpu_user_regs *regs) +{ + int ret = 0; + struct sbiret sbi_ret; + + switch ( fid ) { + case SBI_EXT_BASE_GET_SPEC_VERSION: + regs->a1 = sbi_spec_version; + break; + case SBI_EXT_BASE_GET_IMP_ID: + regs->a1 = sbi_fw_id; + break; + case SBI_EXT_BASE_GET_IMP_VERSION: + regs->a1 = sbi_fw_version; + break; + case SBI_EXT_BASE_GET_MVENDORID: + case SBI_EXT_BASE_GET_MARCHID: + case SBI_EXT_BASE_GET_MIMPID: + sbi_ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0); + ret = sbi_ret.error; + regs->a1 = sbi_ret.value; + break; + case SBI_EXT_BASE_PROBE_EXT: + regs->a1 = vsbi_find_extension(regs->a0) ? 1 : 0; + break; + default: + panic("%s: Unsupported ecall: FID: #%lx, EID: #%lx\n", + __func__, fid, eid); + break; + } + + return ret; +} + +VSBI_EXT_START(base, SBI_EXT_BASE, SBI_EXT_BASE, vsbi_base_ecall_handler) +VSBI_EXT_END -- 2.52.0
Introduce the vSBI framework to handle extension ecall instruction calls from a guest. In this patch series, support is added for only a few extensions and FIDs, just enough to boot the first guest domains and obtain logs from them. This keeps the patch series independent from other ongoing work. It was decided to start with support for the Legacy Extension, as it is still supported by Linux (so we may need it anyway), and because some of its FIDs require less functionality to implement at this stage compared to the more modern extensions. CI tests: https://gitlab.com/xen-project/people/olkur/xen/-/pipelines/2238071752 --- Changes in v4: - First to patches were merged to staging. - Address comments for the last patch. --- Changes in v3: - Address a comments from v2. --- Changes in v2: - Address a comments from v1. --- Oleksii Kurochko (1): xen/riscv: add RISC-V virtual SBI base extension support for guests xen/arch/riscv/include/asm/sbi.h | 6 ++ xen/arch/riscv/vsbi/Makefile | 1 + xen/arch/riscv/vsbi/base-extension.c | 82 ++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 xen/arch/riscv/vsbi/base-extension.c -- 2.52.0
Add support of virtual SBI base extension calls for RISC-V guests, delegating hardware-specific queries to the underlying SBI and handling version and firmware ID queries directly. The changes include: 1. Define new SBI base extension function IDs (SBI_EXT_BASE_GET_MVENDORID, SBI_EXT_BASE_GET_MARCHID, SBI_EXT_BASE_GET_MIMPID). 2. Introduce XEN_SBI_VER_MAJOR, XEN_SBI_VER_MINOR for imeplenataion of SBI_EXT_BASE_GET_SPEC_VERSION. 4. Introduce SBI_XEN_IMPID to implement SBI_EXT_BASE_GET_IMP_ID. 5. Implement handling of SBI base extension functions, including version, firmware ID, and machine-specific queries. Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> --- Changes in v4: - Move definition of XEN_SBI_VER_{MAJOR, MINOR} to base-extension.c. - Correct string format for FID: s/#%#lx/#%lu. - Print first EID then FID (as vsbi/core.c code does). --- Changes in v3: - s/XEN_SBI_IMPID/SBI_XEN_IMPID - Add ASSERT(eid == SBI_EXT_BASE) in vsbi_base_ecall_handler(). - Fix code style for switch/case. - Use current instead of `vcpu` argument as it was dropped from vsbi_base_ecall_handler() prototype. - Add comments for define-s XEN_SBI_VER_{MAJOR, MINOR} and SBI_XEN_IMPID. --- Changes in v2: - s/vsbi-base-extension.*/base-extension.* - Introduce VCPU_SBI_IMPID, XEN_SBI_VER_MINOR and XEN_SBI_VER_MAJOR. - Return VCPU_SBI_IMPID in the case of SBI_EXT_BASE_GET_IMP_ID. - Return Xen version in the case of SBI_EXT_BASE_GET_IMP_VERSION. - Use domain_crash() instead of panic() for default case. - For SBI_EXT_BASE_GET_{MVENDORID,MARCHID,MIMPID} abd SBI_EXT_BASE_PROBE_EXT add handling of a domain is h/w or not. --- xen/arch/riscv/include/asm/sbi.h | 6 ++ xen/arch/riscv/vsbi/Makefile | 1 + xen/arch/riscv/vsbi/base-extension.c | 82 ++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 xen/arch/riscv/vsbi/base-extension.c diff --git a/xen/arch/riscv/include/asm/sbi.h b/xen/arch/riscv/include/asm/sbi.h index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/include/asm/sbi.h +++ b/xen/arch/riscv/include/asm/sbi.h @@ -XXX,XX +XXX,XX @@ #include <xen/cpumask.h> +/* SBI-defined implementation ID */ +#define SBI_XEN_IMPID 7 + #define SBI_EXT_0_1_SET_TIMER 0x0 #define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1 #define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2 @@ -XXX,XX +XXX,XX @@ #define SBI_EXT_BASE_GET_IMP_ID 0x1 #define SBI_EXT_BASE_GET_IMP_VERSION 0x2 #define SBI_EXT_BASE_PROBE_EXT 0x3 +#define SBI_EXT_BASE_GET_MVENDORID 0x4 +#define SBI_EXT_BASE_GET_MARCHID 0x5 +#define SBI_EXT_BASE_GET_MIMPID 0x6 /* SBI function IDs for RFENCE extension */ #define SBI_EXT_RFENCE_REMOTE_FENCE_I 0x0 diff --git a/xen/arch/riscv/vsbi/Makefile b/xen/arch/riscv/vsbi/Makefile index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/riscv/vsbi/Makefile +++ b/xen/arch/riscv/vsbi/Makefile @@ -XXX,XX +XXX,XX @@ +obj-y += base-extension.o obj-y += core.o obj-y += legacy-extension.o diff --git a/xen/arch/riscv/vsbi/base-extension.c b/xen/arch/riscv/vsbi/base-extension.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/riscv/vsbi/base-extension.c @@ -XXX,XX +XXX,XX @@ + +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <xen/lib.h> +#include <xen/sched.h> +#include <xen/version.h> + +#include <asm/processor.h> +#include <asm/sbi.h> +#include <asm/vsbi.h> + +/* Xen-controlled SBI version reported to guests */ +#define XEN_SBI_VER_MAJOR 0 +#define XEN_SBI_VER_MINOR 2 + +static int vsbi_base_ecall_handler(unsigned long eid, unsigned long fid, + struct cpu_user_regs *regs) +{ + int ret = 0; + struct sbiret sbi_ret; + + ASSERT(eid == SBI_EXT_BASE); + + switch ( fid ) + { + case SBI_EXT_BASE_GET_SPEC_VERSION: + regs->a1 = MASK_INSR(XEN_SBI_VER_MAJOR, SBI_SPEC_VERSION_MAJOR_MASK) | + XEN_SBI_VER_MINOR; + break; + + case SBI_EXT_BASE_GET_IMP_ID: + regs->a1 = SBI_XEN_IMPID; + break; + + case SBI_EXT_BASE_GET_IMP_VERSION: + regs->a1 = (xen_major_version() << 16) | xen_minor_version(); + break; + + case SBI_EXT_BASE_GET_MVENDORID: + case SBI_EXT_BASE_GET_MARCHID: + case SBI_EXT_BASE_GET_MIMPID: + if ( is_hardware_domain(current->domain) ) + { + sbi_ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0); + ret = sbi_ret.error; + regs->a1 = sbi_ret.value; + } + else + /* + * vSBI should present a consistent, virtualized view to guests. + * In particular, DomU-visible data must remain stable across + * migration and must not expose hardware-specific details. + * + * These register(s) must be readable in any implementation, + * but a value of 0 can be returned to indicate the field + * is not implemented. + */ + regs->a1 = 0; + + break; + + case SBI_EXT_BASE_PROBE_EXT: + regs->a1 = vsbi_find_extension(regs->a0) ? 1 : 0; + break; + + default: + /* + * TODO: domain_crash() is acceptable here while things are still under + * development. + * It shouldn't stay like this in the end though: guests should not + * be punished like this for something Xen hasn't implemented. + */ + domain_crash(current->domain, + "%s: Unsupported ecall: EID: #%#lx FID: #%lu\n", + __func__, eid, fid); + break; + } + + return ret; +} + +VSBI_EXT(base, SBI_EXT_BASE, SBI_EXT_BASE, vsbi_base_ecall_handler) -- 2.52.0