Reputation: 29
My driver's IOCTL handler redirects IOCTL requests to another driver. This used to work great, but when I needed to add support for the 5.10 kernel, it turned out that the old way didn't work anymore. How can this be done now?
#define TARGET_ID "TGT"
// ...
char id[sizeof(TARGET_ID)];
// ...
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
res = __blkdev_driver_ioctl(dev->bdev_raw, 0, SCSI_IOCTL_TARGET_ID, (unsigned long)id);
set_fs(old_fs);
if(0 == strcmp(id, TARGET_ID))
{
PINFO("*** target driver detected! ***\n");
dev->is_target_driver = true;
}
else
{
...
Upvotes: 0
Views: 892
Reputation: 63
It seems like that force_uaccess_begin()
cannot replace set_fs(KERNEL_DS);
Below is its definition:
static inline mm_segment_t force_uaccess_begin(void)
{
mm_segment_t fs = get_fs();
set_fs(USER_DS);
return fs;
}
And mm_segment_t
, force_uaccess_begin
all have been removed after linux 5.18.
Upvotes: 1
Reputation: 29
Hooray! Hooray! Hooray! ;) This is how it will work:
#define TARGET_ID "TGT"
// ...
char id[sizeof(TARGET_ID)];
// ...
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 4)
mm_segment_t old_fs = force_uaccess_begin();
res = __blkdev_driver_ioctl(dev->bdev_raw, 0, SCSI_IOCTL_TARGET_ID, (unsigned long)id);
force_uaccess_end(old_fs);
#else
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
res = __blkdev_driver_ioctl(dev->bdev_raw, 0, SCSI_IOCTL_TARGET_ID, (unsigned long)id);
set_fs(old_fs);
#endif
if(0 == strcmp(id, TARGET_ID))
{
PINFO("*** target driver detected! ***\n");
dev->is_target_driver = true;
}
else
{
...
Upvotes: 1