Skip to content

Commit

Permalink
Merge pull request torvalds#75 from pscollins/more-hostcalls
Browse files Browse the repository at this point in the history
Add additional host calls
  • Loading branch information
Octavian Purdila committed Feb 23, 2016
2 parents 67afa10 + 9b4f5e5 commit 1bffa2f
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 9 deletions.
16 changes: 16 additions & 0 deletions arch/lkl/include/uapi/asm/host_ops.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef _ASM_UAPI_LKL_HOST_OPS_H
#define _ASM_UAPI_LKL_HOST_OPS_H

/* Defined in {posix,nt}-host.c */
struct lkl_mutex_t;

/**
* lkl_host_operations - host operations used by the Linux kernel
*
Expand All @@ -20,6 +23,11 @@
* @sem_up - perform an up operation on the semaphore
* @sem_down - perform a down operation on the semaphore
*
* @mutex_alloc - allocate and initialize a host mutex
* @mutex_free - free a host mutex
* @mutex_lock - acquire the mutex
* @mutex_unlock - release the mutex
*
* @thread_create - create a new thread and run f(arg) in its context; returns a
* thread handle or NULL if the thread could not be created
* @thread_exit - terminates the current thread
Expand All @@ -39,6 +47,8 @@
* iomem_access
* @iomem_acess - reads or writes to and I/O memory region; addr must be in the
* range returned by ioremap
*
* @gettid - returns the host thread id of the caller
*/
struct lkl_host_operations {
const char *virtio_devices;
Expand All @@ -51,6 +61,11 @@ struct lkl_host_operations {
void (*sem_up)(void *sem);
void (*sem_down)(void *sem);

struct lkl_mutex_t *(*mutex_alloc)(void);
void (*mutex_free)(struct lkl_mutex_t *mutex);
void (*mutex_lock)(struct lkl_mutex_t *mutex);
void (*mutex_unlock)(struct lkl_mutex_t *mutex);

int (*thread_create)(void (*f)(void *), void *arg);
void (*thread_exit)(void);

Expand All @@ -67,6 +82,7 @@ struct lkl_host_operations {
int (*iomem_access)(const volatile void *addr, void *val, int size,
int write);

long (*gettid)(void);
};

/**
Expand Down
40 changes: 40 additions & 0 deletions tools/lkl/lib/nt-host.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <lkl_host.h>
#include "iomem.h"

struct lkl_mutex_t {
HANDLE mutex;
};

static void *sem_alloc(int count)
{
return CreateSemaphore(NULL, count, 100, NULL);
Expand All @@ -25,6 +29,32 @@ static void sem_free(void *sem)
CloseHandle(sem);
}

static struct lkl_mutex_t *mutex_alloc(void)
{
struct lkl_mutex_t *_mutex = malloc(sizeof(struct lkl_mutex_t));
if (!_mutex)
return NULL;

_mutex->mutex = CreateMutex(0, FALSE, 0);
return _mutex;
}

static void mutex_lock(struct lkl_mutex_t *mutex)
{
WaitForSingleObject(mutex->mutex, INFINITE);
}

static void mutex_unlock(struct lkl_mutex_t *_mutex)
{
ReleaseMutex(_mutex->mutex);
}

static void mutex_free(struct lkl_mutex_t *_mutex)
{
CloseHandle(_mutex->mutex);
free(_mutex);
}

static int thread_create(void (*fn)(void *), void *arg)
{
DWORD WINAPI (*win_fn)(LPVOID arg) = (DWORD WINAPI (*)(LPVOID))fn;
Expand Down Expand Up @@ -124,6 +154,11 @@ static void print(const char *str, int len)
write(1, str, len);
}

static long gettid(void)
{
return GetCurrentThreadId();
}

static void *mem_alloc(unsigned long size)
{
return malloc(size);
Expand All @@ -137,6 +172,10 @@ struct lkl_host_operations lkl_host_ops = {
.sem_free = sem_free,
.sem_up = sem_up,
.sem_down = sem_down,
.mutex_alloc = mutex_alloc,
.mutex_free = mutex_free,
.mutex_lock = mutex_lock,
.mutex_unlock = mutex_unlock,
.time = time_ns,
.timer_alloc = timer_alloc,
.timer_set_oneshot = timer_set_oneshot,
Expand All @@ -147,6 +186,7 @@ struct lkl_host_operations lkl_host_ops = {
.ioremap = lkl_ioremap,
.iomem_access = lkl_iomem_access,
.virtio_devices = lkl_virtio_devs,
.gettid = gettid,
};

int handle_get_capacity(union lkl_disk disk, unsigned long long *res)
Expand Down
88 changes: 79 additions & 9 deletions tools/lkl/lib/posix-host.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <poll.h>
#include <lkl_host.h>
#include "iomem.h"
Expand All @@ -34,6 +35,10 @@ static void print(const char *str, int len)
ret = write(STDOUT_FILENO, str, len);
}

struct lkl_mutex_t {
pthread_mutex_t mutex;
};

struct pthread_sem {
#ifdef _POSIX_SEMAPHORES
sem_t sem;
Expand All @@ -44,6 +49,19 @@ struct pthread_sem {
#endif /* _POSIX_SEMAPHORES */
};

#define WARN_UNLESS(exp) do { \
if (exp < 0) \
lkl_printf("%s: %s\n", #exp, strerror(errno)); \
} while (0)

/* pthread_* functions use the reverse convention */
#define WARN_PTHREAD(exp) do { \
int __ret = exp; \
if (__ret > 0) \
lkl_printf("%s: %s\n", #exp, strerror(__ret)); \
} while (0)


static void *sem_alloc(int count)
{
struct pthread_sem *sem;
Expand All @@ -61,7 +79,7 @@ static void *sem_alloc(int count)
#else
pthread_mutex_init(&sem->lock, NULL);
sem->count = count;
pthread_cond_init(&sem->cond, NULL);
WARN_PTHREAD(pthread_cond_init(&sem->cond, NULL));
#endif /* _POSIX_SEMAPHORES */

return sem;
Expand All @@ -77,14 +95,13 @@ static void sem_up(void *_sem)
struct pthread_sem *sem = (struct pthread_sem *)_sem;

#ifdef _POSIX_SEMAPHORES
if (sem_post(&sem->sem) < 0)
lkl_printf("sem_post: %s\n", strerror(errno));
WARN_UNLESS(sem_post(&sem->sem));
#else
pthread_mutex_lock(&sem->lock);
WARN_PTHREAD(pthread_mutex_lock(&sem->lock));
sem->count++;
if (sem->count > 0)
pthread_cond_signal(&sem->cond);
pthread_mutex_unlock(&sem->lock);
WARN_PTHREAD(pthread_cond_signal(&sem->cond));
WARN_PTHREAD(pthread_mutex_unlock(&sem->lock));
#endif /* _POSIX_SEMAPHORES */

}
Expand All @@ -101,14 +118,57 @@ static void sem_down(void *_sem)
if (err < 0 && errno != EINTR)
lkl_printf("sem_wait: %s\n", strerror(errno));
#else
pthread_mutex_lock(&sem->lock);
WARN_PTHREAD(pthread_mutex_lock(&sem->lock));
while (sem->count <= 0)
pthread_cond_wait(&sem->cond, &sem->lock);
WARN_PTHREAD(pthread_cond_wait(&sem->cond, &sem->lock));
sem->count--;
pthread_mutex_unlock(&sem->lock);
WARN_PTHREAD(pthread_mutex_unlock(&sem->lock));
#endif /* _POSIX_SEMAPHORES */
}


