forked from Minki/linux
intel_th: Fix resource handling for ACPI glue layer
The core of the driver expects the resource array from the glue layer
to be indexed by even numbers, as is the case for 64-bit PCI resources.
This doesn't hold true for others, ACPI in this instance, which leads
to an out-of-bounds access and an ioremap() on whatever address that
access fetches.
This patch fixes the problem by reading resource array differently based
on whether the 64-bit flag is set, which would indicate PCI glue layer.
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Fixes: ebc57e399b
("intel_th: Add ACPI glue layer")
CC: stable@vger.kernel.org # v4.17+
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8801922cd9
commit
ebe4582281
@ -488,7 +488,7 @@ static const struct intel_th_subdevice {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = TH_MMIO_SW,
|
||||
.start = 1, /* use resource[1] */
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
@ -581,6 +581,7 @@ intel_th_subdevice_alloc(struct intel_th *th,
|
||||
struct intel_th_device *thdev;
|
||||
struct resource res[3];
|
||||
unsigned int req = 0;
|
||||
bool is64bit = false;
|
||||
int r, err;
|
||||
|
||||
thdev = intel_th_device_alloc(th, subdev->type, subdev->name,
|
||||
@ -590,12 +591,18 @@ intel_th_subdevice_alloc(struct intel_th *th,
|
||||
|
||||
thdev->drvdata = th->drvdata;
|
||||
|
||||
for (r = 0; r < th->num_resources; r++)
|
||||
if (th->resource[r].flags & IORESOURCE_MEM_64) {
|
||||
is64bit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(res, subdev->res,
|
||||
sizeof(struct resource) * subdev->nres);
|
||||
|
||||
for (r = 0; r < subdev->nres; r++) {
|
||||
struct resource *devres = th->resource;
|
||||
int bar = TH_MMIO_CONFIG;
|
||||
int bar = 0; /* cut subdevices' MMIO from resource[0] */
|
||||
|
||||
/*
|
||||
* Take .end == 0 to mean 'take the whole bar',
|
||||
@ -604,6 +611,8 @@ intel_th_subdevice_alloc(struct intel_th *th,
|
||||
*/
|
||||
if (!res[r].end && res[r].flags == IORESOURCE_MEM) {
|
||||
bar = res[r].start;
|
||||
if (is64bit)
|
||||
bar *= 2;
|
||||
res[r].start = 0;
|
||||
res[r].end = resource_size(&devres[bar]) - 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user