Index: /trunk/src/VBox/HostDrivers/Support/SUPDrv.c
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 28461)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 28462)
@@ -211,10 +211,11 @@
     { "RTR0MemKernelIsValidAddr",               (void *)RTR0MemKernelIsValidAddr },
     { "RTR0MemAreKrnlAndUsrDifferent",          (void *)RTR0MemAreKrnlAndUsrDifferent },
-/* These don't work yet on linux - use fast mutexes!
     { "RTSemMutexCreate",                       (void *)RTSemMutexCreate },
     { "RTSemMutexRequest",                      (void *)RTSemMutexRequest },
+    { "RTSemMutexRequestDebug",                 (void *)RTSemMutexRequestDebug },
+    { "RTSemMutexRequestNoResume",              (void *)RTSemMutexRequestNoResume },
+    { "RTSemMutexRequestNoResumeDebug",         (void *)RTSemMutexRequestNoResumeDebug },
     { "RTSemMutexRelease",                      (void *)RTSemMutexRelease },
     { "RTSemMutexDestroy",                      (void *)RTSemMutexDestroy },
-*/
     { "RTProcSelf",                             (void *)RTProcSelf },
     { "RTR0ProcHandleSelf",                     (void *)RTR0ProcHandleSelf },
Index: /trunk/src/VBox/HostDrivers/Support/linux/Makefile
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/linux/Makefile	(revision 28461)
+++ /trunk/src/VBox/HostDrivers/Support/linux/Makefile	(revision 28462)
@@ -94,4 +94,5 @@
 	r0drv/linux/semeventmulti-r0drv-linux.o \
 	r0drv/linux/semfastmutex-r0drv-linux.o \
+	r0drv/linux/semmutex-r0drv-linux.o \
 	r0drv/linux/spinlock-r0drv-linux.o \
 	r0drv/linux/thread-r0drv-linux.o \
Index: /trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv	(revision 28461)
+++ /trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv	(revision 28462)
@@ -39,4 +39,5 @@
     ${PATH_ROOT}/include/iprt/handletable.h=>include/iprt/handletable.h \
     ${PATH_ROOT}/include/iprt/initterm.h=>include/iprt/initterm.h \
+    ${PATH_ROOT}/include/iprt/list.h=>include/iprt/list.h \
     ${PATH_ROOT}/include/iprt/lockvalidator.h=>include/iprt/lockvalidator.h \
     ${PATH_ROOT}/include/iprt/log.h=>include/iprt/log.h \
@@ -141,4 +142,5 @@
     ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c=>r0drv/linux/semeventmulti-r0drv-linux.c \
     ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/semfastmutex-r0drv-linux.c=>r0drv/linux/semfastmutex-r0drv-linux.c \
+    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c=>r0drv/linux/semmutex-r0drv-linux.c \
     ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c=>r0drv/linux/spinlock-r0drv-linux.c \
     ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/string.h=>r0drv/linux/string.h \
Index: /trunk/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c	(revision 28461)
+++ /trunk/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c	(revision 28462)
@@ -320,5 +320,5 @@
     return rtSemMutexLinuxRequest(hMutexSem, cMillies, true /*fInterruptible*/);
 }
-RT_EXPORT_SYMBOL(RTSemMutexRequest);
+RT_EXPORT_SYMBOL(RTSemMutexRequestNoResume);
 
 
@@ -364,4 +364,5 @@
             IPRT_DEBUG_SEMS_STATE(pThis, 'u');
         }
+        rc = VINF_SUCCESS;
     }
     else
Index: /trunk/src/VBox/Runtime/testcase/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/testcase/Makefile.kmk	(revision 28461)
+++ /trunk/src/VBox/Runtime/testcase/Makefile.kmk	(revision 28462)
@@ -91,4 +91,5 @@
 	tstRand \
 	tstRTFsQueries \
+	tstRTR0SemMutexDriver \
 	tstR0ThreadPreemptionDriver \
 	tstSemEvent \
@@ -149,4 +150,5 @@
  	tstLdrObjR0 \
  	tstRTR0MemUserKernel \
+ 	tstRTR0SemMutex \
  	tstR0ThreadPreemption
  ifdef VBOX_WITH_RAW_MODE
