Path: blob/main/stand/kboot/include/host_syscall.h
34865 views
/*1* Copyright (c) 2022, Netflix, Inc.2*3* SPDX-License-Identifier: BSD-2-Clause4*5* Rewritten from the original host_syscall.h Copyright (C) 2014 Nathan Whitehorn6*/78#ifndef _HOST_SYSCALL_H9#define _HOST_SYSCALL_H1011#include <stand.h>12#include <assert.h>1314long host_syscall(int number, ...);1516/*17* Sizes taken from musl's include/alltypes.h.in and expanded for LP64 hosts18*/19typedef uint64_t host_dev_t;20typedef uint64_t host_ino_t;21typedef unsigned int host_mode_t;22typedef unsigned int host_uid_t;23typedef unsigned int host_gid_t;24typedef int64_t host_off_t;25typedef long host_blksize_t;26typedef int64_t host_blkcnt_t;2728#include "stat_arch.h"2930/*31* stat flags32* These are arch independent and match the values in nolib and uapi headers33* with HOST_ prepended.34*/35#define HOST_S_IFMT 017000036#define HOST_S_IFIFO 001000037#define HOST_S_IFCHR 002000038#define HOST_S_IFDIR 004000039#define HOST_S_IFBLK 006000040#define HOST_S_IFREG 010000041#define HOST_S_IFLNK 012000042#define HOST_S_IFSOCK 01400004344#define HOST_S_ISBLK(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFBLK)45#define HOST_S_ISCHR(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFCHR)46#define HOST_S_ISDIR(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFDIR)47#define HOST_S_ISFIFO(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFIFO)48#define HOST_S_ISLNK(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFLNK)49#define HOST_S_ISREG(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFREG)50#define HOST_S_ISSOCK(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFSOCK)5152/*53* Constants for open, fcntl, etc54*55* Note: Some of these are arch dependent on Linux, but are the same for56* powerpc, x86, arm*, and riscv. We should be futureproof, though, since these57* are the 'generic' values and only older architectures (no longer supported by58* FreeBSD) vary.59*60* These are from tools/include/uapi/asm-generic/fcntl.h and use the octal61* notation. Beware, hex is used in other places creating potential confsion.62*/63#define HOST_O_RDONLY 064#define HOST_O_WRONLY 165#define HOST_O_RDWR 266#define HOST_O_CREAT 0010067#define HOST_O_EXCL 0020068#define HOST_O_NOCTTY 0040069#define HOST_O_TRUNC 0100070#define HOST_O_APPEND 0200071#define HOST_O_NONBLOCK 040007273#define HOST_AT_FDCWD -100 /* Relative to current directory */7475/*76* Data types77*/78struct old_utsname {79char sysname[65];80char nodename[65];81char release[65];82char version[65];83char machine[65];84};8586struct host_timeval {87time_t tv_sec;88long tv_usec;89};9091/*92* Must match Linux's values see linux/tools/include/uapi/asm-generic/mman-common.h93* and linux/tools/include/linux/mman.h94*95* And pre-pend HOST_ here.96*/97#define HOST_PROT_READ 0x198#define HOST_PROT_WRITE 0x299#define HOST_PROT_EXEC 0x4100101#define HOST_MAP_SHARED 0x01102#define HOST_MAP_PRIVATE 0x02103#define HOST_MAP_FIXED 0x10104#define HOST_MAP_ANONYMOUS 0x20105106#define HOST_MAP_FAILED ((void *)-1)107108/* Mount flags from uapi */109#define MS_RELATIME (1 << 21)110111#define HOST_REBOOT_MAGIC1 0xfee1dead112#define HOST_REBOOT_MAGIC2 672274793113#define HOST_REBOOT_CMD_KEXEC 0x45584543114115/*116* Values from linux/tools/include/uapi/linux/kexec.h117*/118119/*120* Values match ELF architecture types.121*/122#define HOST_KEXEC_ARCH_X86_64 (62 << 16)123#define HOST_KEXEC_ARCH_PPC64 (21 << 16)124#define HOST_KEXEC_ARCH_ARM (40 << 16)125#define HOST_KEXEC_ARCH_AARCH64 (183 << 16)126#define HOST_KEXEC_ARCH_RISCV (243 << 16)127128/* Arbitrary cap on segments */129#define HOST_KEXEC_SEGMENT_MAX 16130131struct host_kexec_segment {132void *buf;133int bufsz;134void *mem;135int memsz;136};137138struct host_dirent64 {139uint64_t d_ino; /* 64-bit inode number */140int64_t d_off; /* 64-bit offset to next structure */141unsigned short d_reclen; /* Size of this dirent */142unsigned char d_type; /* File type */143char d_name[]; /* Filename (null-terminated) */144};145146/* d_type values */147#define HOST_DT_UNKNOWN 0148#define HOST_DT_FIFO 1149#define HOST_DT_CHR 2150#define HOST_DT_DIR 4151#define HOST_DT_BLK 6152#define HOST_DT_REG 8153#define HOST_DT_LNK 10154#define HOST_DT_SOCK 12155#define HOST_DT_WHT 14156157/*158* System Calls159*/160int host_close(int fd);161int host_dup(int fd);162int host_exit(int code);163int host_fstat(int fd, struct host_kstat *sb);164int host_getdents64(int fd, void *dirp, int count);165int host_getpid(void);166int host_gettimeofday(struct host_timeval *a, void *b);167int host_ioctl(int fd, unsigned long request, unsigned long arg);168int host_kexec_load(unsigned long entry, unsigned long nsegs, struct host_kexec_segment *segs, unsigned long flags);169ssize_t host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence);170int host_mkdir(const char *, host_mode_t);171void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off);172int host_mount(const char *src, const char *target, const char *type,173unsigned long flags, void *data);174int host_munmap(void *addr, size_t len);175int host_open(const char *path, int flags, int mode);176ssize_t host_read(int fd, void *buf, size_t nbyte);177int host_reboot(int, int, int, uintptr_t);178int host_select(int nfds, long *readfds, long *writefds, long *exceptfds,179struct host_timeval *timeout);180int host_stat(const char *path, struct host_kstat *sb);181int host_symlink(const char *path1, const char *path2);182int host_uname(struct old_utsname *);183ssize_t host_write(int fd, const void *buf, size_t nbyte);184185/*186* Wrappers / one-liners187*/188#define host_getmem(size) \189host_mmap(0, size, HOST_PROT_READ | HOST_PROT_WRITE, \190HOST_MAP_PRIVATE | HOST_MAP_ANONYMOUS, -1, 0);191192/*193* Since we have to interface with the 'raw' system call, we have to cope with194* Linux's conventions. To run on the most architectures possible, they don't195* return errors through some CPU flag, but instead, return a negative value for196* an error, and a positive one for success. However, there's some issues since197* addresses have to be returned, some of which are also negative, so Linus198* declared that no successful result could be -4096 to 0. This implements199* that quirk so we can check return values easily.200*/201static __inline bool202is_linux_error(long e)203{204return (e < 0 && e >= -4096);205}206207/*208* Translate Linux errno to FreeBSD errno. The two system have idenitcal errors209* for 1-34. After that, they differ. Linux also has errno that don't map210* exactly to FreeBSD's errno, plus the Linux errno are arch dependent >211* 34. Since we just need to do this for simple cases, use the simple mapping212* function where -1 to -34 are translated to 1 to 34 and all others are EINVAL.213* Pass the linux return value, which will be the -errno. Linux returns these214* values as a 'long' which has to align to CPU register size, so accept that215* size as the error so the assert can catch more values.216*/217static __inline int218host_to_stand_errno(long e)219{220assert(is_linux_error(e));221222return((-e) > 34 ? EINVAL : (-e));223}224#endif225226227