Reputation: 131
I'm trying to update an old kernel driver to run under Debian Bookworm, but I've run into trouble. Because this driver wraps around a different serial driver (e.g. /dev/ttyS4), it uses filp_open() on that other driver, then calls file operations (ioctl, read, write) to control that other driver, with any buffer/struct parameters bounced to/from user space.
However, to achieve this, I believe that the (calling) kernel driver has to (somehow) create buffers in user space to use to call the other driver (the original code used mm_seg_t etc). I thought all I'd have to do was vmalloc() a block of memory, kmalloc() a block of page pointers, then call get_user_pages() on the block. But when I try this, get_user_pages() is returning -14 (EFAULT).
Here's my current attempt:
// Calculate page-aligned size of user data block
size_t szUserdata_sizeof = PAGE_ALIGN(sizeof(struct userdata));
// Calculate the number of pages
int iUserdata_numpages = szUserdata_sizeof / PAGE_SIZE;
// Allocate block of memory in kernel space
struct userdata * pstUserdata_kernel = vmalloc(szUserdata_sizeof);
if (pstUserdata_kernel == NULL) { return -ENOMEM; }
// Array to store pointers to the pinned pages
static struct page **papstUserdata_pages;
papstUserdata_pages = kmalloc(iUserdata_numpages * sizeof(struct page *), GFP_KERNEL);
if (papstUserdata_pages == NULL) { return -ENOMEM; }
// Determine the (fake) user-space address we will be using
unsigned long ulUserdata_user = (unsigned long)pstUserdata_kernel;
// Use get_user_pages() to pin the buffer's pages, simulating user-space memory
long ret = get_user_pages(ulUserdata_user, iUserdata_numpages, FOLL_WRITE, papstUserdata_pages, NULL);
It feels like I'm missing a really tiny piece of the jigsaw here, what do I need to do to get this working? Thanks!
Note: I do know that a more modern (and better) way of having a kernel driver control a different tty kernel driver would be to use tty_kopen_exclusive() etc: but that would mean rewriting most of this driver from scratch (which I don't think I want to do).
Upvotes: 1
Views: 73