@@ -394,5 +396,19 @@
 endif
 
+tstR0ThreadPreemptionDriver_TEMPLATE = VBOXR3TSTEXE
 tstR0ThreadPreemptionDriver_SOURCES = tstR0ThreadPreemptionDriver.cpp
+
+tstRTR0SemMutex_TEMPLATE = VBoxR0
+tstRTR0SemMutex_INST = $(INST_TESTCASE)
+tstRTR0SemMutex_DEFS = IN_RT_R0
+tstRTR0SemMutex_SYSSUFF = .r0
+tstRTR0SemMutex_SOURCES = tstRTR0SemMutex.cpp
+tstRTR0SemMutex_LIBS = $(PATH_LIB)/RuntimeR0$(VBOX_SUFF_LIB)
+if1of ($(VBOX_LDR_FMT), pe lx)
+ tstRTR0SemMutex_LIBS += $(PATH_LIB)/SUPR0$(VBOX_SUFF_LIB)
+endif
+
+tstRTR0SemMutexDriver_TEMPLATE = VBOXR3TSTEXE
+tstRTR0SemMutexDriver_SOURCES = tstRTR0SemMutexDriver.cpp
 
 tstRTFsQueries_SOURCES = tstRTFsQueries.cpp
Index: /trunk/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp	(revision 28462)
+++ /trunk/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp	(revision 28462)
@@ -0,0 +1,188 @@
+/* $Id$ */
+/** @file
+ * IPRT R0 Testcase - Mutex Semaphores.
+ */
+
+/*
+ * Copyright (C) 2009-2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <iprt/semaphore.h>
+
+#include <iprt/err.h>
+#include <iprt/time.h>
+#include <iprt/string.h>
+#include <VBox/sup.h>
+#include "tstRTR0SemMutex.h"
+
+
+
+/**
+ * Service request callback function.
+ *
+ * @returns VBox status code.
+ * @param   pSession    The caller's session.
+ * @param   u64Arg      64-bit integer argument.
+ * @param   pReqHdr     The request header. Input / Output. Optional.
+ */
+DECLEXPORT(int) TSTRTR0SemMutexSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOperation,
+                                             uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr)
+{
+    if (u64Arg)
+        return VERR_INVALID_PARAMETER;
+    if (!VALID_PTR(pReqHdr))
+        return VERR_INVALID_PARAMETER;
+    char   *pszErr = (char *)(pReqHdr + 1);
+    size_t  cchErr = pReqHdr->cbReq - sizeof(*pReqHdr);
+    if (cchErr < 32 || cchErr >= 0x10000)
+        return VERR_INVALID_PARAMETER;
+    *pszErr = '\0';
+
+#define SET_ERROR(szFmt)                do { if (!*pszErr) RTStrPrintf(pszErr, cchErr, "!" szFmt); } while (0)
+#define SET_ERROR1(szFmt, a1)           do { if (!*pszErr) RTStrPrintf(pszErr, cchErr, "!" szFmt, a1); } while (0)
+#define SET_ERROR2(szFmt, a1, a2)       do { if (!*pszErr) RTStrPrintf(pszErr, cchErr, "!" szFmt, a1, a2); } while (0)
+#define SET_ERROR3(szFmt, a1, a2, a3)   do { if (!*pszErr) RTStrPrintf(pszErr, cchErr, "!" szFmt, a1, a2, a3); } while (0)
+#define CHECK_RC_BREAK(rc, rcExpect, szOp) \
+        if ((rc) != (rcExpect)) \
+        { \
+            RTStrPrintf(pszErr, cchErr, "!%s -> %Rrc, expected %Rrc. line %u", szOp, rc, rcExpect, __LINE__); \
+            break; \
+        }
+
+
+    /*
+     * The big switch.
+     */
+    RTSEMMUTEX  hMtx;
+    int         rc;
+    switch (uOperation)
+    {
+        case TSTRTR0SEMMUTEX_SANITY_OK:
+            break;
+
+        case TSTRTR0SEMMUTEX_SANITY_FAILURE:
+            SET_ERROR1("42failure42%1024s", "");
+            break;
+
+        case TSTRTR0SEMMUTEX_BASIC:
+            rc = RTSemMutexCreate(&hMtx);
+            CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexCreate");
+            do
+            {
+                /*
+                 * The interruptible version first.
+                 */
+                /* simple request and release, polling. */
+                rc = RTSemMutexRequestNoResume(hMtx, 0);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease");
+
+                /* simple request and release, wait for ever. */
+                rc = RTSemMutexRequestNoResume(hMtx, RT_INDEFINITE_WAIT);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume(indef_wait)");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease");
+
+                /* simple request and release, wait a tiny while. */
+                rc = RTSemMutexRequestNoResume(hMtx, 133);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume(133)");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease");
+
+                /* nested request and release. */
+                rc = RTSemMutexRequestNoResume(hMtx, RT_INDEFINITE_WAIT);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume#1");
+                rc = RTSemMutexRequestNoResume(hMtx, RT_INDEFINITE_WAIT);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume#2");
+                rc = RTSemMutexRequestNoResume(hMtx, RT_INDEFINITE_WAIT);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume#3");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease#3");
+                rc = RTSemMutexRequestNoResume(hMtx, RT_INDEFINITE_WAIT);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume#3b");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease#3b");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease#2");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease#1");
+
+                /*
+                 * The uninterruptible variant.
+                 */
+                /* simple request and release, polling. */
+                rc = RTSemMutexRequest(hMtx, 0);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequest");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease");
+
+                /* simple request and release, wait for ever. */
+                rc = RTSemMutexRequest(hMtx, RT_INDEFINITE_WAIT);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequest(indef_wait)");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease");
+
+                /* simple request and release, wait a tiny while. */
+                rc = RTSemMutexRequest(hMtx, 133);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequest(133)");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease");
+
+                /* nested request and release. */
+                rc = RTSemMutexRequest(hMtx, RT_INDEFINITE_WAIT);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequest#1");
+                rc = RTSemMutexRequest(hMtx, RT_INDEFINITE_WAIT);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequest#2");
+                rc = RTSemMutexRequest(hMtx, RT_INDEFINITE_WAIT);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequest#3");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease#3");
+                rc = RTSemMutexRequest(hMtx, RT_INDEFINITE_WAIT);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequest#3b");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease#3b");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease#2");
+                rc = RTSemMutexRelease(hMtx);
+                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease#1");
+
+            } while (false);
+
+            rc = RTSemMutexDestroy(hMtx);
+            CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexDestroy");
+            break;
+
+        default:
+            SET_ERROR1("Unknown test #%d", uOperation);
+            break;
+    }
+
+    /* The error indicator is the '!' in the message buffer. */
+    return VINF_SUCCESS;
+}
+
Index: /trunk/src/VBox/Runtime/testcase/tstRTR0SemMutex.h
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTR0SemMutex.h	(revision 28462)
+++ /trunk/src/VBox/Runtime/testcase/tstRTR0SemMutex.h	(revision 28462)
@@ -0,0 +1,44 @@
+/* $Id$ */
+/** @file
+ * IPRT R0 Testcase - Mutex Semaphores, common header.
+ */
+
+/*
+ * Copyright (C) 2009-2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifdef IN_RING0
+RT_C_DECLS_BEGIN
+DECLEXPORT(int) TSTRTR0SemMutexSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOperation,
+                                             uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr);
+RT_C_DECLS_END
+#endif
+
+typedef enum TSTRTR0SEMMUTEX
+{
+    TSTRTR0SEMMUTEX_SANITY_OK = 1,
+    TSTRTR0SEMMUTEX_SANITY_FAILURE,
+    TSTRTR0SEMMUTEX_BASIC
+} TSTRTR0SEMMUTEX;
+
Index: /trunk/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp	(revision 28462)
+++ /trunk/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp	(revision 28462)
@@ -0,0 +1,154 @@
+/* $Id$ */
+/** @file
+ * IPRT R0 Testcase - Thread Preemption, driver program.
+ */
+
+/*
+ * Copyright (C) 2009-2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <iprt/initterm.h>
+
+#include <iprt/err.h>
+#include <iprt/path.h>
+#include <iprt/param.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/test.h>
+#include <iprt/thread.h>
+#ifdef VBOX
+# include <VBox/sup.h>
+# include "tstRTR0SemMutex.h"
+#endif
+
+
+int main(int argc, char **argv)
+{
+#ifndef VBOX
+    RTPrintf("tstSup: SKIPPED\n");
+    return 0;
+#else
+    /*
+     * Init.
+     */
+    RTTEST hTest;
+    int rc = RTTestInitAndCreate("tstR0SemMutex", &hTest);
+    if (rc)
+        return rc;
+    RTTestBanner(hTest);
+
+    PSUPDRVSESSION pSession;
+    rc = SUPR3Init(&pSession);
+    if (RT_FAILURE(rc))
+    {
+        RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc);
+        return RTTestSummaryAndDestroy(hTest);
+    }
+
+    char szPath[RTPATH_MAX];
+    rc = RTPathExecDir(szPath, sizeof(szPath));
+    if (RT_SUCCESS(rc))
+        rc = RTPathAppend(szPath, sizeof(szPath), "tstR0SemMutex.r0");
+    if (RT_FAILURE(rc))
+    {
+        RTTestFailed(hTest, "Failed constructing .r0 filename (rc=%Rrc)", rc);
+        return RTTestSummaryAndDestroy(hTest);
+    }
+
+    void *pvImageBase;
+    rc = SUPR3LoadServiceModule(szPath, "tstR0SemMutex",
+                                "TSTRTR0SemMutexSrvReqHandler",
+                                &pvImageBase);
+    if (RT_FAILURE(rc))
+    {
+        RTTestFailed(hTest, "SUPR3LoadServiceModule(%s,,,) failed with rc=%Rrc\n", szPath, rc);
+        return RTTestSummaryAndDestroy(hTest);
+    }
+
+    /* test request */
+    struct
+    {
+        SUPR0SERVICEREQHDR  Hdr;
+        char                szMsg[256];
+    } Req;
+
+    /*
+     * Sanity checks.
+     */
+    RTTestSub(hTest, "Sanity");
+    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
+    Req.Hdr.cbReq = sizeof(Req);
+    Req.szMsg[0] = '\0';
+    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0SemMutex", sizeof("tstR0SemMutex") - 1,
+                                             TSTRTR0SEMMUTEX_SANITY_OK, 0, &Req.Hdr), VINF_SUCCESS);
+    if (RT_FAILURE(rc))
+        return RTTestSummaryAndDestroy(hTest);
+    RTTESTI_CHECK_MSG(Req.szMsg[0] == '\0', ("%s", Req.szMsg));
+    if (Req.szMsg[0] != '\0')
+        return RTTestSummaryAndDestroy(hTest);
+
+    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
+    Req.Hdr.cbReq = sizeof(Req);
+    Req.szMsg[0] = '\0';
+    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0SemMutex", sizeof("tstR0SemMutex") - 1,
+                                             TSTRTR0SEMMUTEX_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS);
+    if (RT_FAILURE(rc))
+        return RTTestSummaryAndDestroy(hTest);
+    RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1), ("%s", Req.szMsg));
+    if (strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1))
+        return RTTestSummaryAndDestroy(hTest);
+
+    /*
+     * Basic tests, bail out on failure.
+     */
+    RTTestSub(hTest, "Basics");
+    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
+    Req.Hdr.cbReq = sizeof(Req);
+    Req.szMsg[0] = '\0';
+    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0SemMutex", sizeof("tstR0SemMutex") - 1,
+                                             TSTRTR0SEMMUTEX_BASIC, 0, &Req.Hdr), VINF_SUCCESS);
+    if (RT_FAILURE(rc))
+        return RTTestSummaryAndDestroy(hTest);
+    if (Req.szMsg[0] == '!')
+    {
+        RTTestIFailed("%s", &Req.szMsg[1]);
+        return RTTestSummaryAndDestroy(hTest);
+    }
+    if (Req.szMsg[0])
+        RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg);
+
+    /*
+     * More to come
+     */
+
+    /*
+     * Done.
+     */
+    return RTTestSummaryAndDestroy(hTest);
+#endif
+}
+
