2015-05-23 14:35:45 +02:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2010, Stefan Lankes, RWTH Aachen University
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* * 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.
|
|
|
|
* * Neither the name of the University 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 REGENTS 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <hermit/stddef.h>
|
|
|
|
#include <hermit/stdio.h>
|
|
|
|
#include <hermit/tasks.h>
|
|
|
|
#include <hermit/errno.h>
|
|
|
|
#include <hermit/syscall.h>
|
|
|
|
#include <hermit/spinlock.h>
|
2015-08-09 14:34:36 +02:00
|
|
|
#include <hermit/semaphore.h>
|
2015-07-16 22:33:29 +02:00
|
|
|
#include <hermit/time.h>
|
2015-10-17 12:01:46 +02:00
|
|
|
#include <hermit/rcce.h>
|
|
|
|
#include <hermit/memory.h>
|
2016-08-25 17:15:52 +02:00
|
|
|
#include <hermit/signal.h>
|
2016-11-04 12:09:43 +01:00
|
|
|
#include <hermit/logging.h>
|
2017-03-07 00:05:19 +01:00
|
|
|
#include <asm/uhyve.h>
|
2016-01-22 04:41:49 +01:00
|
|
|
#include <sys/poll.h>
|
2015-05-23 14:35:45 +02:00
|
|
|
|
2015-10-03 01:43:17 +02:00
|
|
|
#include <lwip/sockets.h>
|
|
|
|
#include <lwip/err.h>
|
|
|
|
#include <lwip/stats.h>
|
|
|
|
|
2016-11-27 23:21:47 +01:00
|
|
|
/*
|
|
|
|
* Note that linker symbols are not variables, they have no memory allocated for
|
|
|
|
* maintaining a value, rather their address is their value.
|
|
|
|
*/
|
|
|
|
extern const void kernel_start;
|
|
|
|
|
2015-10-05 11:13:08 +02:00
|
|
|
//TODO: don't use one big kernel lock to comminicate with all proxies
|
2016-08-29 16:07:37 +02:00
|
|
|
static spinlock_irqsave_t lwip_lock = SPINLOCK_IRQSAVE_INIT;
|
2015-10-03 01:43:17 +02:00
|
|
|
|
2016-08-02 20:30:52 +02:00
|
|
|
extern spinlock_irqsave_t stdio_lock;
|
2015-10-17 12:01:46 +02:00
|
|
|
extern int32_t isle;
|
|
|
|
extern int32_t possible_isles;
|
2016-05-17 00:00:06 +02:00
|
|
|
extern volatile int libc_sd;
|
2015-10-17 12:01:46 +02:00
|
|
|
|
2017-09-24 00:55:27 +02:00
|
|
|
static inline int socket_send(int fd, const void* buf, size_t len)
|
|
|
|
{
|
|
|
|
int ret, sz = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
ret = lwip_write(fd, (char*)buf + sz, len-sz);
|
|
|
|
if (ret >= 0)
|
|
|
|
sz += ret;
|
|
|
|
else
|
|
|
|
return ret;
|
|
|
|
} while(sz < len);
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int socket_recv(int fd, void* buf, size_t len)
|
|
|
|
{
|
|
|
|
int ret, sz = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
ret = lwip_read(fd, (char*)buf + sz, len-sz);
|
|
|
|
if (ret >= 0)
|
|
|
|
sz += ret;
|
|
|
|
else
|
|
|
|
return ret;
|
|
|
|
} while(sz < len);
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
tid_t sys_getpid(void)
|
2015-08-09 14:34:36 +02:00
|
|
|
{
|
|
|
|
task_t* task = per_core(current_task);
|
|
|
|
|
|
|
|
return task->id;
|
|
|
|
}
|
|
|
|
|
2016-01-01 22:59:18 +01:00
|
|
|
int sys_getprio(tid_t* id)
|
2015-08-09 14:34:36 +02:00
|
|
|
{
|
|
|
|
task_t* task = per_core(current_task);
|
|
|
|
|
2016-01-01 22:59:18 +01:00
|
|
|
if (!id || (task->id == *id))
|
|
|
|
return task->prio;
|
|
|
|
return -EINVAL;
|
2015-08-09 14:34:36 +02:00
|
|
|
}
|
|
|
|
|
2015-12-30 02:17:23 +01:00
|
|
|
int sys_setprio(tid_t* id, int prio)
|
|
|
|
{
|
|
|
|
return -ENOSYS;
|
|
|
|
}
|
|
|
|
|
2015-10-03 01:43:17 +02:00
|
|
|
void NORETURN do_exit(int arg);
|
|
|
|
|
2015-10-05 10:12:34 +02:00
|
|
|
typedef struct {
|
|
|
|
int sysnr;
|
|
|
|
int arg;
|
|
|
|
} __attribute__((packed)) sys_exit_t;
|
|
|
|
|
2015-10-03 01:43:17 +02:00
|
|
|
/** @brief To be called by the systemcall to exit tasks */
|
|
|
|
void NORETURN sys_exit(int arg)
|
|
|
|
{
|
2017-01-16 18:47:13 +01:00
|
|
|
if (is_uhyve()) {
|
2017-05-26 16:46:48 +02:00
|
|
|
uhyve_send(UHYVE_PORT_EXIT, (unsigned) virt_to_phys((size_t) &arg));
|
2017-01-16 18:47:13 +01:00
|
|
|
} else {
|
|
|
|
sys_exit_t sysargs = {__NR_exit, arg};
|
2015-10-03 01:43:17 +02:00
|
|
|
|
2017-01-16 18:47:13 +01:00
|
|
|
spinlock_irqsave_lock(&lwip_lock);
|
|
|
|
if (libc_sd >= 0)
|
|
|
|
{
|
|
|
|
int s = libc_sd;
|
2015-10-03 01:43:17 +02:00
|
|
|
|
2017-09-24 00:55:27 +02:00
|
|
|
socket_send(s, &sysargs, sizeof(sysargs));
|
2017-01-16 18:47:13 +01:00
|
|
|
libc_sd = -1;
|
2016-05-17 00:00:06 +02:00
|
|
|
|
2017-01-16 18:47:13 +01:00
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
2016-05-17 00:00:06 +02:00
|
|
|
|
2017-01-16 18:47:13 +01:00
|
|
|
// switch to LwIP thread
|
|
|
|
reschedule();
|
2016-05-17 00:00:06 +02:00
|
|
|
|
2017-01-16 18:47:13 +01:00
|
|
|
lwip_close(s);
|
|
|
|
} else {
|
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
|
|
|
}
|
2015-10-03 01:43:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
do_exit(arg);
|
|
|
|
}
|
|
|
|
|
2015-10-05 10:12:34 +02:00
|
|
|
typedef struct {
|
|
|
|
int sysnr;
|
|
|
|
int fd;
|
|
|
|
size_t len;
|
|
|
|
} __attribute__((packed)) sys_read_t;
|
|
|
|
|
2017-01-16 18:47:13 +01:00
|
|
|
typedef struct {
|
|
|
|
int fd;
|
|
|
|
char* buf;
|
|
|
|
size_t len;
|
|
|
|
ssize_t ret;
|
|
|
|
} __attribute__((packed)) uhyve_read_t;
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
ssize_t sys_read(int fd, char* buf, size_t len)
|
2015-10-05 10:12:34 +02:00
|
|
|
{
|
|
|
|
sys_read_t sysargs = {__NR_read, fd, len};
|
|
|
|
ssize_t j, ret;
|
|
|
|
|
2016-01-10 03:13:31 +01:00
|
|
|
// do we have an LwIP file descriptor?
|
|
|
|
if (fd & LWIP_FD_BIT) {
|
|
|
|
ret = lwip_read(fd & ~LWIP_FD_BIT, buf, len);
|
2016-01-10 20:20:55 +01:00
|
|
|
if (ret < 0)
|
|
|
|
return -errno;
|
2016-01-10 03:13:31 +01:00
|
|
|
|
2016-01-10 20:20:55 +01:00
|
|
|
return ret;
|
2016-01-10 03:13:31 +01:00
|
|
|
}
|
|
|
|
|
2017-09-21 22:39:34 +02:00
|
|
|
if (is_uhyve()) {
|
|
|
|
uhyve_read_t uhyve_args = {fd, (char*) virt_to_phys((size_t) buf), len, -1};
|
|
|
|
|
|
|
|
uhyve_send(UHYVE_PORT_READ, (unsigned)virt_to_phys((size_t)&uhyve_args));
|
|
|
|
|
|
|
|
return uhyve_args.ret;
|
|
|
|
}
|
|
|
|
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_lock(&lwip_lock);
|
2016-05-17 00:00:06 +02:00
|
|
|
if (libc_sd < 0) {
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
2015-10-05 10:12:34 +02:00
|
|
|
return -ENOSYS;
|
2016-05-17 00:00:06 +02:00
|
|
|
}
|
2015-10-05 10:12:34 +02:00
|
|
|
|
2017-09-21 22:39:34 +02:00
|
|
|
int s = libc_sd;
|
2017-09-24 00:55:27 +02:00
|
|
|
socket_send(s, &sysargs, sizeof(sysargs));
|
2015-10-05 10:12:34 +02:00
|
|
|
|
2017-09-24 00:55:27 +02:00
|
|
|
socket_recv(s, &j, sizeof(j));
|
2015-10-05 10:12:34 +02:00
|
|
|
if (j > 0)
|
|
|
|
{
|
2017-09-24 00:55:27 +02:00
|
|
|
ret = socket_recv(s, buf, j);
|
|
|
|
if (ret < 0) {
|
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
|
|
|
return ret;
|
2015-10-05 10:12:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
2015-10-05 10:12:34 +02:00
|
|
|
|
|
|
|
return j;
|
|
|
|
}
|
|
|
|
|
2016-01-22 04:41:49 +01:00
|
|
|
ssize_t readv(int d, const struct iovec *iov, int iovcnt)
|
|
|
|
{
|
|
|
|
return -ENOSYS;
|
|
|
|
}
|
|
|
|
|
2015-10-05 10:12:34 +02:00
|
|
|
typedef struct {
|
|
|
|
int sysnr;
|
|
|
|
int fd;
|
|
|
|
size_t len;
|
|
|
|
} __attribute__((packed)) sys_write_t;
|
|
|
|
|
2017-01-16 18:47:13 +01:00
|
|
|
typedef struct {
|
|
|
|
int fd;
|
|
|
|
const char* buf;
|
|
|
|
size_t len;
|
|
|
|
} __attribute__((packed)) uhyve_write_t;
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
ssize_t sys_write(int fd, const char* buf, size_t len)
|
2015-05-23 14:35:45 +02:00
|
|
|
{
|
|
|
|
if (BUILTIN_EXPECT(!buf, 0))
|
2017-09-21 22:39:34 +02:00
|
|
|
return -EINVAL;
|
2017-01-16 18:47:13 +01:00
|
|
|
|
|
|
|
ssize_t i, ret;
|
|
|
|
sys_write_t sysargs = {__NR_write, fd, len};
|
|
|
|
|
2016-01-10 03:13:31 +01:00
|
|
|
// do we have an LwIP file descriptor?
|
|
|
|
if (fd & LWIP_FD_BIT) {
|
|
|
|
ret = lwip_write(fd & ~LWIP_FD_BIT, buf, len);
|
2016-01-10 20:20:55 +01:00
|
|
|
if (ret < 0)
|
|
|
|
return -errno;
|
2016-01-10 03:13:31 +01:00
|
|
|
|
2016-01-10 20:20:55 +01:00
|
|
|
return ret;
|
2016-01-10 03:13:31 +01:00
|
|
|
}
|
|
|
|
|
2017-09-21 22:39:34 +02:00
|
|
|
if (is_uhyve()) {
|
|
|
|
uhyve_write_t uhyve_args = {fd, (const char*) virt_to_phys((size_t) buf), len};
|
|
|
|
|
|
|
|
uhyve_send(UHYVE_PORT_WRITE, (unsigned)virt_to_phys((size_t)&uhyve_args));
|
|
|
|
|
|
|
|
return uhyve_args.len;
|
|
|
|
}
|
|
|
|
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_lock(&lwip_lock);
|
2015-12-29 02:22:41 +01:00
|
|
|
if (libc_sd < 0)
|
2015-10-03 01:43:17 +02:00
|
|
|
{
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
2016-05-17 00:00:06 +02:00
|
|
|
|
2016-08-02 20:30:52 +02:00
|
|
|
spinlock_irqsave_lock(&stdio_lock);
|
2015-10-03 01:43:17 +02:00
|
|
|
for(i=0; i<len; i++)
|
|
|
|
kputchar(buf[i]);
|
2016-08-02 20:30:52 +02:00
|
|
|
spinlock_irqsave_unlock(&stdio_lock);
|
2015-10-03 01:43:17 +02:00
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2017-09-21 22:39:34 +02:00
|
|
|
int s = libc_sd;
|
2017-09-24 00:55:27 +02:00
|
|
|
socket_send(s, &sysargs, sizeof(sysargs));
|
2015-10-03 01:43:17 +02:00
|
|
|
|
|
|
|
i=0;
|
2015-10-05 10:12:34 +02:00
|
|
|
while(i < len)
|
2015-10-03 01:43:17 +02:00
|
|
|
{
|
2017-09-24 00:55:27 +02:00
|
|
|
ret = socket_send(s, (char*)buf+i, len-i);
|
2015-10-05 10:12:34 +02:00
|
|
|
if (ret < 0) {
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
2015-10-05 10:12:34 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-03 01:43:17 +02:00
|
|
|
i += ret;
|
|
|
|
}
|
|
|
|
|
2017-09-24 00:55:27 +02:00
|
|
|
if (fd > 2)
|
|
|
|
i = socket_recv(s, &i, sizeof(i));
|
2015-10-03 01:43:17 +02:00
|
|
|
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
2015-10-03 01:43:17 +02:00
|
|
|
|
2015-10-05 10:12:34 +02:00
|
|
|
return i;
|
2015-05-23 14:35:45 +02:00
|
|
|
}
|
|
|
|
|
2016-01-22 04:41:49 +01:00
|
|
|
ssize_t writev(int fildes, const struct iovec *iov, int iovcnt)
|
|
|
|
{
|
|
|
|
return -ENOSYS;
|
|
|
|
}
|
|
|
|
|
2016-01-31 10:13:21 +01:00
|
|
|
ssize_t sys_sbrk(ssize_t incr)
|
2015-05-23 14:35:45 +02:00
|
|
|
{
|
|
|
|
ssize_t ret;
|
2016-03-21 00:18:45 +01:00
|
|
|
vma_t* heap = per_core(current_task)->heap;
|
|
|
|
static spinlock_t heap_lock = SPINLOCK_INIT;
|
2015-05-23 14:35:45 +02:00
|
|
|
|
|
|
|
if (BUILTIN_EXPECT(!heap, 0)) {
|
2016-11-04 12:09:43 +01:00
|
|
|
LOG_ERROR("sys_sbrk: missing heap!\n");
|
2015-12-29 02:22:41 +01:00
|
|
|
do_abort();
|
2015-05-23 14:35:45 +02:00
|
|
|
}
|
|
|
|
|
2016-03-26 10:03:33 +01:00
|
|
|
spinlock_lock(&heap_lock);
|
|
|
|
|
2015-05-23 14:35:45 +02:00
|
|
|
ret = heap->end;
|
2016-05-23 23:50:43 +02:00
|
|
|
|
2016-11-27 23:21:47 +01:00
|
|
|
// check heapp boundaries
|
|
|
|
if ((heap->end >= HEAP_START) && (heap->end+incr < HEAP_START + HEAP_SIZE)) {
|
|
|
|
heap->end += incr;
|
|
|
|
|
|
|
|
// reserve VMA regions
|
2017-07-15 16:24:08 +02:00
|
|
|
if (PAGE_FLOOR(heap->end) > PAGE_FLOOR(ret)) {
|
2016-11-27 23:21:47 +01:00
|
|
|
// region is already reserved for the heap, we have to change the
|
|
|
|
// property
|
2017-07-15 16:24:08 +02:00
|
|
|
vma_free(PAGE_FLOOR(ret), PAGE_CEIL(heap->end));
|
|
|
|
vma_add(PAGE_FLOOR(ret), PAGE_CEIL(heap->end), VMA_HEAP|VMA_USER);
|
2016-11-27 23:21:47 +01:00
|
|
|
}
|
|
|
|
} else ret = -ENOMEM;
|
2015-05-23 14:35:45 +02:00
|
|
|
|
|
|
|
// allocation and mapping of new pages for the heap
|
|
|
|
// is catched by the pagefault handler
|
|
|
|
|
2016-03-21 00:18:45 +01:00
|
|
|
spinlock_unlock(&heap_lock);
|
2015-05-23 14:35:45 +02:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-01-16 18:47:13 +01:00
|
|
|
typedef struct {
|
|
|
|
const char* name;
|
|
|
|
int flags;
|
|
|
|
int mode;
|
|
|
|
int ret;
|
|
|
|
} __attribute__((packed)) uhyve_open_t;
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
int sys_open(const char* name, int flags, int mode)
|
2015-05-23 14:35:45 +02:00
|
|
|
{
|
2017-01-16 18:47:13 +01:00
|
|
|
if (is_uhyve()) {
|
|
|
|
uhyve_open_t uhyve_open = {(const char*)virt_to_phys((size_t)name), flags, mode, -1};
|
|
|
|
|
2017-03-07 00:05:19 +01:00
|
|
|
uhyve_send(UHYVE_PORT_OPEN, (unsigned)virt_to_phys((size_t) &uhyve_open));
|
2017-01-16 18:47:13 +01:00
|
|
|
|
|
|
|
return uhyve_open.ret;
|
|
|
|
}
|
|
|
|
|
2016-05-17 00:00:06 +02:00
|
|
|
int s, i, ret, sysnr = __NR_open;
|
2015-10-05 10:12:34 +02:00
|
|
|
size_t len;
|
2015-10-03 01:43:17 +02:00
|
|
|
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_lock(&lwip_lock);
|
2016-05-17 00:00:06 +02:00
|
|
|
if (libc_sd < 0) {
|
2016-07-25 07:50:34 +02:00
|
|
|
ret = -EINVAL;
|
2016-05-17 00:00:06 +02:00
|
|
|
goto out;
|
|
|
|
}
|
2015-10-03 01:43:17 +02:00
|
|
|
|
2016-05-17 00:00:06 +02:00
|
|
|
s = libc_sd;
|
2015-10-05 10:12:34 +02:00
|
|
|
len = strlen(name)+1;
|
2015-10-03 01:43:17 +02:00
|
|
|
|
2016-02-20 12:09:26 +01:00
|
|
|
//i = 0;
|
2016-05-17 00:00:06 +02:00
|
|
|
//lwip_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
|
2015-10-05 10:12:34 +02:00
|
|
|
|
2017-09-24 00:55:27 +02:00
|
|
|
ret = socket_send(s, &sysnr, sizeof(sysnr));
|
2015-10-03 01:43:17 +02:00
|
|
|
if (ret < 0)
|
|
|
|
goto out;
|
|
|
|
|
2017-09-24 00:55:27 +02:00
|
|
|
ret = socket_send(s, &len, sizeof(len));
|
2015-10-03 01:43:17 +02:00
|
|
|
if (ret < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
i=0;
|
|
|
|
while(i<len)
|
|
|
|
{
|
2017-09-24 00:55:27 +02:00
|
|
|
ret = socket_send(s, name+i, len-i);
|
2015-10-03 01:43:17 +02:00
|
|
|
if (ret < 0)
|
|
|
|
goto out;
|
|
|
|
i += ret;
|
|
|
|
}
|
|
|
|
|
2017-09-24 00:55:27 +02:00
|
|
|
ret = socket_send(s, &flags, sizeof(flags));
|
2015-10-03 01:43:17 +02:00
|
|
|
if (ret < 0)
|
|
|
|
goto out;
|
|
|
|
|
2017-09-24 00:55:27 +02:00
|
|
|
ret = socket_send(s, &mode, sizeof(mode));
|
2015-10-03 01:43:17 +02:00
|
|
|
if (ret < 0)
|
|
|
|
goto out;
|
|
|
|
|
2016-02-20 12:09:26 +01:00
|
|
|
//i = 1;
|
2016-05-17 00:00:06 +02:00
|
|
|
//lwip_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
|
2015-10-05 10:12:34 +02:00
|
|
|
|
2017-09-24 00:55:27 +02:00
|
|
|
socket_recv(s, &ret, sizeof(ret));
|
2015-10-03 01:43:17 +02:00
|
|
|
|
|
|
|
out:
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
2015-10-03 01:43:17 +02:00
|
|
|
|
|
|
|
return ret;
|
2015-07-15 10:05:09 +02:00
|
|
|
}
|
2015-05-23 14:35:45 +02:00
|
|
|
|
2015-10-05 10:12:34 +02:00
|
|
|
typedef struct {
|
|
|
|
int sysnr;
|
|
|
|
int fd;
|
|
|
|
} __attribute__((packed)) sys_close_t;
|
|
|
|
|
2017-01-16 18:47:13 +01:00
|
|
|
typedef struct {
|
|
|
|
int fd;
|
|
|
|
int ret;
|
|
|
|
} __attribute__((packed)) uhyve_close_t;
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
int sys_close(int fd)
|
2015-07-15 10:05:09 +02:00
|
|
|
{
|
2016-05-17 00:00:06 +02:00
|
|
|
int ret, s;
|
2015-10-05 10:12:34 +02:00
|
|
|
sys_close_t sysargs = {__NR_close, fd};
|
2015-10-03 01:43:17 +02:00
|
|
|
|
2016-01-10 03:13:31 +01:00
|
|
|
// do we have an LwIP file descriptor?
|
|
|
|
if (fd & LWIP_FD_BIT) {
|
|
|
|
ret = lwip_close(fd & ~LWIP_FD_BIT);
|
2016-01-10 20:20:55 +01:00
|
|
|
if (ret < 0)
|
|
|
|
return -errno;
|
2016-01-10 03:13:31 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-09-21 22:39:34 +02:00
|
|
|
if (is_uhyve()) {
|
|
|
|
uhyve_close_t uhyve_close = {fd, -1};
|
|
|
|
|
|
|
|
uhyve_send(UHYVE_PORT_CLOSE, (unsigned)virt_to_phys((size_t) &uhyve_close));
|
|
|
|
|
|
|
|
return uhyve_close.ret;
|
|
|
|
}
|
|
|
|
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_lock(&lwip_lock);
|
2016-05-17 00:00:06 +02:00
|
|
|
if (libc_sd < 0) {
|
|
|
|
ret = 0;
|
|
|
|
goto out;
|
|
|
|
}
|
2015-10-03 01:43:17 +02:00
|
|
|
|
2016-05-17 00:00:06 +02:00
|
|
|
s = libc_sd;
|
2017-09-24 00:55:27 +02:00
|
|
|
ret = socket_send(s, &sysargs, sizeof(sysargs));
|
2015-10-05 10:12:34 +02:00
|
|
|
if (ret != sizeof(sysargs))
|
2015-10-03 01:43:17 +02:00
|
|
|
goto out;
|
2017-09-24 00:55:27 +02:00
|
|
|
socket_recv(s, &ret, sizeof(ret));
|
2015-10-03 01:43:17 +02:00
|
|
|
|
|
|
|
out:
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
2015-10-03 01:43:17 +02:00
|
|
|
|
|
|
|
return ret;
|
2015-07-15 10:05:09 +02:00
|
|
|
}
|
2015-05-23 14:35:45 +02:00
|
|
|
|
2017-05-21 23:43:22 +02:00
|
|
|
int sys_spinlock_init(spinlock_t** lock)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (BUILTIN_EXPECT(!lock, 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
*lock = (spinlock_t*) kmalloc(sizeof(spinlock_t));
|
|
|
|
if (BUILTIN_EXPECT(!(*lock), 0))
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = spinlock_init(*lock);
|
|
|
|
if (ret) {
|
|
|
|
kfree(*lock);
|
|
|
|
*lock = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sys_spinlock_destroy(spinlock_t* lock)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (BUILTIN_EXPECT(!lock, 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
ret = spinlock_destroy(lock);
|
|
|
|
if (!ret)
|
|
|
|
kfree(lock);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sys_spinlock_lock(spinlock_t* lock)
|
|
|
|
{
|
|
|
|
if (BUILTIN_EXPECT(!lock, 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return spinlock_lock(lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
int sys_spinlock_unlock(spinlock_t* lock)
|
|
|
|
{
|
|
|
|
if (BUILTIN_EXPECT(!lock, 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return spinlock_unlock(lock);
|
|
|
|
}
|
|
|
|
|
2015-12-30 17:29:53 +01:00
|
|
|
void sys_msleep(unsigned int ms)
|
2015-08-09 14:34:36 +02:00
|
|
|
{
|
2015-12-29 02:22:41 +01:00
|
|
|
if (ms * TIMER_FREQ / 1000 > 0)
|
|
|
|
timer_wait(ms * TIMER_FREQ / 1000);
|
|
|
|
else if (ms > 0)
|
|
|
|
udelay(ms * 1000);
|
2015-08-09 14:34:36 +02:00
|
|
|
}
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
int sys_sem_init(sem_t** sem, unsigned int value)
|
2015-08-09 14:34:36 +02:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (BUILTIN_EXPECT(!sem, 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
*sem = (sem_t*) kmalloc(sizeof(sem_t));
|
|
|
|
if (BUILTIN_EXPECT(!(*sem), 0))
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = sem_init(*sem, value);
|
|
|
|
if (ret) {
|
|
|
|
kfree(*sem);
|
|
|
|
*sem = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
int sys_sem_destroy(sem_t* sem)
|
2015-08-09 14:34:36 +02:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (BUILTIN_EXPECT(!sem, 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
ret = sem_destroy(sem);
|
|
|
|
if (!ret)
|
|
|
|
kfree(sem);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
int sys_sem_wait(sem_t* sem)
|
2015-08-09 14:34:36 +02:00
|
|
|
{
|
|
|
|
if (BUILTIN_EXPECT(!sem, 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return sem_wait(sem, 0);
|
|
|
|
}
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
int sys_sem_post(sem_t* sem)
|
2015-08-09 14:34:36 +02:00
|
|
|
{
|
|
|
|
if (BUILTIN_EXPECT(!sem, 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return sem_post(sem);
|
|
|
|
}
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
int sys_sem_timedwait(sem_t *sem, unsigned int ms)
|
2015-08-09 14:34:36 +02:00
|
|
|
{
|
|
|
|
if (BUILTIN_EXPECT(!sem, 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return sem_wait(sem, ms);
|
|
|
|
}
|
|
|
|
|
2015-12-30 02:17:23 +01:00
|
|
|
int sys_sem_cancelablewait(sem_t* sem, unsigned int ms)
|
|
|
|
{
|
2016-01-04 01:33:37 +01:00
|
|
|
if (BUILTIN_EXPECT(!sem, 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return sem_wait(sem, ms);
|
2015-12-30 02:17:23 +01:00
|
|
|
}
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
int sys_clone(tid_t* id, void* ep, void* argv)
|
2015-08-09 14:34:36 +02:00
|
|
|
{
|
2015-10-03 01:43:17 +02:00
|
|
|
return clone_task(id, ep, argv, per_core(current_task)->prio);
|
2015-08-09 14:34:36 +02:00
|
|
|
}
|
|
|
|
|
2015-10-05 10:12:34 +02:00
|
|
|
typedef struct {
|
|
|
|
int sysnr;
|
|
|
|
int fd;
|
|
|
|
off_t offset;
|
|
|
|
int whence;
|
|
|
|
} __attribute__((packed)) sys_lseek_t;
|
|
|
|
|
2017-01-16 18:47:13 +01:00
|
|
|
typedef struct {
|
|
|
|
int fd;
|
|
|
|
off_t offset;
|
|
|
|
int whence;
|
|
|
|
} __attribute__((packed)) uhyve_lseek_t;
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
off_t sys_lseek(int fd, off_t offset, int whence)
|
2015-10-05 10:12:34 +02:00
|
|
|
{
|
2017-01-16 18:47:13 +01:00
|
|
|
if (is_uhyve()) {
|
|
|
|
uhyve_lseek_t uhyve_lseek = { fd, offset, whence };
|
|
|
|
|
|
|
|
outportl(UHYVE_PORT_LSEEK, (unsigned)virt_to_phys((size_t) &uhyve_lseek));
|
|
|
|
|
|
|
|
return uhyve_lseek.offset;
|
|
|
|
}
|
|
|
|
|
2015-10-05 10:12:34 +02:00
|
|
|
off_t off;
|
|
|
|
sys_lseek_t sysargs = {__NR_lseek, fd, offset, whence};
|
2016-05-17 00:00:06 +02:00
|
|
|
int s;
|
2015-10-05 10:12:34 +02:00
|
|
|
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_lock(&lwip_lock);
|
2015-10-05 10:12:34 +02:00
|
|
|
|
2016-05-17 00:00:06 +02:00
|
|
|
if (libc_sd < 0) {
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
2016-05-17 00:00:06 +02:00
|
|
|
return -ENOSYS;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = libc_sd;
|
2017-09-24 00:55:27 +02:00
|
|
|
socket_send(s, &sysargs, sizeof(sysargs));
|
|
|
|
socket_recv(s, &off, sizeof(off));
|
2015-10-05 10:12:34 +02:00
|
|
|
|
2016-08-29 16:07:37 +02:00
|
|
|
spinlock_irqsave_unlock(&lwip_lock);
|
2015-10-05 10:12:34 +02:00
|
|
|
|
|
|
|
return off;
|
|
|
|
}
|
|
|
|
|
2016-01-26 14:30:00 +01:00
|
|
|
int sys_rcce_init(int session_id)
|
2015-10-17 12:01:46 +02:00
|
|
|
{
|
|
|
|
int i, err = 0;
|
|
|
|
size_t paddr = 0;
|
|
|
|
|
2016-08-27 08:16:25 +02:00
|
|
|
if (is_single_kernel())
|
|
|
|
return -ENOSYS;
|
|
|
|
|
2015-10-17 12:01:46 +02:00
|
|
|
if (session_id <= 0)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
islelock_lock(rcce_lock);
|
|
|
|
|
|
|
|
for(i=0; i<MAX_RCCE_SESSIONS; i++)
|
|
|
|
{
|
|
|
|
if (rcce_mpb[i].id == session_id)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// create new session
|
|
|
|
if (i >=MAX_RCCE_SESSIONS)
|
|
|
|
{
|
|
|
|
for(i=0; i<MAX_RCCE_SESSIONS; i++)
|
|
|
|
{
|
|
|
|
if (rcce_mpb[i].id == 0) {
|
|
|
|
rcce_mpb[i].id = session_id;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i >= MAX_RCCE_SESSIONS)
|
|
|
|
{
|
|
|
|
err = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2016-10-21 00:21:01 +02:00
|
|
|
if (is_hbmem_available())
|
|
|
|
paddr = hbmem_get_pages(RCCE_MPB_SIZE / PAGE_SIZE);
|
|
|
|
else
|
|
|
|
paddr = get_pages(RCCE_MPB_SIZE / PAGE_SIZE);
|
2015-10-17 12:01:46 +02:00
|
|
|
if (BUILTIN_EXPECT(!paddr, 0))
|
|
|
|
{
|
|
|
|
err = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rcce_mpb[i].mpb[isle] = paddr;
|
|
|
|
|
|
|
|
out:
|
|
|
|
islelock_unlock(rcce_lock);
|
|
|
|
|
2016-11-04 12:09:43 +01:00
|
|
|
LOG_INFO("Create MPB for session %d at 0x%zx, using of slot %d\n", session_id, paddr, i);
|
2015-10-17 12:01:46 +02:00
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2016-01-26 14:30:00 +01:00
|
|
|
size_t sys_rcce_malloc(int session_id, int ue)
|
2015-10-17 12:01:46 +02:00
|
|
|
{
|
|
|
|
size_t vaddr = 0;
|
2015-10-18 10:22:52 +02:00
|
|
|
int i, counter = 0;
|
2015-10-17 12:01:46 +02:00
|
|
|
|
2016-08-27 08:16:25 +02:00
|
|
|
if (is_single_kernel())
|
|
|
|
return -ENOSYS;
|
|
|
|
|
2015-10-17 12:01:46 +02:00
|
|
|
if (session_id <= 0)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2015-10-18 10:22:52 +02:00
|
|
|
// after 120 retries (= 120*300 ms) we give up
|
|
|
|
do {
|
|
|
|
for(i=0; i<MAX_RCCE_SESSIONS; i++)
|
|
|
|
{
|
|
|
|
if ((rcce_mpb[i].id == session_id) && rcce_mpb[i].mpb[ue])
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i >= MAX_RCCE_SESSIONS) {
|
|
|
|
counter++;
|
|
|
|
timer_wait((300*TIMER_FREQ)/1000);
|
|
|
|
}
|
|
|
|
} while((i >= MAX_RCCE_SESSIONS) && (counter < 120));
|
|
|
|
|
2016-11-04 12:09:43 +01:00
|
|
|
LOG_DEBUG("i = %d, counter = %d, max %d\n", i, counter, MAX_RCCE_SESSIONS);
|
2015-10-17 12:01:46 +02:00
|
|
|
|
|
|
|
// create new session
|
|
|
|
if (i >= MAX_RCCE_SESSIONS)
|
|
|
|
goto out;
|
|
|
|
|
2015-10-19 23:27:24 +02:00
|
|
|
vaddr = vma_alloc(RCCE_MPB_SIZE, VMA_READ|VMA_WRITE|VMA_USER|VMA_CACHEABLE);
|
2015-10-17 12:01:46 +02:00
|
|
|
if (BUILTIN_EXPECT(!vaddr, 0))
|
|
|
|
goto out;
|
|
|
|
|
2015-10-19 23:27:24 +02:00
|
|
|
if (page_map(vaddr, rcce_mpb[i].mpb[ue], RCCE_MPB_SIZE / PAGE_SIZE, PG_RW|PG_USER|PG_PRESENT)) {
|
2015-10-17 12:01:46 +02:00
|
|
|
vma_free(vaddr, vaddr + 2*PAGE_SIZE);
|
|
|
|
goto out;
|
|
|
|
}
|
2015-10-18 10:22:52 +02:00
|
|
|
|
2016-11-04 12:09:43 +01:00
|
|
|
LOG_INFO("Map MPB of session %d at 0x%zx, using of slot %d, isle %d\n", session_id, vaddr, i, ue);
|
2015-10-17 12:01:46 +02:00
|
|
|
|
2016-04-13 22:56:00 +02:00
|
|
|
if (isle == ue)
|
|
|
|
memset((void*)vaddr, 0x0, RCCE_MPB_SIZE);
|
|
|
|
|
2015-10-17 12:01:46 +02:00
|
|
|
return vaddr;
|
2015-10-18 10:22:52 +02:00
|
|
|
|
|
|
|
out:
|
2016-11-04 12:09:43 +01:00
|
|
|
LOG_ERROR("Didn't find a valid MPB for session %d, isle %d\n", session_id, ue);
|
2015-10-18 10:22:52 +02:00
|
|
|
|
|
|
|
return 0;
|
2015-10-17 12:01:46 +02:00
|
|
|
}
|
|
|
|
|
2016-01-26 14:30:00 +01:00
|
|
|
int sys_rcce_fini(int session_id)
|
2015-10-17 12:01:46 +02:00
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
// we have to free the MPB
|
|
|
|
|
2016-08-27 08:16:25 +02:00
|
|
|
if (is_single_kernel())
|
|
|
|
return -ENOSYS;
|
|
|
|
|
2015-10-17 12:01:46 +02:00
|
|
|
if (session_id <= 0)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
islelock_lock(rcce_lock);
|
|
|
|
|
|
|
|
for(i=0; i<MAX_RCCE_SESSIONS; i++)
|
|
|
|
{
|
|
|
|
if (rcce_mpb[i].id == session_id)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i >= MAX_RCCE_SESSIONS) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2016-10-21 00:21:01 +02:00
|
|
|
if (rcce_mpb[i].mpb[isle]) {
|
|
|
|
if (is_hbmem_available())
|
|
|
|
hbmem_put_pages(rcce_mpb[i].mpb[isle], RCCE_MPB_SIZE / PAGE_SIZE);
|
|
|
|
else
|
|
|
|
put_pages(rcce_mpb[i].mpb[isle], RCCE_MPB_SIZE / PAGE_SIZE);
|
|
|
|
}
|
2015-10-17 12:01:46 +02:00
|
|
|
rcce_mpb[i].mpb[isle] = 0;
|
|
|
|
|
2016-04-13 22:56:00 +02:00
|
|
|
for(j=0; (j<MAX_ISLE) && !rcce_mpb[i].mpb[j]; j++) {
|
|
|
|
PAUSE;
|
|
|
|
}
|
2015-10-17 12:01:46 +02:00
|
|
|
|
|
|
|
// rest full session
|
|
|
|
if (j >= MAX_ISLE)
|
|
|
|
rcce_mpb[i].id = 0;
|
|
|
|
|
|
|
|
out:
|
|
|
|
islelock_unlock(rcce_lock);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
size_t sys_get_ticks(void)
|
2015-10-16 07:07:59 +02:00
|
|
|
{
|
|
|
|
return get_clock_tick();
|
|
|
|
}
|
|
|
|
|
2015-12-29 02:22:41 +01:00
|
|
|
int sys_stat(const char* file, /*struct stat *st*/ void* st)
|
|
|
|
{
|
|
|
|
return -ENOSYS;
|
|
|
|
}
|
|
|
|
|
2016-03-12 23:15:36 +01:00
|
|
|
void sys_yield(void)
|
|
|
|
{
|
2016-03-14 17:49:16 +01:00
|
|
|
#if 0
|
|
|
|
check_workqueues();
|
|
|
|
#else
|
|
|
|
if (BUILTIN_EXPECT(go_down, 0))
|
2016-03-14 12:23:32 +01:00
|
|
|
shutdown_system();
|
|
|
|
check_scheduling();
|
2016-03-14 17:49:16 +01:00
|
|
|
#endif
|
2016-03-12 23:15:36 +01:00
|
|
|
}
|
|
|
|
|
2016-08-25 17:15:52 +02:00
|
|
|
int sys_kill(tid_t dest, int signum)
|
|
|
|
{
|
|
|
|
if(signum < 0) {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
return hermit_kill(dest, signum);
|
|
|
|
}
|
|
|
|
|
|
|
|
int sys_signal(signal_handler_t handler)
|
|
|
|
{
|
|
|
|
return hermit_signal(handler);
|
|
|
|
}
|