可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This question already has an answer here:
-
Is there a way to disable CPU cache (L1/L2) on a Linux system?
2 answers
I am trying to disable the internal and external memory cache of my CPU, my configuration is above:
-DELL Precision WorkStation
-Intel Core 2 Duo E6550 2.33 GHz
-Ubuntu 8.10
I've tried to disable it through BIOS, but it apears that DELL computers doesn't let users to access cache memory, I found then another way, it is to disable cache programmaticaly, Intel Architecture manual A.3 indicates that cr0 register can be set to disable cache by setting bit 30, i wrote the above code then :
invd
mov eax,cr0
mov eax,40000000H ;set bit 30
mov cr0,eax
The program compiled successfully, but when I try to run exe file,it Seg Faults (i'm using NASM)
Anyone can help me?
回答1:
Please note that even if you're in ring 0 because you're in the kernel or run your tool on DOS in protected mode etc, moving 0x40000000 to cr0 will definitely cause a disaster. You see, the control register (cr0) controls all sorts of things that effect the way the processor operates, such as enabling paging, protected mode (not directly) etc. If you unset all those bits, you will end up in a totally different environment and getting a segmentation fault is not surprising at all if you had paging enabled previously.
You should do this instead:
mov eax,cr0
or eax, 40000000H ;set bit 30 without clearing the others
mov cr0,eax
回答2:
That should be "or eax,40000000h" to set bit 30.
But a user process won't be allowed to change control registers anyways. You'll need to make the change in the kernel. I wouldn't doubt that there's some system call or device interface to do what you want.
回答3:
I found this document on the control register at wikipedia. That confirms what you say:
The CR0 register is 32 bits long on
the 386 and higher processors. On
x86-64 processors in long mode, it
(and the other control registers) are
64 bits long. CR0 has various control
flags that modify the basic operation
of the processor.
Bit Name Full Name Description
31 PG Paging If 1,
enable paging and use the CR3
register, else disable paging
30 CD Cache disable
This led me to the Intel 64 and IA-32 Architectures Software Developer’s Manual. It says, and I quote here again:
Most systems restrict access to system
registers (other than the EFLAGS
register) by application programs.
Systems can be designed, however,
where all programs and procedures run
at the most privileged level
(privilege level 0). In such a case,
appli- cation programs would be
allowed to modify the system
registers.
Probably your program is semantically correctYour code has a bug that will probably lock up the machine, but even fixed it would need to run in supervisor mode. Note that you need to or
the value in so as not to affect the other registers (as others have noted).
回答4:
You would need to do this from a driver on windows or linux as only the kernel runs in rung 0 and I don't think you could do it for one process, you would have to do it for all of them.
I'm assuming that you're trying to do memory writes without caching?
Perhaps you want to look into cache flush instructions if your trying to do scary threading code?
回答5:
I would be surprised if any code running in user mode would be able to do that - that would be one hell of a DoS attack.
回答6:
I think you have to log in as root to do that. I was wondering why would you want to disable the cache, in all likelyhood disabling the L1 and L2 will cause the computer to lock up.
回答7:
Actually, it seems to Seg fault at the second instruction (mov eax,cr0), I've just tried to comment all other instructions, and it did seg faults....
But I still don't know why??
I've tryed also to compile/run it in runlevel 0 (telinit 1 command line as root) but it still seg faults...
I'm wondering if the Control Register 0 (cr0) is not write-protected then...?
回答8:
I could finally disable the cache by running the code as Ring0, Thank you DrJokepu, the link you gave me was exactly what I needed..
but I have new problem, cause when I insert the new module who disables the cache, that works grate, I just have to insmod my .ko file, and the procedure init where my code is written is called.
but now I would like to re-enable the cache programmatically again, It should work with writing a clean procedure witch reset the cr0, and call it when remove the module by rmmod it, but actually it does nothing...I can check at cat /proc/modules and it really removed it, but apparently, it hasn't called my clean procedure before removing it....
help?