forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/arch/x86/platform/efi/quirks.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 #define pr_fmt(fmt) "efi: " fmt
23
34 #include <linux/init.h>
....@@ -8,7 +9,6 @@
89 #include <linux/efi.h>
910 #include <linux/slab.h>
1011 #include <linux/memblock.h>
11
-#include <linux/bootmem.h>
1212 #include <linux/acpi.h>
1313 #include <linux/dmi.h>
1414
....@@ -16,6 +16,8 @@
1616 #include <asm/efi.h>
1717 #include <asm/uv/uv.h>
1818 #include <asm/cpu_device_id.h>
19
+#include <asm/realmode.h>
20
+#include <asm/reboot.h>
1921
2022 #define EFI_MIN_RESERVE 5120
2123
....@@ -242,7 +244,7 @@
242244 */
243245 void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
244246 {
245
- phys_addr_t new_phys, new_size;
247
+ struct efi_memory_map_data data = { 0 };
246248 struct efi_mem_range mr;
247249 efi_memory_desc_t md;
248250 int num_entries;
....@@ -270,15 +272,12 @@
270272 num_entries = efi_memmap_split_count(&md, &mr.range);
271273 num_entries += efi.memmap.nr_map;
272274
273
- new_size = efi.memmap.desc_size * num_entries;
274
-
275
- new_phys = efi_memmap_alloc(num_entries);
276
- if (!new_phys) {
275
+ if (efi_memmap_alloc(num_entries, &data) != 0) {
277276 pr_err("Could not allocate boot services memmap\n");
278277 return;
279278 }
280279
281
- new = early_memremap_prot(new_phys, new_size,
280
+ new = early_memremap_prot(data.phys_map, data.size,
282281 pgprot_val(pgprot_encrypted(FIXMAP_PAGE_NORMAL)));
283282 if (!new) {
284283 pr_err("Failed to map new boot services memmap\n");
....@@ -286,9 +285,9 @@
286285 }
287286
288287 efi_memmap_insert(&efi.memmap, new, &mr);
289
- early_memunmap(new, new_size);
288
+ early_memunmap(new, data.size);
290289
291
- efi_memmap_install(new_phys, num_entries);
290
+ efi_memmap_install(&data);
292291 e820__range_update(addr, size, E820_TYPE_RAM, E820_TYPE_RESERVED);
293292 e820__update_table(e820_table);
294293 }
....@@ -303,7 +302,7 @@
303302 * - Not within any part of the kernel
304303 * - Not the BIOS reserved area (E820_TYPE_RESERVED, E820_TYPE_NVS, etc)
305304 */
306
-static bool can_free_region(u64 start, u64 size)
305
+static __init bool can_free_region(u64 start, u64 size)
307306 {
308307 if (start + size > __pa_symbol(_text) && start <= __pa_symbol(_end))
309308 return false;
....@@ -318,6 +317,9 @@
318317 {
319318 efi_memory_desc_t *md;
320319
320
+ if (!efi_enabled(EFI_MEMMAP))
321
+ return;
322
+
321323 for_each_efi_memory_desc(md) {
322324 u64 start = md->phys_addr;
323325 u64 size = md->num_pages << EFI_PAGE_SHIFT;
....@@ -331,7 +333,7 @@
331333
332334 /*
333335 * Because the following memblock_reserve() is paired
334
- * with free_bootmem_late() for this region in
336
+ * with memblock_free_late() for this region in
335337 * efi_free_boot_services(), we must be extremely
336338 * careful not to reserve, and subsequently free,
337339 * critical regions of memory (like the kernel image) or
....@@ -362,18 +364,48 @@
362364 * doesn't make sense as far as the firmware is
363365 * concerned, but it does provide us with a way to tag
364366 * those regions that must not be paired with
365
- * free_bootmem_late().
367
+ * memblock_free_late().
366368 */
367369 md->attribute |= EFI_MEMORY_RUNTIME;
368370 }
369371 }
370372
373
+/*
374
+ * Apart from having VA mappings for EFI boot services code/data regions,
375
+ * (duplicate) 1:1 mappings were also created as a quirk for buggy firmware. So,
376
+ * unmap both 1:1 and VA mappings.
377
+ */
378
+static void __init efi_unmap_pages(efi_memory_desc_t *md)
379
+{
380
+ pgd_t *pgd = efi_mm.pgd;
381
+ u64 pa = md->phys_addr;
382
+ u64 va = md->virt_addr;
383
+
384
+ /*
385
+ * EFI mixed mode has all RAM mapped to access arguments while making
386
+ * EFI runtime calls, hence don't unmap EFI boot services code/data
387
+ * regions.
388
+ */
389
+ if (efi_is_mixed())
390
+ return;
391
+
392
+ if (kernel_unmap_pages_in_pgd(pgd, pa, md->num_pages))
393
+ pr_err("Failed to unmap 1:1 mapping for 0x%llx\n", pa);
394
+
395
+ if (kernel_unmap_pages_in_pgd(pgd, va, md->num_pages))
396
+ pr_err("Failed to unmap VA mapping for 0x%llx\n", va);
397
+}
398
+
371399 void __init efi_free_boot_services(void)
372400 {
373
- phys_addr_t new_phys, new_size;
401
+ struct efi_memory_map_data data = { 0 };
374402 efi_memory_desc_t *md;
375403 int num_entries = 0;
376404 void *new, *new_md;
405
+
406
+ /* Keep all regions for /sys/kernel/debug/efi */
407
+ if (efi_enabled(EFI_DBG))
408
+ return;
377409
378410 for_each_efi_memory_desc(md) {
379411 unsigned long long start = md->phys_addr;
....@@ -393,6 +425,13 @@
393425 }
394426
395427 /*
428
+ * Before calling set_virtual_address_map(), EFI boot services
429
+ * code/data regions were mapped as a quirk for buggy firmware.
430
+ * Unmap them from efi_pgd before freeing them up.
431
+ */
432
+ efi_unmap_pages(md);
433
+
434
+ /*
396435 * Nasty quirk: if all sub-1MB memory is used for boot
397436 * services, we can get here without having allocated the
398437 * real mode trampoline. It's too late to hand boot services
....@@ -407,25 +446,23 @@
407446 */
408447 rm_size = real_mode_size_needed();
409448 if (rm_size && (start + rm_size) < (1<<20) && size >= rm_size) {
410
- set_real_mode_mem(start, rm_size);
449
+ set_real_mode_mem(start);
411450 start += rm_size;
412451 size -= rm_size;
413452 }
414453
415
- free_bootmem_late(start, size);
454
+ memblock_free_late(start, size);
416455 }
417456
418457 if (!num_entries)
419458 return;
420459
421
- new_size = efi.memmap.desc_size * num_entries;
422
- new_phys = efi_memmap_alloc(num_entries);
423
- if (!new_phys) {
460
+ if (efi_memmap_alloc(num_entries, &data) != 0) {
424461 pr_err("Failed to allocate new EFI memmap\n");
425462 return;
426463 }
427464
428
- new = memremap(new_phys, new_size, MEMREMAP_WB);
465
+ new = memremap(data.phys_map, data.size, MEMREMAP_WB);
429466 if (!new) {
430467 pr_err("Failed to map new EFI memmap\n");
431468 return;
....@@ -449,7 +486,7 @@
449486
450487 memunmap(new);
451488
452
- if (efi_memmap_install(new_phys, num_entries)) {
489
+ if (efi_memmap_install(&data) != 0) {
453490 pr_err("Could not install new EFI memmap\n");
454491 return;
455492 }
....@@ -469,6 +506,9 @@
469506 int i, sz, ret = 0;
470507 void *p, *tablep;
471508 struct efi_setup_data *data;
509
+
510
+ if (nr_tables == 0)
511
+ return 0;
472512
473513 if (!efi_setup)
474514 return 0;
....@@ -494,7 +534,7 @@
494534 goto out_memremap;
495535 }
496536
497
- for (i = 0; i < efi.systab->nr_tables; i++) {
537
+ for (i = 0; i < nr_tables; i++) {
498538 efi_guid_t guid;
499539
500540 guid = ((efi_config_table_64_t *)p)->guid;
....@@ -511,16 +551,6 @@
511551 return ret;
512552 }
513553
514
-static const struct dmi_system_id sgi_uv1_dmi[] = {
515
- { NULL, "SGI UV1",
516
- { DMI_MATCH(DMI_PRODUCT_NAME, "Stoutland Platform"),
517
- DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
518
- DMI_MATCH(DMI_BIOS_VENDOR, "SGI.COM"),
519
- }
520
- },
521
- { } /* NULL entry stops DMI scanning */
522
-};
523
-
524554 void __init efi_apply_memmap_quirks(void)
525555 {
526556 /*
....@@ -532,10 +562,6 @@
532562 pr_info("Setup done, disabling due to 32/64-bit mismatch\n");
533563 efi_memmap_unmap();
534564 }
535
-
536
- /* UV2+ BIOS has a fix for this issue. UV1 still needs the quirk. */
537
- if (dmi_check_system(sgi_uv1_dmi))
538
- set_bit(EFI_OLD_MEMMAP, &efi.flags);
539565 }
540566
541567 /*
....@@ -609,12 +635,9 @@
609635 return 1;
610636 }
611637
612
-#define ICPU(family, model, quirk_handler) \
613
- { X86_VENDOR_INTEL, family, model, X86_FEATURE_ANY, \
614
- (unsigned long)&quirk_handler }
615
-
616638 static const struct x86_cpu_id efi_capsule_quirk_ids[] = {
617
- ICPU(5, 9, qrk_capsule_setup_info), /* Intel Quark X1000 */
639
+ X86_MATCH_VENDOR_FAM_MODEL(INTEL, 5, INTEL_FAM5_QUARK_X1000,
640
+ &qrk_capsule_setup_info),
618641 { }
619642 };
620643
....@@ -653,3 +676,78 @@
653676 }
654677
655678 #endif
679
+
680
+/*
681
+ * If any access by any efi runtime service causes a page fault, then,
682
+ * 1. If it's efi_reset_system(), reboot through BIOS.
683
+ * 2. If any other efi runtime service, then
684
+ * a. Return error status to the efi caller process.
685
+ * b. Disable EFI Runtime Services forever and
686
+ * c. Freeze efi_rts_wq and schedule new process.
687
+ *
688
+ * @return: Returns, if the page fault is not handled. This function
689
+ * will never return if the page fault is handled successfully.
690
+ */
691
+void efi_recover_from_page_fault(unsigned long phys_addr)
692
+{
693
+ if (!IS_ENABLED(CONFIG_X86_64))
694
+ return;
695
+
696
+ /*
697
+ * Make sure that an efi runtime service caused the page fault.
698
+ */
699
+ if (efi_rts_work.efi_rts_id == EFI_NONE)
700
+ return;
701
+
702
+ /*
703
+ * Address range 0x0000 - 0x0fff is always mapped in the efi_pgd, so
704
+ * page faulting on these addresses isn't expected.
705
+ */
706
+ if (phys_addr <= 0x0fff)
707
+ return;
708
+
709
+ /*
710
+ * Print stack trace as it might be useful to know which EFI Runtime
711
+ * Service is buggy.
712
+ */
713
+ WARN(1, FW_BUG "Page fault caused by firmware at PA: 0x%lx\n",
714
+ phys_addr);
715
+
716
+ /*
717
+ * Buggy efi_reset_system() is handled differently from other EFI
718
+ * Runtime Services as it doesn't use efi_rts_wq. Although,
719
+ * native_machine_emergency_restart() says that machine_real_restart()
720
+ * could fail, it's better not to compilcate this fault handler
721
+ * because this case occurs *very* rarely and hence could be improved
722
+ * on a need by basis.
723
+ */
724
+ if (efi_rts_work.efi_rts_id == EFI_RESET_SYSTEM) {
725
+ pr_info("efi_reset_system() buggy! Reboot through BIOS\n");
726
+ machine_real_restart(MRR_BIOS);
727
+ return;
728
+ }
729
+
730
+ /*
731
+ * Before calling EFI Runtime Service, the kernel has switched the
732
+ * calling process to efi_mm. Hence, switch back to task_mm.
733
+ */
734
+ arch_efi_call_virt_teardown();
735
+
736
+ /* Signal error status to the efi caller process */
737
+ efi_rts_work.status = EFI_ABORTED;
738
+ complete(&efi_rts_work.efi_rts_comp);
739
+
740
+ clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
741
+ pr_info("Froze efi_rts_wq and disabled EFI Runtime Services\n");
742
+
743
+ /*
744
+ * Call schedule() in an infinite loop, so that any spurious wake ups
745
+ * will never run efi_rts_wq again.
746
+ */
747
+ for (;;) {
748
+ set_current_state(TASK_IDLE);
749
+ schedule();
750
+ }
751
+
752
+ return;
753
+}