diff --git a/haskell/src/SEL4/API/Syscall.lhs b/haskell/src/SEL4/API/Syscall.lhs index 935ad802c8d5f40301309e1a35c22348b6a769e9..94b1ce82f5ebd5cf28fa0a66c91da82893f894bb 100644 --- a/haskell/src/SEL4/API/Syscall.lhs +++ b/haskell/src/SEL4/API/Syscall.lhs @@ -178,13 +178,14 @@ The "Wait" system call blocks waiting to receive a message through a specified e > handleWait :: Kernel () > handleWait = do > thread <- getCurThread -> deleteCallerCap thread > epCPtr <- asUser thread $ liftM CPtr $ getRegister capRegister > (capFaultOnFailure epCPtr True $ do > epCap <- lookupCap thread epCPtr > case epCap of > EndpointCap { capEPCanReceive = True } -> -> withoutFailure $ receiveIPC thread epCap +> withoutFailure $ do +> deleteCallerCap thread +> receiveIPC thread epCap > AsyncEndpointCap { capAEPCanReceive = True } -> > withoutFailure $ receiveAsyncIPC thread epCap > _ -> throw $ MissingCapability { missingCapBitsLeft = 0 }) diff --git a/src/api/syscall.c b/src/api/syscall.c index f3f7d3a3d5d59bac36b4ecd7bb98f309eb90ed37..175d4f0280a77dae1ed40e60c8c33a3f6326e496 100644 --- a/src/api/syscall.c +++ b/src/api/syscall.c @@ -308,8 +308,6 @@ handleWait(void) word_t epCPtr; lookupCap_ret_t lu_ret; - deleteCallerCap(ksCurThread); - epCPtr = getRegister(ksCurThread, capRegister); lu_ret = lookupCap(ksCurThread, epCPtr); @@ -322,6 +320,7 @@ handleWait(void) switch (cap_get_capType(lu_ret.cap)) { case cap_endpoint_cap: + if (unlikely(!cap_endpoint_cap_get_capCanReceive(lu_ret.cap))) { current_lookup_fault = lookup_fault_missing_capability_new(0); current_fault = fault_cap_fault_new(epCPtr, true); @@ -329,6 +328,7 @@ handleWait(void) break; } + deleteCallerCap(ksCurThread); receiveIPC(ksCurThread, lu_ret.cap); break;