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) #84123

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -58,6 +58,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
19 changes: 19 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 Extension
on Armv8.1+ platform.

config NUM_IRQS
int

Expand Down Expand Up @@ -228,6 +235,10 @@ config ARMV8_A

rsource "xen/Kconfig"

if ZVM
rsource "zvm/Kconfig"
endif # ZVM

endif # CPU_CORTEX_A

if CPU_AARCH64_CORTEX_R
Expand Down Expand Up @@ -281,6 +292,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 deactivate */
bl arm_gic_eoi_deactivate
#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 @@ -1000,13 +1000,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_ */
1 change: 1 addition & 0 deletions arch/arm64/core/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,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_MAX_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 @@ -145,7 +145,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 ENABLE_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 ENABLE_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 # ENABLE_VIRT_ARM_ARCH_TIMER
Loading