When we reach the callback of mmap of a struct file_operations in a Linux kernel module, can we assume that the vma->vm_mm->mm_sem is already held before the callback is invoked?
Or do we have to explicitly call down_write(&vma->vm_mm->mmap_sem) before doing remap_pfn_range?
The mmap file operation handler should assume the mmap lock is already write-locked when it is called. The mmap file handler is called via call_mmap() via mmap_region() via do_mmap(), and the following comment appears before the do_mmap() function in "mm/mmap.c":
/*
* The caller must write-lock current->mm->mmap_lock.
*/
N.B. The mmap lock was renamed from mmap_sem to mmap_lock in Linux kernel 5.8. The corresponding comment in the 5.7 kernel is:
/*
* The caller must hold down_write(¤t->mm->mmap_sem).
*/
do_mmap() is called via do_mmap_pgoff() (in "include/linux/mm.h") via vm_mmap_pgoff() (in "mm/util.c") via ksys_mmap_pgoff() (in "mm/mmap.c") via the mmap_pgoff() syscall handler (in "mm/mmap.c"). (N.B. From kernel version 5.9 onwards, do_mmap_pgoff() is eliminated and do_mmap() is called directly from vm_mmap_pgoff().) The mmap lock is write-locked in vm_mmap_pgoff().
Related
Current scenario: ko registers a callback function to the kernel(not a ko) in the ko's init function. Will the kernel call try_module_get/module_get before calling back the function? If it is called, please give a example in kernel. If it is not called, what mechanism is used to ensure that when uninstalling, the kernel does not use ko.Thanks.
i have connected a hardware to an embedded linux board on i2c lines.
I can see the device at /dev/i2c-1
filename = "/dev/i2c-1"
filehandle = open(filename,O_RDWR);
write(filehandle, <buffer to be written>, <number of Bytes>)
(similiarly for read = read(filehandle, <buffer to be read in an array>, <number of Bytes>)
Now my question here is am I using the Linux's i2c-drivers ( read/write) when I am invoking write system calls (and read like above using filehandle).
Also is this implementation independent of i2c module?I verified only after I do modprobe i2c_dev I can see my code running.
Is modprobe i2c_dev loading the i2c module and forming the /dev/i2c-1 in the /dev directory since I have connected the i2c device to it.
User-space interface to I2C
User-space interface to I2C subsystem is provided via /dev/i2c-* files and documented at Documentation/i2c/dev-interface. There are two ways to send I2C message:
send plain buffer via write(); you need to include linux/i2c-dev.h for this
send i2c_msg structure via ioctl() with I2C_RDWR request; you need to include linux/i2c.h for this
See this question for examples.
How /dev/i2c-1 is associated with I2C subsystem
/dev/i2c-1 file is just an interface to I2C subsystem. You can send I2C message, receive I2C message and configure I2C using correspondingly write(), read() and ioctl() syscalls. Once you perform one of these operations over /dev/i2c-1 file, it's being passed through Virtual file system to I2C layer, where those operations are implemented. Actual callbacks for those operations are implemented in drivers/i2c/i2c-dev.c file, more specifically -- in i2cdev_fops structure.
For example, when you perform open() syscall on /dev/i2c-1 file, the i2cdev_open() function is called in kernel, which creates i2c_client structure for further send/receive operations, and that structure is being assigned to file's private data field:
/* This creates an anonymous i2c_client, which may later be
* pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE.
*
* This client is ** NEVER REGISTERED ** with the driver model
* or I2C core code!! It just holds private copies of addressing
* information and maybe a PEC flag.
*/
client = kzalloc(sizeof(*client), GFP_KERNEL);
...
file->private_data = client;
When you perform some operations on that /dev/i2c-1 file next, i2c_client structure will be extracted from file->private_data field, and corresponding function will be called for that structure.
For write() syscall the i2cdev_write() function will be called, which leads to i2c_master_send() function call:
struct i2c_client *client = file->private_data;
...
ret = i2c_master_send(client, tmp, count);
The same way read() leads to i2cdev_read(), which leads to i2c_master_recv(). And ioctl() leads to i2cdev_ioctl(), which just assigns corresponding flags to i2c_client structure.
How /dev/i2c-1 is associated with hardware I2C driver
Operations performed on /dev/i2c-* file lead eventually to execution of I2C hardware driver functions. Let's see one example of it. When we are doing write() syscall, the whole chain will be:
write() -> i2cdev_write() -> i2c_master_send() -> i2c_transfer() -> __i2c_transfer() -> adap->algo->master_xfer(), where adap is i2c_adapter structure, which stores hardware specific data about I2C controller, such as callbacks of I2C hardware driver. That .master_xfer callback is implemented in I2C hardware driver. For example, for OMAP platforms it's implemented in drivers/i2c/busses/i2c-omap.c file, see omap_i2c_xfer() function.
I'm working in an USB ACM driver, "where i need to send notification from kernel space to user space application for invoking a call back function". I'm not much aware of using kernel to user interfaces in code. how well can sysfs help for this scenario. Please send some sample code to use sysfs so that I'll get an idea to implement in my code. I could not find it anywhere. Also pls tell anyother easy way to achieve kernel to user space notification. Thanks in advance.
My suggestion would be to create a sysfs interface to your kernel driver that userspace can access. Each sysfs attribute if created with the correct properties can be read like a file from userspace. You can then use the poll function from userspace to poll for an action on that file. To trigger this action from Kernel space, you can use the sysfs_notify function on your attribute and it will cause your userspace code to wake up. Here is how I would do it
Kernel
1. Create Kobject or attach an attribute to a previous kobject
2. When you want to signal userspace call sysfs_notify on the kobject and attribute
Userspace
Create a new thread that will block while waiting for the sysfs_notify
Open the sysfs attribute from this thread
poll the attribute, once sysfs_notify from the kernel is called it will unblock your poll
call your event handling function
Another alternative would be to use eventfd. You create eventfd, pass the integer file descriptor to kernel space (e.g. through sysfs, or ioctl), then convert the file descriptor you got from user space to eventfd_ctx in kernel space. This is it - you have your notification channel.
User space
#include <sys/eventfd.h>
int efd = eventfd(0, 0);
// pass 'efd' to kernel space
Kernel space
#include <linux/eventfd.h>
// Set up
int efd = /* get from user space - sysfs/ioctl/write/... */;
struct eventfd_ctx* efd_ctx = eventfd_ctx_fdget(efd);
// Signal user space
eventfd_signal(efd_ctx, 1);
// Tear down
eventfd_ctx_put(efd_ctx);
In my kernel module I'd like to create multiple FDs, and pass them later to the user-space via ioctl.
The user-space code will use these FDs to wait for an event using poll() or select().
If I were creating such FDs in the user-space, I'd call eventfd(), but how do that in the kernel-space?
According to system call's expansion macro (#define SYSCALL_DEFINEx) in syscalls.h, maybe you can call sys_eventfd or sys_eventfd2 in the kernel-space.
I have created one kernel module. within the module i have defined some functions say function1(int n) and function2().
There was no error in compiling and inserting the module. What i don't understand is how to call the function1(n) and function2() from a user space program.
I think there is no direct way to do it, you can't link userspace code with the kernel like you do with a library. First, you have to register your function as syscall and then call the syscall with the syscall() function.
See here
Also some interface between kernel and user space possible using socket communication see
this link
And find use full link related to this topic at right side of page.
You can make your driver to react on writes to a /dev/file file or a /proc/file file.
EDIT
Form name file my point is device is as file in kernel and you can access via ioctl()
the pretty good explanation is http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN885
See Link