# HG changeset patch # User Edouard Tisserant # Date 1539033394 -7200 # Node ID ca80d6dac4c84a62cb526a56f28c8b9ec8d0e2e9 # Parent e008dc9d8c9fc8dccc42e93fb1197778e8f867ae devices/rtdmnet.c : abuse RTDM api to allow sendmsg and recvmsg to be called indirectly from userland cobalt process ioctl, while rtdm_socket is created from a kernel thread. diff -r e008dc9d8c9f -r ca80d6dac4c8 devices/rtdmnet.c --- a/devices/rtdmnet.c Sun Oct 07 17:05:42 2018 +0200 +++ b/devices/rtdmnet.c Mon Oct 08 23:16:34 2018 +0200 @@ -80,6 +80,7 @@ struct net_device *netdev; struct rtnet_device *used_netdev; int socket; + struct rtdm_fd *rtdm_fd; ec_device_t *ecdev; uint8_t *rx_buf; // struct sockaddr_ll dest_addr; @@ -195,6 +196,7 @@ ecdev_withdraw(dev->ecdev); } if (!(dev->socket < 0)) { + rtdm_fd_put(dev->rtdm_fd); rtdm_close(dev->socket); dev->socket = -1; } @@ -228,6 +230,24 @@ printk(" rtdm_socket() = %d!\n", dev->socket); return dev->socket; } + + /* HACK : + When this is called, process is 'kernel', i.e. + cobalt_ppd_get(0) == &cobalt_kernel_ppd + + This makes a problem later when recvmsg or sendmsg is indirectly called + from application's cobalt thread through RTDM IOCTL. From such thread, + RTDM can't resolv socket's 'ufd' that rtdm_socket just returned. + + To keep a usable file descriptor for that socket, even when calling + from cobalt thread (i.e. if (cobalt_ppd_get(0) != &cobalt_kernel_ppd)) + we resolve it here in advance */ + dev->rtdm_fd = rtdm_fd_get(dev->socket,0); + if (IS_ERR(dev->rtdm_fd)){ + printk(" rtdm_fd_get() = %d!\n", ret); + ret = PTR_ERR(dev->rtdm_fd); + goto out_err; + } printk(KERN_ERR PFX "Binding socket to interface %i (%s).\n", desc->ifindex, desc->name); @@ -240,12 +260,17 @@ sizeof(struct sockaddr_ll)); if (ret < 0) { printk(" rtdm_bind() = %d!\n", ret); - rtdm_close(dev->socket); - dev->socket = -1; - return ret; + goto out_err; } return 0; + +out_err: + rtdm_fd_put(dev->rtdm_fd); + rtdm_close(dev->socket); + dev->socket = -1; + return ret; + } /*****************************************************************************/ @@ -351,7 +376,8 @@ msg.msg_iovlen = 1; if (rtdm_in_rt_context()) - ret = rtdm_sendmsg(dev->socket, &msg, 0); + /* HACK : call fd ops directly as in rtdm's fd.c */ + ret = dev->rtdm_fd->ops->sendmsg_rt(dev->rtdm_fd, &msg, 0); else ret = nrt_rtdm_sendmsg(dev->socket, &msg); @@ -406,9 +432,10 @@ msg.msg_iov = &iov; msg.msg_iovlen = 1; - if (rtdm_in_rt_context()) - ret = rtdm_recvmsg(dev->socket, &msg, MSG_DONTWAIT); - else + if (rtdm_in_rt_context()){ + /* HACK : call fd ops directly as in rtdm's fd.c */ + ret = dev->rtdm_fd->ops->recvmsg_rt(dev->rtdm_fd, &msg, MSG_DONTWAIT); + }else ret = nrt_rtdm_recvmsg(dev->socket, &msg); if (ret > 0) {