Imported Upstream version 0.3.111 upstream/0.3.111
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 20 Dec 2021 05:33:56 +0000 (14:33 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 20 Dec 2021 05:33:56 +0000 (14:33 +0900)
22 files changed:
.gitignore [deleted file]
Makefile
harness/Makefile
harness/cases/17.t [new file with mode: 0644]
harness/cases/18.t [new file with mode: 0644]
harness/cases/19.t [new file with mode: 0644]
harness/cases/20.t [new file with mode: 0644]
harness/cases/21.t [new file with mode: 0644]
harness/cases/8.t
libaio.spec
src/libaio.h
src/syscall-alpha.h
src/syscall-arm.h
src/syscall-arm64.h [deleted file]
src/syscall-generic.h
src/syscall-i386.h
src/syscall-ia64.h
src/syscall-ppc.h
src/syscall-s390.h
src/syscall-sparc.h
src/syscall-x86_64.h
src/syscall.h

diff --git a/.gitignore b/.gitignore
deleted file mode 100644 (file)
index d4a4309..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-*.rej
-*.orig
-*~
-/*.patch
-
-*.o
-*.o[ls]
-
-/src/libaio.a
-/src/libaio.so*
index 4cedbc9..e9dbdb0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,7 @@
 NAME=libaio
 SPECFILE=$(NAME).spec
 VERSION=$(shell awk '/Version:/ { print $$2 }' $(SPECFILE))
-RELEASE=$(shell awk '/Release:/ { print $$2 }' $(SPECFILE))
-CVSTAG = $(NAME)_$(subst .,-,$(VERSION))_$(subst .,-,$(RELEASE))
+TAG = $(NAME)-$(VERSION)
 RPMBUILD=$(shell `which rpmbuild >&/dev/null` && echo "rpmbuild" || echo "rpm")
 
 prefix=/usr
@@ -28,17 +27,10 @@ clean:
        @$(MAKE) -C harness clean
 
 tag-archive:
-       @cvs -Q tag -F $(CVSTAG)
-
-create-archive: tag-archive
-       @rm -rf /tmp/$(NAME)
-       @cd /tmp; cvs -Q -d $(CVSROOT) export -r$(CVSTAG) $(NAME) || echo GRRRrrrrr -- ignore [export aborted]
-       @mv /tmp/$(NAME) /tmp/$(NAME)-$(VERSION)
-       @cd /tmp; tar czSpf $(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION)
-       @rm -rf /tmp/$(NAME)-$(VERSION)
-       @cp /tmp/$(NAME)-$(VERSION).tar.gz .
-       @rm -f /tmp/$(NAME)-$(VERSION).tar.gz 
-       @echo " "
+       @git tag $(TAG)
+
+create-archive:
+       @git archive --prefix=$(NAME)-$(VERSION)/ -o $(NAME)-$(VERSION).tar.gz $(TAG)
        @echo "The final archive is ./$(NAME)-$(VERSION).tar.gz."
 
 archive: clean tag-archive create-archive
index 2a88e71..f477737 100644 (file)
@@ -6,13 +6,13 @@ PROGS:=$(PARTPROGS) $(EXTRAPROGS)
 HARNESS_SRCS:=main.c
 # io_queue.c
 
-CFLAGS+=-Wall -Werror -I../src -g -O
+CFLAGS+=-Wall -Werror -I../src -g -O2 -DPAGE_SIZE=$(shell getconf PAGESIZE)
 #-lpthread -lrt
 
 all: $(PROGS)
 
 $(PROGS): %.p: %.t $(HARNESS_SRCS)
-       $(CC) $(CFLAGS) -DTEST_NAME=\"$<\" -o $@ main.c ../src/libaio.a
+       $(CC) $(CFLAGS) -DTEST_NAME=\"$<\" -o $@ main.c ../src/libaio.a -lpthread
 
 clean:
        rm -f $(PROGS) *.o runtests.out rofile wofile rwfile
diff --git a/harness/cases/17.t b/harness/cases/17.t
new file mode 100644 (file)
index 0000000..38ada4d
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2014, Dan Aloni, Kernelim Ltd.
+ * Copyright (C) 2014, Benjamin LaHaise <bcrl@kvack.org>.
+ * Copyright (C) 2014, Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Description:
+ *   This regression test ensures that submitting more events than can
+ *   fit in the completion ring will not result in a hung task.
+ */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+#include <assert.h>
+#include <errno.h>
+#include <libaio.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+const int max_events = 32;
+const int io_size = 0x1000;
+struct iocb *io;
+struct iocb **iops;
+struct iovec *iovecs;
+struct io_event *events;
+char *data;
+
+long submitted = 0;
+long completed = 0;
+long pending = 0;
+
+#define SYS_IO_GETEVENTS 0
+#define USER_GETEVENTS 1
+
+static volatile sig_atomic_t done = 0;
+
+struct aio_ring {
+       unsigned        id;     /* kernel internal index number */
+       unsigned        nr;     /* number of io_events */
+       volatile unsigned       head;
+       volatile unsigned       tail;
+
+       unsigned        magic;
+       unsigned        compat_features;
+       unsigned        incompat_features;
+       unsigned        header_length;  /* size of aio_ring */
+
+       struct io_event io_events[0];
+};
+
+int get_ring_size(int nr_events)
+{
+       io_context_t ctx;
+       int ret, ring_size;
+       struct aio_ring *ring;
+
+       memset(&ctx, 0, sizeof(ctx));
+       ret = io_setup(nr_events, &ctx);
+       assert(!ret);
+
+       ring = (void *)ctx;
+       ring_size = ring->nr;
+
+       ret = io_destroy(ctx);
+       assert(!ret);
+
+       return ring_size;
+}
+
+int user_getevents(io_context_t ctx, int nr_events, struct io_event *event)
+{
+       struct aio_ring *ring = (void *)ctx;
+       int completed = 0;
+       while ((completed < nr_events) && (ring->head != ring->tail)) {
+               unsigned new_head = ring->head;
+               *event = ring->io_events[new_head];
+               new_head += 1;
+               new_head %= ring->nr;
+               ring->head = new_head;
+               completed++;
+       }
+       return completed;
+}
+
+void prune(io_context_t io_ctx, int max_ios, int getevents_type)
+{
+       int ret;
+
+       if (getevents_type == USER_GETEVENTS)
+               ret = user_getevents(io_ctx, max_ios, events);
+       else
+               ret = io_getevents(io_ctx, pending, max_ios, events, NULL);
+       if (ret > 0) {
+               printf("Completed: %d\n", ret);
+               completed += ret;
+               pending -= ret;
+       }
+}
+
+void run_test(int max_ios, int getevents_type)
+{
+       int fd, ret;
+       long i, to_submit;
+       struct iocb **iocb_sub;
+       io_context_t io_ctx;
+       const char *filename = "testfile";
+
+       printf("MAX_IOS: %d, %s\n", max_ios, getevents_type == USER_GETEVENTS ?
+              "USER_GETEVENTS" : "IO_GETEVENTS");
+       memset(&io_ctx, 0, sizeof(io_ctx));
+       ret = io_setup(max_events, &io_ctx);
+       assert(!ret);
+
+       io = calloc(max_ios, sizeof(*io));
+       iops = calloc(max_ios, sizeof(*iops));
+       iovecs = calloc(max_ios, sizeof(*iovecs));
+       events = calloc(max_ios, sizeof(*events));
+
+       unlink(filename);
+       fd = open(filename, O_CREAT | O_RDWR | O_DIRECT, 0644);
+       assert(fd >= 0);
+
+       ret = ftruncate(fd, max_ios * io_size);
+       assert(!ret);
+
+       data = mmap(NULL, io_size * max_ios, PROT_READ | PROT_WRITE,
+                   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+       assert(data != MAP_FAILED);
+
+       for (i = 0; i < max_ios; i++) {
+               iops[i] = &io[i];
+               io[i].data = io;
+               iovecs[i].iov_base = &data[io_size * i];
+               iovecs[i].iov_len = io_size;
+               io_prep_preadv(&io[i], fd, &iovecs[i], 1, 0);
+       }
+
+       submitted = completed = pending = 0;
+
+       to_submit = max_ios;
+       iocb_sub = iops;
+
+       while (submitted < max_ios) {
+               printf("Submitting: %ld\n", to_submit);
+
+               ret = io_submit(io_ctx, to_submit, iocb_sub);
+               if (ret >= 0) {
+                       printf("Submitted: %d\n", ret);
+                       submitted += ret;
+                       iocb_sub += ret;
+                       pending += ret;
+                       to_submit -= ret;
+               } else {
+                       if (ret == -EAGAIN) {
+                               printf("Submitted too much, that's okay\n");
+                               prune(io_ctx, max_ios, getevents_type);
+                       }
+               }
+       }
+
+       prune(io_ctx, max_ios, getevents_type);
+       io_destroy(io_ctx);
+       close(fd);
+       ret = munmap(data, io_size * max_ios);
+       assert(!ret);
+
+       printf("Verifying...\n");
+
+       assert(completed == submitted);
+
+       printf("OK\n");
+}
+
+void run_child(void)
+{
+       int ring_size;
+
+       ring_size = get_ring_size(max_events);
+
+       printf("aio ring size: %d\n", ring_size);
+
+       run_test(ring_size-1, SYS_IO_GETEVENTS);
+       run_test(ring_size, SYS_IO_GETEVENTS);
+       run_test(ring_size+1, SYS_IO_GETEVENTS);
+       run_test(ring_size*2, SYS_IO_GETEVENTS);
+       run_test(ring_size*4, SYS_IO_GETEVENTS);
+
+       run_test(ring_size-1, USER_GETEVENTS);
+       run_test(ring_size, USER_GETEVENTS);
+       run_test(ring_size+1, USER_GETEVENTS);
+       run_test(ring_size*2, USER_GETEVENTS);
+       run_test(ring_size*4, USER_GETEVENTS);
+
+       exit(0);
+}
+
+void sighandler(int signo)
+{
+       assert(signo == SIGCHLD);
+       done = 1;
+}
+
+int test_main(void)
+{
+       unsigned int ret;
+       sighandler_t oldhandler;
+       pid_t child;
+
+       switch (child = fork()) {
+       case 0: /* child */
+               run_child();
+               break;
+       case -1:
+               perror("fork");
+               exit(1);
+       default:
+               oldhandler = signal(SIGCHLD, sighandler);
+               assert(oldhandler != SIG_ERR);
+               break;
+       }
+
+       ret = sleep(10);
+       if (ret != 0) {
+               pid_t pid;
+               int status;
+
+               assert(done);
+
+               pid = wait(&status);
+               if (pid != child) {
+                       perror("wait");
+                       exit(1);
+               }
+
+               return WEXITSTATUS(status);
+       }
+
+       return 1; /* failed */
+}
+/*
+ * Local Variables:
+ *  mode: c
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/harness/cases/18.t b/harness/cases/18.t
new file mode 100644 (file)
index 0000000..5587ceb
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+/*
+ * Author: Anatol Pomozov <anatol.pomozov@gmail.com>
+ *
+ * Description: This code tests to make sure that when io_destroy
+ * returns, all outstanding I/Os have been completed.  It does this by
+ * issuing one I/O and then calling io_destroy (without calling
+ * io_getevents).  After the call to io_destroy, the buffer is checked
+ * to ensure that the data was retrieved.  This is done simultaneously
+ * from 100 threads.
+ */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+#include <libaio.h>
+#include <stdbool.h>
+
+#define FILENAME "tempfile"
+#define FILEPATTERN '1'
+#define DESTROY_PATTERN '2'
+
+#define THREADS_NUM 100
+
+void
+aio_worker(void *ptr)
+{
+       int i, j, fd;
+       char buffer[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
+
+       fd = open(FILENAME, O_DIRECT|O_RDONLY);
+       assert(fd >= 0);
+
+       for (i = 0; i < 1000; i++) {
+               io_context_t ctx;
+               struct iocb cb;
+               struct iocb *cbs[1];
+
+               assert(!io_queue_init(1, &ctx));
+               io_prep_pread(&cb, fd, buffer, PAGE_SIZE, 0);
+               cbs[0] = &cb;
+
+               memset(buffer, '0', PAGE_SIZE);
+               assert(io_submit(ctx, 1, &cbs[0]) == 1);
+               // wait random time (0-500ms) ?
+
+               io_destroy(ctx);
+               memset(buffer, DESTROY_PATTERN, PAGE_SIZE);
+               // wait random for (0-500ms) ?
+
+               // check it is still DESTROY_PATTERN
+               for (j = 0; j < PAGE_SIZE; j++) {
+                       if (buffer[j] != DESTROY_PATTERN) {
+                               fprintf(stderr,
+                                       "Buffer has unexpected character: %c\n",
+                                       buffer[j]);
+                               exit(EXIT_FAILURE);
+                       }
+               }
+       }
+
+       close(fd);
+}
+
+int
+test_main(void)
+{
+       int i, fd, ret;
+       char buffer[PAGE_SIZE];
+       pthread_t threads[THREADS_NUM];
+
+       fd = open(FILENAME, O_CREAT|O_TRUNC|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR);
+       assert(fd != -1);
+
+       memset(buffer, FILEPATTERN, PAGE_SIZE);
+       ret = write(fd, buffer, PAGE_SIZE);
+       assert(ret == PAGE_SIZE);
+       close(fd);
+
+       for (i = 0; i < THREADS_NUM; i++) {
+               ret = pthread_create(&threads[i], NULL,
+                                    (void *)&aio_worker, NULL);
+               assert(ret == 0);
+       }
+       for (i = 0; i < THREADS_NUM; i++) {
+               ret = pthread_join(threads[i], NULL);
+               assert(ret == 0);
+       }
+
+       return EXIT_SUCCESS;
+}
+/*
+ * Local Variables:
+ *  mode: c
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/harness/cases/19.t b/harness/cases/19.t
new file mode 100644 (file)
index 0000000..4989510
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2015, Red Hat, Inc.
+ *
+ * This test remaps the aio ring buffer and ensures that I/O completions
+ * can still be reaped from userspace.
+ *
+ * Author: Jeff Moyer <jmoyer@redhat.com>
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <sched.h>
+#include <libaio.h>
+
+#define BUFLEN 4096
+#define TEMPLATE "19.XXXXXX"
+
+volatile sig_atomic_t timed_out = 0;
+
+struct aio_ring {
+       unsigned        id;     /* kernel internal index number */
+       unsigned        nr;     /* number of io_events */
+       volatile unsigned       head;
+       volatile unsigned       tail;
+
+       unsigned        magic;
+       unsigned        compat_features;
+       unsigned        incompat_features;
+       unsigned        header_length;  /* size of aio_ring */
+
+       struct io_event io_events[0];
+};
+
+int
+open_temp_file(void)
+{
+       int fd;
+       char template[sizeof(TEMPLATE)];
+
+       strncpy(template, TEMPLATE, sizeof(TEMPLATE));
+       fd = mkostemp(template, O_DIRECT);
+       if (fd < 0) {
+               perror("mkstemp");
+               exit(1);
+       }
+       unlink(template);
+       return fd;
+}
+
+/*
+ * mmap will do the address space search for us.  when remapping the ring,
+ * the use of MREMAP_FIXED will cause this mapping to be unmapped.
+ *
+ * len - length in bytes
+ *
+ * Returns the available virtual address, or MAP_FAILED on error.
+ */
+void *
+find_unused_va(size_t len)
+{
+       return mmap(0, len, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+}
+
+void
+alarm_handler(int __attribute__((unused))signo)
+{
+       timed_out = 1;
+}
+
+int
+user_getevents(io_context_t ctx, int nr_events, struct io_event *event)
+{
+       struct aio_ring *ring = (void *)ctx;
+       int completed = 0;
+
+       timed_out = 0;
+       signal(SIGALRM, alarm_handler);
+       alarm(30);
+
+       while ((completed < nr_events) && !timed_out) {
+               unsigned new_head;
+
+               if (ring->head == ring->tail) {
+                       sched_yield();
+                       continue;
+               }
+
+               new_head = ring->head;
+               *event = ring->io_events[new_head];
+               new_head += 1;
+               new_head %= ring->nr;
+               ring->head = new_head;
+               completed++;
+       }
+
+       alarm(0);
+       signal(SIGALRM, SIG_DFL);
+
+       return completed;
+}
+
+struct aio_ring *
+remap_ring(struct aio_ring *ring)
+{
+       struct aio_ring *new_ring;
+       size_t ring_size;
+
+       /*
+        * No need to round up to page size as ring->nr was adjusted
+        * already to fill the last page in the ring.
+        */
+       ring_size = sizeof(struct aio_ring) + ring->nr * sizeof(struct io_event);
+
+       /*
+        * Remap the ring.
+        */
+       new_ring = find_unused_va(ring_size);
+       if (new_ring == MAP_FAILED) {
+               fprintf(stderr, "Unable to find suitable va for ring\n");
+               return NULL;
+       }
+
+       new_ring = mremap(ring, ring_size, ring_size,
+                         MREMAP_FIXED|MREMAP_MAYMOVE, new_ring);
+       if (new_ring == MAP_FAILED || new_ring == ring) {
+               perror("mremap");
+               return NULL;
+       }
+
+       return new_ring;
+}
+
+io_context_t
+remap_io_context(io_context_t ctx)
+{
+       struct aio_ring *ring, *new_ring;
+
+       ring = (void *)ctx;
+       new_ring = remap_ring(ring);
+       if (!new_ring)
+               return NULL;
+
+       ctx = (io_context_t)new_ring;
+       return ctx;
+}
+
+int
+do_io(io_context_t ctx, struct iocb *iocbp, int fd)
+{
+       int ret;
+       char buf[BUFLEN];
+
+       io_prep_pwrite(iocbp, fd, buf, BUFLEN, 0);
+       ret = io_submit(ctx, 1, &iocbp);
+       if (ret != 1) {
+               fprintf(stderr, "io_submit failed with %d\n", ret);
+               return 1;
+       }
+       return 0;
+}
+
+int
+check_completion(io_context_t ctx, struct iocb *iocbp)
+{
+       int ret;
+       struct io_event event;
+
+       ret = user_getevents(ctx, 1, &event);
+       if (ret != 1) {
+               fprintf(stderr, "user_getevents timed out.\n");
+               return 1;
+       }
+
+       if (event.obj != iocbp) {
+               fprintf(stderr,
+                       "Error: event->opj (%p) does not match iocbp (%p)\n",
+                       event.obj, iocbp);
+               return 1;
+       }
+
+       return 0;
+}
+
+int
+test_main()
+{
+       int fd;
+       int ret;
+       io_context_t ctx;
+       struct iocb iocb;
+
+       memset(&ctx, 0, sizeof(ctx));
+       fd = open_temp_file();
+
+       ret = io_setup(1, &ctx);
+       if (ret != 0) {
+               fprintf(stderr, "io_setup failed with %d\n", ret);
+               return 1;
+       }
+
+       /*
+        * First, try remapping the ring buffer in-between io_setup and
+        * io_submit.
+        */
+       ctx = remap_io_context(ctx);
+       if (ctx == NULL)
+               return 1;
+
+       ret = do_io(ctx, &iocb, fd);
+       if (ret != 0)
+               return 1;
+
+       ret = check_completion(ctx, &iocb);
+       if (ret != 0)
+               return 1;
+
+       /*
+        * Now remap the ring in between io_submit and getevents.
+        */
+       ret = do_io(ctx, &iocb, fd);
+       if (ret != 0)
+               return 1;
+
+       ctx = remap_io_context(ctx);
+       if (ctx == NULL)
+               return 1;
+
+       ret = check_completion(ctx, &iocb);
+       if (ret != 0)
+               return 1;
+
+       /*
+        * Success, clean up.
+        */
+       ret = io_destroy(ctx);
+       if (ret != 0) {
+               fprintf(stderr, "io_destroy failed with %d\n", ret);
+               return 1;
+       }
+       close(fd);
+
+       return 0;
+}
+/*
+ * Local variables:
+ *  mode: c
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/harness/cases/20.t b/harness/cases/20.t
new file mode 100644 (file)
index 0000000..3b444c0
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2017, Red Hat, Inc.
+ * Author: Jeff Moyer <jmoyer@redhat.com>
+ * Based on test code from Mauricio Faria de Oliveira
+ *                        <mauricfo@linux.vnet.ibm.com>
+ * License: GPLv2
+ *
+ * Description: Ensure that aio-max-nr requests can be allocated, or,
+ * if not, that the reason is not faulty accounting.
+ */
+#include <libaio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#define FAIL 1
+
+#define AIO_MAX_NR     "/proc/sys/fs/aio-max-nr"
+#define AIO_NR         "/proc/sys/fs/aio-nr"
+
+static unsigned aio_max_nr;
+
+int
+read_proc_val(const char *path, unsigned *val)
+{
+       FILE *fp;
+       int ret;
+
+       fp = fopen(path, "r");
+       if (!fp) {
+               fprintf(stderr, "Unable to open proc file \"%s\" for reading\n",
+                       path);
+               return FAIL;
+       }
+
+       ret = fscanf(fp, "%u\n", val);
+       fclose(fp);
+
+       if (ret == EOF) {
+               fprintf(stderr, "Failed to read from proc file \"%s\"\n",
+                       path);
+               return FAIL;
+       }
+
+       return 0;
+}
+
+/*
+ * Create as many ioctx-s with nr_events each as possible (up to aio_max_nr).
+ * Report any failures of -EAGAIN.
+ */
+int
+do_alloc_ioctxs(int nr_events)
+{
+       long ret;
+       unsigned i, avail, aio_nr, nr_ctxs;
+       io_context_t *ioctx;
+
+       ret = read_proc_val(AIO_NR, &aio_nr);
+       if (ret)
+               return FAIL;
+
+       avail = aio_max_nr - aio_nr;
+       nr_ctxs = avail / nr_events;
+       ioctx = calloc(nr_ctxs, sizeof(*ioctx));
+       if (!ioctx) {
+               fprintf(stderr, "allocating %u ioctx-s failed with %d\n",
+                       nr_ctxs, errno);
+               return FAIL;
+       }
+
+       fprintf(stderr, "Creating %u ioctx-s with %u events each...\n", nr_ctxs,
+               nr_events);
+       fflush(stderr);
+       for (i = 0; i < nr_ctxs; i++) {
+               ret = io_setup(nr_events, &ioctx[i]);
+               if (ret) {
+                       /*
+                        * EAGAIN is the only failure case we're interested
+                        * in.  -ENOMEM, for example, is expected in this
+                        * test.
+                        */
+                       if (ret != -EAGAIN)
+                               break;
+
+                       fprintf(stderr,"io_setup(%u) failed on iteration %d.\n",
+                               nr_events, i);
+                       fprintf(stderr, "allocated %u of %u possible events.\n",
+                               nr_events * i, aio_max_nr);
+                       ret = read_proc_val(AIO_NR, &aio_nr);
+                       if (ret == 0)
+                               fprintf(stderr, "aio_nr is currently at %u\n",
+                                       aio_nr);
+
+                       free(ioctx);
+                       return FAIL;
+               }
+       }
+       fprintf(stderr, "Successfully created %u io_context-s\n", i);
+       if (i < nr_ctxs - 1)
+               fprintf(stderr, "Last io_setup call returned %ld (%s)\n", ret,
+                       strerror(-ret));
+       fflush(stderr);
+
+       return 0;
+}
+
+/*
+ * We fork off a child to do the actual work.  The reason is that each
+ * io_destroy will incur an rcu grace period to complete.  That really
+ * adds up, depending on the number of io_contexts created.  We take
+ * advantage of an optimization in the kernel that waits for all
+ * contexts to be torn down in one grace period.  In other words, just
+ * exiting the process without tearing down the ioctx-s using
+ * io_destroy is way faster.
+ */
+int
+alloc_ioctxs(int nr_events)
+{
+       pid_t child;
+       int ret, status;
+
+       child = fork();
+       switch (child) {
+       case 0: /* child */
+               ret = do_alloc_ioctxs(nr_events);
+               exit(ret);
+       case -1:
+               fprintf(stderr, "fork() failed with %d\n", errno);
+               return FAIL;
+       default:
+               break;
+       }
+       if (waitpid(child, &status, 0) < 0)
+               return FAIL;
+       if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
+               return 0;
+
+       return FAIL;
+}
+
+int
+test_main()
+{
+       int ret;
+       unsigned nr_events;
+
+       ret = read_proc_val(AIO_MAX_NR, &aio_max_nr);
+       if (ret)
+               return FAIL;
+
+       fprintf(stderr, "aio_max_nr: %u\n", aio_max_nr);
+
+       nr_events = 1;
+       while (1) {
+               ret = alloc_ioctxs(nr_events);
+               if (ret)
+                       return FAIL;
+
+               if (nr_events == aio_max_nr)
+                       break;
+
+               nr_events *= 2;
+               if (nr_events > aio_max_nr)
+                       nr_events = aio_max_nr;
+       }
+
+       return 0;
+}
+/*
+ * Local variables:
+ *  mode: c
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/harness/cases/21.t b/harness/cases/21.t
new file mode 100644 (file)
index 0000000..441eaa8
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2017, Red Hat, Inc.
+ *
+ * Test RWF_NOWAIT.
+ *
+ * RWF_NOWAIT will cause -EAGAIN to be returned in the io_event for
+ * any I/O that cannot be serviced without blocking the submission
+ * thread.  Instances covered by the kernel at the time this test was
+ * written include:
+ * - O_DIRECT I/O to a file offset that has populated page cache pages
+ * - the submission context cannot obtain the inode lock
+ * - space allocation is necessary
+ * - we need to wait for other I/O (e.g. in the misaligned I/O case)
+ * - ...
+ *
+
+ * The easiest of these to test is that a direct I/O is writing to a
+ * file offset with populated page cache.  We also test to ensure that
+ * we can perform I/O in the absence of the above conditions.
+ *
+ * Author: Jeff Moyer <jmoyer@redhat.com>
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <sched.h>
+#include <libaio.h>
+
+#define TEMPLATE "21.XXXXXX"
+#define BUFLEN 4096
+
+#ifndef RWF_NOWAIT
+#define RWF_NOWAIT     0x00000008
+#endif
+
+int
+open_temp_file()
+{
+       int fd;
+       char temp_file[sizeof(TEMPLATE)];
+
+       strncpy(temp_file, TEMPLATE, sizeof(TEMPLATE));
+       fd = mkstemp(temp_file);
+       if (fd < 0) {
+               perror("mkstemp");
+               return -1;
+       }
+       unlink(temp_file);
+       return fd;
+}
+
+int
+test_main()
+{
+       int fd, flags;
+       int ret;
+       io_context_t ctx;
+       struct iocb iocb, *iocbp = &iocb;
+       struct io_event event;
+       char buf[BUFLEN] __attribute__((aligned (4096)));
+       struct iovec iov;
+
+       fd = open_temp_file();
+       if (fd < 0)
+               return 1;
+
+       memset(&ctx, 0, sizeof(ctx));
+       ret = io_setup(1, &ctx);
+       if (ret != 0) {
+               fprintf(stderr, "io_setup failed with %d\n", ret);
+               return 1;
+       }
+
+       /*
+        * Perform a buffered write to a file.  This instantiates the
+        * block and adds the page to the page cache.
+        */
+       memset(buf, 0xa, BUFLEN);
+       ret = write(fd, buf, BUFLEN);
+       if (ret != BUFLEN) {
+               perror("write");
+               return 1;
+       }
+
+       /*
+        * Now attempt an aio/dio pwritev2 with the RWF_NONBLOCK flag
+        * set.
+        */
+       flags = fcntl(fd, F_GETFL);
+       ret = fcntl(fd, F_SETFL, flags | O_DIRECT);
+       if (ret != 0) {
+               perror("fcntl");
+               return 1;
+       }
+
+       memset(buf, 0, BUFLEN);
+       iov.iov_base = buf;
+       iov.iov_len = BUFLEN;
+       io_prep_preadv2(&iocb, fd, &iov, 1, 0, RWF_NOWAIT);
+
+       ret = io_submit(ctx, 1, &iocbp);
+
+       /*
+        * io_submit will return -EINVAL if RWF_NOWAIT is not supported.
+        */
+       if (ret != 1) {
+               if (ret == -EINVAL) {
+                       fprintf(stderr, "RWF_NOWAIT not supported by kernel.\n");
+                       /* just return success */
+                       return 0;
+               }
+               errno = -ret;
+               perror("io_submit");
+               return 1;
+       }
+
+       ret = io_getevents(ctx, 1, 1, &event, NULL);
+       if (ret != 1) {
+               errno = -ret;
+               perror("io_getevents");
+               return 1;
+       }
+
+       /*
+        * We expect -EAGAIN due to the existence of a page cache page
+        * for the file system block we are writing.
+        */
+       if (event.res != -EAGAIN) {
+               fprintf(stderr, "Expected -EAGAIN, got %lu\n", event.res);
+               return 1;
+       }
+
+       /*
+        * An O_DIRECT write to the page will force the page out of the
+        * page cache, allowing the subsequent RWF_NOWAIT I/O to complete.
+        */
+       ret = pwrite(fd, buf, BUFLEN, 0);
+       if (ret != BUFLEN) {
+               perror("write");
+               return 1;
+       }
+
+       /*
+        * Now retry the RWF_NOWAIT I/O.  This should succeed.
+        */
+       ret = io_submit(ctx, 1, &iocbp);
+       if (ret != 1) {
+               errno = -ret;
+               perror("io_submit");
+               return 1;
+       }
+
+       ret = io_getevents(ctx, 1, 1, &event, NULL);
+       if (ret != 1) {
+               errno = -ret;
+               perror("io_getevents");
+               return 1;
+       }
+
+       if (event.res != BUFLEN) {
+               fprintf(stderr, "Expected %d, got %lu\n", BUFLEN, event.res);
+               return 1;
+       }
+
+       return 0;
+}
+/*
+ * Local variables:
+ *  mode: c
+ *  c-basic-offset: 8
+ * End:
+ */
index e59199f..dbcf044 100644 (file)
@@ -9,12 +9,14 @@ long long get_fs_limit(int fd)
 {
        long long min = 0, max = 9223372036854775807LL;
        char c = 0;
+       int ret;
 
        while (max - min > 1) {
                if (pwrite64(fd, &c, 1, (min + max) / 2) == -1)
                        max = (min + max) / 2;
                else {
-                       ftruncate(fd, 0);
+                       ret = ftruncate(fd, 0);
+                       assert(ret == 0);
                        min = (min + max) / 2;
                }
        }
index dfe97fd..455bb6b 100644 (file)
@@ -1,5 +1,5 @@
 Name: libaio
-Version: 0.3.110
+Version: 0.3.111
 Release: 1
 Summary: Linux-native asynchronous I/O access library
 License: LGPL
@@ -59,6 +59,22 @@ make install prefix=$RPM_BUILD_ROOT/usr \
 %attr(0644,root,root) %{_libdir}/libaio.a
 
 %changelog
+* Tue Mar  6 2018 Jeff Moyer <jmoyer@redhat.com> - 0.3.111-1
+- Add two new tests to the test harness (Jeff Moyer)
+- Generic arch dectection for padding defines (Nathan Rossi)
+- harness: don't hardcode page size (Jeff Moyer)
+- harness: add a test case for mremap (Jeff Moyer)
+- libaio: harness: fix build errors due to attribute warn_unused_result (Mauricio Faria de Oliveira)
+- libaio: harness: fix build error due to linker search order (Mauricio Faria de Oliveira)
+- harness: add test for allocating aio-max-nr ioctxs (Jeff Moyer)
+- Add support for preadv2/pwritev2 (Jeff Moyer)
+- syscall-generic: don't overwrite errno (Jeff Moyer)
+- syscall: get rid of custom syscall implementation (Jeff Moyer)
+- Change syscall-arm64.h to syscall-generic.h (Icenowy Zheng)
+- Use generic syscall number schema for RISC-V (Icenowy Zheng)
+- Add endian detection (LE) and bit width detection (32/64) for RISC-V (Icenowy Zheng)
+- Makefile: convert tag and archive targets to git (Jeff Moyer)
+
 * Fri Jul  5 2013 Jeff Moyer <jmoyer@redhat.com> - 0.3.110-1
 - Add suport for sparc and arm64 (Mike Frysinger and Jeff Moyer)
 - Add generic syscall fallbacks (Mike Frysinger)
index 1223146..564e680 100644 (file)
@@ -52,14 +52,19 @@ typedef enum io_iocb_cmd {
 /* little endian, 32 bits */
 #if defined(__i386__) || (defined(__arm__) && !defined(__ARMEB__)) || \
     defined(__sh__) || defined(__bfin__) || defined(__MIPSEL__) || \
-    defined(__cris__)
+    defined(__cris__) || (defined(__riscv) && __riscv_xlen == 32) || \
+    (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
+         __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_LONG__ == 4)
 #define PADDED(x, y)   x; unsigned y
 #define PADDEDptr(x, y)        x; unsigned y
 #define PADDEDul(x, y) unsigned long x; unsigned y
 
 /* little endian, 64 bits */
 #elif defined(__ia64__) || defined(__x86_64__) || defined(__alpha__) || \
-      (defined(__aarch64__) && defined(__AARCH64EL__))
+      (defined(__aarch64__) && defined(__AARCH64EL__)) || \
+      (defined(__riscv) && __riscv_xlen == 64) || \
+      (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
+          __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_LONG__ == 8)
 #define PADDED(x, y)   x, y
 #define PADDEDptr(x, y)        x
 #define PADDEDul(x, y) unsigned long x
@@ -67,7 +72,9 @@ typedef enum io_iocb_cmd {
 /* big endian, 64 bits */
 #elif defined(__powerpc64__) || defined(__s390x__) || \
       (defined(__sparc__) && defined(__arch64__)) || \
-      (defined(__aarch64__) && defined(__AARCH64EB__))
+      (defined(__aarch64__) && defined(__AARCH64EB__)) || \
+      (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
+           __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_LONG__ == 8)
 #define PADDED(x, y)   unsigned y; x
 #define PADDEDptr(x,y) x
 #define PADDEDul(x, y) unsigned long x
@@ -76,7 +83,9 @@ typedef enum io_iocb_cmd {
 #elif defined(__PPC__) || defined(__s390__) || \
       (defined(__arm__) && defined(__ARMEB__)) || \
       defined(__sparc__) || defined(__MIPSEB__) || defined(__m68k__) || \
-      defined(__hppa__) || defined(__frv__) || defined(__avr32__)
+      defined(__hppa__) || defined(__frv__) || defined(__avr32__) || \
+      (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
+           __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_LONG__ == 4)
 #define PADDED(x, y)   unsigned y; x
 #define PADDEDptr(x, y)        unsigned y; x
 #define PADDEDul(x, y) unsigned y; unsigned long x
@@ -111,7 +120,9 @@ struct io_iocb_vector {
 
 struct iocb {
        PADDEDptr(void *data, __pad1);  /* Return in the io completion event */
-       PADDED(unsigned key, __pad2);   /* For use in identifying io requests */
+       /* key: For use in identifying io requests */
+       /* aio_rw_flags: RWF_* flags (such as RWF_NOWAIT) */
+       PADDED(unsigned key, aio_rw_flags);
 
        short           aio_lio_opcode; 
        short           aio_reqprio;
@@ -202,6 +213,30 @@ static inline void io_prep_pwritev(struct iocb *iocb, int fd, const struct iovec
        iocb->u.c.offset = offset;
 }
 
+static inline void io_prep_preadv2(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset, int flags)
+{
+       memset(iocb, 0, sizeof(*iocb));
+       iocb->aio_fildes = fd;
+       iocb->aio_lio_opcode = IO_CMD_PREADV;
+       iocb->aio_reqprio = 0;
+       iocb->aio_rw_flags = flags;
+       iocb->u.c.buf = (void *)iov;
+       iocb->u.c.nbytes = iovcnt;
+       iocb->u.c.offset = offset;
+}
+
+static inline void io_prep_pwritev2(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset, int flags)
+{
+       memset(iocb, 0, sizeof(*iocb));
+       iocb->aio_fildes = fd;
+       iocb->aio_lio_opcode = IO_CMD_PWRITEV;
+       iocb->aio_reqprio = 0;
+       iocb->aio_rw_flags = flags;
+       iocb->u.c.buf = (void *)iov;
+       iocb->u.c.nbytes = iovcnt;
+       iocb->u.c.offset = offset;
+}
+
 /* Jeff Moyer says this was implemented in Red Hat AS2.1 and RHEL3.
  * AFAICT, it was never in mainline, and should not be used. --RR */
 static inline void io_prep_poll(struct iocb *iocb, int fd, int events)
index 467b74f..0aa4d3d 100644 (file)
@@ -3,207 +3,3 @@
 #define __NR_io_getevents      400
 #define __NR_io_submit         401
 #define __NR_io_cancel         402
-
-#define inline_syscall_r0_asm
-#define inline_syscall_r0_out_constraint        "=v"
-
-#define inline_syscall_clobbers                    \
-   "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \
-   "$22", "$23", "$24", "$25", "$27", "$28", "memory"
-
-#define inline_syscall0(name, args...)                          \
-{                                                               \
-        register long _sc_0 inline_syscall_r0_asm;              \
-        register long _sc_19 __asm__("$19");                    \
-                                                                \
-        _sc_0 = name;                                           \
-        __asm__ __volatile__                                    \
-          ("callsys # %0 %1 <= %2"                              \
-          : inline_syscall_r0_out_constraint (_sc_0),          \
-             "=r"(_sc_19)                                       \
-          : "0"(_sc_0)                                         \
-          : inline_syscall_clobbers,                           \
-             "$16", "$17", "$18", "$20", "$21");                \
-        _sc_ret = _sc_0, _sc_err = _sc_19;                      \
-}
-
-#define inline_syscall1(name,arg1)                              \
-{                                                               \
-        register long _sc_0 inline_syscall_r0_asm;              \
-        register long _sc_16 __asm__("$16");                    \
-        register long _sc_19 __asm__("$19");                    \
-                                                                \
-        _sc_0 = name;                                           \
-        _sc_16 = (long) (arg1);                                 \
-        __asm__ __volatile__                                    \
-          ("callsys # %0 %1 <= %2 %3"                           \
-          : inline_syscall_r0_out_constraint (_sc_0),          \
-             "=r"(_sc_19), "=r"(_sc_16)                         \
-          : "0"(_sc_0), "2"(_sc_16)                            \
-          : inline_syscall_clobbers,                           \
-             "$17", "$18", "$20", "$21");                       \
-        _sc_ret = _sc_0, _sc_err = _sc_19;                      \
-}
-
-#define inline_syscall2(name,arg1,arg2)                         \
-{                                                               \
-        register long _sc_0 inline_syscall_r0_asm;              \
-        register long _sc_16 __asm__("$16");                    \
-        register long _sc_17 __asm__("$17");                    \
-        register long _sc_19 __asm__("$19");                    \
-                                                                \
-        _sc_0 = name;                                           \
-        _sc_16 = (long) (arg1);                                 \
-        _sc_17 = (long) (arg2);                                 \
-        __asm__ __volatile__                                    \
-          ("callsys # %0 %1 <= %2 %3 %4"                        \
-          : inline_syscall_r0_out_constraint (_sc_0),          \
-             "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17)           \
-          : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17)               \
-          : inline_syscall_clobbers,                           \
-             "$18", "$20", "$21");                              \
-        _sc_ret = _sc_0, _sc_err = _sc_19;                      \
-}
-
-#define inline_syscall3(name,arg1,arg2,arg3)                    \
-{                                                               \
-        register long _sc_0 inline_syscall_r0_asm;              \
-        register long _sc_16 __asm__("$16");                    \
-        register long _sc_17 __asm__("$17");                    \
-        register long _sc_18 __asm__("$18");                    \
-        register long _sc_19 __asm__("$19");                    \
-                                                                \
-        _sc_0 = name;                                           \
-        _sc_16 = (long) (arg1);                                 \
-        _sc_17 = (long) (arg2);                                 \
-        _sc_18 = (long) (arg3);                                 \
-        __asm__ __volatile__                                    \
-          ("callsys # %0 %1 <= %2 %3 %4 %5"                     \
-          : inline_syscall_r0_out_constraint (_sc_0),          \
-             "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17),          \
-             "=r"(_sc_18)                                       \
-          : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17),              \
-             "4"(_sc_18)                                        \
-          : inline_syscall_clobbers, "$20", "$21");            \
-        _sc_ret = _sc_0, _sc_err = _sc_19;                      \
-}
-
-#define inline_syscall4(name,arg1,arg2,arg3,arg4)               \
-{                                                               \
-        register long _sc_0 inline_syscall_r0_asm;              \
-        register long _sc_16 __asm__("$16");                    \
-        register long _sc_17 __asm__("$17");                    \
-        register long _sc_18 __asm__("$18");                    \
-        register long _sc_19 __asm__("$19");                    \
-                                                                \
-        _sc_0 = name;                                           \
-        _sc_16 = (long) (arg1);                                 \
-        _sc_17 = (long) (arg2);                                 \
-        _sc_18 = (long) (arg3);                                 \
-        _sc_19 = (long) (arg4);                                 \
-        __asm__ __volatile__                                    \
-          ("callsys # %0 %1 <= %2 %3 %4 %5 %6"                  \
-          : inline_syscall_r0_out_constraint (_sc_0),          \
-             "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17),          \
-             "=r"(_sc_18)                                       \
-          : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17),              \
-             "4"(_sc_18), "1"(_sc_19)                           \
-          : inline_syscall_clobbers, "$20", "$21");            \
-        _sc_ret = _sc_0, _sc_err = _sc_19;                      \
-}
-
-#define inline_syscall5(name,arg1,arg2,arg3,arg4,arg5)          \
-{                                                               \
-        register long _sc_0 inline_syscall_r0_asm;              \
-        register long _sc_16 __asm__("$16");                    \
-        register long _sc_17 __asm__("$17");                    \
-        register long _sc_18 __asm__("$18");                    \
-        register long _sc_19 __asm__("$19");                    \
-        register long _sc_20 __asm__("$20");                    \
-                                                                \
-        _sc_0 = name;                                           \
-        _sc_16 = (long) (arg1);                                 \
-        _sc_17 = (long) (arg2);                                 \
-        _sc_18 = (long) (arg3);                                 \
-        _sc_19 = (long) (arg4);                                 \
-        _sc_20 = (long) (arg5);                                 \
-        __asm__ __volatile__                                    \
-          ("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7"               \
-          : inline_syscall_r0_out_constraint (_sc_0),          \
-             "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17),          \
-             "=r"(_sc_18), "=r"(_sc_20)                         \
-          : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17),              \
-             "4"(_sc_18), "1"(_sc_19), "5"(_sc_20)              \
-          : inline_syscall_clobbers, "$21");                   \
-        _sc_ret = _sc_0, _sc_err = _sc_19;                      \
-}
-
-#define inline_syscall6(name,arg1,arg2,arg3,arg4,arg5,arg6)     \
-{                                                               \
-        register long _sc_0 inline_syscall_r0_asm;              \
-        register long _sc_16 __asm__("$16");                    \
-        register long _sc_17 __asm__("$17");                    \
-        register long _sc_18 __asm__("$18");                    \
-        register long _sc_19 __asm__("$19");                    \
-        register long _sc_20 __asm__("$20");                    \
-        register long _sc_21 __asm__("$21");                    \
-                                                                \
-        _sc_0 = name;                                           \
-        _sc_16 = (long) (arg1);                                 \
-        _sc_17 = (long) (arg2);                                 \
-        _sc_18 = (long) (arg3);                                 \
-        _sc_19 = (long) (arg4);                                 \
-        _sc_20 = (long) (arg5);                                 \
-        _sc_21 = (long) (arg6);                                 \
-        __asm__ __volatile__                                    \
-          ("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7 %8"            \
-          : inline_syscall_r0_out_constraint (_sc_0),          \
-             "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17),          \
-             "=r"(_sc_18), "=r"(_sc_20), "=r"(_sc_21)           \
-          : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), "4"(_sc_18), \
-             "1"(_sc_19), "5"(_sc_20), "6"(_sc_21)              \
-          : inline_syscall_clobbers);                          \
-        _sc_ret = _sc_0, _sc_err = _sc_19;                      \
-}
-
-#define INLINE_SYSCALL1(name, nr, args...)      \
-({                                              \
-        long _sc_ret, _sc_err;                  \
-        inline_syscall##nr(__NR_##name, args);  \
-        if (_sc_err != 0)                       \
-        {                                       \
-            _sc_ret = -(_sc_ret);               \
-        }                                       \
-        _sc_ret;                                \
-})
-
-#define io_syscall1(type,fname,sname,type1,arg1)                       \
-type fname(type1 arg1)                                                 \
-{                                                                       \
-   return (type)INLINE_SYSCALL1(sname, 1, arg1);                        \
-}
-
-#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)            \
-type fname(type1 arg1,type2 arg2)                                      \
-{                                                                      \
-   return (type)INLINE_SYSCALL1(sname, 2, arg1, arg2);                  \
-}
-
-#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
-type fname(type1 arg1,type2 arg2,type3 arg3)                           \
-{                                                                      \
-   return (type)INLINE_SYSCALL1(sname, 3, arg1, arg2, arg3);            \
-}
-
-#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type fname (type1 arg1, type2 arg2, type3 arg3, type4 arg4)            \
-{                                                                      \
-   return (type)INLINE_SYSCALL1(sname, 4, arg1, arg2, arg3, arg4);      \
-}
-
-#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
-         type5,arg5)                                                   \
-type fname (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)    \
-{                                                                      \
-   return (type)INLINE_SYSCALL1(sname, 5, arg1, arg2, arg3, arg4, arg5);\
-}
index 4a9b665..556852b 100644 (file)
 #define __NR_io_getevents              (__NR_SYSCALL_BASE+245)
 #define __NR_io_submit                 (__NR_SYSCALL_BASE+246)
 #define __NR_io_cancel                 (__NR_SYSCALL_BASE+247)
-
-#define __sys2(x) #x
-#define __sys1(x) __sys2(x)
-
-#if defined(__thumb__) || defined(__ARM_EABI__)
-#define __SYS_REG(name) register long __sysreg __asm__("r7") = __NR_##name;
-#define __SYS_REG_LIST(regs...) "r" (__sysreg) , ##regs
-#define __syscall(name) "swi\t0"
-#else
-#define __SYS_REG(name)
-#define __SYS_REG_LIST(regs...) regs
-#define __syscall(name) "swi\t" __sys1(__NR_##name) ""
-#endif
-
-#define io_syscall1(type,fname,sname,type1,arg1)                       \
-type fname(type1 arg1) {                                               \
-  __SYS_REG(sname)                                                     \
-  register long __r0 __asm__("r0") = (long)arg1;                       \
-  register long __res_r0 __asm__("r0");                                        \
-  __asm__ __volatile__ (                                               \
-  __syscall(sname)                                                     \
-       : "=r" (__res_r0)                                               \
-       : __SYS_REG_LIST( "0" (__r0) )                                  \
-       : "memory" );                                                   \
-  return (type) __res_r0;                                              \
-}
-
-#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)            \
-type fname(type1 arg1,type2 arg2) {                                    \
-  __SYS_REG(sname)                                                     \
-  register long __r0 __asm__("r0") = (long)arg1;                       \
-  register long __r1 __asm__("r1") = (long)arg2;                       \
-  register long __res_r0 __asm__("r0");                                        \
-  __asm__ __volatile__ (                                               \
-  __syscall(sname)                                                     \
-       : "=r" (__res_r0)                                               \
-       : __SYS_REG_LIST( "0" (__r0), "r" (__r1) )                      \
-       : "memory" );                                                   \
-  return (type) __res_r0;                                              \
-}
-
-#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
-type fname(type1 arg1,type2 arg2,type3 arg3) {                         \
-  __SYS_REG(sname)                                                     \
-  register long __r0 __asm__("r0") = (long)arg1;                       \
-  register long __r1 __asm__("r1") = (long)arg2;                       \
-  register long __r2 __asm__("r2") = (long)arg3;                       \
-  register long __res_r0 __asm__("r0");                                        \
-  __asm__ __volatile__ (                                               \
-  __syscall(sname)                                                     \
-       : "=r" (__res_r0)                                               \
-       : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2) )          \
-       : "memory" );                                                   \
-  return (type) __res_r0;                                              \
-}
-
-#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\
-type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {           \
-  __SYS_REG(sname)                                                     \
-  register long __r0 __asm__("r0") = (long)arg1;                       \
-  register long __r1 __asm__("r1") = (long)arg2;                       \
-  register long __r2 __asm__("r2") = (long)arg3;                       \
-  register long __r3 __asm__("r3") = (long)arg4;                       \
-  register long __res_r0 __asm__("r0");                                        \
-  __asm__ __volatile__ (                                               \
-  __syscall(sname)                                                     \
-       : "=r" (__res_r0)                                               \
-       : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) ) \
-       : "memory" );                                                   \
-  return (type) __res_r0;                                              \
-}
-
-#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)   \
-type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {\
-  __SYS_REG(sname)                                                     \
-  register long __r0 __asm__("r0") = (long)arg1;                       \
-  register long __r1 __asm__("r1") = (long)arg2;                       \
-  register long __r2 __asm__("r2") = (long)arg3;                       \
-  register long __r3 __asm__("r3") = (long)arg4;                       \
-  register long __r4 __asm__("r4") = (long)arg5;                       \
-  register long __res_r0 __asm__("r0");                                        \
-  __asm__ __volatile__ (                                               \
-  __syscall(sname)                                                     \
-       : "=r" (__res_r0)                                               \
-       : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2),           \
-                         "r" (__r3), "r" (__r4) )                      \
-       : "memory" );                                                   \
-  return (type) __res_r0;                                              \
-}
-
diff --git a/src/syscall-arm64.h b/src/syscall-arm64.h
deleted file mode 100644 (file)
index 031c571..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  linux/include/asm-arm/unistd.h
- *
- *  Copyright (C) 2001-2005 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Please forward _all_ changes to this file to rmk@arm.linux.org.uk,
- * no matter what the change is.  Thanks!
- */
-
-#define __NR_io_setup                  0
-#define __NR_io_destroy                        1
-#define __NR_io_submit                 2
-#define __NR_io_cancel                 3
-#define __NR_io_getevents              4
-
-#define __sys2(x) #x
-#define __sys1(x) __sys2(x)
-
-#define __SYS_REG(name) register long __sysreg __asm__("w8") = __NR_##name;
-#define __SYS_REG_LIST(regs...) "r" (__sysreg) , ##regs
-#define __syscall(name) "svc\t#0"
-
-#define io_syscall1(type,fname,sname,type1,arg1)                       \
-type fname(type1 arg1) {                                               \
-  __SYS_REG(sname)                                                     \
-  register long __x0 __asm__("x0") = (long)arg1;                       \
-  register long __res_x0 __asm__("x0");                                        \
-  __asm__ __volatile__ (                                               \
-  __syscall(sname)                                                     \
-       : "=r" (__res_x0)                                               \
-       : __SYS_REG_LIST( "0" (__x0) )                                  \
-       : "memory" );                                                   \
-  return (type) __res_x0;                                              \
-}
-
-#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)            \
-type fname(type1 arg1,type2 arg2) {                                    \
-  __SYS_REG(sname)                                                     \
-  register long __x0 __asm__("x0") = (long)arg1;                       \
-  register long __x1 __asm__("x1") = (long)arg2;                       \
-  register long __res_x0 __asm__("x0");                                        \
-  __asm__ __volatile__ (                                               \
-  __syscall(sname)                                                     \
-       : "=r" (__res_x0)                                               \
-       : __SYS_REG_LIST( "0" (__x0), "r" (__x1) )                      \
-       : "memory" );                                                   \
-  return (type) __res_x0;                                              \
-}
-
-#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
-type fname(type1 arg1,type2 arg2,type3 arg3) {                         \
-  __SYS_REG(sname)                                                     \
-  register long __x0 __asm__("x0") = (long)arg1;                       \
-  register long __x1 __asm__("x1") = (long)arg2;                       \
-  register long __x2 __asm__("x2") = (long)arg3;                       \
-  register long __res_x0 __asm__("x0");                                        \
-  __asm__ __volatile__ (                                               \
-  __syscall(sname)                                                     \
-       : "=r" (__res_x0)                                               \
-       : __SYS_REG_LIST( "0" (__x0), "r" (__x1), "r" (__x2) )          \
-       : "memory" );                                                   \
-  return (type) __res_x0;                                              \
-}
-
-#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\
-type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {           \
-  __SYS_REG(sname)                                                     \
-  register long __x0 __asm__("x0") = (long)arg1;                       \
-  register long __x1 __asm__("x1") = (long)arg2;                       \
-  register long __x2 __asm__("x2") = (long)arg3;                       \
-  register long __x3 __asm__("x3") = (long)arg4;                       \
-  register long __res_x0 __asm__("x0");                                        \
-  __asm__ __volatile__ (                                               \
-  __syscall(sname)                                                     \
-       : "=r" (__res_x0)                                               \
-       : __SYS_REG_LIST( "0" (__x0), "r" (__x1), "r" (__x2), "r" (__x3) ) \
-       : "memory" );                                                   \
-  return (type) __res_x0;                                              \
-}
-
-#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)   \
-type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {\
-  __SYS_REG(sname)                                                     \
-  register long __x0 __asm__("x0") = (long)arg1;                       \
-  register long __x1 __asm__("x1") = (long)arg2;                       \
-  register long __x2 __asm__("x2") = (long)arg3;                       \
-  register long __x3 __asm__("x3") = (long)arg4;                       \
-  register long __x4 __asm__("x4") = (long)arg5;                       \
-  register long __res_x0 __asm__("x0");                                        \
-  __asm__ __volatile__ (                                               \
-  __syscall(sname)                                                     \
-       : "=r" (__res_x0)                                               \
-       : __SYS_REG_LIST( "0" (__x0), "r" (__x1), "r" (__x2),           \
-                         "r" (__x3), "r" (__x4) )                      \
-       : "memory" );                                                   \
-  return (type) __res_x0;                                              \
-}
index 24d7c7c..b217b53 100644 (file)
@@ -1,29 +1,11 @@
-#include <errno.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-
-#define _body_io_syscall(sname, args...) \
-{ \
-       int ret = syscall(__NR_##sname, ## args); \
-       return ret < 0 ? -errno : ret; \
-}
-
-#define io_syscall1(type,fname,sname,type1,arg1) \
-type fname(type1 arg1) \
-_body_io_syscall(sname, (long)arg1)
-
-#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2) \
-type fname(type1 arg1,type2 arg2) \
-_body_io_syscall(sname, (long)arg1, (long)arg2)
-
-#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
-type fname(type1 arg1,type2 arg2,type3 arg3) \
-_body_io_syscall(sname, (long)arg1, (long)arg2, (long)arg3)
-
-#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type fname (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-_body_io_syscall(sname, (long)arg1, (long)arg2, (long)arg3, (long)arg4)
-
-#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4, type5,arg5) \
-type fname (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
-_body_io_syscall(sname, (long)arg1, (long)arg2, (long)arg3, (long)arg4, (long)arg5)
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * This is based on the include/uapi/asm-generic/unistd.h header file
+ * in the kernel, which is a generic syscall schema for new architectures.
+ */
+
+#define __NR_io_setup                  0
+#define __NR_io_destroy                        1
+#define __NR_io_submit                 2
+#define __NR_io_cancel                 3
+#define __NR_io_getevents              4
index 9576975..266ed93 100644 (file)
@@ -3,70 +3,3 @@
 #define __NR_io_getevents      247
 #define __NR_io_submit         248
 #define __NR_io_cancel         249
-
-#define io_syscall1(type,fname,sname,type1,arg1)       \
-type fname(type1 arg1)                                 \
-{                                                      \
-long __res;                                            \
-__asm__ volatile ("xchgl %%edi,%%ebx\n"                        \
-                 "int $0x80\n"                         \
-                 "xchgl %%edi,%%ebx"                   \
-       : "=a" (__res)                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)));       \
-return __res;                                          \
-}
-
-#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)            \
-type fname(type1 arg1,type2 arg2)                                      \
-{                                                                      \
-long __res;                                                            \
-__asm__ volatile ("xchgl %%edi,%%ebx\n"                                        \
-                 "int $0x80\n"                                         \
-                 "xchgl %%edi,%%ebx"                                   \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)),"c" ((long)(arg2)));    \
-return __res;                                                          \
-}
-
-#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
-type fname(type1 arg1,type2 arg2,type3 arg3)                           \
-{                                                                      \
-long __res;                                                            \
-__asm__ volatile ("xchgl %%edi,%%ebx\n"                                        \
-                 "int $0x80\n"                                         \
-                 "xchgl %%edi,%%ebx"                                   \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)),"c" ((long)(arg2)),     \
-                 "d" ((long)(arg3)));                                  \
-return __res;                                                          \
-}
-
-#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type fname (type1 arg1, type2 arg2, type3 arg3, type4 arg4)            \
-{                                                                      \
-long __res;                                                            \
-__asm__ volatile ("xchgl %%edi,%%ebx\n"                                        \
-                 "int $0x80\n"                                         \
-                 "xchgl %%edi,%%ebx"                                   \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)),"c" ((long)(arg2)),     \
-         "d" ((long)(arg3)),"S" ((long)(arg4)));                       \
-return __res;                                                          \
-} 
-
-#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
-         type5,arg5)                                                   \
-type fname (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)    \
-{                                                                      \
-long __res;                                                            \
-long tmp;                                                              \
-__asm__ volatile ("movl %%ebx,%7\n"                                    \
-                 "movl %2,%%ebx\n"                                     \
-                 "int $0x80\n"                                         \
-                 "movl %7,%%ebx"                                       \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"rm" ((long)(arg1)),"c" ((long)(arg2)),    \
-         "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
-         "m" (tmp));                                                   \
-return __res;                                                          \
-}
index 52ce9dd..a21e93b 100644 (file)
@@ -3,43 +3,3 @@
 #define __NR_io_getevents      1240
 #define __NR_io_submit         1241
 #define __NR_io_cancel         1242
-
-#define __ia64_raw_syscall(fname, sname) \
-       __asm__ (".text\n"                                              \
-               ".globl " SYMSTR(fname) "\n"                            \
-               ".proc " SYMSTR(fname) "\n"                             \
-               SYMSTR(fname) ":\n"                                     \
-               "       mov r15=" SYMSTR( __NR_ ## sname ) "\n"         \
-               "       break 0x100000\n"                               \
-               "       ;;\n"                                           \
-               "       cmp.eq p6,p0=-1,r10\n"                          \
-               "       ;;\n"                                           \
-               "       (p6) sub r8=0,r8\n"                             \
-               "       br.ret.sptk.few b0\n"                           \
-               ".size " SYMSTR(fname) ", . - " SYMSTR(fname) "\n"      \
-               ".endp " SYMSTR(fname) "\n"                             \
-       );
-
-#define io_syscall0(type, name)                                                \
-       extern type name(void);                                         \
-       __ia64_raw_syscall(name);
-
-#define io_syscall1(type, fname, sname, type1, arg1)                   \
-       extern type fname(type1 arg1);                                  \
-       __ia64_raw_syscall(fname, sname);
-
-#define io_syscall2(type, fname, sname, type1, arg1, type2, arg2)      \
-       extern type fname(type1 arg1, type2 arg2);                      \
-       __ia64_raw_syscall(fname, sname);
-
-#define io_syscall3(type, fname, sname, type1, arg1, type2, arg2, type3, arg3) \
-       extern type fname(type1 arg1, type2 arg2, type3 arg3);          \
-       __ia64_raw_syscall(fname, sname);
-
-#define io_syscall4(type, fname, sname, type1, arg1, type2, arg2, type3, arg3, type4, arg4)    \
-       extern type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4);              \
-       __ia64_raw_syscall(fname, sname);
-
-#define io_syscall5(type, fname, sname, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5)       \
-       extern type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5);                  \
-       __ia64_raw_syscall(fname, sname);
index ca70dd2..dcfb118 100644 (file)
@@ -3,92 +3,3 @@
 #define __NR_io_getevents      229
 #define __NR_io_submit         230
 #define __NR_io_cancel         231
-
-/* On powerpc a system call basically clobbers the same registers like a
- * function call, with the exception of LR (which is needed for the
- * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
- * an error return status).
- */
-
-#define __syscall_nr(nr, type, name, args...)                          \
-       unsigned long __sc_ret, __sc_err;                               \
-       {                                                               \
-               register unsigned long __sc_0  __asm__ ("r0");          \
-               register unsigned long __sc_3  __asm__ ("r3");          \
-               register unsigned long __sc_4  __asm__ ("r4");          \
-               register unsigned long __sc_5  __asm__ ("r5");          \
-               register unsigned long __sc_6  __asm__ ("r6");          \
-               register unsigned long __sc_7  __asm__ ("r7");          \
-               register unsigned long __sc_8  __asm__ ("r8");          \
-                                                                       \
-               __sc_loadargs_##nr(name, args);                         \
-               __asm__ __volatile__                                    \
-                       ("sc           \n\t"                            \
-                        "mfcr %0      "                                \
-                       : "=&r" (__sc_0),                               \
-                         "=&r" (__sc_3),  "=&r" (__sc_4),              \
-                         "=&r" (__sc_5),  "=&r" (__sc_6),              \
-                         "=&r" (__sc_7),  "=&r" (__sc_8)               \
-                       : __sc_asm_input_##nr                           \
-                       : "cr0", "ctr", "memory",                       \
-                               "r9", "r10","r11", "r12");              \
-               __sc_ret = __sc_3;                                      \
-               __sc_err = __sc_0;                                      \
-       }                                                               \
-       if (__sc_err & 0x10000000) return -((int)__sc_ret);             \
-       return (type) __sc_ret
-
-#define __sc_loadargs_0(name, dummy...)                                        \
-       __sc_0 = __NR_##name
-#define __sc_loadargs_1(name, arg1)                                    \
-       __sc_loadargs_0(name);                                          \
-       __sc_3 = (unsigned long) (arg1)
-#define __sc_loadargs_2(name, arg1, arg2)                              \
-       __sc_loadargs_1(name, arg1);                                    \
-       __sc_4 = (unsigned long) (arg2)
-#define __sc_loadargs_3(name, arg1, arg2, arg3)                                \
-       __sc_loadargs_2(name, arg1, arg2);                              \
-       __sc_5 = (unsigned long) (arg3)
-#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4)                  \
-       __sc_loadargs_3(name, arg1, arg2, arg3);                        \
-       __sc_6 = (unsigned long) (arg4)
-#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5)            \
-       __sc_loadargs_4(name, arg1, arg2, arg3, arg4);                  \
-       __sc_7 = (unsigned long) (arg5)
-
-#define __sc_asm_input_0 "0" (__sc_0)
-#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)
-#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)
-#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)
-#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)
-#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)
-
-#define io_syscall1(type,fname,sname,type1,arg1)                               \
-type fname(type1 arg1)                                                 \
-{                                                                      \
-       __syscall_nr(1, type, sname, arg1);                             \
-}
-
-#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)            \
-type fname(type1 arg1, type2 arg2)                                     \
-{                                                                      \
-       __syscall_nr(2, type, sname, arg1, arg2);                       \
-}
-
-#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
-type fname(type1 arg1, type2 arg2, type3 arg3)                         \
-{                                                                      \
-       __syscall_nr(3, type, sname, arg1, arg2, arg3);                 \
-}
-
-#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4)             \
-{                                                                      \
-       __syscall_nr(4, type, sname, arg1, arg2, arg3, arg4);           \
-}
-
-#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
-{                                                                      \
-       __syscall_nr(5, type, sname, arg1, arg2, arg3, arg4, arg5);     \
-}
index 3ec5ee3..f0805f5 100644 (file)
@@ -3,129 +3,3 @@
 #define __NR_io_getevents      245
 #define __NR_io_submit         246
 #define __NR_io_cancel         247
-
-#define io_svc_clobber "1", "cc", "memory"
-
-#define io_syscall1(type,fname,sname,type1,arg1)               \
-type fname(type1 arg1) {                                       \
-       register type1 __arg1 asm("2") = arg1;                  \
-       register long __svcres asm("2");                        \
-       long __res;                                             \
-       __asm__ __volatile__ (                                  \
-               "    .if %1 < 256\n"                            \
-               "    svc %b1\n"                                 \
-               "    .else\n"                                   \
-               "    la  %%r1,%1\n"                             \
-               "    .svc 0\n"                                  \
-               "    .endif"                                    \
-               : "=d" (__svcres)                               \
-               : "i" (__NR_##sname),                           \
-                 "0" (__arg1)                                  \
-               : io_svc_clobber );                             \
-       __res = __svcres;                                       \
-       return (type) __res;                                    \
-}
-
-#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)    \
-type fname(type1 arg1, type2 arg2) {                           \
-       register type1 __arg1 asm("2") = arg1;                  \
-       register type2 __arg2 asm("3") = arg2;                  \
-       register long __svcres asm("2");                        \
-       long __res;                                             \
-       __asm__ __volatile__ (                                  \
-               "    .if %1 < 256\n"                            \
-               "    svc %b1\n"                                 \
-               "    .else\n"                                   \
-               "    la %%r1,%1\n"                              \
-               "    svc 0\n"                                   \
-               "    .endif"                                    \
-               : "=d" (__svcres)                               \
-               : "i" (__NR_##sname),                           \
-                 "0" (__arg1),                                 \
-                 "d" (__arg2)                                  \
-               : io_svc_clobber );                             \
-       __res = __svcres;                                       \
-       return (type) __res;                                    \
-}
-
-#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,    \
-                   type3,arg3)                                 \
-type fname(type1 arg1, type2 arg2, type3 arg3) {               \
-       register type1 __arg1 asm("2") = arg1;                  \
-       register type2 __arg2 asm("3") = arg2;                  \
-       register type3 __arg3 asm("4") = arg3;                  \
-       register long __svcres asm("2");                        \
-       long __res;                                             \
-       __asm__ __volatile__ (                                  \
-               "    .if %1 < 256\n"                            \
-               "    svc %b1\n"                                 \
-               "    .else\n"                                   \
-               "    la  %%r1,%1\n"                             \
-               "    svc 0\n"                                   \
-               "    .endif"                                    \
-               : "=d" (__svcres)                               \
-               : "i" (__NR_##sname),                           \
-                 "0" (__arg1),                                 \
-                 "d" (__arg2),                                 \
-                 "d" (__arg3)                                  \
-               : io_svc_clobber );                             \
-       __res = __svcres;                                       \
-       return (type) __res;                                    \
-}
-
-#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,    \
-                   type3,arg3,type4,arg4)                      \
-type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-       register type1 __arg1 asm("2") = arg1;                  \
-       register type2 __arg2 asm("3") = arg2;                  \
-       register type3 __arg3 asm("4") = arg3;                  \
-       register type4 __arg4 asm("5") = arg4;                  \
-       register long __svcres asm("2");                        \
-       long __res;                                             \
-       __asm__ __volatile__ (                                  \
-               "    .if %1 < 256\n"                            \
-               "    svc %b1\n"                                 \
-               "    .else\n"                                   \
-               "    la  %%r1,%1\n"                             \
-               "    svc 0\n"                                   \
-               "    .endif"                                    \
-               : "=d" (__svcres)                               \
-               : "i" (__NR_##sname),                           \
-                 "0" (__arg1),                                 \
-                 "d" (__arg2),                                 \
-                 "d" (__arg3),                                 \
-                 "d" (__arg4)                                  \
-               : io_svc_clobber );                             \
-       __res = __svcres;                                       \
-       return (type) __res;                                    \
-}
-
-#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,    \
-                   type3,arg3,type4,arg4,type5,arg5)           \
-type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-          type5 arg5) {                                        \
-       register type1 __arg1 asm("2") = arg1;                  \
-       register type2 __arg2 asm("3") = arg2;                  \
-       register type3 __arg3 asm("4") = arg3;                  \
-       register type4 __arg4 asm("5") = arg4;                  \
-       register type5 __arg5 asm("6") = arg5;                  \
-       register long __svcres asm("2");                        \
-       long __res;                                             \
-       __asm__ __volatile__ (                                  \
-               "    .if %1 < 256\n"                            \
-               "    svc %b1\n"                                 \
-               "    .else\n"                                   \
-               "    la  %%r1,%1\n"                             \
-               "    svc 0\n"                                   \
-               "    .endif"                                    \
-               : "=d" (__svcres)                               \
-               : "i" (__NR_##sname),                           \
-                 "0" (__arg1),                                 \
-                 "d" (__arg2),                                 \
-                 "d" (__arg3),                                 \
-                 "d" (__arg4),                                 \
-                 "d" (__arg5)                                  \
-               : io_svc_clobber );                             \
-       __res = __svcres;                                       \
-       return (type) __res;                                    \
-}
index dd8033d..3e63e92 100644 (file)
@@ -1,103 +1,5 @@
-#include <errno.h>
-
 #define __NR_io_setup           268
 #define __NR_io_destroy         269
 #define __NR_io_submit          270
 #define __NR_io_cancel          271
 #define __NR_io_getevents       272
-
-#define io_syscall1(type,fname,sname,type1,arg1) \
-type fname(type1 arg1) \
-{ \
-long __res; \
-register long __g1 __asm__ ("g1") = __NR_##sname; \
-register long __o0 __asm__ ("o0") = (long)(arg1); \
-__asm__ __volatile__ ("t 0x10\n\t" \
-                      "bcc 1f\n\t" \
-                      "mov %%o0, %0\n\t" \
-                      "sub %%g0, %%o0, %0\n\t" \
-                      "1:\n\t" \
-                      : "=r" (__res), "=&r" (__o0) \
-                      : "1" (__o0), "r" (__g1) \
-                      : "cc"); \
-return (type) __res; \
-}
-
-#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2) \
-type fname(type1 arg1,type2 arg2) \
-{ \
-long __res; \
-register long __g1 __asm__ ("g1") = __NR_##sname; \
-register long __o0 __asm__ ("o0") = (long)(arg1); \
-register long __o1 __asm__ ("o1") = (long)(arg2); \
-__asm__ __volatile__ ("t 0x10\n\t" \
-                      "bcc 1f\n\t" \
-                      "mov %%o0, %0\n\t" \
-                      "sub %%g0, %%o0, %0\n\t" \
-                      "1:\n\t" \
-                      : "=r" (__res), "=&r" (__o0) \
-                      : "1" (__o0), "r" (__o1), "r" (__g1) \
-                      : "cc"); \
-return (type) __res; \
-}
-
-#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
-type fname(type1 arg1,type2 arg2,type3 arg3) \
-{ \
-long __res; \
-register long __g1 __asm__ ("g1") = __NR_##sname; \
-register long __o0 __asm__ ("o0") = (long)(arg1); \
-register long __o1 __asm__ ("o1") = (long)(arg2); \
-register long __o2 __asm__ ("o2") = (long)(arg3); \
-__asm__ __volatile__ ("t 0x10\n\t" \
-                      "bcc 1f\n\t" \
-                      "mov %%o0, %0\n\t" \
-                      "sub %%g0, %%o0, %0\n\t" \
-                      "1:\n\t" \
-                      : "=r" (__res), "=&r" (__o0) \
-                      : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
-                      : "cc"); \
-return (type) __res; \
-}
-
-#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type fname (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
-long __res; \
-register long __g1 __asm__ ("g1") = __NR_##sname; \
-register long __o0 __asm__ ("o0") = (long)(arg1); \
-register long __o1 __asm__ ("o1") = (long)(arg2); \
-register long __o2 __asm__ ("o2") = (long)(arg3); \
-register long __o3 __asm__ ("o3") = (long)(arg4); \
-__asm__ __volatile__ ("t 0x10\n\t" \
-                      "bcc 1f\n\t" \
-                      "mov %%o0, %0\n\t" \
-                      "sub %%g0, %%o0, %0\n\t" \
-                      "1:\n\t" \
-                      : "=r" (__res), "=&r" (__o0) \
-                      : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
-                      : "cc"); \
-return (type) __res; \
-}
-
-#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
-          type5,arg5) \
-type fname (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
-{ \
-long __res; \
-register long __g1 __asm__ ("g1") = __NR_##sname; \
-register long __o0 __asm__ ("o0") = (long)(arg1); \
-register long __o1 __asm__ ("o1") = (long)(arg2); \
-register long __o2 __asm__ ("o2") = (long)(arg3); \
-register long __o3 __asm__ ("o3") = (long)(arg4); \
-register long __o4 __asm__ ("o4") = (long)(arg5); \
-__asm__ __volatile__ ("t 0x10\n\t" \
-                      "bcc 1f\n\t" \
-                      "mov %%o0, %0\n\t" \
-                      "sub %%g0, %%o0, %0\n\t" \
-                      "1:\n\t" \
-                      : "=r" (__res), "=&r" (__o0) \
-                      : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \
-                      : "cc"); \
-return (type) __res; \
-}
index 9361856..84b2639 100644 (file)
@@ -3,61 +3,3 @@
 #define __NR_io_getevents      208
 #define __NR_io_submit         209
 #define __NR_io_cancel         210
-
-#define __syscall_clobber "r11","rcx","memory" 
-#define __syscall "syscall"
-
-#define io_syscall1(type,fname,sname,type1,arg1)                       \
-type fname(type1 arg1)                                                 \
-{                                                                      \
-long __res;                                                            \
-__asm__ volatile (__syscall                                            \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)) : __syscall_clobber );  \
-return __res;                                                          \
-}
-
-#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)            \
-type fname(type1 arg1,type2 arg2)                                      \
-{                                                                      \
-long __res;                                                            \
-__asm__ volatile (__syscall                                            \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)),"S" ((long)(arg2)) : __syscall_clobber ); \
-return __res;                                                          \
-}
-
-#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
-type fname(type1 arg1,type2 arg2,type3 arg3)                           \
-{                                                                      \
-long __res;                                                            \
-__asm__ volatile (__syscall                                            \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)),"S" ((long)(arg2)),     \
-                 "d" ((long)(arg3)) : __syscall_clobber);              \
-return __res;                                                          \
-}
-
-#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type fname (type1 arg1, type2 arg2, type3 arg3, type4 arg4)            \
-{                                                                      \
-long __res;                                                            \
-__asm__ volatile ("movq %5,%%r10 ;" __syscall                          \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)),"S" ((long)(arg2)),     \
-         "d" ((long)(arg3)),"g" ((long)(arg4)) : __syscall_clobber,"r10" ); \
-return __res;                                                          \
-} 
-
-#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
-         type5,arg5)                                                   \
-type fname (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)    \
-{                                                                      \
-long __res;                                                            \
-__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall          \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)),"S" ((long)(arg2)),     \
-         "d" ((long)(arg3)),"g" ((long)(arg4)),"g" ((long)(arg5)) :    \
-       __syscall_clobber,"r8","r10" );                                 \
-return __res;                                                          \
-}
index a2da030..9b9e9c1 100644 (file)
@@ -1,5 +1,6 @@
 #include <sys/syscall.h>
 #include <unistd.h>
