From 614c4feef09753d6e13ee8a27fc6fbdf9c51b4c5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 14 Jan 2020 12:49:27 +0100 Subject: usb: ehci: Do not use memset on dma coherent memory memset is an optimized operation that at least on ARM64 may only be called on cached memory, see 32e8842c40 ("ARM: lib64: Make string functions aware of MMU configuration"). To avoid crashes in the ehci driver we no longer call memset on memory allocated with dma_alloc_coherent(), but use a simple memzero32 function instead. Reported-by: Elmar Albert Signed-off-by: Sascha Hauer --- drivers/usb/host/ehci-hcd.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f3be177ceb..417ae5df75 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -137,6 +137,15 @@ static struct descriptor { #define ehci_is_TDI() (ehci->flags & EHCI_HAS_TT) +static void memzero32(void *ptr, size_t size) +{ + uint32_t *ptr32 = ptr; + int i; + + for (i = 0; i < size / sizeof(uint32_t); i++) + ptr32[i] = 0x0; +} + static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec) { uint32_t result; @@ -237,7 +246,7 @@ static int ehci_prepare_qtd(struct device_d *dev, if (ret) return ret; } else { - memset(td->qt_buffer, 0, sizeof(td->qt_buffer)); + memzero32(td->qt_buffer, sizeof(td->qt_buffer)); } return 0; @@ -318,7 +327,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, qh->qh_endpt2 = cpu_to_hc32(endpt); qh->qh_curtd = 0; qh->qt_token = 0; - memset(qh->qt_buffer, 0, sizeof(qh->qt_buffer)); + memzero32(qh->qt_buffer, sizeof(qh->qt_buffer)); tdp = &qh->qt_next; @@ -854,7 +863,7 @@ static int ehci_init(struct usb_host *host) */ ehci->periodic_schedules = 0; periodic = ehci->periodic_queue; - memset(periodic, 0, sizeof(*periodic)); + memzero32(periodic, sizeof(*periodic)); periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE); periodic->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); periodic->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); -- cgit v1.2.3