diff options
| author | Dan Williams <dan.j.williams@intel.com> | 2019-02-13 12:28:40 -0500 |
|---|---|---|
| committer | Dan Williams <dan.j.williams@intel.com> | 2019-02-20 17:18:59 -0500 |
| commit | 78153dd45e7e0596ba32b15d02bda08e1513111e (patch) | |
| tree | 2d3cf972ea3713136530f3dbcdd4981a014faa43 | |
| parent | 5479b2757f26fe9908fc341d105b2097fe820b6f (diff) | |
nfit/ars: Avoid stale ARS results
Gate ARS result consumption on whether the OS issued start-ARS since the
previous consumption. The BIOS may only clear its result buffers after a
successful start-ARS.
Fixes: 0caeef63e6d2 ("libnvdimm: Add a poison list and export badblocks")
Cc: <stable@vger.kernel.org>
Reported-by: Krzysztof Rusocki <krzysztof.rusocki@intel.com>
Reported-by: Vishal Verma <vishal.l.verma@intel.com>
Reviewed-by: Toshi Kani <toshi.kani@hpe.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
| -rw-r--r-- | drivers/acpi/nfit/core.c | 17 | ||||
| -rw-r--r-- | drivers/acpi/nfit/nfit.h | 1 |
2 files changed, 17 insertions, 1 deletions
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 629cf91649d2..5c9eb8d700d3 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c | |||
| @@ -2652,7 +2652,10 @@ static int ars_start(struct acpi_nfit_desc *acpi_desc, | |||
| 2652 | 2652 | ||
| 2653 | if (rc < 0) | 2653 | if (rc < 0) |
| 2654 | return rc; | 2654 | return rc; |
| 2655 | return cmd_rc; | 2655 | if (cmd_rc < 0) |
| 2656 | return cmd_rc; | ||
| 2657 | set_bit(ARS_VALID, &acpi_desc->scrub_flags); | ||
| 2658 | return 0; | ||
| 2656 | } | 2659 | } |
| 2657 | 2660 | ||
| 2658 | static int ars_continue(struct acpi_nfit_desc *acpi_desc) | 2661 | static int ars_continue(struct acpi_nfit_desc *acpi_desc) |
| @@ -2745,6 +2748,17 @@ static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc) | |||
| 2745 | */ | 2748 | */ |
| 2746 | if (ars_status->out_length < 44) | 2749 | if (ars_status->out_length < 44) |
| 2747 | return 0; | 2750 | return 0; |
| 2751 | |||
| 2752 | /* | ||
| 2753 | * Ignore potentially stale results that are only refreshed | ||
| 2754 | * after a start-ARS event. | ||
| 2755 | */ | ||
| 2756 | if (!test_and_clear_bit(ARS_VALID, &acpi_desc->scrub_flags)) { | ||
| 2757 | dev_dbg(acpi_desc->dev, "skip %d stale records\n", | ||
| 2758 | ars_status->num_records); | ||
| 2759 | return 0; | ||
| 2760 | } | ||
| 2761 | |||
| 2748 | for (i = 0; i < ars_status->num_records; i++) { | 2762 | for (i = 0; i < ars_status->num_records; i++) { |
| 2749 | /* only process full records */ | 2763 | /* only process full records */ |
| 2750 | if (ars_status->out_length | 2764 | if (ars_status->out_length |
| @@ -3229,6 +3243,7 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc) | |||
| 3229 | struct nfit_spa *nfit_spa; | 3243 | struct nfit_spa *nfit_spa; |
| 3230 | int rc; | 3244 | int rc; |
| 3231 | 3245 | ||
| 3246 | set_bit(ARS_VALID, &acpi_desc->scrub_flags); | ||
| 3232 | list_for_each_entry(nfit_spa, &acpi_desc->spas, list) { | 3247 | list_for_each_entry(nfit_spa, &acpi_desc->spas, list) { |
| 3233 | switch (nfit_spa_type(nfit_spa->spa)) { | 3248 | switch (nfit_spa_type(nfit_spa->spa)) { |
| 3234 | case NFIT_SPA_VOLATILE: | 3249 | case NFIT_SPA_VOLATILE: |
diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h index d14bad687fb8..0cbe5009eb2c 100644 --- a/drivers/acpi/nfit/nfit.h +++ b/drivers/acpi/nfit/nfit.h | |||
| @@ -213,6 +213,7 @@ struct nfit_mem { | |||
| 213 | enum scrub_flags { | 213 | enum scrub_flags { |
| 214 | ARS_BUSY, | 214 | ARS_BUSY, |
| 215 | ARS_CANCEL, | 215 | ARS_CANCEL, |
| 216 | ARS_VALID, | ||
| 216 | ARS_POLL, | 217 | ARS_POLL, |
| 217 | }; | 218 | }; |
| 218 | 219 | ||
