copy_to_user не возвращает ожидаемые данные - PullRequest
0 голосов
/ 01 марта 2019

У меня в драйвере ядра ioctl, и мне нужно вернуть некоторые данные при чтении.Когда я читаю его обратно в пользовательском пространстве, он не показывает ожидаемых результатов.

Фрагмент пользовательского пространства:

typedef struct abc_T {
    int size;
    int addr;
    int data[32];
} abc_T;

// Read
int abc_read(int addr, int size, int *data) {
     abc_T abc = {};
     int fd, retval;
     abc.size = size;
     abc.addr = addr;
     fd = open("/dev/"ABC_DEV, O_RDWR);

     if (fd >=0) {
     retval = ioctl(fd, READ_ABC, &abc);
     if (retval == 0)
         memcpy(data, abc.data, size);

     }
return retval;
}

Ядро:

static int ABC_ioctl(struct file * file, uint cmd, ulong arg)
{
ABC_T abc;
void __user * arg_ptr;
arg_ptr = (void *)arg;
int retval;

if (!access_ok(VERIFY_READ, arg_ptr, sizeof(ABC_T))) {

    return -EACCES;
}

if (copy_from_user(&abc, arg_ptr,
                        sizeof(ABC_T)) != 0) {
    return -EFAULT;
}

switch(cmd) {
case READ_ABC:
retval = read_func(&abc);
if (retval == 0) {
    if (copy_to_user((void __user *)arg, &abc,
                     sizeof(ABC_T) != 0)) {
                retval = -EFAULT;
    } else {
        retval = 0;
    }
}
return retval;
}

Я напечатал результаты (то есть массив данных) в read_func и вижу, что чтениеявляется ожидаемым значением, но когда после copy_to_user, когда я печатаю data в пользовательском пространстве, я вижу все нули.Что-то не так с этим фрагментом?

1 Ответ

0 голосов
/ 01 марта 2019

Ваши родители выключены по вызову copy_to_userдумаю вы хотите проверить, является ли ответ copy_to_user != 0.Вместо этого вы ставите sizeof(ABC_T) != 0 в качестве последнего аргумента.Так как sizeof(ABC_T) не равен нулю, ваш звонок в итоге будет copy_to_user((void __user *)arg, &abc, true).

Исправьте ваши парены и посмотрите, получите ли вы лучшие результаты:

if (copy_to_user((void __user *)arg, &abc, sizeof(ABC_T)) != 0) {
    // ...
}
...