2013-12-13 4 views
4

Я попытался преобразовать kprobe в качестве загружаемого модуля ядра.Какова роль неопределенного обработчика исключений (__und_svc) в kprobes?

Я могу запустить образцы, доступные в папке samples/kprobes/ от Дерево ядра.

Если мы сконфигурируем kprobes в ядре (CONFIG_KPROBES), то макрос svc_entry будет расширен с помощью 64 байтов в обработчике __und_svc().

Ссылка: http://lxr.free-electrons.com/source/arch/arm/kernel/entry-armv.S?a=arm#L245

Моя цель состоит в том, не касаясь стороны ядра, сделать KProbe как модуль ядра.

поэтому ядро ​​скомпилировано без включения CONFIG_KPROBES. поэтому макрос svc_entry будет расширен с помощью 0 в __und_svc()

Я хотел бы очиститься от этих сомнений.

  1. Если KProbe обрабатывается исключение неопределенных команд (bcos KProbe только создано), то почему __und_svc() вызываются. Какова роль обработчика __und_svc() относительно kprobes ??

  2. Если 64-байтная память является обязательной, то как распределить без компиляцию ядра. i.e Как сделать это динамически. ??

Передайте свои знания.

+0

Хотя мне нравятся точные вопросы в SO, я боюсь, что это слишком специфично. Вы также пробовали один из списков рассылки, связанных с ядром? –

+0

Да. Я разместил этот вопрос в списке рассылки systemtap, а также в списке рассылки linux-arm. Недостаток в linux-arm пока не опубликован. – Jeyaram

ответ

5

Возможно, вы не получите ответы, так как ваше понимание вещей не очень хорошее, и потребуется некоторое время для любого пользователя на linux-arm-kernel. Прочтите kprobes.txt и подробно изучите архитектуру ARM.

Если kprobe обрабатывается неопределенное исключение инструкции (создаётся только bcos kprobe), то почему вызывается __und_svc(). Какова роль обработчика __und_svc() относительно kprobes?

На ARM, режим 0b11011 является режимомнеопределенной инструкции. Потока, когда не определено инструкцией случается,

  1. lr_und = рс UNDEF инструкции + 4
  2. SPSR_und = CPSR режима, где произошла инструкция.
  3. Сменить режим на ARM с отключенным прерыванием.
  4. PC = вектор база +-

Основной вектор таблица четыре шага расположен в __vectors_start и это только ветвь к vector_und. Код представляет собой макрос, называемый vector_stub, который вызывает разрешение на вызов либо __und_svc, либо __und_usr.Стек - это 4/8k страница, зарезервированная для каждого процесса. Это страница ядра, которая содержит как структуру задачи, так и стек ядра.

KProbe работы путем размещения неопределенные инструкции на код адреса, которые вы хотите исследовать. Т.е. это связано с неопределенным инструктором . Это должно быть довольно очевидно. Он вызывает две процедуры: call_fpe или do_undefinstr(). Вас интересует второй случай, который получает код операции и вызывает call_undef_hook(). Добавьте крючок с register_undef_hook(); который вы можете увидеть arch_init_kprobes(). Основной обратный вызов kprobe_handler вызывается с struct pt_regs *regs, который является дополнительной памятью, зарезервированной в __und_svc. Обратите внимание, например, kretprobe_trampoline(), который играет трюки со стеком, с которым он в настоящее время работает.

Если 64-байтовая память является обязательной, то как распределить без компиляции ядра. i.e Как сделать это динамически.?

Нет, это не так. Вы можете использовать другой механизм, но вам, возможно, придется изменить код kprobes. Скорее всего, вам придется ограничить функциональность. Также возможно полностью перезаписать фрейм стека и зарезервировать дополнительные 64 байта после факта. Это не распределение как в kmalloc(). Это просто добавление/вычитание числа из указателя стека диспетчера. Я бы предположил, что код переписывает обратный адрес из undefined handler для выполнения в контексте (ISR, нижняя половина/поток IRQ, work_queue, задача ядра) адреса kprobed. Но есть, вероятно, дополнительные проблемы, с которыми вы еще не сталкивались. Если arch_init_kprobes() никогда не вызывается, вы всегда можете сделать бронирование в __und_svc; он просто ест 64 байта стека, что сделает его более вероятным, что стек ядра переполнится. То есть, изменение,

__und_svc: 
    @ Always reserve 64 bytes, even if kprobe is not active. 
    svc_entry 64 

arch_init_kprobes() является то, что на самом деле устанавливает функцию.

+0

спасибо за просветляющий 'call_undef_hook()' родственный материал. Более информативный. Но я не могу изменить __und_svc() из entry-armv.S. В commit 'd30a0c8bf99f0e6a7d8c57bd4524039585ffbced' добавлен только этот 64-байтовый. поэтому я пытаюсь понять, для какой функции/ошибки они добавили. – Jeyaram

+0

Просто исправьте свое ядро. Установите * entry-armv.S *, 'svc_entry' с кодом, который настраивает задачу, а затем всегда используйте' svc_entry 64'. Вам не нужно вытаскивать полный набор патчей. 'git diff d30a0c8bf99 ~ 1..d30a0c8bf99' дает мне полный патч. Вы можете сохранить его и запустить 'echo svc_entry.patch | patch -p1'. Или вы спрашиваете, не можете ли вы перекомпилировать ядро ​​и исправить это? Это почти невозможно; вам нужно переписать все коды * arm/kernel/kprobes.c *. –

+0

Мое требование - не применять патч или даже однократное изменение ядра, изменить kprobes как LKM. поэтому у меня нет опций, кроме переписывания arm/kernel/kprobes.c. – Jeyaram