Index: .gitignore
===================================================================
--- .gitignore	(revision af2d3e372f90cd38e193c600880047f1cb2dcd26)
+++ .gitignore	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -450,4 +450,5 @@
 uspace/srv/taskmon/taskmon
 uspace/srv/test/chardev-test/chardev-test
+uspace/srv/test/ipc-test/ipc-test
 uspace/srv/vfs/vfs
 uspace/srv/vfs/vfs.gz
Index: abi/include/abi/ipc/interfaces.h
===================================================================
--- abi/include/abi/ipc/interfaces.h	(revision af2d3e372f90cd38e193c600880047f1cb2dcd26)
+++ abi/include/abi/ipc/interfaces.h	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -181,5 +181,7 @@
 	    FOURCC_COMPACT('v', 'o', 'l', ' ') | IFACE_EXCHANGE_SERIALIZE,
 	INTERFACE_VBD =
-	    FOURCC_COMPACT('v', 'b', 'd', ' ') | IFACE_EXCHANGE_SERIALIZE
+	    FOURCC_COMPACT('v', 'b', 'd', ' ') | IFACE_EXCHANGE_SERIALIZE,
+	INTERFACE_IPC_TEST =
+	    FOURCC_COMPACT('i', 'p', 'c', 't') | IFACE_EXCHANGE_SERIALIZE
 } iface_t;
 
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision af2d3e372f90cd38e193c600880047f1cb2dcd26)
+++ boot/Makefile.common	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -123,4 +123,5 @@
 	taskmon \
 	test/chardev-test \
+	test/ipc-test \
 	volsrv
 
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision af2d3e372f90cd38e193c600880047f1cb2dcd26)
+++ uspace/Makefile	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -142,4 +142,5 @@
 	srv/hid/rfb \
 	srv/test/chardev-test \
+	srv/test/ipc-test \
 	drv/audio/hdaudio \
 	drv/audio/sb16 \
Index: uspace/app/perf/Makefile
===================================================================
--- uspace/app/perf/Makefile	(revision af2d3e372f90cd38e193c600880047f1cb2dcd26)
+++ uspace/app/perf/Makefile	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -35,4 +35,5 @@
 SOURCES = \
 	perf.c \
+	ipc/ns_ping.c \
 	ipc/ping_pong.c
 
Index: uspace/app/perf/ipc/ns_ping.c
===================================================================
--- uspace/app/perf/ipc/ns_ping.c	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
+++ uspace/app/perf/ipc/ns_ping.c	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <ns.h>
+#include <async.h>
+#include <errno.h>
+#include "../perf.h"
+
+#define MIN_DURATION_SECS  10
+#define NUM_SAMPLES 10
+
+static errno_t ping_pong_measure(uint64_t niter, uint64_t *rduration)
+{
+	struct timespec start;
+	uint64_t count;
+
+	getuptime(&start);
+
+	for (count = 0; count < niter; count++) {
+		errno_t retval = ns_ping();
+
+		if (retval != EOK) {
+			printf("Error sending ping message.\n");
+			return EIO;
+		}
+	}
+
+	struct timespec now;
+	getuptime(&now);
+
+	*rduration = ts_sub_diff(&now, &start) / 1000;
+	return EOK;
+}
+
+static void ping_pong_report(uint64_t niter, uint64_t duration)
+{
+	printf("Completed %" PRIu64 " round trips in %" PRIu64 " us",
+	    niter, duration);
+
+	if (duration > 0) {
+		printf(", %" PRIu64 " rt/s.\n", niter * 1000 * 1000 / duration);
+	} else {
+		printf(".\n");
+	}
+}
+
+const char *bench_ns_ping(void)
+{
+	errno_t rc;
+	uint64_t duration;
+	uint64_t dsmp[NUM_SAMPLES];
+
+	printf("Benchmark ns server ping time\n");
+	printf("Warm up and determine work size...\n");
+
+	struct timespec start;
+	getuptime(&start);
+
+	uint64_t niter = 1;
+
+	while (true) {
+		rc = ping_pong_measure(niter, &duration);
+		if (rc != EOK)
+			return "Failed.";
+
+		ping_pong_report(niter, duration);
+
+		if (duration >= MIN_DURATION_SECS * 1000000)
+			break;
+
+		niter *= 2;
+	}
+
+	printf("Measure %d samples...\n", NUM_SAMPLES);
+
+	int i;
+
+	for (i = 0; i < NUM_SAMPLES; i++) {
+		rc = ping_pong_measure(niter, &dsmp[i]);
+		if (rc != EOK)
+			return "Failed.";
+
+		ping_pong_report(niter, dsmp[i]);
+	}
+
+	double sum = 0.0;
+
+	for (i = 0; i < NUM_SAMPLES; i++)
+		sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
+
+	double avg = sum / NUM_SAMPLES;
+
+	double qd = 0.0;
+	double d;
+	for (i = 0; i < NUM_SAMPLES; i++) {
+		d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
+		qd += d * d;
+	}
+
+	double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
+
+	printf("Average: %.0f rt/s Std.dev^2: %.0f rt/s Samples: %d\n",
+	    avg, stddev, NUM_SAMPLES);
+
+	return NULL;
+}
Index: uspace/app/perf/ipc/ns_ping.def
===================================================================
--- uspace/app/perf/ipc/ns_ping.def	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
+++ uspace/app/perf/ipc/ns_ping.def	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -0,0 +1,5 @@
+{
+	"ns_ping",
+	"Name service IPC ping-pong benchmark",
+	&bench_ns_ping
+},
Index: uspace/app/perf/ipc/ping_pong.c
===================================================================
--- uspace/app/perf/ipc/ping_pong.c	(revision af2d3e372f90cd38e193c600880047f1cb2dcd26)
+++ uspace/app/perf/ipc/ping_pong.c	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -31,5 +31,5 @@
 #include <stdlib.h>
 #include <time.h>
