<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=CPU_Bugs</id>
	<title>CPU Bugs - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=CPU_Bugs"/>
	<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=CPU_Bugs&amp;action=history"/>
	<updated>2026-04-05T12:31:49Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=CPU_Bugs&amp;diff=1105&amp;oldid=prev</id>
		<title>Zhang3：创建页面，内容为“计算机是由人类制造的，因此天生容易出错。 本页描述了各种型号和品牌的已知错误。  == 影响几乎所有现代架构 ==  === Spectre ===  SPECTE漏洞会影响1995年后制造的大多数现代CPU，这些CPU实现了无序执行(x86、x86_64、ARM、AMD，可能还有更多)，并允许用户代码读取物理内存。 没有针对此问题的最佳软件修复程序。 有关更多详细信息，请参阅(https://spectreattac…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=CPU_Bugs&amp;diff=1105&amp;oldid=prev"/>
		<updated>2022-03-31T13:44:55Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“计算机是由人类制造的，因此天生容易出错。 本页描述了各种型号和品牌的已知错误。  == 影响几乎所有现代架构 ==  === Spectre ===  SPECTE漏洞会影响1995年后制造的大多数现代CPU，这些CPU实现了无序执行(x86、x86_64、ARM、AMD，可能还有更多)，并允许用户代码读取物理内存。 没有针对此问题的最佳软件修复程序。 有关更多详细信息，请参阅(https://spectreattac…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;计算机是由人类制造的，因此天生容易出错。 本页描述了各种型号和品牌的已知错误。&lt;br /&gt;
&lt;br /&gt;
== 影响几乎所有现代架构 ==&lt;br /&gt;
&lt;br /&gt;
=== Spectre ===&lt;br /&gt;
&lt;br /&gt;
SPECTE漏洞会影响1995年后制造的大多数现代CPU，这些CPU实现了无序执行(x86、x86_64、ARM、AMD，可能还有更多)，并允许用户代码读取物理内存。 没有针对此问题的最佳软件修复程序。 有关更多详细信息，请参阅(https://spectreattack.com/spectre.pdf 这里）。&lt;br /&gt;
&lt;br /&gt;
==x86功能不全==&lt;br /&gt;
&lt;br /&gt;
=== ESP未清除 ===&lt;br /&gt;
&lt;br /&gt;
当返回到16位模式时，x86 IRET不会清除堆栈寄存器的高位（32:16）。 因此，ESP的内核高16位可能会泄漏到用户空间。 对于64位内核到16位用户空间过渡也是如此。&lt;br /&gt;
&lt;br /&gt;
====缓解措施====&lt;br /&gt;
一种缓解措施是简单地不允许用户模式下的16位代码。 但是，Linux可以执行以下操作来解决此问题: 在32位模式下，它保留了一个用于固定堆栈指针的段。 如果它检测到有16位堆栈返回用户空间，它会设置该段的基址，这样就可以在ESP中设置泄漏的位，而无需移动实际的堆栈指针，然后将该段作为堆栈段加载。 因此，泄漏的比特将等于原始比特，因此不会造成任何损害。&lt;br /&gt;
&lt;br /&gt;
在64位模式下，由于缺乏分段支持，这是不可能的。 因此，Linux采用了另一种方法，并且总是在引导时泄漏随机选择的位。 在引导期间，Linux为每个CPU分配48字节作为ESPFIX堆栈(实际上，只要同一页上有剩余空间，所有CPU都将使用同一页，只是其上的偏移量不同)。 这48个字节被映射到内核空间中，因此ESP的泄漏位是完全随机的。 如果检测到返回到16位堆栈，则在将堆栈切换到该地址并执行返回之前，将返回帧复制到ESPFIX堆栈中。 由于这可能会失败，因此ESPFIX堆栈被映射为只读(对于副本，使用同一页的可写映射)。 因此，如果IRET成功，则不会将任何内容写入ESPFIX堆栈，并且一切正常。 但是，如果出现问题，因为CPU已经在Ring 0中运行，它不会将堆栈切换回原来的位置。 它会尝试将中断帧写入堆栈，但由于堆栈是只读的，因此该操作将失败。 因此，会导致双重故障，这时使用双重故障处理程序 (使用IST堆栈运行) 会更改信息，使其看起来像是在IRET指令上发生的一般保护故障。 然后GPF处理程序就可以正常工作了。&lt;br /&gt;
&lt;br /&gt;
这样，泄漏的位将不等于用户空间在中断开始时拥有的位，但它们在每次引导时都是随机的。 由于ESPFIX堆栈如此之小，大量cpu将具有相同的泄漏ESP位，因此没有重要数据泄漏。&lt;br /&gt;
&lt;br /&gt;
===空选择器加载可能无法清除MSR_GS_BASE===&lt;br /&gt;
&lt;br /&gt;
如果加载了空选择器，英特尔CPU会不指定MSR_GS_BASE会发生什么情况。 英特尔cpu似乎将其加载为零，AMD cpu保留了以前的值 (现在记录在AMD64架构程序员手册第2卷: 系统编程中)。 如果内核试图优化缓慢的MSR操作，那么上下文切换需要考虑这个细节。&lt;br /&gt;
&lt;br /&gt;
==== 缓解措施 ====&lt;br /&gt;
不要将空选择器加载到GS中，以为它会更改GS.base寄存器。 始终使用MSR操作，除非在具有WRFSGSBASE功能的CPU上运行，在这种情况下，GS.base地址可以使用WRGSBASE指令设置。&lt;br /&gt;
&lt;br /&gt;
=== FXSAVE/FNSAVE ===&lt;br /&gt;
&lt;br /&gt;
英特尔和AMD在保存/恢复的上下文方面有所不同。AMD CPU不保存/恢复某些部分 (FIP/FOP) 只有在异常挂起时 (见CVE-2006-1056)&lt;br /&gt;
&lt;br /&gt;
=== SYSRET ===&lt;br /&gt;
&lt;br /&gt;
英特尔CPU不能正确处理非规范返回地址。  如果执行SYSRET时RCX中存在非规范地址，则在带有CPL3寄存器的CPL0中将会出现一般保护错误。(见CVE-2006-0744)&lt;br /&gt;
&lt;br /&gt;
==== 缓解措施 ====&lt;br /&gt;
要执行syscall指令以使其跳转到具有非规范地址的内核空间，唯一可能的方法是将该指令放在地址0x00007ffffffffffe。 这是无效的，因为CPU无处可返回 (返回地址无效)。 为了防止这种情况发生，可以禁止在地址0x00007FFFFFF000处映射可执行页面。 或者，可以直接处理该问题：如果返回地址设置了前16位中的任何一位，则使用iret指令返回到用户空间。 或者，构造必要的堆栈框架，然后直接跳转到GPF处理程序。&lt;br /&gt;
&lt;br /&gt;
=== SS选择器 ===&lt;br /&gt;
&lt;br /&gt;
在AMD CPU上，当内核中断到达(将SS设置为空)并且线程被切换并通过SYSRET返回到用户空间时，SS选择器可能变得不可用。 数值SS值是正确的，但是描述符缓存是错误的。 这只影响SS的32位兼容模式使用。&lt;br /&gt;
&lt;br /&gt;
====缓解措施====&lt;br /&gt;
在内核中断后不要切换线程 (即: 返回用户空间或处理系统调用时，仅从最外层堆栈层切换线程)。 或者，如果在内核中断后切换线程，请始终通过IRET返回。 在某些情况下，您无论如何都需要在系统调用之后跳转到较慢的IRET返回路径，所以您也可以将此作为一种情况。&lt;br /&gt;
&lt;br /&gt;
=== PUSH选择器 ===&lt;br /&gt;
&lt;br /&gt;
在英特尔CPU上，在32位保护模式下运行时，PUSH只会修改堆栈的低16位，并在那里写入选择器。 高16位保持不变。 AMD cpu不这样做。 堆栈的某些部分未初始化可能会产生一些安全影响。&lt;br /&gt;
&lt;br /&gt;
注意：这适用于每次将选择器推送到堆栈时。 因此，在某种中断之后，推送指令和隐式推送都会受到影响。&lt;br /&gt;
&lt;br /&gt;
==缓解措施====&lt;br /&gt;
从堆栈中读取选择器值时，始终屏蔽掉您感兴趣的位。 很多时候，重要的信息只是选择器的RPL (已经包含了信息，无论选择器是内核还是用户空间)，或者TI位。 很少需要实际的表索引。 这样做还可以加强内核中读取选择器的所有部分，防止以后对GDT的修改。&lt;br /&gt;
&lt;br /&gt;
=== NMI中断的嵌套 ===&lt;br /&gt;
&lt;br /&gt;
如果CPU正在执行NMI中断处理程序，CPU保证在执行IRET之前保持NMI屏蔽。 然而，如果出于某种原因，NMI触发了执行IRET的其他异常，则NMI可能会再次触发，可能会覆盖其自己的堆栈，因为在AMD64上，它与IST堆栈一起运行(如果SMI出于某种原因触发IRET，则有趣问题就会发生)。&lt;br /&gt;
&lt;br /&gt;
== Intel ==&lt;br /&gt;
&lt;br /&gt;
=== Transactional Synchronization eXtensions (TSX) Bug ===&lt;br /&gt;
&lt;br /&gt;
2014年8月，英特尔宣布在Haswell、Haswell-E、Haswell-EP和早期Broadwell CPU上的TSX实施中存在错误，导致通过微码（microcode）更新在受影响的CPU上禁用TSX功能。 该错误已在启用vPro的核心M-5Y70 Broadwell CPU的2014年11月F-0中修复。&lt;br /&gt;
&lt;br /&gt;
=== Extended Page Table (EPT) Bug ===&lt;br /&gt;
&lt;br /&gt;
启用EPT时，从MOV到CR3可能会导致意外的页面错误或错误的页面转换。&lt;br /&gt;
&lt;br /&gt;
受影响的处理器:&lt;br /&gt;
*Intel Xeon E5-#### v2，其中####是一个4位数字，后跟一个可选字母。&lt;br /&gt;
*Intel Xeon E7-#### v2，其中#是4位数字。&lt;br /&gt;
*Intel Xeon E3-12## v2，其中##是2位数字，后跟一个可选字母。&lt;br /&gt;
&lt;br /&gt;
=== F00F Bug ===&lt;br /&gt;
&lt;br /&gt;
影响：英特尔i586系列(奔腾1、奔腾MMX、奔腾OverDrive、奔腾MMX OverDrive)&lt;br /&gt;
&lt;br /&gt;
此错误是由于执行锁定CMPXCHG8B eax (F0 0F C7 C8) 而导致的，该错误包含两个操作代码错误，一个不允许的锁定和一个非内存目标，并试图缓存结果，它使cpu进入死锁状态，锁定了所涉及的整个计算机。&lt;br /&gt;
&lt;br /&gt;
要修复此错误，应将包含无效操作码的[[IDT]]条目标记为不可缓存或可写，以消除一个必要的因素，或者将同一页标记为不可写，这会进一步混淆处理器，而将其标记为pagefault处理程序，而不是死锁。 如果要禁用分页，唯一的解决办法是禁用CPU的缓存，这还远远不是很有效。 对各种解决方案的进一步讨论在 [http://www.x86.org/errat/12月97/f00fbug.htm 这里]。&lt;br /&gt;
&lt;br /&gt;
我们可以通过[[CPUID]]指令检查处理器是否为奔腾。 在EAX=1的情况下调用它将返回EAX中的CPU签名。 我们可以从CPU签名中提取族号，并将其与5进行比较，因为奔腾属于族5。&lt;br /&gt;
&lt;br /&gt;
=== FDIV bug ===&lt;br /&gt;
&lt;br /&gt;
奔腾FDIV错误是英特尔P5奔腾浮点单元(FPU)中的错误。 由于该错误，处理器可能会返回不正确的十进制结果，这对于数学和科学等领域所需的精确计算来说是一个麻烦的问题。 由Lynchburg学院的托马斯·R·奈利教授发现，英特尔将该错误归因于浮点除法电路使用的查找表中缺少条目。&lt;br /&gt;
&lt;br /&gt;
此问题仅在原始奔腾处理器的某些型号上发生。 任何一款时钟速度至少为120MHz的奔腾系列处理器都足够新，不会有这种缺陷。&lt;br /&gt;
&lt;br /&gt;
===Buggy HLT===&lt;br /&gt;
&lt;br /&gt;
最初的100 MHz Intel DX芯片中的一些具有错误的HLT状态，促使Linux的开发人员实现了在这些芯片上运行时使用的 “no-hlt” 选项，但这已在以后的芯片中修复。&lt;br /&gt;
&lt;br /&gt;
=== Core-microarchitecture Bugs ===&lt;br /&gt;
&lt;br /&gt;
[http://www.geek.com/images/geeknews/2006Jan/core_duo_errata__2006_01_21__full.gif]&lt;br /&gt;
&lt;br /&gt;
=== 'Meltdown' Page Table Bug ===&lt;br /&gt;
&lt;br /&gt;
现代（1995年及以上）的英特尔x86芯片在无序执行硬件中存在一个缺陷，当内核映射到userland地址空间时，该缺陷允许未经授权的userland软件访问内核内存。 为避免漏洞，建议将内核页表和用户页表分开(即：PTI，页表隔离)。 有关更多详细信息，请访问[https://spectreattack.com/ 本页]。&lt;br /&gt;
&lt;br /&gt;
==AMD==&lt;br /&gt;
&lt;br /&gt;
=== DragonFly BSD Heavy Load Crash ===&lt;br /&gt;
&lt;br /&gt;
AMD已确认其某些处理器包含一个错误，该错误在某些特定条件下可能导致程序错误。 该漏洞最初是由DragonFly BSD开发人员马特·狄龙（Matt Dillon）发现的。&lt;br /&gt;
&lt;br /&gt;
连续的背靠背弹出（back-to-back pops）和(near) return指令会造成处理器错误地更新堆栈指针的情况。 DragonFly的具体表现是重负荷下的随机分段故障。&lt;br /&gt;
&lt;br /&gt;
在前几代AMD Opteron处理器中发现了一个程序异常，该异常发生在某些使用非常特定的GCC编译器构建的环境中。 已为这一小部分客户确定了一种解决方法，这可能会对其产生潜在影响。 此外，这种marginal erratum影响了前四代AMD Opteron处理器，其中包括AMD Opteron 2300，8300 (“Barcelona” 和 “Shanghai”)，2400，8400 (“Istanbul”) 和4100，6100 (“Lisbon” 和 “Magny-Cours”) 系列处理器。&lt;br /&gt;
&lt;br /&gt;
=== Ryzen Bug ===&lt;br /&gt;
&lt;br /&gt;
AMD已经证实，它的一些处理器存在漏洞，在某些特定条件下，当在规范地址边界附近执行代码时，可能会导致程序错误。 需要在规范地址边界之前插入保护页 (未映射的4k页或更大的页)。&lt;br /&gt;
&lt;br /&gt;
=== CPUID Bugs ===&lt;br /&gt;
对于较旧的K5 CPU，由edX中的“CPUID 0x00000001”返回的功能标志不可靠-位9用于指示对PGE的支持(而不用于指示对本地APIC的支持)。 &lt;br /&gt;
&lt;br /&gt;
== Cyrix ==&lt;br /&gt;
&lt;br /&gt;
=== Coma Bug ===&lt;br /&gt;
&lt;br /&gt;
影响：Cyrix 6x86系列&lt;br /&gt;
&lt;br /&gt;
当几个隐式锁定的指令被流水线成无限循环时，会导致此错误。 实际上，当一条指令完成时，随后直接执行以下锁定指令，以保持总线锁定并抑制中断。 在无限循环中，这将锁定处理器上的所有中断，使其毫无用处。&lt;br /&gt;
&lt;br /&gt;
要修复此错误，必须写入cyrix寄存器并在CCR1中设置无锁位，这将禁用除最基本的总线锁之外的所有锁。 这样做的缺点是，在多处理器系统上不再能保证读修改写原子性。 应防止此情况的源代码：(未经测试)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
MOV AL, 0xC1   ; 0xC1指CCR1&lt;br /&gt;
OUT 0x22, AL   ; 选择寄存器&lt;br /&gt;
IN 0x23, AL    ; 加载内容&lt;br /&gt;
OR AL, 0x10    ; 设置No-Lock位&lt;br /&gt;
MOV AH, AL     ;&lt;br /&gt;
MOV AL, 0xC1   ; 0xC1指CCR1&lt;br /&gt;
OUT 0x22, AL   ; 选择寄存器&lt;br /&gt;
MOV AL, AH     ; 加载新内容&lt;br /&gt;
OUT 0x23, AL   ; 使用No-Lock set写新的CCR1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Category:X86 CPU]]&lt;/div&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
</feed>