Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZVM : New-Generation Type 1.5 RTOS Virtualization Solution (Hypervisor) #83991

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f518533
boards: qemu: Add support for qemu_max board
GuoqiXie Jan 13, 2025
020ce3f
arch: arm64: support VHE and vpidr_el2 for arm
GuoqiXie Jan 13, 2025
3384afc
boards: qemu: qemu_max
GuoqiXie Jan 13, 2025
b6fe51a
arm64: zvm: Add support for ARM64 virtualization
GuoqiXie Jan 13, 2025
252d900
arm64: ZVM: Add CPU and Timer Support for ZVM
GuoqiXie Jan 13, 2025
72a7b67
arm64: zvm: Add MMU support for ZVM
GuoqiXie Jan 13, 2025
8f4b007
arm64: reset: Add code for Zephyr on EL2
GuoqiXie Jan 13, 2025
09e66fd
zvm: Add initial virtualization management support
GuoqiXie Jan 13, 2025
6a89946
zvm: Add VM core management functionality
GuoqiXie Jan 13, 2025
5418fe3
zvm: add virtual device and interrupt handling
GuoqiXie Jan 13, 2025
8d02ef1
zvm: add configuration and OS support function
GuoqiXie Jan 13, 2025
d3956db
zvm: add vGIC support for VM
GuoqiXie Jan 13, 2025
25ab7f3
zvm: Add PSCI emulation for CPU and system manage
GuoqiXie Jan 13, 2025
958cb78
zvm: add sched support for VM
GuoqiXie Jan 13, 2025
6c377bf
zvm: add support for virtual and pt devices
GuoqiXie Jan 13, 2025
ef01e9b
samples: qemu_max_smp: configuration and overlay
GuoqiXie Jan 13, 2025
51af7ae
samples: zvm: add samples file for zvm
GuoqiXie Jan 13, 2025
3691b9a
zvm: vdev: add vpl011 and vserial devices
GuoqiXie Jan 14, 2025
919603a
doc: modify ZVM cocumentation.
GuoqiXie Jan 14, 2025
92d785e
zvm: add delete support for mutiple vm
GuoqiXie Jan 14, 2025
0eac6e4
zvm: add vdev deinit function
GuoqiXie Jan 14, 2025
fad5dd8
zvm: release vcpu struct
GuoqiXie Jan 14, 2025
39cb6d9
ZVM: fix delete vm bug
GuoqiXie Jan 15, 2025
3cd2f1c
Format: Fix format issues
GuoqiXie Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions arch/arm64/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
endif()

add_subdirectory_ifdef(CONFIG_XEN xen)
add_subdirectory_ifdef(CONFIG_ZVM zvm)

if(CONFIG_GEN_SW_ISR_TABLE)
if(CONFIG_DYNAMIC_INTERRUPTS)
Expand Down
16 changes: 16 additions & 0 deletions arch/arm64/core/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ config HAS_ARM_SMCCC
Include support for the Secure Monitor Call (SMC) and Hypervisor
Call (HVC) instructions on Armv7 and above architectures.

config HAS_ARM_VHE
bool
default y if CPU_CORTEX_A55 || CPU_CORTEX_A76 || CPU_CORTEX_A76_A55
help
This option signifies the enable of Virtualization Host Extention
on Armv8.1+ platform.

config NUM_IRQS
int

Expand Down Expand Up @@ -219,6 +226,7 @@ config ARMV8_A
It supports the T32 and A32 instruction sets.

rsource "xen/Kconfig"
rsource "zvm/Kconfig"

endif # CPU_CORTEX_A

Expand Down Expand Up @@ -273,6 +281,14 @@ config ARM64_SET_VMPIDR_EL2
This register may already be set by bootloader at the EL2 stage, if
not, Zephyr should set it.

config ARM64_SET_VPIDR_EL2
bool "Set VPIDR_EL2 at EL2 stage"
help
VPIDR_EL2 holds the value of the Virtualization ID.
This is the value returned by EL1 reads of MIDR_EL1.
This register may already be set by bootloader at the EL2 stage, if
not, Zephyr should set it.

if ARM_MMU

config MMU_PAGE_SIZE
Expand Down
14 changes: 13 additions & 1 deletion arch/arm64/core/isr_wrapper.S
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ oob:
msr daifset, #(DAIFSET_IRQ_BIT)

