Introduce architecture-specific functions to create and destroy VCPUs. Note that arch_vcpu_create() currently returns -EOPNOTSUPP, as the virtual timer and interrupt controller are not yet implemented.
As part of this change, add continue_new_vcpu(), which will be used after the first context_switch() of a new vCPU. Since this functionality is not yet implemented, continue_new_vcpu() is currently provided as a stub. Update the STACK_SIZE definition and introduce STACK_ORDER (to align with other architectures) for allocating the vCPU stack. Introduce struct cpu_info to store per-vCPU state that lives at the top of the vCPU's stack. Signed-off-by: Oleksii Kurochko <[email protected]> --- Changes in v2: - Drop BUILD_BUG_ON() in arch_vcpu_create() as a check isn't very useful. - Use vzalloc() instead of alloc_xenheap_page() to use the larger domheap to allocate vCPU's stack. - Drop printk() inside arch_vcpu_create() to not have potential big noise in console as it could be that an amount of vCPUs is pretty big. - Use XVFREE() instead of free_xenheap_pages() as vCPU's stack allocation happens with a usage of vzalloc() now. - Drop stack field as it is enough to have only cpu_info as stack pointer could be calculated based on cpu_info. - Drop cast when v.arch.cpu_info is inialized as it is not necessary to have it. - Drop memset() for arch.cpu_info() as it is enough to have vzalloc(). --- xen/arch/riscv/Makefile | 1 + xen/arch/riscv/domain.c | 59 ++++++++++++++++++++++++++++ xen/arch/riscv/include/asm/config.h | 3 +- xen/arch/riscv/include/asm/current.h | 6 +++ xen/arch/riscv/include/asm/domain.h | 2 + xen/arch/riscv/stubs.c | 10 ----- 6 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 xen/arch/riscv/domain.c diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile index 87c1148b0010..8863d4b15605 100644 --- a/xen/arch/riscv/Makefile +++ b/xen/arch/riscv/Makefile @@ -1,5 +1,6 @@ obj-y += aplic.o obj-y += cpufeature.o +obj-y += domain.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-y += entry.o obj-y += imsic.o diff --git a/xen/arch/riscv/domain.c b/xen/arch/riscv/domain.c new file mode 100644 index 000000000000..9c546267881b --- /dev/null +++ b/xen/arch/riscv/domain.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <xen/init.h> +#include <xen/mm.h> +#include <xen/sched.h> +#include <xen/vmap.h> + +static void continue_new_vcpu(struct vcpu *prev) +{ + BUG_ON("unimplemented\n"); +} + +static void __init __maybe_unused build_assertions(void) +{ + /* + * Enforce the requirement documented in struct cpu_info that + * guest_cpu_user_regs must be the first field. + */ + BUILD_BUG_ON(offsetof(struct cpu_info, guest_cpu_user_regs) != 0); +} + +int arch_vcpu_create(struct vcpu *v) +{ + int rc = 0; + void *stack = vzalloc(STACK_SIZE); + + if ( !stack ) + return -ENOMEM; + + v->arch.cpu_info = stack + STACK_SIZE - sizeof(struct cpu_info); + memset(v->arch.cpu_info, 0, sizeof(*v->arch.cpu_info)); + + v->arch.xen_saved_context.sp = (register_t)v->arch.cpu_info; + v->arch.xen_saved_context.ra = (register_t)continue_new_vcpu; + + /* Idle VCPUs don't need the rest of this setup */ + if ( is_idle_vcpu(v) ) + return rc; + + /* + * As the vtimer and interrupt controller (IC) are not yet implemented, + * return an error. + * + * TODO: Drop this once the vtimer and IC are implemented. + */ + rc = -EOPNOTSUPP; + goto fail; + + return rc; + + fail: + arch_vcpu_destroy(v); + return rc; +} + +void arch_vcpu_destroy(struct vcpu *v) +{ + vfree((char *)v->arch.cpu_info + sizeof(struct cpu_info)); +} diff --git a/xen/arch/riscv/include/asm/config.h b/xen/arch/riscv/include/asm/config.h index 1e08d3bf78be..86a95df018b5 100644 --- a/xen/arch/riscv/include/asm/config.h +++ b/xen/arch/riscv/include/asm/config.h @@ -143,7 +143,8 @@ #define SMP_CACHE_BYTES (1 << 6) -#define STACK_SIZE PAGE_SIZE +#define STACK_ORDER 3 +#define STACK_SIZE (PAGE_SIZE << STACK_ORDER) #define IDENT_AREA_SIZE 64 diff --git a/xen/arch/riscv/include/asm/current.h b/xen/arch/riscv/include/asm/current.h index 0c3ea70c2ec8..58c9f1506b7c 100644 --- a/xen/arch/riscv/include/asm/current.h +++ b/xen/arch/riscv/include/asm/current.h @@ -21,6 +21,12 @@ struct pcpu_info { /* tp points to one of these */ extern struct pcpu_info pcpu_info[NR_CPUS]; +/* Per-VCPU state that lives at the top of the stack */ +struct cpu_info { + /* This should be the first member. */ + struct cpu_user_regs guest_cpu_user_regs; +}; + #define set_processor_id(id) do { \ tp->processor_id = (id); \ } while (0) diff --git a/xen/arch/riscv/include/asm/domain.h b/xen/arch/riscv/include/asm/domain.h index 0d9b4c4b525e..ec7786c76199 100644 --- a/xen/arch/riscv/include/asm/domain.h +++ b/xen/arch/riscv/include/asm/domain.h @@ -49,6 +49,8 @@ struct arch_vcpu register_t ra; } xen_saved_context; + struct cpu_info *cpu_info; + /* CSRs */ register_t hedeleg; register_t hideleg; diff --git a/xen/arch/riscv/stubs.c b/xen/arch/riscv/stubs.c index 29bdb65afbdf..9e30a9a3b50b 100644 --- a/xen/arch/riscv/stubs.c +++ b/xen/arch/riscv/stubs.c @@ -121,16 +121,6 @@ void dump_pageframe_info(struct domain *d) BUG_ON("unimplemented"); } -int arch_vcpu_create(struct vcpu *v) -{ - BUG_ON("unimplemented"); -} - -void arch_vcpu_destroy(struct vcpu *v) -{ - BUG_ON("unimplemented"); -} - void vcpu_switch_to_aarch64_mode(struct vcpu *v) { BUG_ON("unimplemented"); -- 2.52.0
