From: Sasha Levin Date: Sun, 19 Jan 2020 17:46:14 +0000 (-0500) Subject: fixes for 4.14 X-Git-Tag: v4.4.211~47 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=73720e638dff95ff780ff025c25c867c7ecc3b83;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 4.14 Signed-off-by: Sasha Levin --- diff --git a/queue-4.14/mm-huge_memory.c-make-__thp_get_unmapped_area-static.patch b/queue-4.14/mm-huge_memory.c-make-__thp_get_unmapped_area-static.patch new file mode 100644 index 00000000000..0b8f97f0576 --- /dev/null +++ b/queue-4.14/mm-huge_memory.c-make-__thp_get_unmapped_area-static.patch @@ -0,0 +1,38 @@ +From e6de2f5beaf88f7cdea7b5a435d183539b783d65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 May 2019 17:23:17 -0700 +Subject: mm/huge_memory.c: make __thp_get_unmapped_area static + +From: Bharath Vedartham + +[ Upstream commit b3b07077b01ecbbd98efede778c195567de25b71 ] + +__thp_get_unmapped_area is only used in mm/huge_memory.c. Make it static. +Tested by building and booting the kernel. + +Link: http://lkml.kernel.org/r/20190504102353.GA22525@bharath12345-Inspiron-5559 +Signed-off-by: Bharath Vedartham +Acked-by: Michal Hocko +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + mm/huge_memory.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 1adc2e6c50f9..6d835535946d 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -502,7 +502,7 @@ void prep_transhuge_page(struct page *page) + set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); + } + +-unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, ++static unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, + loff_t off, unsigned long flags, unsigned long size) + { + unsigned long addr; +-- +2.20.1 + diff --git a/queue-4.14/mm-huge_memory.c-thp-fix-conflict-of-above-47bit-hin.patch b/queue-4.14/mm-huge_memory.c-thp-fix-conflict-of-above-47bit-hin.patch new file mode 100644 index 00000000000..0e138b2f7e3 --- /dev/null +++ b/queue-4.14/mm-huge_memory.c-thp-fix-conflict-of-above-47bit-hin.patch @@ -0,0 +1,139 @@ +From c2c0078b764a5968f668b223c21c276bb99cf8d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2020 16:29:10 -0800 +Subject: mm/huge_memory.c: thp: fix conflict of above-47bit hint address and + PMD alignment + +From: Kirill A. Shutemov + +[ Upstream commit 97d3d0f9a1cf132c63c0b8b8bd497b8a56283dd9 ] + +Patch series "Fix two above-47bit hint address vs. THP bugs". + +The two get_unmapped_area() implementations have to be fixed to provide +THP-friendly mappings if above-47bit hint address is specified. + +This patch (of 2): + +Filesystems use thp_get_unmapped_area() to provide THP-friendly +mappings. For DAX in particular. + +Normally, the kernel doesn't create userspace mappings above 47-bit, +even if the machine allows this (such as with 5-level paging on x86-64). +Not all user space is ready to handle wide addresses. It's known that +at least some JIT compilers use higher bits in pointers to encode their +information. + +Userspace can ask for allocation from full address space by specifying +hint address (with or without MAP_FIXED) above 47-bits. If the +application doesn't need a particular address, but wants to allocate +from whole address space it can specify -1 as a hint address. + +Unfortunately, this trick breaks thp_get_unmapped_area(): the function +would not try to allocate PMD-aligned area if *any* hint address +specified. + +Modify the routine to handle it correctly: + + - Try to allocate the space at the specified hint address with length + padding required for PMD alignment. + - If failed, retry without length padding (but with the same hint + address); + - If the returned address matches the hint address return it. + - Otherwise, align the address as required for THP and return. + +The user specified hint address is passed down to get_unmapped_area() so +above-47bit hint address will be taken into account without breaking +alignment requirements. + +Link: http://lkml.kernel.org/r/20191220142548.7118-2-kirill.shutemov@linux.intel.com +Fixes: b569bab78d8d ("x86/mm: Prepare to expose larger address space to userspace") +Signed-off-by: Kirill A. Shutemov +Reported-by: Thomas Willhalm +Tested-by: Dan Williams +Cc: "Aneesh Kumar K . V" +Cc: "Bruggeman, Otto G" +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + mm/huge_memory.c | 38 ++++++++++++++++++++++++-------------- + 1 file changed, 24 insertions(+), 14 deletions(-) + +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 6d835535946d..92915cc87549 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -502,13 +502,13 @@ void prep_transhuge_page(struct page *page) + set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); + } + +-static unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, ++static unsigned long __thp_get_unmapped_area(struct file *filp, ++ unsigned long addr, unsigned long len, + loff_t off, unsigned long flags, unsigned long size) + { +- unsigned long addr; + loff_t off_end = off + len; + loff_t off_align = round_up(off, size); +- unsigned long len_pad; ++ unsigned long len_pad, ret; + + if (off_end <= off_align || (off_end - off_align) < size) + return 0; +@@ -517,30 +517,40 @@ static unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long le + if (len_pad < len || (off + len_pad) < off) + return 0; + +- addr = current->mm->get_unmapped_area(filp, 0, len_pad, ++ ret = current->mm->get_unmapped_area(filp, addr, len_pad, + off >> PAGE_SHIFT, flags); +- if (IS_ERR_VALUE(addr)) ++ ++ /* ++ * The failure might be due to length padding. The caller will retry ++ * without the padding. ++ */ ++ if (IS_ERR_VALUE(ret)) + return 0; + +- addr += (off - addr) & (size - 1); +- return addr; ++ /* ++ * Do not try to align to THP boundary if allocation at the address ++ * hint succeeds. ++ */ ++ if (ret == addr) ++ return addr; ++ ++ ret += (off - ret) & (size - 1); ++ return ret; + } + + unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) + { ++ unsigned long ret; + loff_t off = (loff_t)pgoff << PAGE_SHIFT; + +- if (addr) +- goto out; + if (!IS_DAX(filp->f_mapping->host) || !IS_ENABLED(CONFIG_FS_DAX_PMD)) + goto out; + +- addr = __thp_get_unmapped_area(filp, len, off, flags, PMD_SIZE); +- if (addr) +- return addr; +- +- out: ++ ret = __thp_get_unmapped_area(filp, addr, len, off, flags, PMD_SIZE); ++ if (ret) ++ return ret; ++out: + return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags); + } + EXPORT_SYMBOL_GPL(thp_get_unmapped_area); +-- +2.20.1 + diff --git a/queue-4.14/series b/queue-4.14/series index e1488105a98..053415351e0 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -28,3 +28,7 @@ btrfs-fix-memory-leak-in-qgroup-accounting.patch mm-page-writeback.c-avoid-potential-division-by-zero-in-wb_min_max_ratio.patch net-stmmac-16kb-buffer-must-be-16-byte-aligned.patch net-stmmac-enable-16kb-buffer-size.patch +usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch +usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch +mm-huge_memory.c-make-__thp_get_unmapped_area-static.patch +mm-huge_memory.c-thp-fix-conflict-of-above-47bit-hin.patch diff --git a/queue-4.14/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch b/queue-4.14/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch new file mode 100644 index 00000000000..2998bb293d7 --- /dev/null +++ b/queue-4.14/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch @@ -0,0 +1,49 @@ +From 8f8b41e3b9e3fdae7c2384598c66b6d87380b404 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Jan 2020 10:50:23 +0100 +Subject: USB: serial: io_edgeport: handle unbound ports on URB completion + +From: Johan Hovold + +[ Upstream commit e37d1aeda737a20b1846a91a3da3f8b0f00cf690 ] + +Check for NULL port data in the shared interrupt and bulk completion +callbacks to avoid dereferencing a NULL pointer in case a device sends +data for a port device which isn't bound to a driver (e.g. due to a +malicious device having unexpected endpoints or after an allocation +failure on port probe). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Sasha Levin +--- + drivers/usb/serial/io_edgeport.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c +index 8810de817095..3705b64ab948 100644 +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -720,7 +720,7 @@ static void edge_interrupt_callback(struct urb *urb) + if (txCredits) { + port = edge_serial->serial->port[portNumber]; + edge_port = usb_get_serial_port_data(port); +- if (edge_port->open) { ++ if (edge_port && edge_port->open) { + spin_lock_irqsave(&edge_port->ep_lock, + flags); + edge_port->txCredits += txCredits; +@@ -1847,7 +1847,7 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, + if (rxLen && edge_serial->rxPort < serial->num_ports) { + port = serial->port[edge_serial->rxPort]; + edge_port = usb_get_serial_port_data(port); +- if (edge_port->open) { ++ if (edge_port && edge_port->open) { + dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n", + __func__, rxLen, + edge_serial->rxPort); +-- +2.20.1 + diff --git a/queue-4.14/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch b/queue-4.14/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch new file mode 100644 index 00000000000..b51d1c5579e --- /dev/null +++ b/queue-4.14/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch @@ -0,0 +1,99 @@ +From 81936a3ec782d83832124b3f3da55e8139342a68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Jun 2018 00:32:06 +0200 +Subject: USB: serial: io_edgeport: use irqsave() in USB's complete callback + +From: John Ogness + +[ Upstream commit dd1fae527612543e560e84f2eba4f6ef2006ac55 ] + +The USB completion callback does not disable interrupts while acquiring +the lock. We want to remove the local_irq_disable() invocation from +__usb_hcd_giveback_urb() and therefore it is required for the callback +handler to disable the interrupts while acquiring the lock. +The callback may be invoked either in IRQ or BH context depending on the +USB host controller. +Use the _irqsave() variant of the locking primitives. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Johan Hovold +Signed-off-by: Sasha Levin +--- + drivers/usb/serial/io_edgeport.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c +index 467870f504a5..8810de817095 100644 +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -652,6 +652,7 @@ static void edge_interrupt_callback(struct urb *urb) + struct usb_serial_port *port; + unsigned char *data = urb->transfer_buffer; + int length = urb->actual_length; ++ unsigned long flags; + int bytes_avail; + int position; + int txCredits; +@@ -683,7 +684,7 @@ static void edge_interrupt_callback(struct urb *urb) + if (length > 1) { + bytes_avail = data[0] | (data[1] << 8); + if (bytes_avail) { +- spin_lock(&edge_serial->es_lock); ++ spin_lock_irqsave(&edge_serial->es_lock, flags); + edge_serial->rxBytesAvail += bytes_avail; + dev_dbg(dev, + "%s - bytes_avail=%d, rxBytesAvail=%d, read_in_progress=%d\n", +@@ -706,7 +707,8 @@ static void edge_interrupt_callback(struct urb *urb) + edge_serial->read_in_progress = false; + } + } +- spin_unlock(&edge_serial->es_lock); ++ spin_unlock_irqrestore(&edge_serial->es_lock, ++ flags); + } + } + /* grab the txcredits for the ports if available */ +@@ -719,9 +721,11 @@ static void edge_interrupt_callback(struct urb *urb) + port = edge_serial->serial->port[portNumber]; + edge_port = usb_get_serial_port_data(port); + if (edge_port->open) { +- spin_lock(&edge_port->ep_lock); ++ spin_lock_irqsave(&edge_port->ep_lock, ++ flags); + edge_port->txCredits += txCredits; +- spin_unlock(&edge_port->ep_lock); ++ spin_unlock_irqrestore(&edge_port->ep_lock, ++ flags); + dev_dbg(dev, "%s - txcredits for port%d = %d\n", + __func__, portNumber, + edge_port->txCredits); +@@ -762,6 +766,7 @@ static void edge_bulk_in_callback(struct urb *urb) + int retval; + __u16 raw_data_length; + int status = urb->status; ++ unsigned long flags; + + if (status) { + dev_dbg(&urb->dev->dev, "%s - nonzero read bulk status received: %d\n", +@@ -781,7 +786,7 @@ static void edge_bulk_in_callback(struct urb *urb) + + usb_serial_debug_data(dev, __func__, raw_data_length, data); + +- spin_lock(&edge_serial->es_lock); ++ spin_lock_irqsave(&edge_serial->es_lock, flags); + + /* decrement our rxBytes available by the number that we just got */ + edge_serial->rxBytesAvail -= raw_data_length; +@@ -805,7 +810,7 @@ static void edge_bulk_in_callback(struct urb *urb) + edge_serial->read_in_progress = false; + } + +- spin_unlock(&edge_serial->es_lock); ++ spin_unlock_irqrestore(&edge_serial->es_lock, flags); + } + + +-- +2.20.1 +