Module: xenomai-jki Branch: for-upstream Commit: 910bd3b9dd2b0b273fe3c4c4100673456ce10f44 URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=910bd3b9dd2b0b273fe3c4c4100673456ce10f44
Author: Jan Kiszka <jan.kis...@siemens.com> Date: Fri Mar 30 18:06:27 2012 +0200 Add regression test for mprotect on pinned memory This tests both the original issue of mprotect reintroducing COW pages to Xenomai processes as well as the recently fixed zero page corruption. Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- src/testsuite/regression/posix/Makefile.am | 2 +- src/testsuite/regression/posix/Makefile.in | 15 ++++- src/testsuite/regression/posix/check.h | 10 +++ src/testsuite/regression/posix/mprotect.c | 98 ++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 4 deletions(-) diff --git a/src/testsuite/regression/posix/Makefile.am b/src/testsuite/regression/posix/Makefile.am index 26bc8f2..ad59bac 100644 --- a/src/testsuite/regression/posix/Makefile.am +++ b/src/testsuite/regression/posix/Makefile.am @@ -4,7 +4,7 @@ noinst_HEADERS = check.h CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) -tst_PROGRAMS = leaks shm +tst_PROGRAMS = leaks shm mprotect CPPFLAGS = $(XENO_USER_CFLAGS) \ -I$(top_srcdir)/include/posix \ diff --git a/src/testsuite/regression/posix/Makefile.in b/src/testsuite/regression/posix/Makefile.in index ff424e2..8ee1992 100644 --- a/src/testsuite/regression/posix/Makefile.in +++ b/src/testsuite/regression/posix/Makefile.in @@ -36,7 +36,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -tst_PROGRAMS = leaks$(EXEEXT) shm$(EXEEXT) +tst_PROGRAMS = leaks$(EXEEXT) shm$(EXEEXT) mprotect$(EXEEXT) subdir = src/testsuite/regression/posix DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in @@ -62,6 +62,11 @@ leaks_OBJECTS = leaks.$(OBJEXT) leaks_LDADD = $(LDADD) leaks_DEPENDENCIES = ../../../skins/posix/libpthread_rt.la \ ../../../skins/common/libxenomai.la +mprotect_SOURCES = mprotect.c +mprotect_OBJECTS = mprotect.$(OBJEXT) +mprotect_LDADD = $(LDADD) +mprotect_DEPENDENCIES = ../../../skins/posix/libpthread_rt.la \ + ../../../skins/common/libxenomai.la shm_SOURCES = shm.c shm_OBJECTS = shm.$(OBJEXT) shm_LDADD = $(LDADD) @@ -79,8 +84,8 @@ LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = leaks.c shm.c -DIST_SOURCES = leaks.c shm.c +SOURCES = leaks.c mprotect.c shm.c +DIST_SOURCES = leaks.c mprotect.c shm.c HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags @@ -330,6 +335,9 @@ clean-tstPROGRAMS: leaks$(EXEEXT): $(leaks_OBJECTS) $(leaks_DEPENDENCIES) @rm -f leaks$(EXEEXT) $(LINK) $(leaks_OBJECTS) $(leaks_LDADD) $(LIBS) +mprotect$(EXEEXT): $(mprotect_OBJECTS) $(mprotect_DEPENDENCIES) + @rm -f mprotect$(EXEEXT) + $(LINK) $(mprotect_OBJECTS) $(mprotect_LDADD) $(LIBS) shm$(EXEEXT): $(shm_OBJECTS) $(shm_DEPENDENCIES) @rm -f shm$(EXEEXT) $(LINK) $(shm_OBJECTS) $(shm_LDADD) $(LIBS) @@ -341,6 +349,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/leaks.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mprotect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shm.Po@am__quote@ .c.o: diff --git a/src/testsuite/regression/posix/check.h b/src/testsuite/regression/posix/check.h index 52f6ada..3d532cf 100644 --- a/src/testsuite/regression/posix/check.h +++ b/src/testsuite/regression/posix/check.h @@ -25,4 +25,14 @@ rc; \ }) +#define check_mmap(expr) \ + ({ \ + void *rc = (expr); \ + if (rc == MAP_FAILED) { \ + fprintf(stderr, "%s:%d: "#expr ": %s\n", __FILE__, __LINE__, strerror(errno)); \ + exit(EXIT_FAILURE); \ + } \ + rc; \ + }) + #endif /* POSIX_CHECK_H */ diff --git a/src/testsuite/regression/posix/mprotect.c b/src/testsuite/regression/posix/mprotect.c new file mode 100644 index 0000000..43c6ad0 --- /dev/null +++ b/src/testsuite/regression/posix/mprotect.c @@ -0,0 +1,98 @@ +/* + * Test if implicit pinning of memory via mprotect works. + * + * Copyright (C) Jan Kiszka <jan.kis...@siemens.com> + * + * Released under the terms of GPLv2. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <signal.h> +#include <sys/mman.h> +#include <pthread.h> +#include <rtdk.h> + +#include "check.h" + +#define MEMSIZE 0x10000 + +static void check_value_inner(const char *fn, int line, const char *msg, + int value, int expected) +{ + if (value == expected) + return; + + pthread_set_mode_np(PTHREAD_WARNSW, 0); + fprintf(stderr, + "FAILURE %s:%d: %s returned %u instead of %u\n", + fn, line, msg, value, expected); + exit(EXIT_FAILURE); +} + +#define check_value(msg, value, expected) do { \ + int __value = value; \ + check_value_inner(__FUNCTION__, __LINE__, msg, __value, \ + expected); \ +} while (0) + +void sigdebug_handler(int sig, siginfo_t *si, void *context) +{ + unsigned int reason = si->si_value.sival_int; + + fprintf(stderr, "FAILURE: sigdebug_handler triggered, reason %d\n", + reason); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + unsigned char *zero_mem, *test1_mem, *test2_mem; + struct sched_param param = { .sched_priority = 1 }; + struct timespec zero = { .tv_sec = 0, .tv_nsec = 0 }; + struct sigaction sa; + + zero_mem = check_mmap(mmap(0, MEMSIZE, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0)); + test1_mem = check_mmap(mmap(0, MEMSIZE, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0)); + + sigemptyset(&sa.sa_mask); + sa.sa_sigaction = sigdebug_handler; + sa.sa_flags = SA_SIGINFO; + check_unix(sigaction(SIGDEBUG, &sa, NULL)); + + check_unix(mlockall(MCL_CURRENT | MCL_FUTURE)); + + check_pthread(pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m)); + + printf("memory read\n"); + check_value("read mem", test1_mem[0], 0); + + pthread_set_mode_np(PTHREAD_WARNSW, 0); + test2_mem = check_mmap(mmap(0, MEMSIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0)); + check_unix(mprotect(test2_mem, MEMSIZE, + PROT_READ | PROT_WRITE | PROT_EXEC)); + + nanosleep(&zero, NULL); + pthread_set_mode_np(0, PTHREAD_WARNSW); + + printf("memory write after exec enable\n"); + test2_mem[0] = 0xff; + + pthread_set_mode_np(PTHREAD_WARNSW, 0); + check_unix(mprotect(test1_mem, MEMSIZE, PROT_READ | PROT_WRITE)); + + nanosleep(&zero, NULL); + pthread_set_mode_np(0, PTHREAD_WARNSW); + + printf("memory write after write enable\n"); + test1_mem[0] = 0xff; + check_value("read zero", zero_mem[0], 0); + + pthread_set_mode_np(PTHREAD_WARNSW, 0); + fprintf(stderr, "Test OK\n"); + + return 0; +} _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git