static enum hrtimer_restart MonitorTimerCB(struct hrtimer *timer) { MvpkmVM *vm = container_of(timer, MvpkmVM, monTimer.timer); Mvpkm_WakeGuest(vm, ACTION_TIMER); return HRTIMER_NORESTART; }
static int MksckDgramSendMsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len) { int err = 0; struct sock *sk = sock->sk; Mksck *peerMksck; Mksck_Datagram *dg; uint32 needed; uint32 write; Mksck_Address fromAddr; if (msg->msg_flags & MSG_OOB) return -EOPNOTSUPP; if (len > MKSCK_XFER_MAX) return -EMSGSIZE; lock_sock(sk); do { Mksck *mksck; Mksck_Address peerAddr = { .addr = (msg->msg_name ? ((struct sockaddr_mk *)msg->msg_name)->mk_addr.addr : MKSCK_ADDR_UNDEF) }; err = MksckTryBind(sk); if (err) break; mksck = sk->sk_protinfo; fromAddr = mksck->addr; peerMksck = mksck->peer; if (peerMksck) { if (peerAddr.addr != MKSCK_ADDR_UNDEF && peerAddr.addr != mksck->peerAddr.addr) { err = -EISCONN; break; } ATOMIC_ADDV(peerMksck->refCount, 1); } else if (peerAddr.addr == MKSCK_ADDR_UNDEF) { err = -ENOTCONN; } else { err = LockPeer(peerAddr, &peerMksck); } } while (0); release_sock(sk); if (err) return err; needed = MKSCK_DGSIZE(len); while (1) { err = Mutex_Lock(&peerMksck->mutex, MutexModeEX); if (err < 0) goto decRefc; if (peerMksck->shutDown & MKSCK_SHUT_RD) { err = -ENOTCONN; goto unlockDecRefc; } write = Mksck_FindSendRoom(peerMksck, needed); if (write != MKSCK_FINDSENDROOM_FULL) break; if (msg->msg_flags & MSG_DONTWAIT) { err = -EAGAIN; goto unlockDecRefc; } peerMksck->foundFull++; err = Mutex_UnlSleep(&peerMksck->mutex, MutexModeEX, MKSCK_CVAR_ROOM); if (err < 0) { PRINTK("MksckDgramSendMsg: aborted\n"); goto decRefc; } } dg = (void *)&peerMksck->buff[write]; dg->fromAddr = fromAddr; dg->len = len; err = memcpy_fromiovec(dg->data, msg->msg_iov, len); if (err != 0) goto unlockDecRefc; Mksck_IncWriteIndex(peerMksck, write, needed); Mutex_UnlWake(&peerMksck->mutex, MutexModeEX, MKSCK_CVAR_FILL, false); if (peerMksck->rcvCBEntryMVA != 0) { MksckPage *peerMksckPage = Mksck_ToSharedPage(peerMksck); err = Mutex_Lock(&peerMksckPage->mutex, MutexModeSH); if (err == 0) { uint32 sockIdx = peerMksck->index; struct MvpkmVM *vm = (struct MvpkmVM *)peerMksckPage->vmHKVA; if (vm) { WorldSwitchPage *wsp = vm->wsp; ASSERT(sockIdx < 8 * sizeof(peerMksckPage->wakeVMMRecv)); ATOMIC_ORV(peerMksckPage->wakeVMMRecv, 1U << sockIdx); if (wsp) Mvpkm_WakeGuest(vm, ACTION_MKSCK); } Mutex_Unlock(&peerMksckPage->mutex, MutexModeSH); } } if (!err) err = len; decRefc: Mksck_DecRefc(peerMksck); return err; unlockDecRefc: Mutex_Unlock(&peerMksck->mutex, MutexModeEX); goto decRefc; } static int MksckFault(struct vm_area_struct *vma, struct vm_fault *vmf) { return VM_FAULT_SIGBUS; } static int MksckMMap(struct file *file, struct socket *sock, struct vm_area_struct *vma) { vma->vm_ops = &mksckVMOps; return 0; }