Skip to content

Commit

Permalink
[LibOS] Continue importing Linux types
Browse files Browse the repository at this point in the history
This is a part of making our LibOS independent from the host headers
(we want this b/c the host may not even be Linux).

Signed-off-by: Michał Kowalczyk <mkow@invisiblethingslab.com>
  • Loading branch information
mkow authored and dimakuv committed Sep 18, 2023
1 parent eed050c commit b6fc88d
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 63 deletions.
18 changes: 18 additions & 0 deletions libos/include/arch/x86_64/linux_abi/types_arch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/* Copyright (C) 2023 Intel Corporation
* Michał Kowalczyk <mkow@invisiblethingslab.com>
*/

#pragma once

#include <stdint.h>

typedef unsigned int uid_t;
typedef unsigned int gid_t;
typedef int pid_t;
typedef unsigned int mode_t;
typedef long off_t;
typedef long long loff_t;
typedef uint32_t dev_t;
typedef unsigned long ino_t;
typedef int clockid_t;
12 changes: 7 additions & 5 deletions libos/include/libos_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#pragma once

#include "libos_types.h"
#include "linux_abi/futex.h"
#include "linux_abi/sysinfo.h"

typedef void (*libos_syscall_t)(void);
Expand Down Expand Up @@ -43,8 +44,8 @@ long libos_syscall_readv(unsigned long fd, struct iovec* vec, unsigned long vlen
long libos_syscall_writev(unsigned long fd, struct iovec* vec, unsigned long vlen);
long libos_syscall_access(const char* file, mode_t mode);
long libos_syscall_pipe(int* fildes);
long libos_syscall_select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds,
struct __kernel_timeval* timeout);
long libos_syscall_select(int nfds, struct linux_fd_set* readfds, struct linux_fd_set* writefds,
struct linux_fd_set* errorfds, struct __kernel_timeval* timeout);
long libos_syscall_sched_yield(void);
long libos_syscall_msync(unsigned long start, size_t len, int flags);
long libos_syscall_mincore(void* start, size_t len, unsigned char* vec);
Expand Down Expand Up @@ -86,7 +87,7 @@ long libos_syscall_waitid(int which, pid_t id, siginfo_t* infop, int options,
struct __kernel_rusage* ru);
long libos_syscall_wait4(pid_t pid, int* stat_addr, int options, struct __kernel_rusage* ru);
long libos_syscall_kill(pid_t pid, int sig);
long libos_syscall_uname(struct new_utsname* buf);
long libos_syscall_uname(struct linux_new_utsname* buf);
long libos_syscall_fcntl(int fd, int cmd, unsigned long arg);
long libos_syscall_flock(unsigned int fd, unsigned int cmd);
long libos_syscall_fsync(int fd);
Expand Down Expand Up @@ -179,8 +180,9 @@ long libos_syscall_renameat(int olddfd, const char* pathname, int newdfd, const
long libos_syscall_fchmodat(int dfd, const char* filename, mode_t mode);
long libos_syscall_fchownat(int dfd, const char* filename, uid_t user, gid_t group, int flags);
long libos_syscall_faccessat(int dfd, const char* filename, mode_t mode);
long libos_syscall_pselect6(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
struct __kernel_timespec* tsp, void* sigmask_argpack);
long libos_syscall_pselect6(int nfds, struct linux_fd_set* readfds, struct linux_fd_set* writefds,
struct linux_fd_set* exceptfds, struct __kernel_timespec* tsp,
void* sigmask_argpack);
long libos_syscall_ppoll(struct pollfd* fds, unsigned int nfds, struct timespec* tsp,
const __sigset_t* sigmask_ptr, size_t sigsetsize);
long libos_syscall_set_robust_list(struct robust_list_head* head, size_t len);
Expand Down
7 changes: 7 additions & 0 deletions libos/include/linux_abi/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <asm/fcntl.h>
#include <asm/stat.h>
#include <asm/statfs.h>
#include <linux/fadvise.h>
#include <linux/fcntl.h>
#include <stdint.h>
Expand Down Expand Up @@ -43,3 +44,9 @@ struct linux_dirent_tail {
#define LINUX_DT_LNK 10
#define LINUX_DT_SOCK 12
#define LINUX_DT_WHT 14

#define SEEK_SET 0 /* seek relative to beginning of file */
#define SEEK_CUR 1 /* seek relative to current file position */
#define SEEK_END 2 /* seek relative to end of file */
#define SEEK_DATA 3 /* seek to the next data */
#define SEEK_HOLE 4 /* seek to the next hole */
7 changes: 7 additions & 0 deletions libos/include/linux_abi/poll.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
/* Types and structures used by various Linux ABIs (e.g. syscalls). */
/* These need to be binary-identical with the ones used by Linux. */

#include <asm/poll.h>
#include <linux/eventpoll.h>

struct linux_fd_set {
unsigned long fds_bits[1024 / (8 * sizeof(unsigned long))];
};

#ifndef EPOLLNVAL
/* This is not defined in the older kernels e.g. the default kernel on Ubuntu 18.04. */
#define EPOLLNVAL ((uint32_t)0x00000020)
Expand Down
11 changes: 11 additions & 0 deletions libos/include/linux_abi/sysinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@
/* Types and structures used by various Linux ABIs (e.g. syscalls). */
/* These need to be binary-identical with the ones used by Linux. */

#define __NEW_UTS_LEN 64

struct linux_new_utsname {
char sysname[__NEW_UTS_LEN + 1];
char nodename[__NEW_UTS_LEN + 1];
char release[__NEW_UTS_LEN + 1];
char version[__NEW_UTS_LEN + 1];
char machine[__NEW_UTS_LEN + 1];
char domainname[__NEW_UTS_LEN + 1];
};

/* Copied and slightly adapted from linux/include/uapi/linux/sysinfo.h, ver 5.11. */
struct sysinfo {
long uptime; /* Seconds since boot */
Expand Down
30 changes: 1 addition & 29 deletions libos/include/linux_abi/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,4 @@
/* Types and structures used by various Linux ABIs (e.g. syscalls). */
/* These need to be binary-identical with the ones used by Linux. */

// TODO: remove all of these includes and make this header libc-independent.
#include <asm/poll.h>
#include <asm/posix_types.h>
#include <asm/siginfo.h>
#include <asm/signal.h>
#include <asm/stat.h>
#include <asm/statfs.h>
#include <linux/aio_abi.h>
#include <linux/eventpoll.h>
#include <linux/futex.h>
#include <linux/msg.h>
#include <linux/perf_event.h>
#include <linux/sem.h>
#include <linux/types.h>
#include <linux/utsname.h>
#include <linux/version.h>

typedef __kernel_uid_t uid_t;
typedef __kernel_gid_t gid_t;
typedef __kernel_pid_t pid_t;
typedef __kernel_mode_t mode_t;
typedef __kernel_off_t off_t;
typedef __kernel_loff_t loff_t;
typedef __kernel_old_dev_t dev_t;
typedef __kernel_ino_t ino_t;
typedef __kernel_clockid_t clockid_t;
typedef __kernel_fd_set fd_set;

typedef unsigned int __kernel_uid_t;
#include "linux_abi/types_arch.h"
12 changes: 6 additions & 6 deletions libos/src/fs/libos_fs_pseudo.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,12 @@ static int count_nlink(const char* name, void* arg) {
return 0;
}

static dev_t makedev(unsigned int major, unsigned int minor) {
dev_t dev;
dev = (((dev_t)(major & 0x00000fffu)) << 8);
dev |= (((dev_t)(major & 0xfffff000u)) << 32);
dev |= (((dev_t)(minor & 0x000000ffu)) << 0);
dev |= (((dev_t)(minor & 0xffffff00u)) << 12);
static uint64_t makedev(unsigned int major, unsigned int minor) {
uint64_t dev;
dev = (((uint64_t)(major & 0x00000fffu)) << 8);
dev |= (((uint64_t)(major & 0xfffff000u)) << 32);
dev |= (((uint64_t)(minor & 0x000000ffu)) << 0);
dev |= (((uint64_t)(minor & 0xffffff00u)) << 12);
return dev;
}

Expand Down
1 change: 1 addition & 0 deletions libos/src/libos_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "libos_types.h"
#include "libos_vma.h"
#include "linux_abi/fs.h"
#include "linux_abi/futex.h"
#include "linux_abi/ioctl.h"
#include "linux_abi/memory.h"
#include "linux_abi/net.h"
Expand Down
46 changes: 25 additions & 21 deletions libos/src/sys/libos_poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ typedef unsigned long __fd_mask;
#define __FDS_BITS(set) ((set)->fds_bits)
#endif

#define __FD_ZERO(set) \
do { \
unsigned int i; \
fd_set* arr = (set); \
for (i = 0; i < sizeof(fd_set) / sizeof(__fd_mask); i++) \
__FDS_BITS(arr)[i] = 0; \
#define __FD_ZERO(set) \
do { \
unsigned int i; \
struct linux_fd_set* arr = (set); \
for (i = 0; i < sizeof(struct linux_fd_set) / sizeof(__fd_mask); i++) \
__FDS_BITS(arr)[i] = 0; \
} while (0)

#define __FD_ELT(d) ((d) / __NFDBITS)
Expand Down Expand Up @@ -275,8 +275,8 @@ long libos_syscall_ppoll(struct pollfd* fds, unsigned int nfds, struct timespec*
return ret;
}

static long do_select(int nfds, fd_set* read_set, fd_set* write_set, fd_set* except_set,
uint64_t* timeout_us) {
static long do_select(int nfds, struct linux_fd_set* read_set, struct linux_fd_set* write_set,
struct linux_fd_set* except_set, uint64_t* timeout_us) {
size_t total_fds = 0;
for (size_t i = 0; i < (size_t)nfds; i++) {
if ((read_set && __FD_ISSET(i, read_set)) || (write_set && __FD_ISSET(i, write_set))
Expand Down Expand Up @@ -365,18 +365,20 @@ static long do_select(int nfds, fd_set* read_set, fd_set* write_set, fd_set* exc
return ret;
}

long libos_syscall_select(int nfds, fd_set* read_set, fd_set* write_set, fd_set* except_set,
struct __kernel_timeval* tv) {
long libos_syscall_select(int nfds, struct linux_fd_set* read_set, struct linux_fd_set* write_set,
struct linux_fd_set* except_set, struct __kernel_timeval* tv) {
if (nfds < 0 || (uint64_t)nfds > get_rlimit_cur(RLIMIT_NOFILE) || nfds > INT_MAX)
return -EINVAL;

/* Each of `read_set`, `write_set` and `except_set` is an array of fd_set items; each fd_set
* item has a single inline array `fd_set::fds_bits` of constant size (typically 128B, which
* allows to accommodate 1024 bits, i.e. 1024 file descriptors). Therefore we calculate how many
* fd_set items are required to accommodate `nfds` number of file descriptors, i.e., we
* calculate the length of each of `read_set`, `write_set` and `except_set` arrays. */
static_assert(sizeof(((fd_set*)0)->fds_bits) == sizeof(fd_set), "unexpected fd_set struct");
size_t fd_set_arr_len = UDIV_ROUND_UP(nfds, BITS_IN_TYPE(((fd_set*)0)->fds_bits));
/* Each of `read_set`, `write_set` and `except_set` is an array of linux_fd_set items; each
* linux_fd_set item has a single inline array `linux_fd_set::fds_bits` of constant size
* (typically 128B, which allows to accommodate 1024 bits, i.e. 1024 file descriptors).
* Therefore we calculate how many linux_fd_set items are required to accommodate `nfds` number
* of file descriptors, i.e., we calculate the length of each of `read_set`, `write_set` and
* `except_set` arrays. */
static_assert(sizeof(((struct linux_fd_set*)0)->fds_bits) == sizeof(struct linux_fd_set),
"unexpected struct linux_fd_set struct");
size_t fd_set_arr_len = UDIV_ROUND_UP(nfds, BITS_IN_TYPE(((struct linux_fd_set*)0)->fds_bits));
if (read_set && !is_user_memory_writable(read_set, fd_set_arr_len * sizeof(*read_set))) {
return -EFAULT;
}
Expand Down Expand Up @@ -413,14 +415,16 @@ struct sigset_argpack {
size_t size;
};

long libos_syscall_pselect6(int nfds, fd_set* read_set, fd_set* write_set, fd_set* except_set,
struct __kernel_timespec* tsp, void* _sigmask_argpack) {
long libos_syscall_pselect6(int nfds, struct linux_fd_set* read_set, struct linux_fd_set* write_set,
struct linux_fd_set* except_set, struct __kernel_timespec* tsp,
void* _sigmask_argpack) {
if (nfds < 0 || (uint64_t)nfds > get_rlimit_cur(RLIMIT_NOFILE) || nfds > INT_MAX)
return -EINVAL;

/* for explanation on calculations below, see libos_syscall_select() */
static_assert(sizeof(((fd_set*)0)->fds_bits) == sizeof(fd_set), "unexpected fd_set struct");
size_t fd_set_arr_len = UDIV_ROUND_UP(nfds, BITS_IN_TYPE(((fd_set*)0)->fds_bits));
static_assert(sizeof(((struct linux_fd_set*)0)->fds_bits) == sizeof(struct linux_fd_set),
"unexpected linux_fd_set struct");
size_t fd_set_arr_len = UDIV_ROUND_UP(nfds, BITS_IN_TYPE(((struct linux_fd_set*)0)->fds_bits));
if (read_set && !is_user_memory_writable(read_set, fd_set_arr_len * sizeof(*read_set))) {
return -EFAULT;
}
Expand Down
5 changes: 3 additions & 2 deletions libos/src/sys/libos_uname.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
#include "libos_internal.h"
#include "libos_table.h"
#include "linux_abi/errors.h"
#include "linux_abi/sysinfo.h"

/* This structure is *not* shared between Gramine processes, despite it should. As a result,
* effects of set{host,domain}name in process A will not be visible in process B.
* These syscalls are rarely used and are implemented in Gramine mainly to enable LTP to test
* our `uname` implementation. */
static struct new_utsname g_current_uname = {
static struct linux_new_utsname g_current_uname = {
.sysname = "Linux",
.nodename = "(none)", /* overwritten by PAL-provided value at startup */
.release = "3.10.0",
Expand All @@ -30,7 +31,7 @@ static struct new_utsname g_current_uname = {
.domainname = "(none)", /* this seems to be the default on Linux */
};

long libos_syscall_uname(struct new_utsname* buf) {
long libos_syscall_uname(struct linux_new_utsname* buf) {
if (!is_user_memory_writable(buf, sizeof(*buf)))
return -EFAULT;

Expand Down

0 comments on commit b6fc88d

Please sign in to comment.