acpi, nfit: fix acpi_check_dsm() vs zero functions implemented
QEMU 2.6 implements nascent support for nvdimm DSMs. Depending on configuration it may only implement the function0 dsm to indicate that no other DSMs are available. Commit31eca76ba2
"nfit, libnvdimm: limited/whitelisted dimm command marshaling mechanism" breaks QEMU, but QEMU is spec compliant. Per the spec the way to indicate that no functions are supported is: If Function Index is zero, the return is a buffer containing one bit for each function index, starting with zero. Bit 0 indicates whether there is support for any functions other than function 0 for the specified UUID and Revision ID. If set to zero, no functions are supported (other than function zero) for the specified UUID and Revision ID. Update the nfit driver to determine the family (interface UUID) without requiring the implementation to define any other functions, i.e. short-circuit acpi_check_dsm() to succeed per the spec. The nfit driver appears to be the only user passing funcs==0 to acpi_check_dsm(), so this behavior change of the common routine should be limited to the probing done by the nfit driver. Cc: Len Brown <lenb@kernel.org> Cc: Jerry Hoemann <jerry.hoemann@hpe.com> Acked-by: "Rafael J. Wysocki" <rafael@kernel.org> Fixes:31eca76ba2
("nfit, libnvdimm: limited/whitelisted dimm command marshaling mechanism") Reported-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> Tested-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
1ee6667cd8
commit
4995734e97
@ -1131,11 +1131,11 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Until standardization materializes we need to consider up to 3
|
* Until standardization materializes we need to consider up to 3
|
||||||
* different command sets. Note, that checking for function0 (bit0)
|
* different command sets. Note, that checking for zero functions
|
||||||
* tells us if any commands are reachable through this uuid.
|
* tells us if any commands might be reachable through this uuid.
|
||||||
*/
|
*/
|
||||||
for (i = NVDIMM_FAMILY_INTEL; i <= NVDIMM_FAMILY_HPE2; i++)
|
for (i = NVDIMM_FAMILY_INTEL; i <= NVDIMM_FAMILY_HPE2; i++)
|
||||||
if (acpi_check_dsm(adev_dimm->handle, to_nfit_uuid(i), 1, 1))
|
if (acpi_check_dsm(adev_dimm->handle, to_nfit_uuid(i), 1, 0))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* limit the supported commands to those that are publicly documented */
|
/* limit the supported commands to those that are publicly documented */
|
||||||
|
@ -680,9 +680,6 @@ bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 funcs)
|
|||||||
u64 mask = 0;
|
u64 mask = 0;
|
||||||
union acpi_object *obj;
|
union acpi_object *obj;
|
||||||
|
|
||||||
if (funcs == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL);
|
obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return false;
|
return false;
|
||||||
@ -695,6 +692,9 @@ bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 funcs)
|
|||||||
mask |= (((u64)obj->buffer.pointer[i]) << (i * 8));
|
mask |= (((u64)obj->buffer.pointer[i]) << (i * 8));
|
||||||
ACPI_FREE(obj);
|
ACPI_FREE(obj);
|
||||||
|
|
||||||
|
if (funcs == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bit 0 indicates whether there's support for any functions other than
|
* Bit 0 indicates whether there's support for any functions other than
|
||||||
* function 0 for the specified UUID and revision.
|
* function 0 for the specified UUID and revision.
|
||||||
|
Loading…
Reference in New Issue
Block a user