All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jorge Fernandez Monteagudo <jorgefm@cirsa.com>
To: "kernelnewbies@kernelnewbies.org" <kernelnewbies@kernelnewbies.org>
Subject: How to replace set_fs(KERNEL_DS) for a kernel 5.10.x module driver version
Date: Tue, 12 Jan 2021 07:21:46 +0000	[thread overview]
Message-ID: <DB9PR10MB45220B4E01D354626848B0D2A1AA0@DB9PR10MB4522.EURPRD10.PROD.OUTLOOK.COM> (raw)

Hi all, this is my first post in this mailing list... I hope to find an answer. I've post the question in stackoverflow with the same tittle with no answers yet. Since then, I've been able to reduce the demo kernel module to minimum in order to show but I see. The minimum kernel module code is attached at the end.

My kernel module was working ok up to kernel 5.10.x. My kernel module adds a layer above the cdc-acm class driver to use all the infrastructure this driver because the hardware it controls has a ttyACMx device. The minimum kernel module code attached shows how I open the ttyACMx device and try to set the baudrate. Once the device is opened I use the unlocked_ioctl function with TCSETS to set the new device properties. 

		ret = fd->f_op->unlocked_ioctl(fd, TCSETS, (unsigned long int) &newtio);

I get an EFAULT (-14) error from this function. I've track down the error to drivers/tty/tty_ioctl.c, set_termios function in the next code:

#ifdef TCGETS2
    } else if (opt & TERMIOS_OLD) {
        if (user_termios_to_kernel_termios_1(&tmp_termios,
                        (struct termios __user *)arg))
            return -EFAULT;
    } else {

where 'user_termios_to_kernel_termios_1' is a macro to 'copy_from_user' then I think there is a problem with the parameter 'newtio'. To solve this in the previous kernel versions ( < 5.10.x) I had the code with get_fs()/set_fs() but now these functions and the KERNEL_DS definitions are gone... 

As a reference when I run this kernel module in a 4.15.0-128-generic I get when inserted and removed:

# dmesg
...
[431743.226926] cdc_acm 3-5.2:1.0: ttyACM0: USB ACM device
[431749.633030] testdrv:testdrv_init: testdrv_init
[431749.633351] testdrv:testdrv_init: fd      : 00000000e9327576
[431749.633355] testdrv:testdrv_init: fd->f_op: 00000000c761e065
[431749.633357] testdrv:testdrv_init: ioctl   : 00000000608ed60c
[431749.633517] testdrv:usbox_serial_baudrate_set: _unlocked_ioctl: 0
[431749.633519] testdrv:usbox_serial_baudrate_set: ret: 0
[431761.532905] testdrv:testdrv_exit: testdrv_exit

and the same driver with 5.10.0-1-amd64:

# dmesg
...
[    4.731179] cdc_acm 2-3:1.0: ttyACM0: USB ACM device
...
[  168.263871] testdrv: loading out-of-tree module taints kernel.
[  168.264337] testdrv:testdrv_init: testdrv_init
[  168.266360] testdrv:testdrv_init: fd      : 00000000bd0e50a3
[  168.266363] testdrv:testdrv_init: fd->f_op: 00000000dc488f77
[  168.266364] testdrv:testdrv_init: ioctl   : 00000000c31431c2
[  168.266370] testdrv:usbox_serial_baudrate_set: _unlocked_ioctl: -14
[  168.266371] testdrv:usbox_serial_baudrate_set: ret: -14
[  168.266372] testdrv:testdrv_init: errno: EINVAL

​Anybody can help me to make it work the minimum kernel module attached?
Thank you!
Jorge

----
#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/file.h>
#include <linux/tty.h>
#include <linux/version.h>
#include <linux/uaccess.h>


/* ttyACM file descriptor */
static struct file *fd;

static int usbox_serial_baudrate_set(struct file *fd)
{
	int ret;
	mm_segment_t old_fs;
	struct termios newtio;
	//struct termios __user newtio;
	//void __user *unewtio = (void __user *) &newtio;

	memset(&newtio, 0, sizeof(newtio));
	newtio.c_cflag = (B115200 | CS8 | CLOCAL | CREAD);

#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
	old_fs = get_fs();
	set_fs( get_ds() );
#elif LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)
	old_fs = get_fs();
	set_fs( KERNEL_DS );
#else
	old_fs = force_uaccess_begin();
#endif

	if (fd->f_op->unlocked_ioctl) {
		ret = fd->f_op->unlocked_ioctl(fd, TCSETS, (unsigned long int) &newtio);
		pr_info("_unlocked_ioctl: %d\n", ret);
	} else {
		ret = -ENOTTY;
	}

#if LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)
	set_fs(old_fs);
#else
	force_uaccess_end(old_fs);
#endif

	pr_info("ret: %d\n", ret );
	return ret;
}

static int __init testdrv_init(void)
{
	pr_info("testdrv_init\n");

	fd = filp_open( "/dev/ttyACM0", O_RDWR|O_NOCTTY, 0);
	if (IS_ERR(fd)) {
		pr_info("error from filp_open()\n");
		return -ENODEV;
	}

	pr_info ("fd      : %p\n", fd);
	pr_info ("fd->f_op: %p\n", fd->f_op);
	pr_info ("ioctl   : %p\n", fd->f_op->unlocked_ioctl);

	if ((fd->f_op == NULL) || (fd->f_op->unlocked_ioctl == NULL)) {
		pr_info("errno: ENODEV\n");
		return -ENODEV;
	}

	// Set baudrate.
	if (usbox_serial_baudrate_set(fd) != 0 ) {
		filp_close(fd, NULL);
		pr_info("errno: EINVAL\n");
		return -EINVAL;
	}

	return 0;
}

static void __exit testdrv_exit(void)
{
	pr_info("testdrv_exit\n");

	if (fd != NULL) {
		filp_close(fd, NULL);
		fd = NULL;
	}
}

module_init(testdrv_init);
module_exit(testdrv_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Unknonw");
MODULE_DESCRIPTION("testdrv");
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

             reply	other threads:[~2021-01-12  7:22 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-12  7:21 Jorge Fernandez Monteagudo [this message]
2021-01-12  7:29 ` How to replace set_fs(KERNEL_DS) for a kernel 5.10.x module driver version Greg KH
2021-01-12  7:39   ` Jorge Fernandez Monteagudo
2021-01-12  8:16     ` Greg KH
2021-01-12  8:26       ` Jorge Fernandez Monteagudo
2021-01-12  8:56         ` Greg KH
2021-01-12  9:12           ` Jorge Fernandez Monteagudo
2021-01-12  9:28             ` Greg KH
2021-01-12  9:55               ` Jorge Fernandez Monteagudo
2021-01-12 10:26                 ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DB9PR10MB45220B4E01D354626848B0D2A1AA0@DB9PR10MB4522.EURPRD10.PROD.OUTLOOK.COM \
    --to=jorgefm@cirsa.com \
    --cc=kernelnewbies@kernelnewbies.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.