diff options
-rw-r--r-- | arch/x86/pci/mmconfig-shared.c | 28 | ||||
-rw-r--r-- | drivers/acpi/apei/apei-base.c | 32 |
2 files changed, 54 insertions, 6 deletions
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 326198a4434e..676e5e04e4d4 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -610,6 +610,32 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) | |||
610 | return 0; | 610 | return 0; |
611 | } | 611 | } |
612 | 612 | ||
613 | #ifdef CONFIG_ACPI_APEI | ||
614 | extern int (*arch_apei_filter_addr)(int (*func)(__u64 start, __u64 size, | ||
615 | void *data), void *data); | ||
616 | |||
617 | static int pci_mmcfg_for_each_region(int (*func)(__u64 start, __u64 size, | ||
618 | void *data), void *data) | ||
619 | { | ||
620 | struct pci_mmcfg_region *cfg; | ||
621 | int rc; | ||
622 | |||
623 | if (list_empty(&pci_mmcfg_list)) | ||
624 | return 0; | ||
625 | |||
626 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { | ||
627 | rc = func(cfg->res.start, resource_size(&cfg->res), data); | ||
628 | if (rc) | ||
629 | return rc; | ||
630 | } | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | #define set_apei_filter() (arch_apei_filter_addr = pci_mmcfg_for_each_region) | ||
635 | #else | ||
636 | #define set_apei_filter() | ||
637 | #endif | ||
638 | |||
613 | static void __init __pci_mmcfg_init(int early) | 639 | static void __init __pci_mmcfg_init(int early) |
614 | { | 640 | { |
615 | pci_mmcfg_reject_broken(early); | 641 | pci_mmcfg_reject_broken(early); |
@@ -644,6 +670,8 @@ void __init pci_mmcfg_early_init(void) | |||
644 | else | 670 | else |
645 | acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); | 671 | acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); |
646 | __pci_mmcfg_init(1); | 672 | __pci_mmcfg_init(1); |
673 | |||
674 | set_apei_filter(); | ||
647 | } | 675 | } |
648 | } | 676 | } |
649 | 677 | ||
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 2cd7bdd6c8b3..a85ac07f3da3 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -449,7 +449,7 @@ int apei_resources_sub(struct apei_resources *resources1, | |||
449 | } | 449 | } |
450 | EXPORT_SYMBOL_GPL(apei_resources_sub); | 450 | EXPORT_SYMBOL_GPL(apei_resources_sub); |
451 | 451 | ||
452 | static int apei_get_nvs_callback(__u64 start, __u64 size, void *data) | 452 | static int apei_get_res_callback(__u64 start, __u64 size, void *data) |
453 | { | 453 | { |
454 | struct apei_resources *resources = data; | 454 | struct apei_resources *resources = data; |
455 | return apei_res_add(&resources->iomem, start, size); | 455 | return apei_res_add(&resources->iomem, start, size); |
@@ -457,7 +457,15 @@ static int apei_get_nvs_callback(__u64 start, __u64 size, void *data) | |||
457 | 457 | ||
458 | static int apei_get_nvs_resources(struct apei_resources *resources) | 458 | static int apei_get_nvs_resources(struct apei_resources *resources) |
459 | { | 459 | { |
460 | return acpi_nvs_for_each_region(apei_get_nvs_callback, resources); | 460 | return acpi_nvs_for_each_region(apei_get_res_callback, resources); |
461 | } | ||
462 | |||
463 | int (*arch_apei_filter_addr)(int (*func)(__u64 start, __u64 size, | ||
464 | void *data), void *data); | ||
465 | static int apei_get_arch_resources(struct apei_resources *resources) | ||
466 | |||
467 | { | ||
468 | return arch_apei_filter_addr(apei_get_res_callback, resources); | ||
461 | } | 469 | } |
462 | 470 | ||
463 | /* | 471 | /* |
@@ -470,7 +478,7 @@ int apei_resources_request(struct apei_resources *resources, | |||
470 | { | 478 | { |
471 | struct apei_res *res, *res_bak = NULL; | 479 | struct apei_res *res, *res_bak = NULL; |
472 | struct resource *r; | 480 | struct resource *r; |
473 | struct apei_resources nvs_resources; | 481 | struct apei_resources nvs_resources, arch_res; |
474 | int rc; | 482 | int rc; |
475 | 483 | ||
476 | rc = apei_resources_sub(resources, &apei_resources_all); | 484 | rc = apei_resources_sub(resources, &apei_resources_all); |
@@ -485,10 +493,20 @@ int apei_resources_request(struct apei_resources *resources, | |||
485 | apei_resources_init(&nvs_resources); | 493 | apei_resources_init(&nvs_resources); |
486 | rc = apei_get_nvs_resources(&nvs_resources); | 494 | rc = apei_get_nvs_resources(&nvs_resources); |
487 | if (rc) | 495 | if (rc) |
488 | goto res_fini; | 496 | goto nvs_res_fini; |
489 | rc = apei_resources_sub(resources, &nvs_resources); | 497 | rc = apei_resources_sub(resources, &nvs_resources); |
490 | if (rc) | 498 | if (rc) |
491 | goto res_fini; | 499 | goto nvs_res_fini; |
500 | |||
501 | if (arch_apei_filter_addr) { | ||
502 | apei_resources_init(&arch_res); | ||
503 | rc = apei_get_arch_resources(&arch_res); | ||
504 | if (rc) | ||
505 | goto arch_res_fini; | ||
506 | rc = apei_resources_sub(resources, &arch_res); | ||
507 | if (rc) | ||
508 | goto arch_res_fini; | ||
509 | } | ||
492 | 510 | ||
493 | rc = -EINVAL; | 511 | rc = -EINVAL; |
494 | list_for_each_entry(res, &resources->iomem, list) { | 512 | list_for_each_entry(res, &resources->iomem, list) { |
@@ -536,7 +554,9 @@ err_unmap_iomem: | |||
536 | break; | 554 | break; |
537 | release_mem_region(res->start, res->end - res->start); | 555 | release_mem_region(res->start, res->end - res->start); |
538 | } | 556 | } |
539 | res_fini: | 557 | arch_res_fini: |
558 | apei_resources_fini(&arch_res); | ||
559 | nvs_res_fini: | ||
540 | apei_resources_fini(&nvs_resources); | 560 | apei_resources_fini(&nvs_resources); |
541 | return rc; | 561 | return rc; |
542 | } | 562 | } |