|
@@ -487,6 +487,27 @@ static inline void setup_cpu_entry_area(int cpu)
|
|
|
#endif
|
|
|
|
|
|
__set_fixmap(get_cpu_entry_area_index(cpu, gdt), get_cpu_gdt_paddr(cpu), gdt_prot);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The Intel SDM says (Volume 3, 7.2.1):
|
|
|
+ *
|
|
|
+ * Avoid placing a page boundary in the part of the TSS that the
|
|
|
+ * processor reads during a task switch (the first 104 bytes). The
|
|
|
+ * processor may not correctly perform address translations if a
|
|
|
+ * boundary occurs in this area. During a task switch, the processor
|
|
|
+ * reads and writes into the first 104 bytes of each TSS (using
|
|
|
+ * contiguous physical addresses beginning with the physical address
|
|
|
+ * of the first byte of the TSS). So, after TSS access begins, if
|
|
|
+ * part of the 104 bytes is not physically contiguous, the processor
|
|
|
+ * will access incorrect information without generating a page-fault
|
|
|
+ * exception.
|
|
|
+ *
|
|
|
+ * There are also a lot of errata involving the TSS spanning a page
|
|
|
+ * boundary. Assert that we're not doing that.
|
|
|
+ */
|
|
|
+ BUILD_BUG_ON((offsetof(struct tss_struct, x86_tss) ^
|
|
|
+ offsetofend(struct tss_struct, x86_tss)) & PAGE_MASK);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/* Load the original GDT from the per-cpu structure */
|