replace arch_switch_to with pure asm code instead of inline asm

after compile, the compiled code could change rsp, so use pure asm code
to avoid such problem which will cause schedule switch failure.

Tracked-On: #2410
Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com>
This commit is contained in:
Jason Chen CJ 2019-01-24 19:31:03 +08:00 committed by wenlingz
parent c233bf54a2
commit 285b64faec
5 changed files with 44 additions and 39 deletions

View File

@ -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

View File

@ -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

View File

@ -1,36 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <types.h>
#include <spinlock.h>
#include <list.h>
#include <schedule.h>
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");
}

View File

@ -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);
}
}

View File

@ -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 */