[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 6/6] plat/kvm: System call trap handler (x86_64)
Implements `_ukplat_syscall()` for KVM. The handler is saving the CPU registers to the stack and calling `ukplat_syscall_handler()` with a reference to the saved registers. On return, the register values are loaded back to the CPU. Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> --- plat/common/x86/syscall.S | 111 ++++++++++++++++++++++++++++++++++++++ plat/kvm/Config.uk | 3 +- plat/kvm/Makefile.uk | 3 ++ plat/kvm/x86/setup.c | 4 ++ 4 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 plat/common/x86/syscall.S diff --git a/plat/common/x86/syscall.S b/plat/common/x86/syscall.S new file mode 100644 index 00000000..b367a5d7 --- /dev/null +++ b/plat/common/x86/syscall.S @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> + * + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. + */ + +#include <uk/arch/lcpu.h> + +#define ENTRY(X) .globl X ; X : + +ENTRY(_ukplat_syscall) + cli + /* + * Push arguments in the order of 'struct __regs' to the stack. + * We are going to handover a refernce to this stack area as + * `struct __regs *` argument to the system call handler. + */ + pushq $0 /* exception frame filled with zeros */ + pushq $0 /* (rip, cs, eflags, rsp, ss) */ + pushq $0 /* */ + pushq $0 /* */ + pushq $0 /* */ + pushq %rax /* orig_rax */ + pushq %rdi + pushq %rsi + pushq %rdx + pushq %rcx + pushq %rax + pushq %r8 + pushq %r9 + pushq %r10 + pushq %r11 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + /* padding */ + subq $(__REGS_PAD_SIZE), %rsp + sti + + /* + * Handle call + * NOTE: Handler function is going to modify saved registers state + * NOTE: Stack pointer as "struct __regs *" argument + * (calling convention: 1st arg on %rdi) + */ + movq %rsp, %rdi + call ukplat_syscall_handler + + cli + /* Load the updated state back to registers */ + addq $(__REGS_PAD_SIZE), %rsp + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + popq %r11 + popq %r10 + popq %r9 + popq %r8 + popq %rax + popq %rcx + popq %rdx + popq %rsi + popq %rdi + /* orig_rax and exception frame */ + addq $(6 * 8), %rsp + sti + + /* + * Return from system call, inspired by HermiTux [1] + * NOTE: We can't use sysret because it changes protection mode [1] + * + * [1] Pierre et al., 2019, A binary-compatible Unikernel, + * Proceedings of the 15th ACM SIGPLAN/SIGOPS International + * Conference on Virtual Execution Environments (VEE 2019)) + */ + jmp *%rcx diff --git a/plat/kvm/Config.uk b/plat/kvm/Config.uk index 2bce43ea..432cdd95 100644 --- a/plat/kvm/Config.uk +++ b/plat/kvm/Config.uk @@ -1,8 +1,7 @@ menuconfig PLAT_KVM bool "KVM guest" default n - depends on (ARCH_X86_64 || ARCH_ARM_64) - depends on !HAVE_SYSCALL + depends on (ARCH_X86_64 || (ARCH_ARM_64 && !HAVE_SYSCALL)) select LIBUKDEBUG select LIBUKALLOC select LIBUKTIMECONV diff --git a/plat/kvm/Makefile.uk b/plat/kvm/Makefile.uk index c900d456..63ed9950 100644 --- a/plat/kvm/Makefile.uk +++ b/plat/kvm/Makefile.uk @@ -51,6 +51,9 @@ LIBKVMPLAT_SRCS-$(CONFIG_ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/x86/thread_start LIBKVMPLAT_SRCS-$(CONFIG_ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/thread.c|common LIBKVMPLAT_SRCS-$(CONFIG_ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/sw_ctx.c|common endif +ifeq ($(CONFIG_HAVE_SYSCALL),y) +LIBKVMPLAT_SRCS-$(CONFIG_ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/x86/syscall.S|common +endif LIBKVMPLAT_SRCS-$(CONFIG_ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/entry64.S LIBKVMPLAT_SRCS-$(CONFIG_ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/traps.c LIBKVMPLAT_SRCS-$(CONFIG_ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/cpu_vectors_x86_64.S diff --git a/plat/kvm/x86/setup.c b/plat/kvm/x86/setup.c index 44eb7adc..9c7a93a8 100644 --- a/plat/kvm/x86/setup.c +++ b/plat/kvm/x86/setup.c @@ -287,6 +287,10 @@ void _libkvmplat_entry(void *arg) uk_pr_info(" stack top: %p\n", (void *) _libkvmplat_cfg.bstack.start); +#ifdef CONFIG_HAVE_SYSCALL + _init_syscall(); +#endif /* CONFIG_HAVE_SYSCALL */ + /* * Switch away from the bootstrap stack as early as possible. */ -- 2.20.1 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |