KeStallExecutionProcessor в обработчике прерывания

Тема в разделе "WASM.NT.KERNEL", создана пользователем katrus, 11 ноя 2009.

  1. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    В обработчике прерывания клавиатуры (пс2) есть вызов KeStallExecutionProcessor. Судя по мсдн эта функция может быть вызвана с произвольным уровнем IRQL. Но, как оказалось, в Вин7 KeStallExecutionProcessor вызывает KeSetSystemGroupAffinityThread которая в свою очередь работает только при IRQL <= APC_LEVEL.

    Имеется в наличии миндамп совершенно явно показывающой, что прерывание произошло в контексте потока бегущего с HIGH_LEVEL, и вызов KeSetSystemGroupAffinityThread бросает IRQL_NOT_LESS_OR_EQUAL.

    Теперь самое удивительное... Стандартный обработчик прерываний от клавиатуры i8042I8042prt!KeyboardInterruptService сам по себе вызывает KeStallExecutionProcessor. Исходник KeyboardInterruptService можно найти в DDK. Также я пореверсил i8042prt.sys в Вин7, чтоб достоверно убедиться, что это так. Совершенно непонятно почему KeyboardInterruptService может нормально работать в стандартном обработчилке прерывания.
     
  2. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Driver Verifier включи.
     
  3. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Фокус в том, что у себя я такую проблему не могу восоздать.
     
  4. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    А чем можно заменить KeStallExecutionProcessor , чтоб гаратированно выполнялось даже на высокоприоритетный IRQL?
     
  5. Forever

    Forever Виталий

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    244
    Циклом типа такого:
    int i = 0;
    while (true) {
    __asm nop;
    ++ i;
    if ( i == 10000000 ) {
    break;
    }
    }
    Правда это будет работать только в случае, если тебе не важна точная величина задержки.
     
  6. AntiFreeze

    AntiFreeze Дмитрий

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    65
    KeStallExecutionProcessor выполняется на любом IRQL. В частности, я пробовал вызывать на IPI_LEVEL, на Win7.
    Ради интереса посмотрел код hal!KeStallExecutionProcessor. KeSetSystemGroupAffinityThread там не нашёл (тоже Win7).
    Возможно, у вас какая-то другая проблема или специфичный hal ? Дайте больше информации.
     
  7. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    katrus
    Зачем KeStallExecutionProcessor может запрашивать привязку? Возможно, для того, чтобы не допустить перепланирование потока на _других_ процессорах. Почему KeSetSystemGroupAffinityThread должна выполняться на IRQL ниже DPC? Вероятно, из-за того, что при вызове может потребоваться перепланирование потока на другом процессоре – а на уровне DPC+ это слегка невозможно. Может ли быть, что Майкрософт жульничает и позволяет вызывать KeSetSystemGroupAffinityThread на повышенных IRQL если целевой процессор\группа совпадают с текущим? Но это не делает чувства – на таких IRQL поток и так не планируется. Что ж, посмотрим на дизасм.

    [зырк-зырк]
    KeStallExecutionProcessor может придти к nt!KeSetSystemGroupAffinityThread только таким путём:
    hal!KeStallExecutionProcessor -> hal!HalpTscStallExecutionProcessor -> nt!KeSetSystemGroupAffinityThread

    Код (Text):
    1. lkd> vertarget
    2. Windows 7 Kernel Version 7600 MP (2 procs) Free x64
    3.  
    4. lkd> uf hal!HalpTscStallExecutionProcessor
    5. hal!HalpTscStallExecutionProcessor:
    6. [..]
    7. hal!HalpTscStallExecutionProcessor+0x3c:
    8. fffff800`0281f110 mov     rax,cr8           ; <<<<
    9. fffff800`0281f114 cmp     al,2              ; <<<< Ta-da!
    10. fffff800`0281f116 jae     hal!HalpTscStallExecutionProcessor+0x6b (fffff800`0281f13f)  Branch
    11.  
    12. hal!HalpTscStallExecutionProcessor+0x44:
    13. fffff800`0281f118 xor     ecx,ecx
    14. fffff800`0281f11a mov     sil,1
    15. fffff800`0281f11d call    qword ptr [hal!_imp_KeGetCurrentProcessorNumberEx (fffff800`0282d5e8)]
    16. fffff800`0281f123 lea     rcx,[rsp+20h]
    17. fffff800`0281f128 mov     edx,eax
    18. fffff800`0281f12a call    hal!KeProcessorGroupAffinity (fffff800`0282c118)
    19. fffff800`0281f12f lea     rdx,[rsp+30h]
    20. fffff800`0281f134 lea     rcx,[rsp+20h]
    21. fffff800`0281f139 call    qword ptr [hal!_imp_KeSetSystemGroupAffinityThread (fffff800`0282d1c8)]
    22. ; ^ больше путей прихода к KeSetSystemGroupAffinityThread в этой функции нет ^
    23.  
    24. hal!HalpTscStallExecutionProcessor+0x6b:
    25. fffff800`0281f13f rdtsc
    26. [..]
    Таким образом, всё решено наилучшим образом и без читерства – простой проверкой текущего IQRL и условным переходом. Действительно, незачем привязываться к процессору\группе на таких IRQL.