ACPI: NFIT: Fix ARS zero-sized allocation
Pending commit in -next "devres: handle zero size in devm_kmalloc()"
triggers a boot regression due to the ARS implementation expecting NULL
from a zero-sized allocation. Avoid the zero-sized allocation by
skipping ARS, otherwise crashes with the following signature when
de-referencing ZERO_SIZE_PTR.
BUG: kernel NULL pointer dereference, address: 0000000000000018
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
RIP: 0010:__acpi_nfit_scrub+0x28a/0x350 [nfit]
[..]
Call Trace:
? acpi_nfit_query_poison+0x6a/0x180 [nfit]
acpi_nfit_scrub+0x36/0xb0 [nfit]
process_one_work+0x23c/0x580
worker_thread+0x50/0x3b0
Otherwise the implementation correctly aborts when NULL is returned from
devm_kzalloc() in ars_status_alloc().
Link: https://lore.kernel.org/r/159624590643.3037264.14157533719042907758.stgit@dwillia2-desk3.amr.corp.intel.com
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
This commit is contained in:
committed by
Vishal Verma
parent
49688e654e
commit
9f1048d47e
@@ -3334,7 +3334,7 @@ static void acpi_nfit_init_ars(struct acpi_nfit_desc *acpi_desc,
|
|||||||
static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
|
static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
|
||||||
{
|
{
|
||||||
struct nfit_spa *nfit_spa;
|
struct nfit_spa *nfit_spa;
|
||||||
int rc;
|
int rc, do_sched_ars = 0;
|
||||||
|
|
||||||
set_bit(ARS_VALID, &acpi_desc->scrub_flags);
|
set_bit(ARS_VALID, &acpi_desc->scrub_flags);
|
||||||
list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
|
list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
|
||||||
@@ -3346,7 +3346,7 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(nfit_spa, &acpi_desc->spas, list)
|
list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
|
||||||
switch (nfit_spa_type(nfit_spa->spa)) {
|
switch (nfit_spa_type(nfit_spa->spa)) {
|
||||||
case NFIT_SPA_VOLATILE:
|
case NFIT_SPA_VOLATILE:
|
||||||
case NFIT_SPA_PM:
|
case NFIT_SPA_PM:
|
||||||
@@ -3354,6 +3354,13 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
|
|||||||
rc = ars_register(acpi_desc, nfit_spa);
|
rc = ars_register(acpi_desc, nfit_spa);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kick off background ARS if at least one
|
||||||
|
* region successfully registered ARS
|
||||||
|
*/
|
||||||
|
if (!test_bit(ARS_FAILED, &nfit_spa->ars_state))
|
||||||
|
do_sched_ars++;
|
||||||
break;
|
break;
|
||||||
case NFIT_SPA_BDW:
|
case NFIT_SPA_BDW:
|
||||||
/* nothing to register */
|
/* nothing to register */
|
||||||
@@ -3372,7 +3379,9 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
|
|||||||
/* don't register unknown regions */
|
/* don't register unknown regions */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (do_sched_ars)
|
||||||
sched_ars(acpi_desc);
|
sched_ars(acpi_desc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user