информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Сетевые кракеры и правда о деле ЛевинаГде водятся OGRы
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Google заблокировала 2 с лишним... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / hacking
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
w2k-kernel, блокировка прерываний на всех cpu для smp 22.06.04 14:56  
Автор: leo <Леонид Юрьев> Статус: Elderman
Отредактировано 22.06.04 15:00  Количество правок: 4
<"чистая" ссылка>
Нужно пройтись по регистрам чипсета, поэтому необходимо заблокировать прерывания на всех процессорах. На SMP-системах это не совсем просто...

Я пока сделал через interlocked-зацикливание в DPC, на "идеальном" SMP это всегда работаеет. Но на многих SMP-системах не каждый процессор может непосредственно послать IPI (поставить DPC в очередь) к любому другому, и в результате система может зациклиться.

Кто-нибудь знает про готовые решения?

    // мой код пока примерно такой:

    class TSingleProcessorMode
    {
        KDPC DpcTraps[MAXIMUM_PROCESSORS];
        volatile LONG Stall;
        KIRQL SavedIrql;
        CCHAR CpuCount;
        KPRIORITY SavedPriority;
        static void DpcRoutine(KDPC *pDpc, void *pContext, void *pArg1, void *pArg2);
    public:
        void Initialize();
        void Enter();
        void Exit();
    };

    void TSingleProcessorMode::Initialize()
    {
        RtlZeroMemory(this, sizeof(TSingleProcessorMode));
        CpuCount = (CCHAR) GetNumberOfProcessors();
        if(CpuCount > 1)
        {
            for(CCHAR i = 0; i < CpuCount; i++)
            {
                KeInitializeDpc(&DpcTraps[i], DpcRoutine, this);
                KeSetImportanceDpc(&DpcTraps[i], LowImportance);
                KeSetTargetProcessorDpc(&DpcTraps[i], i);
            }
        }
    }

    void TSingleProcessorMode::DpcRoutine(KDPC *pDpc, void *pContext, void *pArg1, void *pArg2)
    {
        TSingleProcessorMode *pThis = (TSingleProcessorMode *) pContext;

        InterlockedDecrement(&pThis->Stall);
        do
            __Crt::ProcessorPause();
        while(pThis->Stall > 0);

        if(pThis->Stall >= 0)
        {
            KIRQL Irql;
            KeRaiseIrql(HIGH_LEVEL, &Irql);
            DbgPrint("SingleProcessorMode: cpu %d stalled\n", KeGetCurrentProcessorNumber());
            do
                __Crt::ProcessorPause();
            while(pThis->Stall >= 0);
            KeLowerIrql(Irql);
        }
    }

    void TSingleProcessorMode::Enter()
    {
        DbgPrint("SingleProcessorMode: entering\n");
        if(CpuCount > 1)
        {
            SavedPriority = KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY);
            KAFFINITY ActiveProcessors = KeQueryActiveProcessors();
            KeRaiseIrql(DISPATCH_LEVEL, &SavedIrql);
            CCHAR CurrentProcessor = (CCHAR) KeGetCurrentProcessorNumber();
            Stall = 1;
            for(CCHAR i = CpuCount - 1; i >= 0; i--)
                if(i != CurrentProcessor && (ActiveProcessors & (1u << i)) != 0)
                {
                    InterlockedIncrement(&Stall);
                    KeInsertQueueDpc(&DpcTraps[i], 0, 0);
                }
            KeLowerIrql(SavedIrql);
            InterlockedDecrement(&Stall);
            __Crt::ProcessorPause();
            KeRaiseIrql(HIGH_LEVEL, &SavedIrql);
            if(Stall > 0)
            {
                DbgPrint("SingleProcessorMode: wait for %d cpu\n", Stall);
                KeLowerIrql(SavedIrql);
                do
                    __Crt::ProcessorPause();
                while(Stall > 0);
                KeRaiseIrql(HIGH_LEVEL, &SavedIrql);
            }
        }
        else
            KeRaiseIrql(HIGH_LEVEL, &SavedIrql);
    }

    void TSingleProcessorMode::Exit()
    {
        if(CpuCount > 1)
        {
            InterlockedExchange(&Stall, -1);
            KeLowerIrql(SavedIrql);
            KeSetPriorityThread(KeGetCurrentThread(), SavedPriority);
        }
        else
            KeLowerIrql(SavedIrql);
        DbgPrint("SingleProcessorMode: exit\n");
    }

---
красота получилась... 24.06.04 12:50  
Автор: leo <Леонид Юрьев> Статус: Elderman
Отредактировано 24.06.04 12:51  Количество правок: 1
<"чистая" ссылка>
пришлось повозиться, но получилось красиво :-)

итоговая DPC-функция
На Борланде, Да еще объектном!!! Мсье понимает толк в извращениях... 8-) 23.06.04 04:37  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
cl 23.06.04 09:41  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.2179 for 80x86

из комплекта Windows DDK 3790
А TSingleProcessorMode по привычке? 24.06.04 08:12  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Не совсем так 24.06.04 11:25  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
Я придерживаюсь такой идеи:
имена типов вида CBlaBlaBla - для классов C++ с конструкторами;
имена типов вида TBlaBlaBla - для классов С++ без конструкторов и структур C;
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach