能力值:
( LV2,RANK:10 )
|
-
-
2 楼
提升IRQL至DISPATCH_LEVEL行不行
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
提升IRQL至DISPATCH_LEVEL,对于只有一个CPU的机器是可以的,多处理器下就不行了,有没有好办法啊?
|
能力值:
( LV3,RANK:20 )
|
-
-
4 楼
先把该函数头写成jmp到别的地方空循环或直接返回失败
自己KeDelayExecution一下,让别的线程运行完前20字节.
把前20字节改回来.
把函数头改回来.
|
能力值:
( LV12,RANK:450 )
|
-
-
5 楼
投递dpc、ipi。
参见windows内核调试子系统是怎么冻结别的cpu的。
|
能力值:
( LV6,RANK:90 )
|
-
-
6 楼
受 weolar的启发,想起在 <软件调试>里提到 kdEnterDebugger可以 让 系统进入单一任务状态,冻结其他cpu.它的调用链好像是这样的吧.
KdEnterDebugger->KeFreezeExcution->KeDisableInterrupt->_disable()
__INTRIN_INLINE void _disable(void)
{
__asm__("cli");
}
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
cli不也一样是对单CPU来说的吗?
可以看下关于spinlock..那个偶也没玩过
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
谢谢大家.....
看来还是投递DPC会比较通用一些,起码移植性比较好一些.
|
能力值:
( LV6,RANK:90 )
|
-
-
9 楼
我查reactos,最后的disable()函数是这样的,但一个cli就可以冻结其他cpu。。我也比较困惑,不知道是不是reactos没有完全实现kdenterdebugger的功能
|
能力值:
( LV3,RANK:30 )
|
-
-
10 楼
楼上的是怎么得出一个CPU cli了, 冻结了其它CPU结论的?
|
能力值:
( LV6,RANK:90 )
|
-
-
11 楼
看reactos源码, 一路跟踪 KdEnterDebugger()下来发现此函数关键操作就一个cli,
可能reactos没有完全实现kdEnterDebugger()
|
能力值:
( LV3,RANK:30 )
|
-
-
12 楼
但是,wrk也是这样的
|
能力值:
( LV6,RANK:90 )
|
-
-
13 楼
哪位高人能给我们解惑下
|
能力值:
( LV3,RANK:30 )
|
-
-
14 楼
刚刚试了试, cli并不是理解的那样只本禁止本地中断, 我的双核系统在cli后, 其它CPU也不响应中断了
|
能力值:
( LV6,RANK:90 )
|
-
-
15 楼
cli应该是全局的吧,楼上也验证了这点.
我的疑惑不是这里,虽说所有cpu都不能响应中断,但并不是说所用cpu都停止运行了,它们还是仍然在继续跑(如果之前它们都在跑指令流的话).只是此时它们是没法处理可屏蔽中断了.
我想在关中断的情况下,只要指令流中有会引发软硬中断的系统调用,它们应该会很快被阻塞住,即被冻结.不知道是不是这样.
我猜测的流程是这样..
假设有cpu0 cpu1
当前线程在cpu0 上执行cli指令后,就继续执行后面的指令.cli执行后,cpu1并不是立即被冻结,而是继续在原有的指令流上跑,直到碰到会引发软硬中断的指令,因被关中断,就被阻塞住了,即被冻结.而指令流中引发软硬中断的指令出现的几率实在是太大了,随便一个系统调用就是一个软中断.所以,cpu1在关中断后会被迅速冻结.而cpu0则同时继续跑,直到后面的sti,然后两个cpu又一起运作.
没学过多核方面的咚咚,以上纯属猜测..抛砖引玉,还望深藏不露的大大们露一手
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
我反汇编了一下KeFreezeExecution
lkd> u KeFreezeExecution
nt!KeFreezeExecution:
80500922 e869000000 call nt!KeDisableInterrupts (80500990)
80500927 c705403f558004000000 mov dword ptr [nt!KiFreezeFlag (80553f40)],4 //设置了全局变量
80500931 c20800 ret 8 //这函数没用到参数,为什么返回时会带一个8,不理解啊?难道KeFreezeExecution有参数,代码里没用到?
lkd> u KeDisableInterrupts L10
nt!KeDisableInterrupts:
80500990 9c pushfd
80500991 58 pop eax
80500992 2500020000 and eax,200h //这里和EFLAGS寄存器的IF位进行与操作,好象也不是测试IF位是否被清除.
80500997 c1e809 shr eax,9 //这里移位有什么意思啊?没看懂
8050099a fa cli //清除IF位
8050099b c3 ret
不明白?
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
昨天看了大家的回复,今天特地去了书店看了<<软件调试>>,其中的关于蓝屏描述的那一章里,我在里面看到了一个信息:WINDOWS在蓝屏的时候会调用KiSendXXXX函数来冻结其他CPU.隔了几个小时回到家,这个函数全名想不起来了.....郁闷.似乎这个函数可以实现同步.....
|
能力值:
( LV6,RANK:90 )
|
-
-
18 楼
nt!KeFreezeExecution:
80500922 e869000000 call nt!KeDisableInterrupts (80500990)
80500927 c705403f558004000000 mov dword ptr [nt!KiFreezeFlag (80553f40)],4 //设置了全局变量
80500931 c20800 ret 8 //这函数没用到参数,为什么返回时会带一个8,不理解啊?难道KeFreezeExecution有参数,代码里没用到?
的确是有参数,楼主反汇编xp出来的代码也是一句cli,呵呵,那一句cli应该是能冻结其他cpu,估计就是我的那个理解吧。^_^
|
能力值:
( LV12,RANK:450 )
|
-
-
19 楼
你们都说错了。我还是说清楚吧,KeFreezeExecution在单核下确实只要cli就行了。
但在多核下肯定不行。事实上cpu的apic早就提供了ipi机制,也就是处理器间中断。
KeFreezeExecution首先判断本cpu有没有被中断,如果是则调用KiIpiServiceRoutine响应ipi例程。
否则调用KiIpiSend发送IPI中断。这是个NMI(不可屏蔽),别的cpu会由apic执行KiIpiServiceRoutine。
至于KiIpiSend是怎么个原理,这得看inter手册。我只记得是设置apic的某个寄存器……
关于这部分的详细实现可以看kgdb的代码(arch/x86/Kconfig和arch/x86/kernel都可以看看),虽然是linux的,但原理是相似的。
|
能力值:
( LV12,RANK:450 )
|
-
-
20 楼
另外再提一下,inline hook如果只需要修改8个字节一下,
intel提供了个lock cmpxchg8b qword ptr [xxx];指令可以原子操作,比用各种同步操作方便多了。
不过以防万一,记得cmpxchg8b完了后再刷新一下TLB。
|
能力值:
( LV6,RANK:90 )
|
-
-
21 楼
多谢weolar,解答疑惑,偶去狂补下ipi
|
能力值:
( LV2,RANK:10 )
|
-
-
22 楼
[QUOTE=weolar;803291]另外再提一下,inline hook如果只需要修改8个字节一下,
intel提供了个lock cmpxchg8b qword ptr [xxx];指令可以原子操作,比用各种同步操作方便多了。
不过以防万一,记得cmpxchg8b完了后再刷新一下TLB。[/QUOTE]
能说一下如何刷新TLB吗?感激万分.......
|
能力值:
( LV6,RANK:90 )
|
-
-
23 楼
miflushtlb(),
不知道干嘛要冲刷tlb,只是替换内存某区域的内容。又不涉及页面表项的改变
|
能力值:
( LV4,RANK:50 )
|
-
-
24 楼
提升IRQL本身是不是创建了自旋锁。个人认为在处理多CPU同步的问题,使用自旋锁是最明智的,其他同步事件都不好使。
|
能力值:
( LV3,RANK:30 )
|
-
-
25 楼
显然他说这话没经过大脑
|
|
|