как узнать существует ли PID в user mode из модуля ядра
От: reider  
Дата: 05.06.20 10:51
Оценка:
как узнать существует ли PID в user mode из модуля ядра?
Собственно у меня есть следующий код обработчика прерываний:
static irqreturn_t irq_handler_(int irq, void *dev_id, struct pt_regs *regs)
{
    disable_irq(IRQ1);
    struct siginfo info;
    struct task_struct *t;
    memset(&info, 0, sizeof(struct siginfo));
    info.si_signo = SIG_TEST;
    info.si_code = SIG_FRM_KERNEL+1;
    info.si_int = 2345;
    rcu_read_lock();
    PID = ioctl_pid;
    if(PID != 0) {
        t = find_task_by_vpid(PID);
        if(t == NULL){
            printk("no such pid2\n");
            rcu_read_unlock();
        } else {
            rcu_read_unlock();
            int ret = send_sig_info(SIG_TEST, &info, t);    //send the signal
            if (ret < 0) {
                printk("error sending signal2\n");
            }
        }
    } else {
        rcu_read_unlock();
    }
    Clear_CPLD_IRQ_();
    enable_irq(IRQ1);
    return IRQ_HANDLED;
}

И через какое-то время работы я получаю краш следующего содержания:
NIP [c003ba9c] find_task_by_vpid+0x2c/0x4cfind_task_by_vpi d[ 782.391934] Unable to handle kernel paging request for data at address 0x000 00010
[ 782.399498] Faulting instruction address: 0xc003ba9c
[ 782.404538] Oops: Kernel access of bad area, sig: 11 1
[ 782.409927] PREEMPT MPC830x RDB
[ 782.413065] Modules linked in: main
[ 782.416566] NIP: c003ba9c LR: d10bd4a0 CTR: c003ba70
[ 782.421521] REGS: cfff9e20 TRAP: 0300 Not tainted (2.6.29.6-rt23)
[ 782.427853] MSR: 00009032 <EE,ME,IR,DR> CR: 24004484 XER: 20000000
[ 782.434248] DAR: 00000010, DSISR: 20000000
[ 782.438334] TASK = cf8cad80[1251] 'awk' THREAD: cfb0e000
[ 782.443454] GPR00: d10bd4a0 cfff9ed0 cf8cad80 00000000 00000388 00000000 cfff 9f64 00009032
[ 782.451851] GPR08: 00000001 00000000 00000004 c003ba70 00000000 10033b68 1001 9450 00000000
[ 782.460252] GPR16: 100b54c0 c02df6ac c02e1318 c037b948 c037b928 cfff803c 0000 0000 c037b920
[ 782.468652] GPR24: 00000000 00010000 d10be7f0 d10c0000 cfff9ee8 cd4f9e20 d10b e9b8 cfff9ed0
[ 782.477259] NIP [c003ba9c] find_task_by_vpid+0x2c/0x4c
[ 782.482403] LR [d10bd4a0] irq_handler+0x7c/0x104 [main]
[ 782.487611] Call Trace:
[ 782.490058] [cfff9ed0] [cd4f9e20] 0xcd4f9e20 (unreliable)
[ 782.495471] [cfff9ee0] [d10bd4a0] irq_handler+0x7c/0x104 [main]
[ 782.501395] [cfff9f80] [c0058f3c] handle_IRQ_event+0xe0/0x204
[ 782.507143] [cfff9fd0] [c005b4c4] handle_level_irq+0xe0/0x194
[ 782.512899] [cfff9ff0] [c0012e54] call_handle_irq+0x18/0x28
[ 782.518479] [cfb0fdb0] [c0006998] do_IRQ+0xc4/0x174
[ 782.523364] [cfb0fde0] [c0013afc] ret_from_except+0x0/0x14
[ 782.528862] --- Exception: 501 at preempt_schedule+0x88/0xac
[ 782.528875] LR = preempt_schedule+0x78/0xac
[ 782.539030] [cfb0fec0] [c00277b8] do_exit+0x5a8/0x6fc
[ 782.544085] [cfb0ff10] [c0027960] do_group_exit+0x54/0xd8
[ 782.549485] [cfb0ff30] [c0027a0c] sys_exit_group+0x28/0x44
[ 782.554974] [cfb0ff40] [c0013464] ret_from_syscall+0x0/0x38
[ 782.560549] --- Exception: c01 at 0xfe5c318
[ 782.560560] LR = 0xfe5c2e4
[ 782.567755] Instruction dump:
[ 782.570722] 4e800020 7c0802a6 90010004 60000000 9421fff0 7c0802a6 90010014 93 e1000c
[ 782.578510] 7c3f0b78 81220348 7c641b78 38600000 <80a90010> 4bffff55 81610000 800b0004
[ 782.587027] Kernel panic — not syncing: Fatal exception in interrupt
[ 782.593429] Rebooting in 180 seconds..


Как я понимаю если каждый раз не искать task по pid то проблема решиться?
Re: как узнать существует ли PID в user mode из модуля ядра
От: lunc  
Дата: 06.07.20 19:25
Оценка:
Здравствуйте, reider, Вы писали:

R>как узнать существует ли PID в user mode из модуля ядра?


В принципе, так, как Вы и делаете, но не из обработчика прерывания. Глядя на find_task_by_vpid(), которая использует current, думаю, что она будет работать только из контекста процесса или softirq. Не смотрел, чему равен current в прерывании — может вытесненному процессу, а может, как раз нулю. Контекст прерывания должен быть довольно коротким и не здорово в нем по списку процссов ходить. Можно просто добвавить задание, например в work queue, в обработчике прерывания и потом уже в этой workqueue сделать, что нужно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.