static struct lkl_mutex_t *mutex_alloc(void)
{
struct lkl_mutex_t *_mutex = malloc(sizeof(struct lkl_mutex_t));
pthread_mutex_t *mutex = NULL;
pthread_mutexattr_t attr;

if (!_mutex)
return NULL;

mutex = &_mutex->mutex;
WARN_PTHREAD(pthread_mutexattr_init(&attr));

/* PTHREAD_MUTEX_ERRORCHECK is *very* useful for debugging,
* but has some overhead, so we provide an option to turn it
* off. */
#ifdef DEBUG
WARN_PTHREAD(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP));
#endif /* DEBUG */

WARN_PTHREAD(pthread_mutex_init(mutex, &attr));

return _mutex;
}

static void mutex_lock(struct lkl_mutex_t *mutex)
{
WARN_PTHREAD(pthread_mutex_lock(&mutex->mutex));
}

static void mutex_unlock(struct lkl_mutex_t *_mutex)
{
pthread_mutex_t *mutex = &_mutex->mutex;
WARN_PTHREAD(pthread_mutex_unlock(mutex));
}

static void mutex_free(struct lkl_mutex_t *_mutex)
{
pthread_mutex_t *mutex = &_mutex->mutex;
WARN_PTHREAD(pthread_mutex_destroy(mutex));
free(_mutex);
}

