I am trying to write directly from a kernel module into a process that it creates without a copy. Note that I cannot simply allocate the memory in kernel mode and map it to userland like you would normally do, I need the memory to eventually originate from the process itself (eventually from a call to the CUDA runtime).
Right now I have a proc file setup with a write callback which I use to send the buffer from userland:
char *buffer;const size_t PAGE_SIZE = getpagesize();posix_memalign(&buffer,PAGE_SIZE,PAGE_SIZE);*buffer = 89;FILE *fp = fopen("/proc/dt/alloc", "w");fwrite(buffer, 1, 100, fp);
In the kernel module I map the page to kernel memory and modify the first byte as follows:
static ssize_t write_proc_alloc(struct file *file, const char __user *ubuf, size_t count, loff_t *data){ struct page *pages[1]; mmap_read_lock(current->mm); pin_user_pages((unsigned long)ubuf,1, FOLL_WRITE, pages); char *buf = kmap(pages[0]); *buf = 123; kunmap(pages[0]); set_page_dirty(pages[0]); unpin_user_pages(pages, 1); mmap_read_unlock(current->mm);}
I have made sure to set the page to dirty after, and yet still it remains unchanged after fwrite
returns. Why is my modification not visible, and how do I directly modify the provided buffer without having to resort to copy_to_user
and the like?