/* Signal end-of-interrupt */
ldp x0, xzr, [sp], #16
ldp x0, xzr, [sp]

spurious_continue:
#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
Expand All @@ -107,6 +107,18 @@ spurious_continue:
bl z_soc_irq_eoi
#endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */

ldp x0, xzr, [sp]
#ifdef CONFIG_ZVM
/* switch handle preprocess */
bl zvm_switch_handle_pre
mov x1, x0
ldp x0, xzr, [sp], #16
/* passthrough device may need deactive */
bl arm_gic_eoi_deactive
#else
ldp x0, xzr, [sp], #16
#endif

#ifdef CONFIG_TRACING
bl sys_trace_isr_exit
#endif
Expand Down
8 changes: 7 additions & 1 deletion arch/arm64/core/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -965,13 +965,19 @@ void z_arm64_mm_init(bool is_primary_core)

__ASSERT(CONFIG_MMU_PAGE_SIZE == KB(4),
"Only 4K page size is supported\n");
#if defined(CONFIG_ZVM) && defined(CONFIG_HAS_ARM_VHE)
__ASSERT(GET_EL(read_currentel()) == MODE_EL2,
"Exception level not EL2, MMU not enabled!\n");

/* Ensure that MMU is already not enabled */
__ASSERT((read_sctlr_el2() & SCTLR_M_BIT) == 0, "MMU is already enabled\n");
#else
__ASSERT(GET_EL(read_currentel()) == MODE_EL1,
"Exception level not EL1, MMU not enabled!\n");

/* Ensure that MMU is already not enabled */
__ASSERT((read_sctlr_el1() & SCTLR_M_BIT) == 0, "MMU is already enabled\n");

#endif
/*
* Only booting core setup up the page tables.
*/
Expand Down
11 changes: 11 additions & 0 deletions arch/arm64/core/offsets/offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ GEN_NAMED_OFFSET_SYM(arm_smccc_res_t, a6, a6_a7);

#endif /* CONFIG_HAS_ARM_SMCCC */

#ifdef CONFIG_ZVM
GEN_OFFSET_SYM(zvm_vcpu_context_t, regs);
GEN_OFFSET_SYM(vcpu_t, arch);
GEN_OFFSET_SYM(vcpu_arch_t, ctxt);
GEN_OFFSET_SYM(arch_commom_regs_t, callee_saved_regs);
GEN_OFFSET_SYM(arch_commom_regs_t, esf_handle_regs);
GEN_OFFSET_SYM(arch_commom_regs_t, pc);
GEN_OFFSET_SYM(arch_commom_regs_t, pstate);
GEN_OFFSET_SYM(arch_commom_regs_t, lr);
#endif /* CONFIG_ZVM */

GEN_ABS_SYM_END

#endif /* _ARM_OFFSETS_INC_ */
2 changes: 1 addition & 1 deletion arch/arm64/core/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void z_prep_c(void)
{
/* Initialize tpidrro_el0 with our struct _cpu instance address */
write_tpidrro_el0((uintptr_t)&_kernel.cpus[0]);

arch_set_cpu_id_elx();
z_bss_zero();
z_data_copy();
#ifdef CONFIG_ARM64_SAFE_EXCEPTION_STACK
Expand Down
11 changes: 11 additions & 0 deletions arch/arm64/core/reset.S
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__reset_prep_c)
/* Set SP_EL1 */
msr sp_el1, x24

#if defined(CONFIG_HAS_ARM_VHE)
msr SPsel, #1
mov sp, x24
#endif
b out
1:
/* Disable alignment fault checking */
Expand Down Expand Up @@ -238,6 +242,13 @@ switch_el:
mov_imm x0, (SPSR_DAIF_MASK | SPSR_MODE_EL1T)
msr spsr_el2, x0

/* Is VHE mode? */
mrs x0, hcr_el2
and x0, x0, #HCR_E2H_BIT
cbz x0, nvhe_branch
b 1f

nvhe_branch:
adr x0, 1f
msr elr_el2, x0
eret
Expand Down
24 changes: 24 additions & 0 deletions arch/arm64/core/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <zephyr/sys/barrier.h>
#include "boot.h"

uint64_t cpu_vmpidr_el2_list[CONFIG_MP_NUM_CPUS] = {0};

void z_arm64_el2_init(void);

