summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2020-03-25 13:28:41 +0100
committerArnd Bergmann <arnd@arndb.de>2020-03-25 13:28:42 +0100
commit5fc0458767461bd53b4a74fc003e6175aa853a46 (patch)
tree35a88c69de101e3c18a0285ddce6a7c051465e28 /drivers
parent1822d610c5a7581d1bce457e9cdfc0fdce0eda1a (diff)
parenta6dd255bdd7d00bbdbf78ba00bde9fc64f86c3a7 (diff)
Merge tag 'hisi-drivers-for-5.7' of git://github.com/hisilicon/linux-hisi into arm/drivers
ARM64: hisi: SoC driver updates for 5.7 - Fix up the device resources for the broken firmware to avoid use-after-free warnings from KASAN in the host removal path * tag 'hisi-drivers-for-5.7' of git://github.com/hisilicon/linux-hisi: bus: hisi_lpc: Fixup IO ports addresses to avoid use-after-free in host removal Link: https://lore.kernel.org/r/5E61F700.5060301@hisilicon.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bus/hisi_lpc.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c
index 8101df901830..378f5d62a991 100644
--- a/drivers/bus/hisi_lpc.c
+++ b/drivers/bus/hisi_lpc.c
@@ -358,6 +358,26 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev,
}
/*
+ * Released firmware describes the IO port max address as 0x3fff, which is
+ * the max host bus address. Fixup to a proper range. This will probably
+ * never be fixed in firmware.
+ */
+static void hisi_lpc_acpi_fixup_child_resource(struct device *hostdev,
+ struct resource *r)
+{
+ if (r->end != 0x3fff)
+ return;
+
+ if (r->start == 0xe4)
+ r->end = 0xe4 + 0x04 - 1;
+ else if (r->start == 0x2f8)
+ r->end = 0x2f8 + 0x08 - 1;
+ else
+ dev_warn(hostdev, "unrecognised resource %pR to fixup, ignoring\n",
+ r);
+}
+
+/*
* hisi_lpc_acpi_set_io_res - set the resources for a child
* @child: the device node to be updated the I/O resource
* @hostdev: the device node associated with host controller
@@ -418,8 +438,11 @@ static int hisi_lpc_acpi_set_io_res(struct device *child,
return -ENOMEM;
}
count = 0;
- list_for_each_entry(rentry, &resource_list, node)
- resources[count++] = *rentry->res;
+ list_for_each_entry(rentry, &resource_list, node) {
+ resources[count] = *rentry->res;
+ hisi_lpc_acpi_fixup_child_resource(hostdev, &resources[count]);
+ count++;
+ }
acpi_dev_free_resource_list(&resource_list);