В моем драйвере ядра есть обработчик ioctl, который читает и записывает ioctl. У меня также есть приложение пользовательского пространства, которое использует этот IOCTL для записи / чтения данных.
Когда я использую этот ioctl в своем приложении пользовательского пространства, он вызывает OOPS ядра с "BUG: unable to handle kernel paging request at ffffffffffffffff"
Фрагмент пользовательского пространства:
typedef struct abc_T {
uint8_t size;
uint8_t addr;
uint8_t data[64];
} abc_T;
// Read
int abc_read(uint8_t addr, uint8_t size, uint8_t * data) {
abc_T abc = {};
int fd;
int retval = 0;
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);
}
close(fd);
return retval;
}
// Write
int abc_write(uint8_t addr, uint8_t size, uint8_t * data) {
abc_T abc = {};
int fd;
int retval = 0;
abc.size = size;
abc.addr = addr;
memcpy(abc.data, data, size);
fd = open("/dev/"ABC_DEV, O_RDWR);
if (fd >=0) {
retval = ioctl(fd, WRITE_ABC, &abc);
}
close(fd);
return retval;
}
Ядро:
static int ABC_ioctl(struct file * file, uint cmd, ulong arg)
{
ABC_T abc;
int retval;
if (copy_from_user(&abc, (void *)arg,
sizeof(ABC_T)) != 0) {
return -EFAULT;
}
switch(cmd) {
case READ_ABC:
retval = read_func(&abc);
if (retval == 0) {
if (copy_to_user((void *)arg, &abc,
sizeof(ABC_T)) != 0) {
retval = -EFAULT;
} else {
retval = 0;
}
}
break;
case WRITE_ABC:
ret_val = write_func(&abc);
break;
return retval;
}
Error:
BUG: unable to handle kernel paging request at ffffffffffffffff
IP: [<ffffffffffffffff>] 0xfffffffffffffffe
PGD 1e0f067 PUD 1e11067 PMD 0
Oops: 0010 [#1] PREEMPT SMP
...
Call Trace:
[<ffffffff8117a8b8>] ? vfs_write+0x198/0x1b0
[<ffffffff8118ccc0>] ? SyS_ioctl+0x80/0x90
[<ffffffff8117b139>] ? SyS_write+0x49/0xa0
[<ffffffff819af419>] ? system_call_fastpath+0x16/0x1b
Code: Bad RIP value.
RIP [<ffffffffffffffff>] 0xfffffffffffffffe
...
Не уверен, что не так в этом.
Может кто-нибудь, пожалуйста, помогите?
Обновление: с размером массива 32 в abc_T я не вижу проблемы. Но когда я изменяю размер массива на 64, я вижу проблему. Любая помощь будет оценена.
Обновление 2: при размере массива 64 в abc_T, если чтение / запись size
равно <= 32, проблем не возникает, только когда <code>size для чтения / записи больше 32, наблюдается сбой ,