Linux kernel 写cr0(读cr0()| 0x10000)做什么?

Linux kernel 写cr0(读cr0()| 0x10000)做什么?,linux-kernel,linux-device-driver,Linux Kernel,Linux Device Driver,我在网上搜索了很多,但没有找到关于write\u cr0(read\u cr0()| 0x10000)真正做什么的简短解释。它与Linux内核和开发LKM有关。我想知道它到底做了什么,以及它的安全问题是什么 它用于删除syscall表上的写保护。 但它到底是如何工作的?CR0是x86 CPU上可用的控制寄存器之一,它包含控制与内存保护、多任务处理、分页等相关的CPU功能的标志。您可以在本手册第3卷第2.5节中找到完整的描述 这些寄存器由编译器通常不会生成的特殊指令访问,因此read\u cr0(

我在网上搜索了很多,但没有找到关于
write\u cr0(read\u cr0()| 0x10000)
真正做什么的简短解释。它与Linux内核和开发LKM有关。我想知道它到底做了什么,以及它的安全问题是什么

它用于删除syscall表上的写保护。 但它到底是如何工作的?CR0是x86 CPU上可用的控制寄存器之一,它包含控制与内存保护、多任务处理、分页等相关的CPU功能的标志。您可以在本手册第3卷第2.5节中找到完整的描述

这些寄存器由编译器通常不会生成的特殊指令访问,因此
read\u cr0()
是一个函数,它执行指令读取该寄存器(通过内联汇编),并将结果返回到通用寄存器中。同样地,
write\u cr0()
写入此寄存器

函数调用可能是内联的,因此生成的代码类似于

mov eax, cr0
or eax, 0x10000
mov cr0, eax

带有
0x10000
的OR设置位16,即写保护位。在早期的32位x86 CPU上,无论页面是否标记为只读,始终允许在主管级别(如内核)运行的代码写入所有虚拟内存。此位使之成为可选的,因此当设置此位时,此类访问将导致页面错误。这行代码可能跟在前一行之后,前一行暂时清除了位。

您所说的是什么体系结构?你读过哪些文档?它是否说明了位16的用途?下一次,您应该添加内核版本、文件和行号,这样我们可以提供更好的帮助(可能还有一个链接,例如[我建议您使用它,以便快速理解内核结构])。注:
write\u cr0
是一个包装器:在虚拟机上,它有不同的含义,在真实的CPU上,它调用
native\u write\u cr0
,但它不是一个内联函数(在任何情况下,使用CR寄存器已经很慢)。