void __weak z_arm64_el_highest_plat_init(void)
Expand Down Expand Up @@ -151,11 +153,32 @@ void z_arm64_el2_init(void)
zero_cnthp_ctl_el2();
#endif

#ifdef CONFIG_ARM64_SET_VPIDR_EL2
reg = read_midr_el1();
write_vpidr_el2(reg);
#endif

#ifdef CONFIG_ARM64_SET_VMPIDR_EL2
reg = read_mpidr_el1();
write_vmpidr_el2(reg);
#endif

#if defined(CONFIG_ZVM) && defined(CONFIG_HAS_ARM_VHE)
reg = read_hcr_el2();
reg |= HCR_VHE_FLAGS;
write_hcr_el2(reg);

reg = read_mpidr_el1();
cpu_vmpidr_el2_list[MPIDR_TO_CORE(GET_MPIDR())] = reg;

/* Disable CP15 trapping to EL2 of EL1 accesses to System register */
zero_sysreg(hstr_el2);
/* Disable Debug related register */
zero_sysreg(mdcr_el2);
/* Init stage-2 translation table base register */
zero_sysreg(vttbr_el2);
#endif

/*
* Enable this if/when we use the hypervisor timer.
* write_cnthp_cval_el2(~(uint64_t)0);
Expand Down Expand Up @@ -187,6 +210,7 @@ void z_arm64_el1_init(void)
write_sctlr_el1(reg);

write_cntv_cval_el0(~(uint64_t)0);
write_cntp_cval_el0(~(uint64_t)0);
/*
* Enable these if/when we use the corresponding timers.
* write_cntp_cval_el0(~(uint64_t)0);
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/core/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ void arch_secondary_cpu_init(int cpu_num)

/* Initialize tpidrro_el0 with our struct _cpu instance address */
write_tpidrro_el0((uintptr_t)&_kernel.cpus[cpu_num]);

arch_set_cpu_id_elx();
z_arm64_mm_init(false);

#ifdef CONFIG_ARM64_SAFE_EXCEPTION_STACK
Expand Down
7 changes: 6 additions & 1 deletion arch/arm64/core/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,14 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack,
pInitCtx->elr = (uint64_t)z_thread_entry;
#endif

#if defined(CONFIG_ZVM) && defined(CONFIG_HAS_ARM_VHE)
pInitCtx->spsr = SPSR_MODE_EL2H | DAIF_FIQ_BIT;
/* init thread's vcpu_struct */
thread->vcpu_struct = NULL;
#else
/* Keep using SP_EL1 */
pInitCtx->spsr = SPSR_MODE_EL1H | DAIF_FIQ_BIT;

#endif
/* thread birth happens through the exception return path */
thread->arch.exception_depth = 1;

Expand Down
14 changes: 14 additions & 0 deletions arch/arm64/core/zvm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2024-2025 HNU-ESNL: Guoqi Xie, Chenglai Xiong, Xingyu Hu and etc.
# Copyright 2024-2025 openEuler SIG-Zephyr
# SPDX-License-Identifier: Apache-2.0

zephyr_library()

zephyr_library_sources(
cpu.c
mmu.c
timer.c
switch.c
hyp_entry.S
hyp_vector.S
)
32 changes: 32 additions & 0 deletions arch/arm64/core/zvm/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2024-2025 HNU-ESNL: Guoqi Xie, Chenglai Xiong, Xingyu Hu and etc.
# Copyright 2024-2025 openEuler SIG-Zephyr
# SPDX-License-Identifier: Apache-2.0

if ARM_MMU

config ZVM_MAX_VM_XLAT_TABLES
int "Maximum numbers of VM stage-2 translation tables"
default 1024
help
This option specifies the maximum number of vm translation tables.
Translation tables are allocated at compile time and used at runtime as needed.
If the runtime need exceeds the preallocated number of translation tables,
it will result in an assertion failure.

endif # ARM_MMU

config VIRT_ARM_ARCH_TIMER
bool "Enable VIRT ARM arch timer"
default y
help
This option enables the ARM arch timer for the virtual machine.

if VIRT_ARM_ARCH_TIMER

config VIRT_ARM_ARCH_TIMER_PRIORITY
int "VIRT ARM arch timer priority"
default 78
help
This option specifies the priority of the ARM arch timer for the virtual machine.

endif # VIRT_ARM_ARCH_TIMER
Loading
Loading