From b96fb7823791b58fd1cd76e66e654b3340b30e7b Mon Sep 17 00:00:00 2001 From: maniatro111 Date: Tue, 22 Feb 2022 11:15:58 +0200 Subject: [PATCH] plat/linuxu: Add support for arm64 on linuxu This commit adds support for arm64 architecture on linuxu platform. It adds all the necessary syscalls for arm64 in a new header file. Also, I added the necessary changes in the syscall.h and Makefile.uk files so that it will compile with arm64 syscalls when that option is selected. Signed-off-by: maniatro111 Reviewed-by: Stefan Jumarea Approved-by: Alexander Jung Tested-by: Unikraft CI GitHub-Closes: #418 --- plat/linuxu/Config.uk | 2 +- plat/linuxu/Makefile.uk | 4 +- plat/linuxu/arm64/entry64.S | 46 ++++ plat/linuxu/arm64/link.lds.S | 9 + plat/linuxu/include/linuxu/syscall-arm_32.h | 2 +- plat/linuxu/include/linuxu/syscall-arm_64.h | 224 ++++++++++++++++++++ plat/linuxu/include/linuxu/syscall-x86_64.h | 2 +- plat/linuxu/include/linuxu/syscall.h | 10 +- plat/linuxu/irq.c | 2 + 9 files changed, 295 insertions(+), 6 deletions(-) create mode 100644 plat/linuxu/arm64/entry64.S create mode 100644 plat/linuxu/arm64/link.lds.S create mode 100644 plat/linuxu/include/linuxu/syscall-arm_64.h diff --git a/plat/linuxu/Config.uk b/plat/linuxu/Config.uk index 179e56d58..3624d8d96 100644 --- a/plat/linuxu/Config.uk +++ b/plat/linuxu/Config.uk @@ -1,7 +1,7 @@ menuconfig PLAT_LINUXU bool "Linux user space" default n - depends on ((ARCH_X86_64 && !HAVE_SYSCALL && !HAVE_SMP) || (ARCH_ARM_32 && !HAVE_SYSCALL && !HAVE_SMP)) + depends on !HAVE_SYSCALL && !HAVE_SMP && ((!ARCH_ARM_32 && !ARCH_ARM_64) || !HAVE_SCHED) depends on !HAVE_PAGING select LIBUKDEBUG select LIBUKALLOC diff --git a/plat/linuxu/Makefile.uk b/plat/linuxu/Makefile.uk index 4cfe6219c..5bd8ce300 100644 --- a/plat/linuxu/Makefile.uk +++ b/plat/linuxu/Makefile.uk @@ -29,7 +29,7 @@ LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/x86/cpu_featu LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_X86_32) += $(LIBLINUXUPLAT_BASE)/x86/entry32.S LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_X86_64) += $(LIBLINUXUPLAT_BASE)/x86/entry64.S LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_ARM_32) += $(LIBLINUXUPLAT_BASE)/arm/entry32.S -LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBLINUXUPLAT_BASE)/arm/entry64.S +LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBLINUXUPLAT_BASE)/arm64/entry64.S ifeq ($(CONFIG_HAVE_SCHED),y) LIBLINUXUPLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/sw_ctx.c|common LIBLINUXUPLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/thread.c|common @@ -50,6 +50,8 @@ LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_X86_64) += \ $(LIBLINUXUPLAT_BASE)/x86/link64.lds.S LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_ARM_32) += \ $(LIBLINUXUPLAT_BASE)/arm/link.lds.S +LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += \ + $(LIBLINUXUPLAT_BASE)/arm64/link.lds.S ## ## LINUXUTAPNET Source diff --git a/plat/linuxu/arm64/entry64.S b/plat/linuxu/arm64/entry64.S new file mode 100644 index 000000000..a88d6c1f8 --- /dev/null +++ b/plat/linuxu/arm64/entry64.S @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Simon Kuenzer , + * Florin Postolache + * + * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation, + * 2022, Florin Postolache, + * 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. + */ + +.section .text + +.global _liblinuxuplat_start +_liblinuxuplat_start: + ldr x0, [sp] // argc to r0 + add x1, sp, #8 // argv to r1 + bl _liblinuxuplat_entry + + // Protection +_liblinuxuplat_err: + b _liblinuxuplat_err diff --git a/plat/linuxu/arm64/link.lds.S b/plat/linuxu/arm64/link.lds.S new file mode 100644 index 000000000..6d4fe3336 --- /dev/null +++ b/plat/linuxu/arm64/link.lds.S @@ -0,0 +1,9 @@ +#include + +SECTIONS +{ + CTORTAB_SECTION + + INITTAB_SECTION +} +INSERT BEFORE .rodata diff --git a/plat/linuxu/include/linuxu/syscall-arm_32.h b/plat/linuxu/include/linuxu/syscall-arm_32.h index c2e82afe3..be04aa894 100644 --- a/plat/linuxu/include/linuxu/syscall-arm_32.h +++ b/plat/linuxu/include/linuxu/syscall-arm_32.h @@ -38,7 +38,7 @@ #define __SC_READ 3 #define __SC_WRITE 4 -#define __SC_OPEN 5 +#define __SC_OPENAT 322 #define __SC_CLOSE 6 #define __SC_MMAP 192 /* use mmap2() since mmap() is obsolete */ #define __SC_MUNMAP 91 diff --git a/plat/linuxu/include/linuxu/syscall-arm_64.h b/plat/linuxu/include/linuxu/syscall-arm_64.h new file mode 100644 index 000000000..3571fe0c8 --- /dev/null +++ b/plat/linuxu/include/linuxu/syscall-arm_64.h @@ -0,0 +1,224 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Simon Kuenzer , + * Florin Postolache + * + * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation, + * 2022, Florin Postolache, + * 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. + */ + +#ifndef __SYSCALL_ARM_64_H__ +#define __SYSCALL_ARM_64_H__ + +#include + +#define __SC_READ 63 +#define __SC_WRITE 64 +#define __SC_OPENAT 56 /* changed to openat because open is not on arm64 */ +#define __SC_CLOSE 57 +#define __SC_MMAP 222 /* use mmap2() since mmap() is obsolete */ +#define __SC_MUNMAP 215 +#define __SC_EXIT 93 +#define __SC_IOCTL 29 +#define __SC_FSTAT 80 +#define __SC_FCNTL 25 +#define __SC_RT_SIGPROCMASK 135 +#define __SC_ARCH_PRCTL 167 +#define __SC_RT_SIGACTION 134 +#define __SC_TIMER_CREATE 107 +#define __SC_TIMER_SETTIME 110 +#define __SC_TIMER_GETTIME 108 +#define __SC_TIMER_GETOVERRUN 109 +#define __SC_TIMER_DELETE 111 +#define __SC_CLOCK_GETTIME 113 +#define __SC_SOCKET 198 +#define __SC_PSELECT6 72 + +#ifndef O_TMPFILE +#define O_TMPFILE 020040000 +#endif + +/* NOTE: from `man syscall`: + * + * ARM64 + * + * instruction syscall # retval + * ------------------------------ + * svc #0 x8 x0 + * + * arg1 arg2 arg3 arg4 arg5 arg6 arg7 + * ---------------------------------------- + * x0 x1 x2 x3 x4 x5 + * + */ + +#define syscall0(num) \ +({ \ + register long _num asm("x8") = (num); \ + register long _ret asm("x0"); \ + \ + asm volatile ("svc #0"% \ + : /* output */ \ + "=r" (_ret) \ + : /* input */ \ + "r" (_num) \ + : /* clobbers */ \ + "memory"); \ + _ret; \ +}) + +#define syscall1(num, arg0) \ +({ \ + register long _num asm("x8") = (num); \ + register long _a0ret asm("x0") = (arg0); \ + \ + asm volatile ("svc #0" \ + : /* output */ \ + "=r" (_a0ret) \ + : /* input */ \ + "r" (_num), \ + "r" (_a0ret) \ + : /* clobbers */ \ + "memory"); \ + _a0ret; \ +}) + +#define syscall2(num, arg0, arg1) \ +({ \ + register long _num asm("x8") = (num); \ + register long _a0ret asm("x0") = (arg0); \ + register long _arg1 asm("x1") = (arg1); \ + \ + asm volatile ("svc #0" \ + : /* output */ \ + "=r" (_a0ret) \ + : /* input */ \ + "r" (_num), \ + "r" (_a0ret), \ + "r" (_arg1) \ + : /* clobbers */ \ + "memory"); \ + _a0ret; \ +}) + +#define syscall3(num, arg0, arg1, arg2) \ +({ \ + register long _num asm("x8") = (num); \ + register long _a0ret asm("x0") = (arg0); \ + register long _arg1 asm("x1") = (arg1); \ + register long _arg2 asm("x2") = (arg2); \ + \ + asm volatile ("svc #0" \ + : /* output */ \ + "=r" (_a0ret) \ + : /* input */ \ + "r" (_num), \ + "r" (_a0ret), \ + "r" (_arg1), \ + "r" (_arg2) \ + : /* clobbers */ \ + "memory"); \ + _a0ret; \ +}) + +#define syscall4(num, arg0, arg1, arg2, arg3) \ +({ \ + register long _num asm("x8") = (num); \ + register long _a0ret asm("x0") = (arg0); \ + register long _arg1 asm("x1") = (arg1); \ + register long _arg2 asm("x2") = (arg2); \ + register long _arg3 asm("x3") = (arg3); \ + \ + asm volatile ("svc #0" \ + : /* output */ \ + "=r" (_a0ret) \ + : /* input */ \ + "r" (_num), \ + "r" (_a0ret), \ + "r" (_arg1), \ + "r" (_arg2), \ + "r" (_arg3) \ + : /* clobbers */ \ + "memory"); \ + _a0ret; \ +}) + +#define syscall5(num, arg0, arg1, arg2, arg3, arg4) \ +({ \ + register long _num asm("x8") = (num); \ + register long _a0ret asm("x0") = (arg0); \ + register long _arg1 asm("x1") = (arg1); \ + register long _arg2 asm("x2") = (arg2); \ + register long _arg3 asm("x3") = (arg3); \ + register long _arg4 asm("x4") = (arg4); \ + \ + asm volatile ("svc #0" \ + : /* output */ \ + "=r" (_a0ret) \ + : /* input */ \ + "r" (_num), \ + "r" (_a0ret), \ + "r" (_arg1), \ + "r" (_arg2), \ + "r" (_arg3), \ + "r" (_arg4) \ + : /* clobbers */ \ + "memory"); \ + _a0ret; \ +}) + +#define syscall6(num, arg0, arg1, arg2, arg3, arg4, \ + arg5) \ +({ \ + register long _num asm("x8") = (num); \ + register long _a0ret asm("x0") = (arg0); \ + register long _arg1 asm("x1") = (arg1); \ + register long _arg2 asm("x2") = (arg2); \ + register long _arg3 asm("x3") = (arg3); \ + register long _arg4 asm("x4") = (arg4); \ + register long _arg5 asm("x5") = (arg5); \ + \ + asm volatile ("svc #0" \ + : /* output */ \ + "=r" (_a0ret) \ + : /* input */ \ + "r" (_num), \ + "r" (_a0ret), \ + "r" (_arg1), \ + "r" (_arg2), \ + "r" (_arg3), \ + "r" (_arg4), \ + "r" (_arg5) \ + : /* clobbers */ \ + "memory"); \ + _a0ret; \ +}) + + +#endif /* __SYSCALL_ARM_64_H__ */ diff --git a/plat/linuxu/include/linuxu/syscall-x86_64.h b/plat/linuxu/include/linuxu/syscall-x86_64.h index c1d02f857..05f9c9bd6 100644 --- a/plat/linuxu/include/linuxu/syscall-x86_64.h +++ b/plat/linuxu/include/linuxu/syscall-x86_64.h @@ -38,7 +38,7 @@ #define __SC_READ 0 #define __SC_WRITE 1 -#define __SC_OPEN 2 +#define __SC_OPENAT 257 #define __SC_CLOSE 3 #define __SC_FSTAT 5 #define __SC_MMAP 9 diff --git a/plat/linuxu/include/linuxu/syscall.h b/plat/linuxu/include/linuxu/syscall.h index 6dc80aee2..9975abe5a 100644 --- a/plat/linuxu/include/linuxu/syscall.h +++ b/plat/linuxu/include/linuxu/syscall.h @@ -45,6 +45,8 @@ #include #elif defined __ARM_32__ #include +#elif defined __ARM_64__ +#include #else #error "Unsupported architecture" #endif @@ -111,6 +113,10 @@ static inline int sys_fstat(int fd, struct k_stat *statbuf) #define F_SETFD 2 #endif +#ifndef AT_FDCWD +#define AT_FDCWD (-100) +#endif + static inline int sys_open(const char *pathname, int flags, ...) { mode_t mode = 0; @@ -123,8 +129,8 @@ static inline int sys_open(const char *pathname, int flags, ...) mode = va_arg(ap, mode_t); va_end(ap); } - - fd = syscall3(__SC_OPEN, (long)pathname, (long)flags, (long)mode); + fd = syscall4(__SC_OPENAT, AT_FDCWD, (long)pathname, (long)flags, + (long)mode); if ((fd >= 0) && (flags & O_CLOEXEC)) syscall3(__SC_FCNTL, (long) fd, (long)F_SETFD, (long)FD_CLOEXEC); diff --git a/plat/linuxu/irq.c b/plat/linuxu/irq.c index fd4181bec..5d838971c 100644 --- a/plat/linuxu/irq.c +++ b/plat/linuxu/irq.c @@ -140,6 +140,8 @@ void __restorer(void); asm("__restorer:mov $15,%rax\nsyscall"); #elif defined __ARM_32__ asm("__restorer:mov r7, #0x77\nsvc 0x0"); +#elif defined __ARM_64__ +asm("__restorer:mov x8, #0x8b\nsvc #0"); #else #error "Unsupported architecture" #endif -- 2.39.5