[Xenomai] rtdm_safe_copy_from_user() causing mode switch

Jackson Jones jackson.jones at gmail.com
Sat Oct 7 03:56:54 CEST 2017


I noticed that when I call rtdm_safe_copy_from_user() it causes a mode
switch. I am looking to pass a uint32_t (u32 in kernel space) from
user-space to a rtdm driver.

Is there a way of doing this that avoids a mode switch. I am doing this in
an rtdm spi driver for the imx6. It is used to change the transfer size
(number of words) for the next call to transfer_iobufs (using the
SPI_RTIOC_TRANSFER ioctl).

Below is a modified spi_master_ioctl_rt which is inside of spi-master.c. I
added an ioctl to do this. I verified that the ioctls SPI_RTIOC_SET_CONFIG,
and SPI_RTIOC_GET_CONFIG cause a mode switch as well as the former calls
rtdm_safe_copy_from_user() and the latter calls rtdm_safe_copy_to_user().
Any advice would be appreciated.

147 static int spi_master_ioctl_rt(struct rtdm_fd *fd,
148                    unsigned int request, void *arg)
149 {
150     struct rtdm_spi_remote_slave *slave = fd_to_slave(fd);
151     struct rtdm_spi_master *master = slave->master;
152     struct rtdm_spi_config config;
153     u32 new_size = 0;
154     int ret;
155
156     switch (request) {
157     case SPI_RTIOC_SET_CONFIG:
158         ret = rtdm_safe_copy_from_user(fd, &config,
159                            arg, sizeof(config));
160         if (ret == 0)
161             ret = update_slave_config(slave, &config);
162         break;
163     case SPI_RTIOC_GET_CONFIG:
164         rtdm_mutex_lock(&master->bus_lock);
165         config = slave->config;
166         rtdm_mutex_unlock(&master->bus_lock);
167         ret = rtdm_safe_copy_to_user(fd, arg,
168                          &config, sizeof(config));
169         break;
170     case SPI_RTIOC_TRANSFER:
171         ret = -EINVAL;
172         if (master->ops->transfer_iobufs) {
173             rtdm_mutex_lock(&master->bus_lock);
174             ret = do_chip_select(slave);
175             if (ret == 0) {
176                 ret = master->ops->transfer_iobufs(slave);
177                 do_chip_deselect(slave);
178             }
179             rtdm_mutex_unlock(&master->bus_lock);
180         }
181         break;
182
183     // A hack to change the transfer size of the transfer buffers
184     case SPI_RTIOC_CHANGE_XFER_SIZE:
185         ret = rtdm_safe_copy_from_user(fd, &new_size,
186                            arg, sizeof(u32));
187         if (ret == 0)
188             master->ops->change_xfer_size(slave, new_size);
189         break;
190
191     default:
192         ret = -ENOSYS;
193     }
194
195     return ret;
196 }

Thanks,

Jackson Jones


More information about the Xenomai mailing list