History

Revert "x86-64/efi: Use EFI to deal with platform wall clock (again)"

This reverts commit bd52276fa1d4 ("x86-64/efi: Use EFI to deal with platform wall clock (again)"), and the two supporting commits: da5a108d05b4: "x86/kernel: remove tboot 1:1 page table creation code" 185034e72d59: "x86, efi: 1:1 pagetable mapping for virtual EFI calls") as they all depend semantically on commit 53b87cf088e2 ("x86, mm: Include the entire kernel memory map in trampoline_pgd") that got reverted earlier due to the problems it caused. This was pointed out by Yinghai Lu, and verified by me on my Macbook Air that uses EFI.

Linus Torvalds committed 13 years ago

Commit 11520e51 parent 5bd665f7 files · +116 −55Browse files

Unified · Split

7 files
  1. arch/x86/include/asm/efi.h +7 −21
  2. arch/x86/kernel/tboot.c +73 −5
  3. arch/x86/mm/pageattr.c +4 −6
  4. arch/x86/platform/efi/efi.c +26 −4
  5. arch/x86/platform/efi/efi_64.c +0 −15
  6. include/linux/efi.h +2 −0
  7. init/main.c +4 −4
arch/x86/include/asm/efi.h+7−21
@@ -69,37 +69,23 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3, · 68 unmodified lines
6969 efi_call6((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3), \
7070 (u64)(a4), (u64)(a5), (u64)(a6))
7171
72−extern unsigned long efi_call_virt_prelog(void);
73−extern void efi_call_virt_epilog(unsigned long);
74−
75−#define efi_callx(x, func, ...) \
76− ({ \
77− efi_status_t __status; \
78− unsigned long __pgd; \
79− \
80− __pgd = efi_call_virt_prelog(); \
81− __status = efi_call##x(func, __VA_ARGS__); \
82− efi_call_virt_epilog(__pgd); \
83− __status; \
84− })
85−
8672 #define efi_call_virt0(f) \
87− efi_callx(0, (void *)(efi.systab->runtime->f))
73+ efi_call0((void *)(efi.systab->runtime->f))
8874 #define efi_call_virt1(f, a1) \
89− efi_callx(1, (void *)(efi.systab->runtime->f), (u64)(a1))
75+ efi_call1((void *)(efi.systab->runtime->f), (u64)(a1))
9076 #define efi_call_virt2(f, a1, a2) \
91− efi_callx(2, (void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2))
77+ efi_call2((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2))
9278 #define efi_call_virt3(f, a1, a2, a3) \
93− efi_callx(3, (void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
79+ efi_call3((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
9480 (u64)(a3))
9581 #define efi_call_virt4(f, a1, a2, a3, a4) \
96− efi_callx(4, (void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
82+ efi_call4((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
9783 (u64)(a3), (u64)(a4))
9884 #define efi_call_virt5(f, a1, a2, a3, a4, a5) \
99− efi_callx(5, (void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
85+ efi_call5((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
10086 (u64)(a3), (u64)(a4), (u64)(a5))
10187 #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \
102− efi_callx(6, (void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
88+ efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
10389 (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
10490
10591 extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
arch/x86/kernel/tboot.c+73−5
@@ -103,13 +103,71 @@ void __init tboot_probe(void) · 102 unmodified lines
103103 pr_debug("tboot_size: 0x%x\n", tboot->tboot_size);
104104 }
105105
106+static pgd_t *tboot_pg_dir;
107+static struct mm_struct tboot_mm = {
108+ .mm_rb = RB_ROOT,
109+ .pgd = swapper_pg_dir,
110+ .mm_users = ATOMIC_INIT(2),
111+ .mm_count = ATOMIC_INIT(1),
112+ .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem),
113+ .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
114+ .mmlist = LIST_HEAD_INIT(init_mm.mmlist),
115+};
116+
106117 static inline void switch_to_tboot_pt(void)
107118 {
108−#ifdef CONFIG_X86_32
109− load_cr3(initial_page_table);
110−#else
111− write_cr3(real_mode_header->trampoline_pgd);
112−#endif
119+ write_cr3(virt_to_phys(tboot_pg_dir));
120+}
121+
122+static int map_tboot_page(unsigned long vaddr, unsigned long pfn,
123+ pgprot_t prot)
124+{
125+ pgd_t *pgd;
126+ pud_t *pud;
127+ pmd_t *pmd;
128+ pte_t *pte;
129+
130+ pgd = pgd_offset(&tboot_mm, vaddr);
131+ pud = pud_alloc(&tboot_mm, pgd, vaddr);
132+ if (!pud)
133+ return -1;
134+ pmd = pmd_alloc(&tboot_mm, pud, vaddr);
135+ if (!pmd)
136+ return -1;
137+ pte = pte_alloc_map(&tboot_mm, NULL, pmd, vaddr);
138+ if (!pte)
139+ return -1;
140+ set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot));
141+ pte_unmap(pte);
142+ return 0;
143+}
144+
145+static int map_tboot_pages(unsigned long vaddr, unsigned long start_pfn,
146+ unsigned long nr)
147+{
148+ /* Reuse the original kernel mapping */
149+ tboot_pg_dir = pgd_alloc(&tboot_mm);
150+ if (!tboot_pg_dir)
151+ return -1;
152+
153+ for (; nr > 0; nr--, vaddr += PAGE_SIZE, start_pfn++) {
154+ if (map_tboot_page(vaddr, start_pfn, PAGE_KERNEL_EXEC))
155+ return -1;
156+ }
157+
158+ return 0;
159+}
160+
161+static void tboot_create_trampoline(void)
162+{
163+ u32 map_base, map_size;
164+
165+ /* Create identity map for tboot shutdown code. */
166+ map_base = PFN_DOWN(tboot->tboot_base);
167+ map_size = PFN_UP(tboot->tboot_size);
168+ if (map_tboot_pages(map_base << PAGE_SHIFT, map_base, map_size))
169+ panic("tboot: Error mapping tboot pages (mfns) @ 0x%x, 0x%x\n",
170+ map_base, map_size);
113171 }
114172
115173 #ifdef CONFIG_ACPI_SLEEP
@@ -167,6 +225,14 @@ void tboot_shutdown(u32 shutdown_type) · 51 unmodified lines
167225 if (!tboot_enabled())
168226 return;
169227
228+ /*
229+ * if we're being called before the 1:1 mapping is set up then just
230+ * return and let the normal shutdown happen; this should only be
231+ * due to very early panic()
232+ */
233+ if (!tboot_pg_dir)
234+ return;
235+
170236 /* if this is S3 then set regions to MAC */
171237 if (shutdown_type == TB_SHUTDOWN_S3)
172238 if (tboot_setup_sleep())
@@ -277,6 +343,8 @@ static __init int tboot_late_init(void) · 104 unmodified lines
277343 if (!tboot_enabled())
278344 return 0;
279345
346+ tboot_create_trampoline();
347+
280348 atomic_set(&ap_wfs_count, 0);
281349 register_hotcpu_notifier(&tboot_cpu_notifier);
282350
arch/x86/mm/pageattr.c+4−6
@@ -919,13 +919,11 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, · 918 unmodified lines
919919
920920 /*
921921 * On success we use clflush, when the CPU supports it to
922− * avoid the wbindv. If the CPU does not support it, in the
923− * error case, and during early boot (for EFI) we fall back
924− * to cpa_flush_all (which uses wbinvd):
922+ * avoid the wbindv. If the CPU does not support it and in the
923+ * error case we fall back to cpa_flush_all (which uses
924+ * wbindv):
925925 */
926− if (early_boot_irqs_disabled)
927− __cpa_flush_all((void *)(long)cache);
928− else if (!ret && cpu_has_clflush) {
926+ if (!ret && cpu_has_clflush) {
929927 if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) {
930928 cpa_flush_array(addr, numpages, cache,
931929 cpa.flags, pages);
arch/x86/platform/efi/efi.c+26−4
@@ -239,7 +239,22 @@ static efi_status_t __init phys_efi_set_virtual_address_map( · 238 unmodified lines
239239 return status;
240240 }
241241
242−static int efi_set_rtc_mmss(unsigned long nowtime)
242+static efi_status_t __init phys_efi_get_time(efi_time_t *tm,
243+ efi_time_cap_t *tc)
244+{
245+ unsigned long flags;
246+ efi_status_t status;
247+
248+ spin_lock_irqsave(&rtc_lock, flags);
249+ efi_call_phys_prelog();
250+ status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm),
251+ virt_to_phys(tc));
252+ efi_call_phys_epilog();
253+ spin_unlock_irqrestore(&rtc_lock, flags);
254+ return status;
255+}
256+
257+int efi_set_rtc_mmss(unsigned long nowtime)
243258 {
244259 int real_seconds, real_minutes;
245260 efi_status_t status;
@@ -268,7 +283,7 @@ static int efi_set_rtc_mmss(unsigned long nowtime) · 22 unmodified lines
268283 return 0;
269284 }
270285
271−static unsigned long efi_get_time(void)
286+unsigned long efi_get_time(void)
272287 {
273288 efi_status_t status;
274289 efi_time_t eft;
@@ -624,13 +639,18 @@ static int __init efi_runtime_init(void) · 349 unmodified lines
624639 }
625640 /*
626641 * We will only need *early* access to the following
627− * EFI runtime service before set_virtual_address_map
642+ * two EFI runtime services before set_virtual_address_map
628643 * is invoked.
629644 */
645+ efi_phys.get_time = (efi_get_time_t *)runtime->get_time;
630646 efi_phys.set_virtual_address_map =
631647 (efi_set_virtual_address_map_t *)
632648 runtime->set_virtual_address_map;
633−
649+ /*
650+ * Make efi_get_time can be called before entering
651+ * virtual mode.
652+ */
653+ efi.get_time = phys_efi_get_time;
634654 early_iounmap(runtime, sizeof(efi_runtime_services_t));
635655
636656 return 0;
@@ -716,10 +736,12 @@ void __init efi_init(void) · 79 unmodified lines
716736 efi_enabled = 0;
717737 return;
718738 }
739+#ifdef CONFIG_X86_32
719740 if (efi_is_native()) {
720741 x86_platform.get_wallclock = efi_get_time;
721742 x86_platform.set_wallclock = efi_set_rtc_mmss;
722743 }
744+#endif
723745
724746 #if EFI_DEBUG
725747 print_efi_memmap();
arch/x86/platform/efi/efi_64.c+0−15
@@ -58,21 +58,6 @@ static void __init early_code_mapping_set_exec(int executable) · 57 unmodified lines
5858 }
5959 }
6060
61−unsigned long efi_call_virt_prelog(void)
62−{
63− unsigned long saved;
64−
65− saved = read_cr3();
66− write_cr3(real_mode_header->trampoline_pgd);
67−
68− return saved;
69−}
70−
71−void efi_call_virt_epilog(unsigned long saved)
72−{
73− write_cr3(saved);
74−}
75−
7661 void __init efi_call_phys_prelog(void)
7762 {
7863 unsigned long vaddress;
include/linux/efi.h+2−0
@@ -587,6 +587,8 @@ extern u64 efi_mem_attribute (unsigned long phys_addr, unsigned long size); · 586 unmodified lines
587587 extern int __init efi_uart_console_only (void);
588588 extern void efi_initialize_iomem_resources(struct resource *code_resource,
589589 struct resource *data_resource, struct resource *bss_resource);
590+extern unsigned long efi_get_time(void);
591+extern int efi_set_rtc_mmss(unsigned long nowtime);
590592 extern void efi_reserve_boot_services(void);
591593 extern struct efi_memory_map memmap;
592594
init/main.c+4−4
@@ -463,10 +463,6 @@ static void __init mm_init(void) · 462 unmodified lines
463463 percpu_init_late();
464464 pgtable_cache_init();
465465 vmalloc_init();
466−#ifdef CONFIG_X86
467− if (efi_enabled)
468− efi_enter_virtual_mode();
469−#endif
470466 }
471467
472468 asmlinkage void __init start_kernel(void)
@@ -607,6 +603,10 @@ asmlinkage void __init start_kernel(void) · 134 unmodified lines
607603 calibrate_delay();
608604 pidmap_init();
609605 anon_vma_init();
606+#ifdef CONFIG_X86
607+ if (efi_enabled)
608+ efi_enter_virtual_mode();
609+#endif
610610 thread_info_cache_init();
611611 cred_init();
612612 fork_init(totalram_pages);