static int thread_create(void (*fn)(void *), void *arg)
{
pthread_t thread;
Expand Down Expand Up @@ -177,6 +237,11 @@ static void panic(void)
assert(0);
}

static long gettid(void)
{
return syscall(SYS_gettid);
}

struct lkl_host_operations lkl_host_ops = {
.panic = panic,
.thread_create = thread_create,
Expand All @@ -185,6 +250,10 @@ struct lkl_host_operations lkl_host_ops = {
.sem_free = sem_free,
.sem_up = sem_up,
.sem_down = sem_down,
.mutex_alloc = mutex_alloc,
.mutex_free = mutex_free,
.mutex_lock = mutex_lock,
.mutex_unlock = mutex_unlock,
.time = time_ns,
.timer_alloc = timer_alloc,
.timer_set_oneshot = timer_set_oneshot,
Expand All @@ -195,6 +264,7 @@ struct lkl_host_operations lkl_host_ops = {
.ioremap = lkl_ioremap,
.iomem_access = lkl_iomem_access,
.virtio_devices = lkl_virtio_devs,
.gettid = gettid,
};

static int fd_get_capacity(union lkl_disk disk, unsigned long long *res)
Expand Down
51 changes: 51 additions & 0 deletions tools/lkl/tests/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,54 @@ static int test_lo_ifup(char *str, int len)
return TEST_FAILURE;
}

static int test_mutex(char *str, int len)
{
long ret = TEST_SUCCESS;
/* Can't do much to verify that this works, so we'll just let
* Valgrind warn us on CI if we've made bad memory
* accesses. */

struct lkl_mutex_t *mutex = lkl_host_ops.mutex_alloc();
lkl_host_ops.mutex_lock(mutex);
lkl_host_ops.mutex_unlock(mutex);
lkl_host_ops.mutex_free(mutex);

snprintf(str, len, "%ld", ret);

return ret;
}

static int test_semaphore(char *str, int len)
{
long ret = TEST_SUCCESS;
/* Can't do much to verify that this works, so we'll just let
* Valgrind warn us on CI if we've made bad memory
* accesses. */

struct lkl_sem_t *sem = lkl_host_ops.sem_alloc(1);
lkl_host_ops.sem_down(sem);
lkl_host_ops.sem_up(sem);
lkl_host_ops.sem_free(sem);

snprintf(str, len, "%ld", ret);

return ret;
}

static int test_gettid(char *str, int len)
{
long tid = lkl_host_ops.gettid();
snprintf(str, len, "%ld", tid);

/* As far as I know, thread IDs are non-zero on all reasonable
* systems. */
if (tid) {
return TEST_SUCCESS;
} else {
return TEST_FAILURE;
}
}

static struct cl_option *find_short_opt(char name)
{
struct cl_option *opt;
Expand Down Expand Up @@ -722,6 +770,9 @@ int main(int argc, char **argv)
TEST(getdents64);
TEST(umount);
TEST(lo_ifup);
TEST(mutex);
TEST(semaphore);
TEST(gettid);

lkl_sys_halt();

Expand Down

0 comments on commit 1bffa2f

Please sign in to comment.