+#include <errno.h>
 
 #define _SYMSTR(str)   #str
 #define SYMSTR(str)    _SYMSTR(str)
 #include "syscall-arm.h"
 #elif defined(__sparc__)
 #include "syscall-sparc.h"
-#elif defined(__aarch64__)
-#include "syscall-arm64.h"
-#else
-#warning "using generic syscall method"
+#elif defined(__aarch64__) || defined(__riscv)
 #include "syscall-generic.h"
+#else
+#warning "using system call numbers from sys/syscall.h"
 #endif
+
+#define _body_io_syscall(sname, args...)       \
+{                                              \
+       int ret, saved_errno;                   \
+       saved_errno = errno;                    \
+       ret= syscall(__NR_##sname, ## args);    \
+       if (ret < 0) {                          \
+               ret = -errno;                   \
+               errno = saved_errno;            \
+       }                                       \
+       return ret;                             \
+}
+
+#define io_syscall1(type,fname,sname,type1,arg1) \
+type fname(type1 arg1) \
+_body_io_syscall(sname, (long)arg1)
+
+#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2) \
+type fname(type1 arg1,type2 arg2) \
+_body_io_syscall(sname, (long)arg1, (long)arg2)
+
+#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
+type fname(type1 arg1,type2 arg2,type3 arg3) \
+_body_io_syscall(sname, (long)arg1, (long)arg2, (long)arg3)
+
+#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type fname (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+_body_io_syscall(sname, (long)arg1, (long)arg2, (long)arg3, (long)arg4)
+
+#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4, type5,arg5) \
+type fname (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+_body_io_syscall(sname, (long)arg1, (long)arg2, (long)arg3, (long)arg4, (long)arg5)