ioctl support copy_to_user_variant_buffer

This commit is contained in:
zy
2023-11-17 03:24:48 -05:00
parent 78fa8f9d33
commit 9ad92898da
3 changed files with 48 additions and 19 deletions

View File

@@ -1,12 +1,12 @@
#include <linux/cdev.h> // for cdev
#include "monitor_kernel.h"
#include <linux/cdev.h> // for cdev
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/slab.h> // for kmalloc
#include "monitor_kernel.h"
#include <linux/slab.h> // for kmalloc
#define DEVICE_NAME "variable_monitor"
@@ -21,11 +21,11 @@ struct my_device_data {
static int device_open(struct inode *inode, struct file *file) {
struct my_device_data *data;
printk(KERN_INFO "variable_monitor fun: %s with pid %d\n", __FUNCTION__, current->pid);
printk(KERN_INFO "variable_monitor fun: %s with pid %d\n", __FUNCTION__,
current->pid);
// save pid
data = kmalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
if (!data) return -ENOMEM;
data->pid = current->pid;
file->private_data = data;
return 0;
@@ -34,26 +34,49 @@ static int device_open(struct inode *inode, struct file *file) {
static int device_release(struct inode *inode, struct file *file) {
// load pid
struct my_device_data *data = file->private_data;
printk(KERN_INFO "variable_monitor fun: %s with pid %d\n", __FUNCTION__, data->pid);
printk(KERN_INFO "variable_monitor fun: %s with pid %d\n", __FUNCTION__,
data->pid);
// clear watch with pid
clear_watch(data->pid);
kfree(data); // free data memory
kfree(data); // free data memory
return 0;
}
static long device_ioctl(struct file *file, unsigned int ioctl_num,
unsigned long ioctl_param) {
int ret = 0;
watch_arg warg;
// copy watch_arg
if (copy_from_user(&warg, (watch_arg *)ioctl_param, sizeof(warg))) {
return -EACCES;
ioctl_dump_param dump_param;
switch (ioctl_num) {
case 0:
// copy watch_arg
if (copy_from_user(&warg, (watch_arg *)ioctl_param, sizeof(warg))) {
return -EACCES;
}
printk(KERN_INFO
"Watch_arg: task_id=%d, name=%s, ptr=%p, length_byte=%d, "
"time_ns=%ld, threshold=%lld\n",
warg.task_id, warg.name, warg.ptr, warg.length_byte, warg.time_ns,
warg.threshold);
// start watch variable
start_watch_variable(warg);
break;
case 1:
ret = copy_from_user(&dump_param, (void *)ioctl_param,
sizeof(ioctl_dump_param));
if (!ret) {
ret = copy_to_user_variant_buffer(
&load_monitor_variant_buffer, dump_param.user_ptr_len,
dump_param.user_buf, dump_param.user_buf_len);
}
printk(KERN_INFO "copy_to_user \n");
/* code */
break;
default:
break;
}
printk(KERN_INFO "Watch_arg: task_id=%d, name=%s, ptr=%p, length_byte=%d, "
"time_ns=%ld, threshold=%lld\n",
warg.task_id, warg.name, warg.ptr, warg.length_byte, warg.time_ns,
warg.threshold);
// start watch variable
start_watch_variable(warg);
return 0;
}