aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2019-02-13 12:28:40 -0500
committerDan Williams <dan.j.williams@intel.com>2019-02-20 17:18:59 -0500
commit78153dd45e7e0596ba32b15d02bda08e1513111e (patch)
tree2d3cf972ea3713136530f3dbcdd4981a014faa43
parent5479b2757f26fe9908fc341d105b2097fe820b6f (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.c17
-rw-r--r--drivers/acpi/nfit/nfit.h1
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
2658static int ars_continue(struct acpi_nfit_desc *acpi_desc) 2661static 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 {
213enum scrub_flags { 213enum 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