-#include <ns.h>
+#include <ipc_test.h>
 #include <async.h>
 #include <errno.h>
@@ -39,5 +39,6 @@
 #define NUM_SAMPLES 10
 
-static errno_t ping_pong_measure(uint64_t niter, uint64_t *rduration)
+static errno_t ping_pong_measure(ipc_test_t *test, uint64_t niter,
+    uint64_t *rduration)
 {
 	struct timespec start;
@@ -47,5 +48,5 @@
 
 	for (count = 0; count < niter; count++) {
-		errno_t retval = ns_ping();
+		errno_t retval = ipc_test_ping(test);
 
 		if (retval != EOK) {
@@ -79,6 +80,12 @@
 	uint64_t duration;
 	uint64_t dsmp[NUM_SAMPLES];
+	ipc_test_t *test;
+	const char *msg;
 
-	printf("Benchmark ns server ping time\n");
+	printf("Benchmark IPC test server ping time\n");
+	rc = ipc_test_create(&test);
+	if (rc != EOK)
+		return "Failed contacting IPC test server.";
+
 	printf("Warm up and determine work size...\n");
 
@@ -89,7 +96,9 @@
 
 	while (true) {
-		rc = ping_pong_measure(niter, &duration);
-		if (rc != EOK)
-			return "Failed.";
+		rc = ping_pong_measure(test, niter, &duration);
+		if (rc != EOK) {
+			msg = "Failed.";
+			goto error;
+		}
 
 		ping_pong_report(niter, duration);
@@ -106,7 +115,9 @@
 
 	for (i = 0; i < NUM_SAMPLES; i++) {
-		rc = ping_pong_measure(niter, &dsmp[i]);
-		if (rc != EOK)
-			return "Failed.";
+		rc = ping_pong_measure(test, niter, &dsmp[i]);
+		if (rc != EOK) {
+			msg = "Failed.";
+			goto error;
+		}
 
 		ping_pong_report(niter, dsmp[i]);
@@ -132,4 +143,8 @@
 	    avg, stddev, NUM_SAMPLES);
 
+	ipc_test_destroy(test);
 	return NULL;
+error:
+	ipc_test_destroy(test);
+	return msg;
 }
Index: uspace/app/perf/perf.c
===================================================================
--- uspace/app/perf/perf.c	(revision af2d3e372f90cd38e193c600880047f1cb2dcd26)
+++ uspace/app/perf/perf.c	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -42,4 +42,5 @@
 benchmark_t benchmarks[] = {
 #include "ipc/ping_pong.def"
+#include "ipc/ns_ping.def"
 	{ NULL, NULL, NULL }
 };
Index: uspace/app/perf/perf.h
===================================================================
--- uspace/app/perf/perf.h	(revision af2d3e372f90cd38e193c600880047f1cb2dcd26)
+++ uspace/app/perf/perf.h	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -46,4 +46,5 @@
 } benchmark_t;
 
+extern const char *bench_ns_ping(void);
 extern const char *bench_ping_pong(void);
 
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision af2d3e372f90cd38e193c600880047f1cb2dcd26)
+++ uspace/lib/c/Makefile	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -70,4 +70,5 @@
 	generic/gsort.c \
 	generic/inttypes.c \
+	generic/ipc_test.c \
 	generic/loc.c \
 	generic/mem.c \
Index: uspace/lib/c/generic/ipc_test.c
===================================================================
--- uspace/lib/c/generic/ipc_test.c	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
+++ uspace/lib/c/generic/ipc_test.c	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file IPC test service API
+ */
+
+#include <abi/ipc/interfaces.h>
+#include <errno.h>
+#include <ipc/services.h>
+#include <ipc/ipc_test.h>
+#include <loc.h>
+#include <stdlib.h>
+#include <ipc_test.h>
+
+/** Create IPC test service session.
+ *
+ * @param rvol Place to store pointer to volume service session.
+ * @return     EOK on success, ENOMEM if out of memory, EIO if service
+ *             cannot be contacted.
+ */
+errno_t ipc_test_create(ipc_test_t **rtest)
+{
+	ipc_test_t *test;
+	service_id_t test_svcid;
+	errno_t rc;
+
+	test = calloc(1, sizeof(ipc_test_t));
+	if (test == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = loc_service_get_id(SERVICE_NAME_IPC_TEST, &test_svcid, 0);
+	if (rc != EOK) {
+		rc = ENOENT;
+		goto error;
+	}
+
+	test->sess = loc_service_connect(test_svcid, INTERFACE_IPC_TEST, 0);
+	if (test->sess == NULL) {
+		rc = EIO;
+		goto error;
+	}
+
+	*rtest = test;
+	return EOK;
+error:
+	free(test);
+	return rc;
+}
+
+/** Destroy IPC test service session.
+ *
+ * @param test IPC test service session
+ */
+void ipc_test_destroy(ipc_test_t *test)
+{
+	if (test == NULL)
+		return;
+
+	async_hangup(test->sess);
+	free(test);
+}
+
+/** Simple ping.
+ *
+ * @param test IPC test service
+ * @return EOK on success or an error code
+ */
+errno_t ipc_test_ping(ipc_test_t *test)
+{
+	async_exch_t *exch;
+	errno_t retval;
+
+	exch = async_exchange_begin(test->sess);
+	retval = async_req_0_0(exch, IPC_TEST_PING);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return retval;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/ipc_test.h
===================================================================
--- uspace/lib/c/include/ipc/ipc_test.h	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
+++ uspace/lib/c/include/ipc/ipc_test.h	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_IPC_TEST_H_
+#define LIBC_IPC_IPC_TEST_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	IPC_TEST_PING = IPC_FIRST_USER_METHOD
+} ipc_test_request_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision af2d3e372f90cd38e193c600880047f1cb2dcd26)
+++ uspace/lib/c/include/ipc/services.h	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -57,4 +57,5 @@
 #define SERVICE_NAME_DNSR     "net/dnsr"
 #define SERVICE_NAME_INET     "net/inet"
+#define SERVICE_NAME_IPC_TEST "ipc-test"
 #define SERVICE_NAME_NETCONF  "net/netconf"
 #define SERVICE_NAME_UDP      "net/udp"
Index: uspace/lib/c/include/ipc_test.h
===================================================================
--- uspace/lib/c/include/ipc_test.h	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
+++ uspace/lib/c/include/ipc_test.h	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_TEST_H_
+#define LIBC_IPC_TEST_H_
+
+#include <async.h>
+#include <errno.h>
+
+typedef struct {
+	async_sess_t *sess;
+} ipc_test_t;
+
+extern errno_t ipc_test_create(ipc_test_t **);
+extern void ipc_test_destroy(ipc_test_t *);
+extern errno_t ipc_test_ping(ipc_test_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/test/ipc-test/Makefile
===================================================================
--- uspace/srv/test/ipc-test/Makefile	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
+++ uspace/srv/test/ipc-test/Makefile	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2018 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../../..
+BINARY = ipc-test
+
+SOURCES = \
+	main.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/test/ipc-test/main.c
===================================================================
--- uspace/srv/test/ipc-test/main.c	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
+++ uspace/srv/test/ipc-test/main.c	(revision 1edd6d0c4201fd549dcce1ac7154c0ee7d6ab4c9)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <async.h>
+#include <errno.h>
+#include <str_error.h>
+#include <ipc/ipc_test.h>
+#include <ipc/services.h>
+#include <loc.h>
+#include <mem.h>
+#include <stdio.h>
+#include <task.h>
+
+#define NAME  "ipc-test"
+
+static service_id_t svc_id;
+
+static void ipc_test_connection(ipc_call_t *icall, void *arg)
+{
+	/* Accept connection */
+	async_accept_0(icall);
+
+	while (true) {
+		ipc_call_t call;
+		async_get_call(&call);
+
+		if (!IPC_GET_IMETHOD(call)) {
+			async_answer_0(&call, EOK);
+			break;
+		}
+
+		switch (IPC_GET_IMETHOD(call)) {
+		case IPC_TEST_PING:
+			async_answer_0(&call, EOK);
+			break;
+		default:
+			async_answer_0(&call, ENOTSUP);
+			break;
+		}
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	errno_t rc;
+
+	printf("%s: IPC test service\n", NAME);
+	async_set_fallback_port_handler(ipc_test_connection, NULL);
+
+	rc = loc_server_register(NAME);
+	if (rc != EOK) {
+		printf("%s: Failed registering server. (%s)\n", NAME,
+		    str_error(rc));
+		return rc;
+	}
+
+	rc = loc_service_register(SERVICE_NAME_IPC_TEST, &svc_id);
+	if (rc != EOK) {
+		printf("%s: Failed registering service. (%s)\n", NAME,
+		    str_error(rc));
+		return rc;
+	}
+
+	printf("%s: Accepting connections\n", NAME);
+	task_retval(0);
+	async_manager();
+
+	/* Not reached */
+	return 0;
+}
