| 1 | APEI tables generating and CPER record |
| 2 | ====================================== |
| 3 | |
| 4 | .. |
| 5 | Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD. |
| 6 | |
| 7 | This work is licensed under the terms of the GNU GPL, version 2 or later. |
| 8 | See the COPYING file in the top-level directory. |
| 9 | |
| 10 | Design Details |
| 11 | -------------- |
| 12 | |
| 13 | :: |
| 14 | |
| 15 | etc/acpi/tables etc/hardware_errors |
| 16 | ==================== =============================== |
| 17 | + +--------------------------+ +----------------------------+ |
| 18 | | | HEST | +--------->| error_block_address1 |------+ |
| 19 | | +--------------------------+ | +----------------------------+ | |
| 20 | | | GHES1 | | +------->| error_block_address2 |------+-+ |
| 21 | | +--------------------------+ | | +----------------------------+ | | |
| 22 | | | ................. | | | | .............. | | | |
| 23 | | | error_status_address-----+-+ | -----------------------------+ | | |
| 24 | | | ................. | | +--->| error_block_addressN |------+-+---+ |
| 25 | | | read_ack_register--------+-+ | | +----------------------------+ | | | |
| 26 | | | read_ack_preserve | +-+---+--->| read_ack_register1 | | | | |
| 27 | | | read_ack_write | | | +----------------------------+ | | | |
| 28 | + +--------------------------+ | +-+--->| read_ack_register2 | | | | |
| 29 | | | GHES2 | | | | +----------------------------+ | | | |
| 30 | + +--------------------------+ | | | | ............. | | | | |
| 31 | | | ................. | | | | +----------------------------+ | | | |
| 32 | | | error_status_address-----+---+ | | +->| read_ack_registerN | | | | |
| 33 | | | ................. | | | | +----------------------------+ | | | |
| 34 | | | read_ack_register--------+-----+ | | |Generic Error Status Block 1|<-----+ | | |
| 35 | | | read_ack_preserve | | | |-+------------------------+-+ | | |
| 36 | | | read_ack_write | | | | | CPER | | | | |
| 37 | + +--------------------------| | | | | CPER | | | | |
| 38 | | | ............... | | | | | .... | | | | |
| 39 | + +--------------------------+ | | | | CPER | | | | |
| 40 | | | GHESN | | | |-+------------------------+-| | | |
| 41 | + +--------------------------+ | | |Generic Error Status Block 2|<-------+ | |
| 42 | | | ................. | | | |-+------------------------+-+ | |
| 43 | | | error_status_address-----+-------+ | | | CPER | | | |
| 44 | | | ................. | | | | CPER | | | |
| 45 | | | read_ack_register--------+---------+ | | .... | | | |
| 46 | | | read_ack_preserve | | | CPER | | | |
| 47 | | | read_ack_write | +-+------------------------+-+ | |
| 48 | + +--------------------------+ | .......... | | |
| 49 | |----------------------------+ | |
| 50 | |Generic Error Status Block N |<----------+ |
| 51 | |-+-------------------------+-+ |
| 52 | | | CPER | | |
| 53 | | | CPER | | |
| 54 | | | .... | | |
| 55 | | | CPER | | |
| 56 | +-+-------------------------+-+ |
| 57 | |
| 58 | |
| 59 | (1) QEMU generates the ACPI HEST table. This table goes in the current |
| 60 | "etc/acpi/tables" fw_cfg blob. Each error source has different |
| 61 | notification types. |
| 62 | |
| 63 | (2) A new fw_cfg blob called "etc/hardware_errors" is introduced. QEMU |
| 64 | also needs to populate this blob. The "etc/hardware_errors" fw_cfg blob |
| 65 | contains an address registers table and an Error Status Data Block table. |
| 66 | |
| 67 | (3) The address registers table contains N Error Block Address entries |
| 68 | and N Read Ack Register entries. The size for each entry is 8-byte. |
| 69 | The Error Status Data Block table contains N Error Status Data Block |
| 70 | entries. The size for each entry is defined at the source code as |
| 71 | ACPI_GHES_MAX_RAW_DATA_LENGTH (currently 1024 bytes). The total size |
| 72 | for the "etc/hardware_errors" fw_cfg blob is |
| 73 | (N * 8 * 2 + N * ACPI_GHES_MAX_RAW_DATA_LENGTH) bytes. |
| 74 | N is the number of the kinds of hardware error sources. |
| 75 | |
| 76 | (4) QEMU generates the ACPI linker/loader script for the firmware. The |
| 77 | firmware pre-allocates memory for "etc/acpi/tables", "etc/hardware_errors" |
| 78 | and copies blob contents there. |
| 79 | |
| 80 | (5) QEMU generates N ADD_POINTER commands, which patch addresses in the |
| 81 | "error_status_address" fields of the HEST table with a pointer to the |
| 82 | corresponding "address registers" in the "etc/hardware_errors" blob. |
| 83 | |
| 84 | (6) QEMU generates N ADD_POINTER commands, which patch addresses in the |
| 85 | "read_ack_register" fields of the HEST table with a pointer to the |
| 86 | corresponding "read_ack_register" within the "etc/hardware_errors" blob. |
| 87 | |
| 88 | (7) QEMU generates N ADD_POINTER commands for the firmware, which patch |
| 89 | addresses in the "error_block_address" fields with a pointer to the |
| 90 | respective "Error Status Data Block" in the "etc/hardware_errors" blob. |
| 91 | |
| 92 | (8) QEMU defines a third and write-only fw_cfg blob to store the location |
| 93 | where the error block offsets, read ack registers and CPER records are |
| 94 | stored. |
| 95 | |
| 96 | Up to QEMU 9.2, the location was at "etc/hardware_errors_addr", and |
| 97 | contains a GPA for the beginning of "etc/hardware_errors". |
| 98 | |
| 99 | Newer versions place the location at "etc/acpi_table_hest_addr", |
| 100 | pointing to the GPA of the HEST table. |
| 101 | |
| 102 | Using above mentioned 'fw_cfg' files, the firmware can send back the |
| 103 | guest-side allocation addresses to QEMU. They contain a 8-byte entry. |
| 104 | QEMU generates a single WRITE_POINTER command for the firmware. The |
| 105 | firmware will write back the start address of either "etc/hardware_errors" |
| 106 | or HEST table at the corresponding fw_cfg file. |
| 107 | |
| 108 | (9) When QEMU gets a SIGBUS from the kernel, QEMU writes CPER into corresponding |
| 109 | "Error Status Data Block", guest memory, and then injects platform specific |
| 110 | interrupt (in case of arm/virt machine it's Synchronous External Abort) as a |
| 111 | notification which is necessary for notifying the guest. |
| 112 | |
| 113 | (10) This notification (in virtual hardware) will be handled by the guest |
| 114 | kernel, on receiving notification, guest APEI driver could read the CPER error |
| 115 | and take appropriate action. |
| 116 | |
| 117 | (11) kvm_arch_on_sigbus_vcpu() reports RAS errors via a SEA notifications, |
| 118 | when a SIGBUS event is triggered. |