diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 8db29c726..18a7a60df 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -170,7 +170,7 @@ C_SRCS += arch/x86/pm.c S_SRCS += arch/x86/wakeup.S C_SRCS += arch/x86/static_checks.c C_SRCS += arch/x86/trampoline.c -C_SRCS += arch/x86/sched.c +S_SRCS += arch/x86/sched.S C_SRCS += arch/x86/guest/vcpuid.c C_SRCS += arch/x86/guest/vcpu.c C_SRCS += arch/x86/guest/vm.c diff --git a/hypervisor/arch/x86/sched.S b/hypervisor/arch/x86/sched.S new file mode 100644 index 000000000..4a4ad42a7 --- /dev/null +++ b/hypervisor/arch/x86/sched.S @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Function schedule() will finally call arch_switch_to here for x86 platform, which use + * the pointer of previous & next sched_obj->host_sp as the input parameters (rdi & rsi). + * + * Function arch_switch_to will save rflags, rbx, rbp, r12~r15, and rdi in the previous + * sched_obj's stack, then switch stack pointer(rsp) from previous to next sched_obj (saved + * in sched_obj->host_sp) and restore above registers from next sched_obj's stack. + * It make sure the execution context return to the same point of next sched_obj when it got + * scheduled last time. + */ + .text + + .code64 + .align 8 + .global arch_switch_to +arch_switch_to: + pushf + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushq %rdi + movq %rsp, (%rdi) + movq (%rsi), %rsp + popq %rdi + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + popf + retq diff --git a/hypervisor/arch/x86/sched.c b/hypervisor/arch/x86/sched.c deleted file mode 100644 index eb71a5413..000000000 --- a/hypervisor/arch/x86/sched.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2019 Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -void arch_switch_to(struct sched_object *prev, struct sched_object *next) -{ - asm volatile ("pushf\n" - "pushq %%rbx\n" - "pushq %%rbp\n" - "pushq %%r12\n" - "pushq %%r13\n" - "pushq %%r14\n" - "pushq %%r15\n" - "pushq %%rdi\n" - "movq %%rsp, %0\n" - "movq %1, %%rsp\n" - "popq %%rdi\n" - "popq %%r15\n" - "popq %%r14\n" - "popq %%r13\n" - "popq %%r12\n" - "popq %%rbp\n" - "popq %%rbx\n" - "popf\n" - "retq\n" - : "=m"(prev->host_sp) - : "r"(next->host_sp) - : "memory"); -} diff --git a/hypervisor/common/schedule.c b/hypervisor/common/schedule.c index ccd100913..815eca9ba 100644 --- a/hypervisor/common/schedule.c +++ b/hypervisor/common/schedule.c @@ -164,7 +164,7 @@ void schedule(void) prepare_switch(prev, next); release_schedule_lock(pcpu_id); - arch_switch_to(prev, next); + arch_switch_to(&prev->host_sp, &next->host_sp); } } diff --git a/hypervisor/include/common/schedule.h b/hypervisor/include/common/schedule.h index 262d31d8d..0a8f87307 100644 --- a/hypervisor/include/common/schedule.h +++ b/hypervisor/include/common/schedule.h @@ -50,6 +50,6 @@ int32_t need_offline(uint16_t pcpu_id); void schedule(void); void run_sched_thread(struct sched_object *obj); -void arch_switch_to(struct sched_object *prev, struct sched_object *next); +void arch_switch_to(void *prev_sp, void *next_sp); #endif /* SCHEDULE_H */