diff options
| -rw-r--r-- | drivers/acpi/apei/ghes.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index ce3683d93a13..46766ef7ef5d 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
| @@ -413,27 +413,31 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev) | |||
| 413 | { | 413 | { |
| 414 | #ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE | 414 | #ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE |
| 415 | unsigned long pfn; | 415 | unsigned long pfn; |
| 416 | int flags = -1; | ||
| 416 | int sec_sev = ghes_severity(gdata->error_severity); | 417 | int sec_sev = ghes_severity(gdata->error_severity); |
| 417 | struct cper_sec_mem_err *mem_err; | 418 | struct cper_sec_mem_err *mem_err; |
| 418 | mem_err = (struct cper_sec_mem_err *)(gdata + 1); | 419 | mem_err = (struct cper_sec_mem_err *)(gdata + 1); |
| 419 | 420 | ||
| 420 | if (sec_sev == GHES_SEV_CORRECTED && | 421 | if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) |
| 421 | (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED) && | 422 | return; |
| 422 | (mem_err->validation_bits & CPER_MEM_VALID_PA)) { | 423 | |
| 423 | pfn = mem_err->physical_addr >> PAGE_SHIFT; | 424 | pfn = mem_err->physical_addr >> PAGE_SHIFT; |
| 424 | if (pfn_valid(pfn)) | 425 | if (!pfn_valid(pfn)) { |
| 425 | memory_failure_queue(pfn, 0, MF_SOFT_OFFLINE); | 426 | pr_warn_ratelimited(FW_WARN GHES_PFX |
| 426 | else if (printk_ratelimit()) | 427 | "Invalid address in generic error data: %#llx\n", |
| 427 | pr_warn(FW_WARN GHES_PFX | 428 | mem_err->physical_addr); |
| 428 | "Invalid address in generic error data: %#llx\n", | 429 | return; |
| 429 | mem_err->physical_addr); | ||
| 430 | } | ||
| 431 | if (sev == GHES_SEV_RECOVERABLE && | ||
| 432 | sec_sev == GHES_SEV_RECOVERABLE && | ||
| 433 | mem_err->validation_bits & CPER_MEM_VALID_PA) { | ||
| 434 | pfn = mem_err->physical_addr >> PAGE_SHIFT; | ||
| 435 | memory_failure_queue(pfn, 0, 0); | ||
| 436 | } | 430 | } |
| 431 | |||
| 432 | /* iff following two events can be handled properly by now */ | ||
| 433 | if (sec_sev == GHES_SEV_CORRECTED && | ||
| 434 | (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED)) | ||
| 435 | flags = MF_SOFT_OFFLINE; | ||
| 436 | if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE) | ||
| 437 | flags = 0; | ||
| 438 | |||
| 439 | if (flags != -1) | ||
| 440 | memory_failure_queue(pfn, 0, flags); | ||
| 437 | #endif | 441 | #endif |
| 438 | } | 442 | } |
| 439 | 443 | ||
