diff options
author | Len Brown <len.brown@intel.com> | 2012-03-30 16:12:23 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-03-30 16:14:02 -0400 |
commit | 73f05330497b98c45d157b7d0c60673798bb4c3b (patch) | |
tree | 67fc16c0f55c482882aea49eaa1d8d95b23722e0 /drivers/acpi/apei | |
parent | 1a05e4678724c4a5fe7b9e4e208b616dfe8c3a32 (diff) | |
parent | 8cdde126aa60ced0d63ff137378e09dd01dfadda (diff) |
Merge branch 'apei' into release
Conflicts:
drivers/acpi/apei/apei-base.c
This was a conflict between
15afae604651d4e17652d2ffb56f5e36f991cfef
(CPI, APEI: Fix incorrect APEI register bit width check and usage)
and
653f4b538f66d37db560e0f56af08117136d29b7
(ACPICA: Expand OSL memory read/write interfaces to 64 bits)
The former changed a parameter in the call to acpi_os_read_memory64()
and the later replaced all calls to acpi_os_read_memory64()
with calls to acpi_os_read_memory().
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/apei')
-rw-r--r-- | drivers/acpi/apei/apei-base.c | 61 | ||||
-rw-r--r-- | drivers/acpi/apei/cper.c | 2 | ||||
-rw-r--r-- | drivers/acpi/apei/einj.c | 17 | ||||
-rw-r--r-- | drivers/acpi/apei/erst.c | 2 |
4 files changed, 56 insertions, 26 deletions
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index ca773683d87e..5577762daee1 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -558,33 +558,48 @@ void apei_resources_release(struct apei_resources *resources) | |||
558 | } | 558 | } |
559 | EXPORT_SYMBOL_GPL(apei_resources_release); | 559 | EXPORT_SYMBOL_GPL(apei_resources_release); |
560 | 560 | ||
561 | static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr) | 561 | static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, |
562 | u32 *access_bit_width) | ||
562 | { | 563 | { |
563 | u32 width, space_id; | 564 | u32 bit_width, bit_offset, access_size_code, space_id; |
564 | 565 | ||
565 | width = reg->bit_width; | 566 | bit_width = reg->bit_width; |
567 | bit_offset = reg->bit_offset; | ||
568 | access_size_code = reg->access_width; | ||
566 | space_id = reg->space_id; | 569 | space_id = reg->space_id; |
567 | /* Handle possible alignment issues */ | 570 | /* Handle possible alignment issues */ |
568 | memcpy(paddr, ®->address, sizeof(*paddr)); | 571 | memcpy(paddr, ®->address, sizeof(*paddr)); |
569 | if (!*paddr) { | 572 | if (!*paddr) { |
570 | pr_warning(FW_BUG APEI_PFX | 573 | pr_warning(FW_BUG APEI_PFX |
571 | "Invalid physical address in GAR [0x%llx/%u/%u]\n", | 574 | "Invalid physical address in GAR [0x%llx/%u/%u/%u/%u]\n", |
572 | *paddr, width, space_id); | 575 | *paddr, bit_width, bit_offset, access_size_code, |
576 | space_id); | ||
573 | return -EINVAL; | 577 | return -EINVAL; |
574 | } | 578 | } |
575 | 579 | ||
576 | if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) { | 580 | if (access_size_code < 1 || access_size_code > 4) { |
577 | pr_warning(FW_BUG APEI_PFX | 581 | pr_warning(FW_BUG APEI_PFX |
578 | "Invalid bit width in GAR [0x%llx/%u/%u]\n", | 582 | "Invalid access size code in GAR [0x%llx/%u/%u/%u/%u]\n", |
579 | *paddr, width, space_id); | 583 | *paddr, bit_width, bit_offset, access_size_code, |
584 | space_id); | ||
585 | return -EINVAL; | ||
586 | } | ||
587 | *access_bit_width = 1UL << (access_size_code + 2); | ||
588 | |||
589 | if ((bit_width + bit_offset) > *access_bit_width) { | ||
590 | pr_warning(FW_BUG APEI_PFX | ||
591 | "Invalid bit width + offset in GAR [0x%llx/%u/%u/%u/%u]\n", | ||
592 | *paddr, bit_width, bit_offset, access_size_code, | ||
593 | space_id); | ||
580 | return -EINVAL; | 594 | return -EINVAL; |
581 | } | 595 | } |
582 | 596 | ||
583 | if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && | 597 | if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && |
584 | space_id != ACPI_ADR_SPACE_SYSTEM_IO) { | 598 | space_id != ACPI_ADR_SPACE_SYSTEM_IO) { |
585 | pr_warning(FW_BUG APEI_PFX | 599 | pr_warning(FW_BUG APEI_PFX |
586 | "Invalid address space type in GAR [0x%llx/%u/%u]\n", | 600 | "Invalid address space type in GAR [0x%llx/%u/%u/%u/%u]\n", |
587 | *paddr, width, space_id); | 601 | *paddr, bit_width, bit_offset, access_size_code, |
602 | space_id); | ||
588 | return -EINVAL; | 603 | return -EINVAL; |
589 | } | 604 | } |
590 | 605 | ||
@@ -595,23 +610,25 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr) | |||
595 | int apei_read(u64 *val, struct acpi_generic_address *reg) | 610 | int apei_read(u64 *val, struct acpi_generic_address *reg) |
596 | { | 611 | { |
597 | int rc; | 612 | int rc; |
613 | u32 access_bit_width; | ||
598 | u64 address; | 614 | u64 address; |
599 | acpi_status status; | 615 | acpi_status status; |
600 | 616 | ||
601 | rc = apei_check_gar(reg, &address); | 617 | rc = apei_check_gar(reg, &address, &access_bit_width); |
602 | if (rc) | 618 | if (rc) |
603 | return rc; | 619 | return rc; |
604 | 620 | ||
605 | *val = 0; | 621 | *val = 0; |
606 | switch(reg->space_id) { | 622 | switch(reg->space_id) { |
607 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 623 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
608 | status = acpi_os_read_memory((acpi_physical_address) | 624 | status = acpi_os_read_memory((acpi_physical_address) address, |
609 | address, val, reg->bit_width); | 625 | val, access_bit_width); |
610 | if (ACPI_FAILURE(status)) | 626 | if (ACPI_FAILURE(status)) |
611 | return -EIO; | 627 | return -EIO; |
612 | break; | 628 | break; |
613 | case ACPI_ADR_SPACE_SYSTEM_IO: | 629 | case ACPI_ADR_SPACE_SYSTEM_IO: |
614 | status = acpi_os_read_port(address, (u32 *)val, reg->bit_width); | 630 | status = acpi_os_read_port(address, (u32 *)val, |
631 | access_bit_width); | ||
615 | if (ACPI_FAILURE(status)) | 632 | if (ACPI_FAILURE(status)) |
616 | return -EIO; | 633 | return -EIO; |
617 | break; | 634 | break; |
@@ -627,22 +644,23 @@ EXPORT_SYMBOL_GPL(apei_read); | |||
627 | int apei_write(u64 val, struct acpi_generic_address *reg) | 644 | int apei_write(u64 val, struct acpi_generic_address *reg) |
628 | { | 645 | { |
629 | int rc; | 646 | int rc; |
647 | u32 access_bit_width; | ||
630 | u64 address; | 648 | u64 address; |
631 | acpi_status status; | 649 | acpi_status status; |
632 | 650 | ||
633 | rc = apei_check_gar(reg, &address); | 651 | rc = apei_check_gar(reg, &address, &access_bit_width); |
634 | if (rc) | 652 | if (rc) |
635 | return rc; | 653 | return rc; |
636 | 654 | ||
637 | switch (reg->space_id) { | 655 | switch (reg->space_id) { |
638 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 656 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
639 | status = acpi_os_write_memory((acpi_physical_address) | 657 | status = acpi_os_write_memory((acpi_physical_address) address, |
640 | address, val, reg->bit_width); | 658 | val, access_bit_width); |
641 | if (ACPI_FAILURE(status)) | 659 | if (ACPI_FAILURE(status)) |
642 | return -EIO; | 660 | return -EIO; |
643 | break; | 661 | break; |
644 | case ACPI_ADR_SPACE_SYSTEM_IO: | 662 | case ACPI_ADR_SPACE_SYSTEM_IO: |
645 | status = acpi_os_write_port(address, val, reg->bit_width); | 663 | status = acpi_os_write_port(address, val, access_bit_width); |
646 | if (ACPI_FAILURE(status)) | 664 | if (ACPI_FAILURE(status)) |
647 | return -EIO; | 665 | return -EIO; |
648 | break; | 666 | break; |
@@ -661,23 +679,24 @@ static int collect_res_callback(struct apei_exec_context *ctx, | |||
661 | struct apei_resources *resources = data; | 679 | struct apei_resources *resources = data; |
662 | struct acpi_generic_address *reg = &entry->register_region; | 680 | struct acpi_generic_address *reg = &entry->register_region; |
663 | u8 ins = entry->instruction; | 681 | u8 ins = entry->instruction; |
682 | u32 access_bit_width; | ||
664 | u64 paddr; | 683 | u64 paddr; |
665 | int rc; | 684 | int rc; |
666 | 685 | ||
667 | if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)) | 686 | if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)) |
668 | return 0; | 687 | return 0; |
669 | 688 | ||
670 | rc = apei_check_gar(reg, &paddr); | 689 | rc = apei_check_gar(reg, &paddr, &access_bit_width); |
671 | if (rc) | 690 | if (rc) |
672 | return rc; | 691 | return rc; |
673 | 692 | ||
674 | switch (reg->space_id) { | 693 | switch (reg->space_id) { |
675 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 694 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
676 | return apei_res_add(&resources->iomem, paddr, | 695 | return apei_res_add(&resources->iomem, paddr, |
677 | reg->bit_width / 8); | 696 | access_bit_width / 8); |
678 | case ACPI_ADR_SPACE_SYSTEM_IO: | 697 | case ACPI_ADR_SPACE_SYSTEM_IO: |
679 | return apei_res_add(&resources->ioport, paddr, | 698 | return apei_res_add(&resources->ioport, paddr, |
680 | reg->bit_width / 8); | 699 | access_bit_width / 8); |
681 | default: | 700 | default: |
682 | return -EINVAL; | 701 | return -EINVAL; |
683 | } | 702 | } |
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index 5d4189464d63..e6defd86b424 100644 --- a/drivers/acpi/apei/cper.c +++ b/drivers/acpi/apei/cper.c | |||
@@ -362,6 +362,7 @@ void apei_estatus_print(const char *pfx, | |||
362 | gedata_len = gdata->error_data_length; | 362 | gedata_len = gdata->error_data_length; |
363 | apei_estatus_print_section(pfx, gdata, sec_no); | 363 | apei_estatus_print_section(pfx, gdata, sec_no); |
364 | data_len -= gedata_len + sizeof(*gdata); | 364 | data_len -= gedata_len + sizeof(*gdata); |
365 | gdata = (void *)(gdata + 1) + gedata_len; | ||
365 | sec_no++; | 366 | sec_no++; |
366 | } | 367 | } |
367 | } | 368 | } |
@@ -396,6 +397,7 @@ int apei_estatus_check(const struct acpi_hest_generic_status *estatus) | |||
396 | if (gedata_len > data_len - sizeof(*gdata)) | 397 | if (gedata_len > data_len - sizeof(*gdata)) |
397 | return -EINVAL; | 398 | return -EINVAL; |
398 | data_len -= gedata_len + sizeof(*gdata); | 399 | data_len -= gedata_len + sizeof(*gdata); |
400 | gdata = (void *)(gdata + 1) + gedata_len; | ||
399 | } | 401 | } |
400 | if (data_len) | 402 | if (data_len) |
401 | return -EINVAL; | 403 | return -EINVAL; |
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 4ca087dd5f4f..8e1793649ec0 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -74,6 +74,8 @@ struct vendor_error_type_extension { | |||
74 | u8 reserved[3]; | 74 | u8 reserved[3]; |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static u32 notrigger; | ||
78 | |||
77 | static u32 vendor_flags; | 79 | static u32 vendor_flags; |
78 | static struct debugfs_blob_wrapper vendor_blob; | 80 | static struct debugfs_blob_wrapper vendor_blob; |
79 | static char vendor_dev[64]; | 81 | static char vendor_dev[64]; |
@@ -238,7 +240,7 @@ static void *einj_get_parameter_address(void) | |||
238 | return v5param; | 240 | return v5param; |
239 | } | 241 | } |
240 | } | 242 | } |
241 | if (paddrv4) { | 243 | if (param_extension && paddrv4) { |
242 | struct einj_parameter *v4param; | 244 | struct einj_parameter *v4param; |
243 | 245 | ||
244 | v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param)); | 246 | v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param)); |
@@ -496,9 +498,11 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2) | |||
496 | if (rc) | 498 | if (rc) |
497 | return rc; | 499 | return rc; |
498 | trigger_paddr = apei_exec_ctx_get_output(&ctx); | 500 | trigger_paddr = apei_exec_ctx_get_output(&ctx); |
499 | rc = __einj_error_trigger(trigger_paddr, type, param1, param2); | 501 | if (notrigger == 0) { |
500 | if (rc) | 502 | rc = __einj_error_trigger(trigger_paddr, type, param1, param2); |
501 | return rc; | 503 | if (rc) |
504 | return rc; | ||
505 | } | ||
502 | rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION); | 506 | rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION); |
503 | 507 | ||
504 | return rc; | 508 | return rc; |
@@ -700,6 +704,11 @@ static int __init einj_init(void) | |||
700 | einj_debug_dir, &error_param2); | 704 | einj_debug_dir, &error_param2); |
701 | if (!fentry) | 705 | if (!fentry) |
702 | goto err_unmap; | 706 | goto err_unmap; |
707 | |||
708 | fentry = debugfs_create_x32("notrigger", S_IRUSR | S_IWUSR, | ||
709 | einj_debug_dir, ¬rigger); | ||
710 | if (!fentry) | ||
711 | goto err_unmap; | ||
703 | } | 712 | } |
704 | 713 | ||
705 | if (vendor_dev[0]) { | 714 | if (vendor_dev[0]) { |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index eb9fab5b96e4..e4d9d24eb73d 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -917,7 +917,7 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) | |||
917 | { | 917 | { |
918 | if ((erst_tab->header_length != | 918 | if ((erst_tab->header_length != |
919 | (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) | 919 | (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) |
920 | && (erst_tab->header_length != sizeof(struct acpi_table_einj))) | 920 | && (erst_tab->header_length != sizeof(struct acpi_table_erst))) |
921 | return -EINVAL; | 921 | return -EINVAL; |
922 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) | 922 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) |
923 | return -EINVAL; | 923 | return -EINVAL; |