From: Greg Kroah-Hartman Date: Wed, 19 Apr 2017 16:05:53 +0000 (+0200) Subject: 3.18 patches X-Git-Tag: v4.4.63~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a1ac2f644256cff2b2a15020c1b87757893a001f;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18 patches --- diff --git a/mbox_todo-3.18 b/mbox_todo-3.18 index ee898236a7d..7c61f49fbea 100644 --- a/mbox_todo-3.18 +++ b/mbox_todo-3.18 @@ -431,5576 +431,116 @@ index 0fcdbe7ca648..623f01772bec 100644 -- 2.12.2 -From 804a935963a91acd1764ba914f825dd2a29c5871 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Wed, 15 Mar 2017 09:57:56 +0800 -Subject: [PATCH 037/251] Linux 4.4.54 -Status: RO -Content-Length: 301 -Lines: 18 - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index 10aec937e9e4..7f54ac081cf3 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 4 - PATCHLEVEL = 4 --SUBLEVEL = 53 -+SUBLEVEL = 54 - EXTRAVERSION = - NAME = Blurry Fish Butt - --- -2.12.2 - -From 28ec98bc2e4a175b60f45d505e715a33b93dd077 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Sat, 18 Mar 2017 19:10:23 +0800 -Subject: [PATCH 073/251] Linux 4.4.55 -Status: RO -Content-Length: 301 -Lines: 18 - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index 7f54ac081cf3..d9cc21df444d 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 4 - PATCHLEVEL = 4 --SUBLEVEL = 54 -+SUBLEVEL = 55 - EXTRAVERSION = - NAME = Blurry Fish Butt - --- -2.12.2 - -From 0136bca4e0f65075b0b4716a270f8b04c6c46abc Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Wed, 22 Mar 2017 12:17:51 +0100 -Subject: [PATCH 102/251] Linux 4.4.56 -Status: RO -Content-Length: 301 -Lines: 18 - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index d9cc21df444d..cf9303a5d621 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 4 - PATCHLEVEL = 4 --SUBLEVEL = 55 -+SUBLEVEL = 56 - EXTRAVERSION = - NAME = Blurry Fish Butt - --- -2.12.2 - -From 4cb0c0b73d1c79a8ce260836b3f27650aa1c57f1 Mon Sep 17 00:00:00 2001 -From: Linus Torvalds -Date: Thu, 2 Mar 2017 12:17:22 -0800 -Subject: [PATCH 120/251] give up on gcc ilog2() constant optimizations -Status: RO -Content-Length: 4200 -Lines: 125 - -commit 474c90156c8dcc2fa815e6716cc9394d7930cb9c upstream. - -gcc-7 has an "optimization" pass that completely screws up, and -generates the code expansion for the (impossible) case of calling -ilog2() with a zero constant, even when the code gcc compiles does not -actually have a zero constant. - -And we try to generate a compile-time error for anybody doing ilog2() on -a constant where that doesn't make sense (be it zero or negative). So -now gcc7 will fail the build due to our sanity checking, because it -created that constant-zero case that didn't actually exist in the source -code. - -There's a whole long discussion on the kernel mailing about how to work -around this gcc bug. The gcc people themselevs have discussed their -"feature" in - - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72785 - -but it's all water under the bridge, because while it looked at one -point like it would be solved by the time gcc7 was released, that was -not to be. - -So now we have to deal with this compiler braindamage. - -And the only simple approach seems to be to just delete the code that -tries to warn about bad uses of ilog2(). - -So now "ilog2()" will just return 0 not just for the value 1, but for -any non-positive value too. - -It's not like I can recall anybody having ever actually tried to use -this function on any invalid value, but maybe the sanity check just -meant that such code never made it out in public. - -Reported-by: Laura Abbott -Cc: John Stultz , -Cc: Thomas Gleixner -Cc: Ard Biesheuvel -Signed-off-by: Linus Torvalds -Cc: Jiri Slaby -Signed-off-by: Greg Kroah-Hartman ---- - include/linux/log2.h | 13 ++----------- - tools/include/linux/log2.h | 13 ++----------- - 2 files changed, 4 insertions(+), 22 deletions(-) - -diff --git a/include/linux/log2.h b/include/linux/log2.h -index fd7ff3d91e6a..f38fae23bdac 100644 ---- a/include/linux/log2.h -+++ b/include/linux/log2.h -@@ -16,12 +16,6 @@ - #include - - /* -- * deal with unrepresentable constant logarithms -- */ --extern __attribute__((const, noreturn)) --int ____ilog2_NaN(void); -- --/* - * non-constant log of base 2 calculators - * - the arch may override these in asm/bitops.h if they can be implemented - * more efficiently than using fls() and fls64() -@@ -85,7 +79,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) - #define ilog2(n) \ - ( \ - __builtin_constant_p(n) ? ( \ -- (n) < 1 ? ____ilog2_NaN() : \ -+ (n) < 2 ? 0 : \ - (n) & (1ULL << 63) ? 63 : \ - (n) & (1ULL << 62) ? 62 : \ - (n) & (1ULL << 61) ? 61 : \ -@@ -148,10 +142,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) - (n) & (1ULL << 4) ? 4 : \ - (n) & (1ULL << 3) ? 3 : \ - (n) & (1ULL << 2) ? 2 : \ -- (n) & (1ULL << 1) ? 1 : \ -- (n) & (1ULL << 0) ? 0 : \ -- ____ilog2_NaN() \ -- ) : \ -+ 1 ) : \ - (sizeof(n) <= 4) ? \ - __ilog2_u32(n) : \ - __ilog2_u64(n) \ -diff --git a/tools/include/linux/log2.h b/tools/include/linux/log2.h -index 41446668ccce..d5677d39c1e4 100644 ---- a/tools/include/linux/log2.h -+++ b/tools/include/linux/log2.h -@@ -13,12 +13,6 @@ - #define _TOOLS_LINUX_LOG2_H - - /* -- * deal with unrepresentable constant logarithms -- */ --extern __attribute__((const, noreturn)) --int ____ilog2_NaN(void); -- --/* - * non-constant log of base 2 calculators - * - the arch may override these in asm/bitops.h if they can be implemented - * more efficiently than using fls() and fls64() -@@ -78,7 +72,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) - #define ilog2(n) \ - ( \ - __builtin_constant_p(n) ? ( \ -- (n) < 1 ? ____ilog2_NaN() : \ -+ (n) < 2 ? 0 : \ - (n) & (1ULL << 63) ? 63 : \ - (n) & (1ULL << 62) ? 62 : \ - (n) & (1ULL << 61) ? 61 : \ -@@ -141,10 +135,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) - (n) & (1ULL << 4) ? 4 : \ - (n) & (1ULL << 3) ? 3 : \ - (n) & (1ULL << 2) ? 2 : \ -- (n) & (1ULL << 1) ? 1 : \ -- (n) & (1ULL << 0) ? 0 : \ -- ____ilog2_NaN() \ -- ) : \ -+ 1 ) : \ - (sizeof(n) <= 4) ? \ - __ilog2_u32(n) : \ - __ilog2_u64(n) \ --- -2.12.2 - -From a5c3f390eb7799c3d1d92121382372b1fd365fa3 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Sun, 26 Mar 2017 12:13:55 +0200 -Subject: [PATCH 133/251] Linux 4.4.57 +From ba46d8fab00a8e1538df241681d9161c8ec85778 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Tue, 21 Mar 2017 13:44:28 +0100 +Subject: [PATCH 225/251] libceph: force GFP_NOIO for socket allocations Status: RO -Content-Length: 301 -Lines: 18 - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index cf9303a5d621..841675e63a38 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 4 - PATCHLEVEL = 4 --SUBLEVEL = 56 -+SUBLEVEL = 57 - EXTRAVERSION = - NAME = Blurry Fish Butt - --- -2.12.2 - -From a87693ec42f24334ece33fac6ea639956f50bd90 Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:05 +0530 -Subject: [PATCH 192/251] PCI: Separate VF BAR updates from standard BAR - updates -Content-Length: 4390 -Lines: 137 - -From: Bjorn Helgaas - -[ Upstream commit 6ffa2489c51da77564a0881a73765ea2169f955d ] - -Previously pci_update_resource() used the same code path for updating -standard BARs and VF BARs in SR-IOV capabilities. +Content-Length: 4579 +Lines: 104 -Split the VF BAR update into a new pci_iov_update_resource() internal -interface, which makes it simpler to compute the BAR address (we can get -rid of pci_resource_bar() and pci_iov_resource_bar()). +commit 633ee407b9d15a75ac9740ba9d3338815e1fcb95 upstream. -This patch: +sock_alloc_inode() allocates socket+inode and socket_wq with +GFP_KERNEL, which is not allowed on the writeback path: - - Renames pci_update_resource() to pci_std_update_resource(), - - Adds pci_iov_update_resource(), - - Makes pci_update_resource() a wrapper that calls the appropriate one, + Workqueue: ceph-msgr con_work [libceph] + ffff8810871cb018 0000000000000046 0000000000000000 ffff881085d40000 + 0000000000012b00 ffff881025cad428 ffff8810871cbfd8 0000000000012b00 + ffff880102fc1000 ffff881085d40000 ffff8810871cb038 ffff8810871cb148 + Call Trace: + [] schedule+0x29/0x70 + [] schedule_timeout+0x1bd/0x200 + [] ? ttwu_do_wakeup+0x2c/0x120 + [] ? ttwu_do_activate.constprop.135+0x66/0x70 + [] wait_for_completion+0xbf/0x180 + [] ? try_to_wake_up+0x390/0x390 + [] flush_work+0x165/0x250 + [] ? worker_detach_from_pool+0xd0/0xd0 + [] xlog_cil_force_lsn+0x81/0x200 [xfs] + [] ? __slab_free+0xee/0x234 + [] _xfs_log_force_lsn+0x4d/0x2c0 [xfs] + [] ? lookup_page_cgroup_used+0xe/0x30 + [] ? xfs_reclaim_inode+0xa3/0x330 [xfs] + [] xfs_log_force_lsn+0x3f/0xf0 [xfs] + [] ? xfs_reclaim_inode+0xa3/0x330 [xfs] + [] xfs_iunpin_wait+0xc6/0x1a0 [xfs] + [] ? wake_atomic_t_function+0x40/0x40 + [] xfs_reclaim_inode+0xa3/0x330 [xfs] + [] xfs_reclaim_inodes_ag+0x257/0x3d0 [xfs] + [] xfs_reclaim_inodes_nr+0x33/0x40 [xfs] + [] xfs_fs_free_cached_objects+0x15/0x20 [xfs] + [] super_cache_scan+0x178/0x180 + [] shrink_slab_node+0x14e/0x340 + [] ? mem_cgroup_iter+0x16b/0x450 + [] shrink_slab+0x100/0x140 + [] do_try_to_free_pages+0x335/0x490 + [] try_to_free_pages+0xb9/0x1f0 + [] ? __alloc_pages_direct_compact+0x69/0x1be + [] __alloc_pages_nodemask+0x69a/0xb40 + [] alloc_pages_current+0x9e/0x110 + [] new_slab+0x2c5/0x390 + [] __slab_alloc+0x33b/0x459 + [] ? sock_alloc_inode+0x2d/0xd0 + [] ? inet_sendmsg+0x71/0xc0 + [] ? sock_alloc_inode+0x2d/0xd0 + [] kmem_cache_alloc+0x1a2/0x1b0 + [] sock_alloc_inode+0x2d/0xd0 + [] alloc_inode+0x26/0xa0 + [] new_inode_pseudo+0x1a/0x70 + [] sock_alloc+0x1e/0x80 + [] __sock_create+0x95/0x220 + [] sock_create_kern+0x24/0x30 + [] con_work+0xef9/0x2050 [libceph] + [] ? rbd_img_request_submit+0x4c/0x60 [rbd] + [] process_one_work+0x159/0x4f0 + [] worker_thread+0x11b/0x530 + [] ? create_worker+0x1d0/0x1d0 + [] kthread+0xc9/0xe0 + [] ? flush_kthread_worker+0x90/0x90 + [] ret_from_fork+0x58/0x90 + [] ? flush_kthread_worker+0x90/0x90 -No functional change intended. +Use memalloc_noio_{save,restore}() to temporarily force GFP_NOIO here. -Signed-off-by: Bjorn Helgaas -Reviewed-by: Gavin Shan -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sumit Semwal +Link: http://tracker.ceph.com/issues/19309 +Reported-by: Sergey Jerusalimov +Signed-off-by: Ilya Dryomov +Reviewed-by: Jeff Layton Signed-off-by: Greg Kroah-Hartman --- - drivers/pci/iov.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ - drivers/pci/pci.h | 1 + - drivers/pci/setup-res.c | 13 +++++++++++-- - 3 files changed, 62 insertions(+), 2 deletions(-) + net/ceph/messenger.c | 6 ++++++ + 1 file changed, 6 insertions(+) -diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c -index 31f31d460fc9..a6b100168396 100644 ---- a/drivers/pci/iov.c -+++ b/drivers/pci/iov.c -@@ -572,6 +572,56 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno) - 4 * (resno - PCI_IOV_RESOURCES); - } - -+/** -+ * pci_iov_update_resource - update a VF BAR -+ * @dev: the PCI device -+ * @resno: the resource number -+ * -+ * Update a VF BAR in the SR-IOV capability of a PF. -+ */ -+void pci_iov_update_resource(struct pci_dev *dev, int resno) -+{ -+ struct pci_sriov *iov = dev->is_physfn ? dev->sriov : NULL; -+ struct resource *res = dev->resource + resno; -+ int vf_bar = resno - PCI_IOV_RESOURCES; -+ struct pci_bus_region region; -+ u32 new; -+ int reg; -+ -+ /* -+ * The generic pci_restore_bars() path calls this for all devices, -+ * including VFs and non-SR-IOV devices. If this is not a PF, we -+ * have nothing to do. -+ */ -+ if (!iov) -+ return; -+ -+ /* -+ * Ignore unimplemented BARs, unused resource slots for 64-bit -+ * BARs, and non-movable resources, e.g., those described via -+ * Enhanced Allocation. -+ */ -+ if (!res->flags) -+ return; -+ -+ if (res->flags & IORESOURCE_UNSET) -+ return; -+ -+ if (res->flags & IORESOURCE_PCI_FIXED) -+ return; -+ -+ pcibios_resource_to_bus(dev->bus, ®ion, res); -+ new = region.start; -+ new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK; -+ -+ reg = iov->pos + PCI_SRIOV_BAR + 4 * vf_bar; -+ pci_write_config_dword(dev, reg, new); -+ if (res->flags & IORESOURCE_MEM_64) { -+ new = region.start >> 16 >> 16; -+ pci_write_config_dword(dev, reg + 4, new); -+ } -+} -+ - resource_size_t __weak pcibios_iov_resource_alignment(struct pci_dev *dev, - int resno) - { -diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h -index d390fc1475ec..eda77d1baec1 100644 ---- a/drivers/pci/pci.h -+++ b/drivers/pci/pci.h -@@ -277,6 +277,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) - int pci_iov_init(struct pci_dev *dev); - void pci_iov_release(struct pci_dev *dev); - int pci_iov_resource_bar(struct pci_dev *dev, int resno); -+void pci_iov_update_resource(struct pci_dev *dev, int resno); - resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); - void pci_restore_iov_state(struct pci_dev *dev); - int pci_iov_bus_range(struct pci_bus *bus); -diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c -index 604011e047d6..ac58c566fb1a 100644 ---- a/drivers/pci/setup-res.c -+++ b/drivers/pci/setup-res.c -@@ -25,8 +25,7 @@ +diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c +index b8d927c56494..a6b2f2138c9d 100644 +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include #include - #include "pci.h" - -- --void pci_update_resource(struct pci_dev *dev, int resno) -+static void pci_std_update_resource(struct pci_dev *dev, int resno) - { - struct pci_bus_region region; - bool disable; -@@ -110,6 +109,16 @@ void pci_update_resource(struct pci_dev *dev, int resno) - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - -+void pci_update_resource(struct pci_dev *dev, int resno) -+{ -+ if (resno <= PCI_ROM_RESOURCE) -+ pci_std_update_resource(dev, resno); -+#ifdef CONFIG_PCI_IOV -+ else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) -+ pci_iov_update_resource(dev, resno); -+#endif -+} -+ - int pci_claim_resource(struct pci_dev *dev, int resource) - { - struct resource *res = &dev->resource[resource]; --- -2.12.2 - -From cef498a2c75adca3b4e3fc348e47498496eec809 Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:06 +0530 -Subject: [PATCH 193/251] PCI: Remove pci_resource_bar() and - pci_iov_resource_bar() -Content-Length: 5197 -Lines: 160 - -From: Bjorn Helgaas - -[ Upstream commit 286c2378aaccc7343ebf17ec6cd86567659caf70 ] - -pci_std_update_resource() only deals with standard BARs, so we don't have -to worry about the complications of VF BARs in an SR-IOV capability. - -Compute the BAR address inline and remove pci_resource_bar(). That makes -pci_iov_resource_bar() unused, so remove that as well. - -Signed-off-by: Bjorn Helgaas -Reviewed-by: Gavin Shan -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/pci/iov.c | 18 ------------------ - drivers/pci/pci.c | 30 ------------------------------ - drivers/pci/pci.h | 6 ------ - drivers/pci/setup-res.c | 13 +++++++------ - 4 files changed, 7 insertions(+), 60 deletions(-) - -diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c -index a6b100168396..2f8ea6f84c97 100644 ---- a/drivers/pci/iov.c -+++ b/drivers/pci/iov.c -@@ -555,24 +555,6 @@ void pci_iov_release(struct pci_dev *dev) - } - - /** -- * pci_iov_resource_bar - get position of the SR-IOV BAR -- * @dev: the PCI device -- * @resno: the resource number -- * -- * Returns position of the BAR encapsulated in the SR-IOV capability. -- */ --int pci_iov_resource_bar(struct pci_dev *dev, int resno) --{ -- if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END) -- return 0; -- -- BUG_ON(!dev->is_physfn); -- -- return dev->sriov->pos + PCI_SRIOV_BAR + -- 4 * (resno - PCI_IOV_RESOURCES); --} -- --/** - * pci_iov_update_resource - update a VF BAR - * @dev: the PCI device - * @resno: the resource number -diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c -index e311a9bf2c90..a01e6d5fedec 100644 ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -4472,36 +4472,6 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags) - } - EXPORT_SYMBOL(pci_select_bars); - --/** -- * pci_resource_bar - get position of the BAR associated with a resource -- * @dev: the PCI device -- * @resno: the resource number -- * @type: the BAR type to be filled in -- * -- * Returns BAR position in config space, or 0 if the BAR is invalid. -- */ --int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) --{ -- int reg; -- -- if (resno < PCI_ROM_RESOURCE) { -- *type = pci_bar_unknown; -- return PCI_BASE_ADDRESS_0 + 4 * resno; -- } else if (resno == PCI_ROM_RESOURCE) { -- *type = pci_bar_mem32; -- return dev->rom_base_reg; -- } else if (resno < PCI_BRIDGE_RESOURCES) { -- /* device specific resource */ -- *type = pci_bar_unknown; -- reg = pci_iov_resource_bar(dev, resno); -- if (reg) -- return reg; -- } -- -- dev_err(&dev->dev, "BAR %d: invalid resource\n", resno); -- return 0; --} -- - /* Some architectures require additional programming to enable VGA */ - static arch_set_vga_state_t arch_set_vga_state; - -diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h -index eda77d1baec1..c43e448873ca 100644 ---- a/drivers/pci/pci.h -+++ b/drivers/pci/pci.h -@@ -232,7 +232,6 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, - int pci_setup_device(struct pci_dev *dev); - int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, - struct resource *res, unsigned int reg); --int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); - void pci_configure_ari(struct pci_dev *dev); - void __pci_bus_size_bridges(struct pci_bus *bus, - struct list_head *realloc_head); -@@ -276,7 +275,6 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) - #ifdef CONFIG_PCI_IOV - int pci_iov_init(struct pci_dev *dev); - void pci_iov_release(struct pci_dev *dev); --int pci_iov_resource_bar(struct pci_dev *dev, int resno); - void pci_iov_update_resource(struct pci_dev *dev, int resno); - resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); - void pci_restore_iov_state(struct pci_dev *dev); -@@ -291,10 +289,6 @@ static inline void pci_iov_release(struct pci_dev *dev) - - { - } --static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno) --{ -- return 0; --} - static inline void pci_restore_iov_state(struct pci_dev *dev) + #include + #include +@@ -478,11 +479,16 @@ static int ceph_tcp_connect(struct ceph_connection *con) { - } -diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c -index ac58c566fb1a..674e76c9334e 100644 ---- a/drivers/pci/setup-res.c -+++ b/drivers/pci/setup-res.c -@@ -32,7 +32,6 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) - u16 cmd; - u32 new, check, mask; - int reg; -- enum pci_bar_type type; - struct resource *res = dev->resource + resno; - - if (dev->is_virtfn) { -@@ -66,14 +65,16 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) - else - mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; - -- reg = pci_resource_bar(dev, resno, &type); -- if (!reg) -- return; -- if (type != pci_bar_unknown) { -+ if (resno < PCI_ROM_RESOURCE) { -+ reg = PCI_BASE_ADDRESS_0 + 4 * resno; -+ } else if (resno == PCI_ROM_RESOURCE) { - if (!(res->flags & IORESOURCE_ROM_ENABLE)) - return; -+ -+ reg = dev->rom_base_reg; - new |= PCI_ROM_ADDRESS_ENABLE; -- } -+ } else -+ return; - - /* - * We can't update a 64-bit BAR atomically, so when possible, --- -2.12.2 - -From 1278c9f87f1127b806a7733d3091df3ed2ab31c6 Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:07 +0530 -Subject: [PATCH 194/251] PCI: Add comments about ROM BAR updating -Content-Length: 2629 -Lines: 68 - -From: Bjorn Helgaas - -[ Upstream commit 0b457dde3cf8b7c76a60f8e960f21bbd4abdc416 ] - -pci_update_resource() updates a hardware BAR so its address matches the -kernel's struct resource UNLESS it's a disabled ROM BAR. We only update -those when we enable the ROM. - -It's not obvious from the code why ROM BARs should be handled specially. -Apparently there are Matrox devices with defective ROM BARs that read as -zero when disabled. That means that if pci_enable_rom() reads the disabled -BAR, sets PCI_ROM_ADDRESS_ENABLE (without re-inserting the address), and -writes it back, it would enable the ROM at address zero. - -Add comments and references to explain why we can't make the code look more -rational. - -The code changes are from 755528c860b0 ("Ignore disabled ROM resources at -setup") and 8085ce084c0f ("[PATCH] Fix PCI ROM mapping"). - -Link: https://lkml.org/lkml/2005/8/30/138 -Signed-off-by: Bjorn Helgaas -Reviewed-by: Gavin Shan -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman - [sumits: minor fixup in rom.c for 4.4.y] -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/pci/rom.c | 5 +++++ - drivers/pci/setup-res.c | 6 ++++++ - 2 files changed, 11 insertions(+) - -diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c -index eb0ad530dc43..3eea7fc5e1a2 100644 ---- a/drivers/pci/rom.c -+++ b/drivers/pci/rom.c -@@ -31,6 +31,11 @@ int pci_enable_rom(struct pci_dev *pdev) - if (!res->flags) - return -1; + struct sockaddr_storage *paddr = &con->peer_addr.in_addr; + struct socket *sock; ++ unsigned int noio_flag; + int ret; -+ /* -+ * Ideally pci_update_resource() would update the ROM BAR address, -+ * and we would only set the enable bit here. But apparently some -+ * devices have buggy ROM BARs that read as zero when disabled. -+ */ - pcibios_resource_to_bus(pdev->bus, ®ion, res); - pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); - rom_addr &= ~PCI_ROM_ADDRESS_MASK; -diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c -index 674e76c9334e..d1ba5e0067c5 100644 ---- a/drivers/pci/setup-res.c -+++ b/drivers/pci/setup-res.c -@@ -68,6 +68,12 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) - if (resno < PCI_ROM_RESOURCE) { - reg = PCI_BASE_ADDRESS_0 + 4 * resno; - } else if (resno == PCI_ROM_RESOURCE) { + BUG_ON(con->sock); + -+ /* -+ * Apparently some Matrox devices have ROM BARs that read -+ * as zero when disabled, so don't update ROM BARs unless -+ * they're enabled. See https://lkml.org/lkml/2005/8/30/138. -+ */ - if (!(res->flags & IORESOURCE_ROM_ENABLE)) - return; - --- -2.12.2 - -From 40a85d68185f9d9e7d370919f8a3532b0d259266 Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:08 +0530 -Subject: [PATCH 195/251] PCI: Decouple IORESOURCE_ROM_ENABLE and - PCI_ROM_ADDRESS_ENABLE -Content-Length: 1362 -Lines: 35 - -From: Bjorn Helgaas - -[ Upstream commit 7a6d312b50e63f598f5b5914c4fd21878ac2b595 ] - -Remove the assumption that IORESOURCE_ROM_ENABLE == PCI_ROM_ADDRESS_ENABLE. -PCI_ROM_ADDRESS_ENABLE is the ROM enable bit defined by the PCI spec, so if -we're reading or writing a BAR register value, that's what we should use. -IORESOURCE_ROM_ENABLE is a corresponding bit in struct resource flags. - -Signed-off-by: Bjorn Helgaas -Reviewed-by: Gavin Shan -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/pci/probe.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c -index 71d9a6d1bd56..b83df942794f 100644 ---- a/drivers/pci/probe.c -+++ b/drivers/pci/probe.c -@@ -226,7 +226,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, - mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK; - } - } else { -- res->flags |= (l & IORESOURCE_ROM_ENABLE); -+ if (l & PCI_ROM_ADDRESS_ENABLE) -+ res->flags |= IORESOURCE_ROM_ENABLE; - l64 = l & PCI_ROM_ADDRESS_MASK; - sz64 = sz & PCI_ROM_ADDRESS_MASK; - mask64 = (u32)PCI_ROM_ADDRESS_MASK; --- -2.12.2 - -From 131f7969048b8ede0be57f64930e9ef8fee0c53b Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:09 +0530 -Subject: [PATCH 196/251] PCI: Don't update VF BARs while VF memory space is - enabled -Content-Length: 1908 -Lines: 55 - -From: Bjorn Helgaas - -[ Upstream commit 546ba9f8f22f71b0202b6ba8967be5cc6dae4e21 ] - -If we update a VF BAR while it's enabled, there are two potential problems: - - 1) Any driver that's using the VF has a cached BAR value that is stale - after the update, and - - 2) We can't update 64-bit BARs atomically, so the intermediate state - (new lower dword with old upper dword) may conflict with another - device, and an access by a driver unrelated to the VF may cause a bus - error. - -Warn about attempts to update VF BARs while they are enabled. This is a -programming error, so use dev_WARN() to get a backtrace. - -Signed-off-by: Bjorn Helgaas -Reviewed-by: Gavin Shan -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/pci/iov.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c -index 2f8ea6f84c97..47c46d07f110 100644 ---- a/drivers/pci/iov.c -+++ b/drivers/pci/iov.c -@@ -567,6 +567,7 @@ void pci_iov_update_resource(struct pci_dev *dev, int resno) - struct resource *res = dev->resource + resno; - int vf_bar = resno - PCI_IOV_RESOURCES; - struct pci_bus_region region; -+ u16 cmd; - u32 new; - int reg; - -@@ -578,6 +579,13 @@ void pci_iov_update_resource(struct pci_dev *dev, int resno) - if (!iov) - return; - -+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &cmd); -+ if ((cmd & PCI_SRIOV_CTRL_VFE) && (cmd & PCI_SRIOV_CTRL_MSE)) { -+ dev_WARN(&dev->dev, "can't update enabled VF BAR%d %pR\n", -+ vf_bar, res); -+ return; -+ } -+ - /* - * Ignore unimplemented BARs, unused resource slots for 64-bit - * BARs, and non-movable resources, e.g., those described via --- -2.12.2 - -From d4f09ea7e35c02a765f58e900fbc159ff00c70e2 Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:10 +0530 -Subject: [PATCH 197/251] PCI: Update BARs using property bits appropriate for - type -Content-Length: 1846 -Lines: 52 - -From: Bjorn Helgaas - -[ Upstream commit 45d004f4afefdd8d79916ee6d97a9ecd94bb1ffe ] - -The BAR property bits (0-3 for memory BARs, 0-1 for I/O BARs) are supposed -to be read-only, but we do save them in res->flags and include them when -updating the BAR. - -Mask the I/O property bits with ~PCI_BASE_ADDRESS_IO_MASK (0x3) instead of -PCI_REGION_FLAG_MASK (0xf) to make it obvious that we can't corrupt bits -2-3 of I/O addresses. - -Use PCI_ROM_ADDRESS_MASK for ROM BARs. This means we'll only check the top -21 bits (instead of the 28 bits we used to check) of a ROM BAR to see if -the update was successful. - -Signed-off-by: Bjorn Helgaas -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/pci/setup-res.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c -index d1ba5e0067c5..032a6b1ea512 100644 ---- a/drivers/pci/setup-res.c -+++ b/drivers/pci/setup-res.c -@@ -58,12 +58,17 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) - return; - - pcibios_resource_to_bus(dev->bus, ®ion, res); -+ new = region.start; - -- new = region.start | (res->flags & PCI_REGION_FLAG_MASK); -- if (res->flags & IORESOURCE_IO) -+ if (res->flags & IORESOURCE_IO) { - mask = (u32)PCI_BASE_ADDRESS_IO_MASK; -- else -+ new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK; -+ } else if (resno == PCI_ROM_RESOURCE) { -+ mask = (u32)PCI_ROM_ADDRESS_MASK; -+ } else { - mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; -+ new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK; -+ } - - if (resno < PCI_ROM_RESOURCE) { - reg = PCI_BASE_ADDRESS_0 + 4 * resno; --- -2.12.2 - -From bcbdcf48469b062b6ee00b560b44de28f387d2e0 Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:11 +0530 -Subject: [PATCH 198/251] PCI: Ignore BAR updates on virtual functions -Content-Length: 1848 -Lines: 56 - -From: Bjorn Helgaas - -[ Upstream commit 63880b230a4af502c56dde3d4588634c70c66006 ] - -VF BARs are read-only zero, so updating VF BARs will not have any effect. -See the SR-IOV spec r1.1, sec 3.4.1.11. - -We already ignore these updates because of 70675e0b6a1a ("PCI: Don't try to -restore VF BARs"); this merely restructures it slightly to make it easier -to split updates for standard and SR-IOV BARs. - -Signed-off-by: Bjorn Helgaas -Reviewed-by: Gavin Shan -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/pci/pci.c | 4 ---- - drivers/pci/setup-res.c | 5 ++--- - 2 files changed, 2 insertions(+), 7 deletions(-) - -diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c -index a01e6d5fedec..0e53488f8ec1 100644 ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -519,10 +519,6 @@ static void pci_restore_bars(struct pci_dev *dev) - { - int i; - -- /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */ -- if (dev->is_virtfn) -- return; -- - for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) - pci_update_resource(dev, i); - } -diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c -index 032a6b1ea512..25062966cbfa 100644 ---- a/drivers/pci/setup-res.c -+++ b/drivers/pci/setup-res.c -@@ -34,10 +34,9 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) - int reg; - struct resource *res = dev->resource + resno; - -- if (dev->is_virtfn) { -- dev_warn(&dev->dev, "can't update VF BAR%d\n", resno); -+ /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */ -+ if (dev->is_virtfn) - return; -- } - - /* - * Ignore resources for unimplemented BARs and unused resource slots --- -2.12.2 - -From 4110080574acd69677c869ba49207150c09c9c0f Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:12 +0530 -Subject: [PATCH 199/251] PCI: Do any VF BAR updates before enabling the BARs -Content-Length: 2118 -Lines: 63 - -From: Gavin Shan - -[ Upstream commit f40ec3c748c6912f6266c56a7f7992de61b255ed ] - -Previously we enabled VFs and enable their memory space before calling -pcibios_sriov_enable(). But pcibios_sriov_enable() may update the VF BARs: -for example, on PPC PowerNV we may change them to manage the association of -VFs to PEs. - -Because 64-bit BARs cannot be updated atomically, it's unsafe to update -them while they're enabled. The half-updated state may conflict with other -devices in the system. - -Call pcibios_sriov_enable() before enabling the VFs so any BAR updates -happen while the VF BARs are disabled. - -[bhelgaas: changelog] -Tested-by: Carol Soto -Signed-off-by: Gavin Shan -Signed-off-by: Bjorn Helgaas - -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/pci/iov.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c -index 47c46d07f110..357527712539 100644 ---- a/drivers/pci/iov.c -+++ b/drivers/pci/iov.c -@@ -303,13 +303,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) - return rc; - } - -- pci_iov_set_numvfs(dev, nr_virtfn); -- iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; -- pci_cfg_access_lock(dev); -- pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); -- msleep(100); -- pci_cfg_access_unlock(dev); -- - iov->initial_VFs = initial; - if (nr_virtfn < initial) - initial = nr_virtfn; -@@ -320,6 +313,13 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) - goto err_pcibios; - } - -+ pci_iov_set_numvfs(dev, nr_virtfn); -+ iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; -+ pci_cfg_access_lock(dev); -+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); -+ msleep(100); -+ pci_cfg_access_unlock(dev); -+ - for (i = 0; i < initial; i++) { - rc = virtfn_add(dev, i, 0); - if (rc) --- -2.12.2 - -From 9fd9e1436380419a9a74f7ad90d85e09b1ed8058 Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:13 +0530 -Subject: [PATCH 200/251] vfio/spapr: Postpone allocation of userspace version - of TCE table -Content-Length: 2738 -Lines: 78 - -From: Alexey Kardashevskiy - -[ Upstream commit 39701e56f5f16ea0cf8fc9e8472e645f8de91d23 ] - -The iommu_table struct manages a hardware TCE table and a vmalloc'd -table with corresponding userspace addresses. Both are allocated when -the default DMA window is created and this happens when the very first -group is attached to a container. - -As we are going to allow the userspace to configure container in one -memory context and pas container fd to another, we have to postpones -such allocations till a container fd is passed to the destination -user process so we would account locked memory limit against the actual -container user constrainsts. - -This postpones the it_userspace array allocation till it is used first -time for mapping. The unmapping patch already checks if the array is -allocated. - -Signed-off-by: Alexey Kardashevskiy -Reviewed-by: David Gibson -Acked-by: Alex Williamson -Signed-off-by: Michael Ellerman -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/vfio/vfio_iommu_spapr_tce.c | 20 +++++++------------- - 1 file changed, 7 insertions(+), 13 deletions(-) - -diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c -index 0582b72ef377..1a9f18b40be6 100644 ---- a/drivers/vfio/vfio_iommu_spapr_tce.c -+++ b/drivers/vfio/vfio_iommu_spapr_tce.c -@@ -511,6 +511,12 @@ static long tce_iommu_build_v2(struct tce_container *container, - unsigned long hpa; - enum dma_data_direction dirtmp; - -+ if (!tbl->it_userspace) { -+ ret = tce_iommu_userspace_view_alloc(tbl); -+ if (ret) -+ return ret; -+ } -+ - for (i = 0; i < pages; ++i) { - struct mm_iommu_table_group_mem_t *mem = NULL; - unsigned long *pua = IOMMU_TABLE_USERSPACE_ENTRY(tbl, -@@ -584,15 +590,6 @@ static long tce_iommu_create_table(struct tce_container *container, - WARN_ON(!ret && !(*ptbl)->it_ops->free); - WARN_ON(!ret && ((*ptbl)->it_allocated_size != table_size)); - -- if (!ret && container->v2) { -- ret = tce_iommu_userspace_view_alloc(*ptbl); -- if (ret) -- (*ptbl)->it_ops->free(*ptbl); -- } -- -- if (ret) -- decrement_locked_vm(table_size >> PAGE_SHIFT); -- - return ret; - } - -@@ -1064,10 +1061,7 @@ static int tce_iommu_take_ownership(struct tce_container *container, - if (!tbl || !tbl->it_map) - continue; - -- rc = tce_iommu_userspace_view_alloc(tbl); -- if (!rc) -- rc = iommu_take_ownership(tbl); -- -+ rc = iommu_take_ownership(tbl); - if (rc) { - for (j = 0; j < i; ++j) - iommu_release_ownership( --- -2.12.2 - -From 7023f502c8355717ad4e400144b0833dee105602 Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:14 +0530 -Subject: [PATCH 201/251] block: allow WRITE_SAME commands with the SG_IO ioctl -Content-Length: 3332 -Lines: 80 - -From: Mauricio Faria de Oliveira - -[ Upstream commit 25cdb64510644f3e854d502d69c73f21c6df88a9 ] - -The WRITE_SAME commands are not present in the blk_default_cmd_filter -write_ok list, and thus are failed with -EPERM when the SG_IO ioctl() -is executed without CAP_SYS_RAWIO capability (e.g., unprivileged users). -[ sg_io() -> blk_fill_sghdr_rq() > blk_verify_command() -> -EPERM ] - -The problem can be reproduced with the sg_write_same command - - # sg_write_same --num 1 --xferlen 512 /dev/sda - # - - # capsh --drop=cap_sys_rawio -- -c \ - 'sg_write_same --num 1 --xferlen 512 /dev/sda' - Write same: pass through os error: Operation not permitted - # - -For comparison, the WRITE_VERIFY command does not observe this problem, -since it is in that list: - - # capsh --drop=cap_sys_rawio -- -c \ - 'sg_write_verify --num 1 --ilen 512 --lba 0 /dev/sda' - # - -So, this patch adds the WRITE_SAME commands to the list, in order -for the SG_IO ioctl to finish successfully: - - # capsh --drop=cap_sys_rawio -- -c \ - 'sg_write_same --num 1 --xferlen 512 /dev/sda' - # - -That case happens to be exercised by QEMU KVM guests with 'scsi-block' devices -(qemu "-device scsi-block" [1], libvirt "" [2]), -which employs the SG_IO ioctl() and runs as an unprivileged user (libvirt-qemu). - -In that scenario, when a filesystem (e.g., ext4) performs its zero-out calls, -which are translated to write-same calls in the guest kernel, and then into -SG_IO ioctls to the host kernel, SCSI I/O errors may be observed in the guest: - - [...] sd 0:0:0:0: [sda] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE - [...] sd 0:0:0:0: [sda] tag#0 Sense Key : Aborted Command [current] - [...] sd 0:0:0:0: [sda] tag#0 Add. Sense: I/O process terminated - [...] sd 0:0:0:0: [sda] tag#0 CDB: Write Same(10) 41 00 01 04 e0 78 00 00 08 00 - [...] blk_update_request: I/O error, dev sda, sector 17096824 - -Links: -[1] http://git.qemu.org/?p=qemu.git;a=commit;h=336a6915bc7089fb20fea4ba99972ad9a97c5f52 -[2] https://libvirt.org/formatdomain.html#elementsDisks (see 'disk' -> 'device') - -Signed-off-by: Mauricio Faria de Oliveira -Signed-off-by: Brahadambal Srinivasan -Reported-by: Manjunatha H R -Reviewed-by: Christoph Hellwig -Signed-off-by: Jens Axboe -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - block/scsi_ioctl.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c -index 0774799942e0..c6fee7437be4 100644 ---- a/block/scsi_ioctl.c -+++ b/block/scsi_ioctl.c -@@ -182,6 +182,9 @@ static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) - __set_bit(WRITE_16, filter->write_ok); - __set_bit(WRITE_LONG, filter->write_ok); - __set_bit(WRITE_LONG_2, filter->write_ok); -+ __set_bit(WRITE_SAME, filter->write_ok); -+ __set_bit(WRITE_SAME_16, filter->write_ok); -+ __set_bit(WRITE_SAME_32, filter->write_ok); - __set_bit(ERASE, filter->write_ok); - __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok); - __set_bit(MODE_SELECT, filter->write_ok); --- -2.12.2 - -From 4e2c66bb6658f6f4583c8920adeecb7bcc90bd9f Mon Sep 17 00:00:00 2001 -From: Sumit Semwal -Date: Sat, 25 Mar 2017 21:48:16 +0530 -Subject: [PATCH 203/251] uvcvideo: uvc_scan_fallback() for webcams with broken - chain -Content-Length: 5053 -Lines: 172 - -From: Henrik Ingo - -[ Upstream commit e950267ab802c8558f1100eafd4087fd039ad634 ] - -Some devices have invalid baSourceID references, causing uvc_scan_chain() -to fail, but if we just take the entities we can find and put them -together in the most sensible chain we can think of, turns out they do -work anyway. Note: This heuristic assumes there is a single chain. - -At the time of writing, devices known to have such a broken chain are - - Acer Integrated Camera (5986:055a) - - Realtek rtl157a7 (0bda:57a7) - -Signed-off-by: Henrik Ingo -Signed-off-by: Laurent Pinchart -Signed-off-by: Mauro Carvalho Chehab -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/media/usb/uvc/uvc_driver.c | 118 +++++++++++++++++++++++++++++++++++-- - 1 file changed, 112 insertions(+), 6 deletions(-) - -diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c -index 5cefca95734e..885f689ac870 100644 ---- a/drivers/media/usb/uvc/uvc_driver.c -+++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -1595,6 +1595,114 @@ static const char *uvc_print_chain(struct uvc_video_chain *chain) - return buffer; - } - -+static struct uvc_video_chain *uvc_alloc_chain(struct uvc_device *dev) -+{ -+ struct uvc_video_chain *chain; -+ -+ chain = kzalloc(sizeof(*chain), GFP_KERNEL); -+ if (chain == NULL) -+ return NULL; -+ -+ INIT_LIST_HEAD(&chain->entities); -+ mutex_init(&chain->ctrl_mutex); -+ chain->dev = dev; -+ v4l2_prio_init(&chain->prio); -+ -+ return chain; -+} -+ -+/* -+ * Fallback heuristic for devices that don't connect units and terminals in a -+ * valid chain. -+ * -+ * Some devices have invalid baSourceID references, causing uvc_scan_chain() -+ * to fail, but if we just take the entities we can find and put them together -+ * in the most sensible chain we can think of, turns out they do work anyway. -+ * Note: This heuristic assumes there is a single chain. -+ * -+ * At the time of writing, devices known to have such a broken chain are -+ * - Acer Integrated Camera (5986:055a) -+ * - Realtek rtl157a7 (0bda:57a7) -+ */ -+static int uvc_scan_fallback(struct uvc_device *dev) -+{ -+ struct uvc_video_chain *chain; -+ struct uvc_entity *iterm = NULL; -+ struct uvc_entity *oterm = NULL; -+ struct uvc_entity *entity; -+ struct uvc_entity *prev; -+ -+ /* -+ * Start by locating the input and output terminals. We only support -+ * devices with exactly one of each for now. -+ */ -+ list_for_each_entry(entity, &dev->entities, list) { -+ if (UVC_ENTITY_IS_ITERM(entity)) { -+ if (iterm) -+ return -EINVAL; -+ iterm = entity; -+ } -+ -+ if (UVC_ENTITY_IS_OTERM(entity)) { -+ if (oterm) -+ return -EINVAL; -+ oterm = entity; -+ } -+ } -+ -+ if (iterm == NULL || oterm == NULL) -+ return -EINVAL; -+ -+ /* Allocate the chain and fill it. */ -+ chain = uvc_alloc_chain(dev); -+ if (chain == NULL) -+ return -ENOMEM; -+ -+ if (uvc_scan_chain_entity(chain, oterm) < 0) -+ goto error; -+ -+ prev = oterm; -+ -+ /* -+ * Add all Processing and Extension Units with two pads. The order -+ * doesn't matter much, use reverse list traversal to connect units in -+ * UVC descriptor order as we build the chain from output to input. This -+ * leads to units appearing in the order meant by the manufacturer for -+ * the cameras known to require this heuristic. -+ */ -+ list_for_each_entry_reverse(entity, &dev->entities, list) { -+ if (entity->type != UVC_VC_PROCESSING_UNIT && -+ entity->type != UVC_VC_EXTENSION_UNIT) -+ continue; -+ -+ if (entity->num_pads != 2) -+ continue; -+ -+ if (uvc_scan_chain_entity(chain, entity) < 0) -+ goto error; -+ -+ prev->baSourceID[0] = entity->id; -+ prev = entity; -+ } -+ -+ if (uvc_scan_chain_entity(chain, iterm) < 0) -+ goto error; -+ -+ prev->baSourceID[0] = iterm->id; -+ -+ list_add_tail(&chain->list, &dev->chains); -+ -+ uvc_trace(UVC_TRACE_PROBE, -+ "Found a video chain by fallback heuristic (%s).\n", -+ uvc_print_chain(chain)); -+ -+ return 0; -+ -+error: -+ kfree(chain); -+ return -EINVAL; -+} -+ - /* - * Scan the device for video chains and register video devices. - * -@@ -1617,15 +1725,10 @@ static int uvc_scan_device(struct uvc_device *dev) - if (term->chain.next || term->chain.prev) - continue; - -- chain = kzalloc(sizeof(*chain), GFP_KERNEL); -+ chain = uvc_alloc_chain(dev); - if (chain == NULL) - return -ENOMEM; - -- INIT_LIST_HEAD(&chain->entities); -- mutex_init(&chain->ctrl_mutex); -- chain->dev = dev; -- v4l2_prio_init(&chain->prio); -- - term->flags |= UVC_ENTITY_FLAG_DEFAULT; - - if (uvc_scan_chain(chain, term) < 0) { -@@ -1639,6 +1742,9 @@ static int uvc_scan_device(struct uvc_device *dev) - list_add_tail(&chain->list, &dev->chains); - } - -+ if (list_empty(&dev->chains)) -+ uvc_scan_fallback(dev); -+ - if (list_empty(&dev->chains)) { - uvc_printk(KERN_INFO, "No valid video chain found.\n"); - return -1; --- -2.12.2 - -From 540d6d756ff82a23eb5bb73aa8149bab15eb407a Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Wed, 11 Jan 2017 17:09:50 +0100 -Subject: [PATCH 207/251] fbcon: Fix vc attr at deinit -Content-Length: 4857 -Lines: 144 - -commit 8aac7f34369726d1a158788ae8aff3002d5eb528 upstream. - -fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust -the vc attrs dynamically when vc_hi_font_mask is changed at -fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in -the existing console buffer with one bit shift up (for 9 bits), while -it remaps with one bit shift down (for 8 bits) when the value is -cleared. It works fine as long as the font gets updated after fbcon -was initialized. - -However, we hit a bizarre problem when the console is switched to -another fb driver (typically from vesafb or efifb to drmfb). At -switching to the new fb driver, we temporarily rebind the console to -the dummy console, then rebind to the new driver. During the -switching, we leave the modified attrs as is. Thus, the new fbcon -takes over the old buffer as if it were to contain 8 bits chars -(although the attrs are still shifted for 9 bits), and effectively -this results in the yellow color texts instead of the original white -color, as found in the bugzilla entry below. - -An easy fix for this is to re-adjust the attrs before leaving the -fbcon at con_deinit callback. Since the code to adjust the attrs is -already present in the current fbcon code, in this patch, we simply -factor out the relevant code, and call it from fbcon_deinit(). - -Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619 -Signed-off-by: Takashi Iwai -Signed-off-by: Bartlomiej Zolnierkiewicz -Cc: Arnd Bergmann -Signed-off-by: Greg Kroah-Hartman ---- - drivers/video/console/fbcon.c | 67 ++++++++++++++++++++++++++----------------- - 1 file changed, 40 insertions(+), 27 deletions(-) - -diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c -index 6e92917ba77a..4e3c78d88832 100644 ---- a/drivers/video/console/fbcon.c -+++ b/drivers/video/console/fbcon.c -@@ -1168,6 +1168,8 @@ static void fbcon_free_font(struct display *p, bool freefont) - p->userfont = 0; - } - -+static void set_vc_hi_font(struct vc_data *vc, bool set); -+ - static void fbcon_deinit(struct vc_data *vc) - { - struct display *p = &fb_display[vc->vc_num]; -@@ -1203,6 +1205,9 @@ finished: - if (free_font) - vc->vc_font.data = NULL; - -+ if (vc->vc_hi_font_mask) -+ set_vc_hi_font(vc, false); -+ - if (!con_is_bound(&fb_con)) - fbcon_exit(); - -@@ -2439,32 +2444,10 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font) - return 0; - } - --static int fbcon_do_set_font(struct vc_data *vc, int w, int h, -- const u8 * data, int userfont) -+/* set/clear vc_hi_font_mask and update vc attrs accordingly */ -+static void set_vc_hi_font(struct vc_data *vc, bool set) - { -- struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; -- struct fbcon_ops *ops = info->fbcon_par; -- struct display *p = &fb_display[vc->vc_num]; -- int resize; -- int cnt; -- char *old_data = NULL; -- -- if (CON_IS_VISIBLE(vc) && softback_lines) -- fbcon_set_origin(vc); -- -- resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); -- if (p->userfont) -- old_data = vc->vc_font.data; -- if (userfont) -- cnt = FNTCHARCNT(data); -- else -- cnt = 256; -- vc->vc_font.data = (void *)(p->fontdata = data); -- if ((p->userfont = userfont)) -- REFCOUNT(data)++; -- vc->vc_font.width = w; -- vc->vc_font.height = h; -- if (vc->vc_hi_font_mask && cnt == 256) { -+ if (!set) { - vc->vc_hi_font_mask = 0; - if (vc->vc_can_do_color) { - vc->vc_complement_mask >>= 1; -@@ -2487,7 +2470,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, - ((c & 0xfe00) >> 1) | (c & 0xff); - vc->vc_attr >>= 1; - } -- } else if (!vc->vc_hi_font_mask && cnt == 512) { -+ } else { - vc->vc_hi_font_mask = 0x100; - if (vc->vc_can_do_color) { - vc->vc_complement_mask <<= 1; -@@ -2519,8 +2502,38 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, - } else - vc->vc_video_erase_char = c & ~0x100; - } -- - } -+} -+ -+static int fbcon_do_set_font(struct vc_data *vc, int w, int h, -+ const u8 * data, int userfont) -+{ -+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; -+ struct fbcon_ops *ops = info->fbcon_par; -+ struct display *p = &fb_display[vc->vc_num]; -+ int resize; -+ int cnt; -+ char *old_data = NULL; -+ -+ if (CON_IS_VISIBLE(vc) && softback_lines) -+ fbcon_set_origin(vc); -+ -+ resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); -+ if (p->userfont) -+ old_data = vc->vc_font.data; -+ if (userfont) -+ cnt = FNTCHARCNT(data); -+ else -+ cnt = 256; -+ vc->vc_font.data = (void *)(p->fontdata = data); -+ if ((p->userfont = userfont)) -+ REFCOUNT(data)++; -+ vc->vc_font.width = w; -+ vc->vc_font.height = h; -+ if (vc->vc_hi_font_mask && cnt == 256) -+ set_vc_hi_font(vc, false); -+ else if (!vc->vc_hi_font_mask && cnt == 512) -+ set_vc_hi_font(vc, true); - - if (resize) { - int cols, rows; --- -2.12.2 - -From 0a5766a6a73b1eb6a0dfa74adc40272e555ac2f0 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Thu, 30 Mar 2017 09:36:33 +0200 -Subject: [PATCH 209/251] Linux 4.4.58 -Status: RO -Content-Length: 301 -Lines: 18 - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index 841675e63a38..3efe2ea99e2d 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 4 - PATCHLEVEL = 4 --SUBLEVEL = 57 -+SUBLEVEL = 58 - EXTRAVERSION = - NAME = Blurry Fish Butt - --- -2.12.2 - -From a9a76a3e318ea559365210916378380109199121 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 8 Feb 2017 11:52:29 +0100 -Subject: [PATCH 210/251] xfrm: policy: init locks early -Content-Length: 2241 -Lines: 62 - -commit c282222a45cb9503cbfbebfdb60491f06ae84b49 upstream. - -Dmitry reports following splat: - INFO: trying to register non-static key. - the code is fine but needs lockdep annotation. - turning off the locking correctness validator. - CPU: 0 PID: 13059 Comm: syz-executor1 Not tainted 4.10.0-rc7-next-20170207 #1 -[..] - spin_lock_bh include/linux/spinlock.h:304 [inline] - xfrm_policy_flush+0x32/0x470 net/xfrm/xfrm_policy.c:963 - xfrm_policy_fini+0xbf/0x560 net/xfrm/xfrm_policy.c:3041 - xfrm_net_init+0x79f/0x9e0 net/xfrm/xfrm_policy.c:3091 - ops_init+0x10a/0x530 net/core/net_namespace.c:115 - setup_net+0x2ed/0x690 net/core/net_namespace.c:291 - copy_net_ns+0x26c/0x530 net/core/net_namespace.c:396 - create_new_namespaces+0x409/0x860 kernel/nsproxy.c:106 - unshare_nsproxy_namespaces+0xae/0x1e0 kernel/nsproxy.c:205 - SYSC_unshare kernel/fork.c:2281 [inline] - -Problem is that when we get error during xfrm_net_init we will call -xfrm_policy_fini which will acquire xfrm_policy_lock before it was -initialized. Just move it around so locks get set up first. - -Reported-by: Dmitry Vyukov -Fixes: 283bc9f35bbbcb0e9 ("xfrm: Namespacify xfrm state/policy locks") -Signed-off-by: Florian Westphal -Signed-off-by: Steffen Klassert -Signed-off-by: Greg Kroah-Hartman ---- - net/xfrm/xfrm_policy.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c -index b5e665b3cfb0..36a50ef9295d 100644 ---- a/net/xfrm/xfrm_policy.c -+++ b/net/xfrm/xfrm_policy.c -@@ -3030,6 +3030,11 @@ static int __net_init xfrm_net_init(struct net *net) - { - int rv; - -+ /* Initialize the per-net locks here */ -+ spin_lock_init(&net->xfrm.xfrm_state_lock); -+ rwlock_init(&net->xfrm.xfrm_policy_lock); -+ mutex_init(&net->xfrm.xfrm_cfg_mutex); -+ - rv = xfrm_statistics_init(net); - if (rv < 0) - goto out_statistics; -@@ -3046,11 +3051,6 @@ static int __net_init xfrm_net_init(struct net *net) - if (rv < 0) - goto out; - -- /* Initialize the per-net locks here */ -- spin_lock_init(&net->xfrm.xfrm_state_lock); -- rwlock_init(&net->xfrm.xfrm_policy_lock); -- mutex_init(&net->xfrm.xfrm_cfg_mutex); -- - return 0; - - out: --- -2.12.2 - -From cce7e56dd73f75fef0a7f594fb129285a660fec0 Mon Sep 17 00:00:00 2001 -From: Andy Whitcroft -Date: Wed, 22 Mar 2017 07:29:31 +0000 -Subject: [PATCH 211/251] xfrm_user: validate XFRM_MSG_NEWAE - XFRMA_REPLAY_ESN_VAL replay_window -Content-Length: 1832 -Lines: 45 - -commit 677e806da4d916052585301785d847c3b3e6186a upstream. - -When a new xfrm state is created during an XFRM_MSG_NEWSA call we -validate the user supplied replay_esn to ensure that the size is valid -and to ensure that the replay_window size is within the allocated -buffer. However later it is possible to update this replay_esn via a -XFRM_MSG_NEWAE call. There we again validate the size of the supplied -buffer matches the existing state and if so inject the contents. We do -not at this point check that the replay_window is within the allocated -memory. This leads to out-of-bounds reads and writes triggered by -netlink packets. This leads to memory corruption and the potential for -priviledge escalation. - -We already attempt to validate the incoming replay information in -xfrm_new_ae() via xfrm_replay_verify_len(). This confirms that the user -is not trying to change the size of the replay state buffer which -includes the replay_esn. It however does not check the replay_window -remains within that buffer. Add validation of the contained -replay_window. - -CVE-2017-7184 -Signed-off-by: Andy Whitcroft -Acked-by: Steffen Klassert -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman ---- - net/xfrm/xfrm_user.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c -index 805681a7d356..0e1f833bc77d 100644 ---- a/net/xfrm/xfrm_user.c -+++ b/net/xfrm/xfrm_user.c -@@ -415,6 +415,9 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es - if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen) - return -EINVAL; - -+ if (up->replay_window > up->bmp_len * sizeof(__u32) * 8) -+ return -EINVAL; -+ - return 0; - } - --- -2.12.2 - -From 22c9e7c092f63335ba7a7301e0e0b4c4ebed53a8 Mon Sep 17 00:00:00 2001 -From: Andy Whitcroft -Date: Thu, 23 Mar 2017 07:45:44 +0000 -Subject: [PATCH 212/251] xfrm_user: validate XFRM_MSG_NEWAE incoming ESN size - harder -Content-Length: 1382 -Lines: 35 - -commit f843ee6dd019bcece3e74e76ad9df0155655d0df upstream. - -Kees Cook has pointed out that xfrm_replay_state_esn_len() is subject to -wrapping issues. To ensure we are correctly ensuring that the two ESN -structures are the same size compare both the overall size as reported -by xfrm_replay_state_esn_len() and the internal length are the same. - -CVE-2017-7184 -Signed-off-by: Andy Whitcroft -Acked-by: Steffen Klassert -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman ---- - net/xfrm/xfrm_user.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c -index 0e1f833bc77d..7a5a64e70b4d 100644 ---- a/net/xfrm/xfrm_user.c -+++ b/net/xfrm/xfrm_user.c -@@ -412,7 +412,11 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es - up = nla_data(rp); - ulen = xfrm_replay_state_esn_len(up); - -- if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen) -+ /* Check the overall length and the internal bitmap length to avoid -+ * potential overflow. */ -+ if (nla_len(rp) < ulen || -+ xfrm_replay_state_esn_len(replay_esn) != ulen || -+ replay_esn->bmp_len != up->bmp_len) - return -EINVAL; - - if (up->replay_window > up->bmp_len * sizeof(__u32) * 8) --- -2.12.2 - -From 927d04793f8a587532a5c26057bcdcb33bc8f5ba Mon Sep 17 00:00:00 2001 -From: Ladi Prosek -Date: Thu, 23 Mar 2017 08:04:18 +0100 -Subject: [PATCH 213/251] virtio_balloon: init 1st buffer in stats vq -Content-Length: 1861 -Lines: 47 - -commit fc8653228c8588a120f6b5dad6983b7b61ff669e upstream. - -When init_vqs runs, virtio_balloon.stats is either uninitialized or -contains stale values. The host updates its state with garbage data -because it has no way of knowing that this is just a marker buffer -used for signaling. - -This patch updates the stats before pushing the initial buffer. - -Alternative fixes: -* Push an empty buffer in init_vqs. Not easily done with the current - virtio implementation and violates the spec "Driver MUST supply the - same subset of statistics in all buffers submitted to the statsq". -* Push a buffer with invalid tags in init_vqs. Violates the same - spec clause, plus "invalid tag" is not really defined. - -Note: the spec says: - When using the legacy interface, the device SHOULD ignore all values in - the first buffer in the statsq supplied by the driver after device - initialization. Note: Historically, drivers supplied an uninitialized - buffer in the first buffer. - -Unfortunately QEMU does not seem to implement the recommendation -even for the legacy interface. - -Signed-off-by: Ladi Prosek -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Greg Kroah-Hartman ---- - drivers/virtio/virtio_balloon.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c -index 56f7e2521202..01d15dca940e 100644 ---- a/drivers/virtio/virtio_balloon.c -+++ b/drivers/virtio/virtio_balloon.c -@@ -416,6 +416,8 @@ static int init_vqs(struct virtio_balloon *vb) - * Prime this virtqueue with one buffer so the hypervisor can - * use it to signal us later (it can't be broken yet!). - */ -+ update_balloon_stats(vb); -+ - sg_init_one(&sg, vb->stats, sizeof vb->stats); - if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL) - < 0) --- -2.12.2 - -From 800791e7e0fd9835be2f55c55147c379888b7442 Mon Sep 17 00:00:00 2001 -From: Bjorn Andersson -Date: Tue, 14 Mar 2017 08:23:26 -0700 -Subject: [PATCH 214/251] pinctrl: qcom: Don't clear status bit on irq_unmask -Content-Length: 1223 -Lines: 33 - -commit a6566710adaa4a7dd5e0d99820ff9c9c30ee5951 upstream. - -Clearing the status bit on irq_unmask will discard any pending interrupt -that did arrive after the irq_ack, i.e. while the IRQ handler function -was executing. - -Fixes: f365be092572 ("pinctrl: Add Qualcomm TLMM driver") -Cc: Stephen Boyd -Reported-by: Timur Tabi -Signed-off-by: Bjorn Andersson -Signed-off-by: Linus Walleij -Signed-off-by: Greg Kroah-Hartman ---- - drivers/pinctrl/qcom/pinctrl-msm.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c -index 146264a41ec8..9736f9be5447 100644 ---- a/drivers/pinctrl/qcom/pinctrl-msm.c -+++ b/drivers/pinctrl/qcom/pinctrl-msm.c -@@ -597,10 +597,6 @@ static void msm_gpio_irq_unmask(struct irq_data *d) - - spin_lock_irqsave(&pctrl->lock, flags); - -- val = readl(pctrl->regs + g->intr_status_reg); -- val &= ~BIT(g->intr_status_bit); -- writel(val, pctrl->regs + g->intr_status_reg); -- - val = readl(pctrl->regs + g->intr_cfg_reg); - val |= BIT(g->intr_enable_bit); - writel(val, pctrl->regs + g->intr_cfg_reg); --- -2.12.2 - -From 7a5202190810dde1467718235c1f650fcf57592a Mon Sep 17 00:00:00 2001 -From: Eric Biggers -Date: Tue, 21 Feb 2017 15:07:11 -0800 -Subject: [PATCH 222/251] fscrypt: remove broken support for detecting keyring - key revocation -Content-Length: 10256 -Lines: 300 - -commit 1b53cf9815bb4744958d41f3795d5d5a1d365e2d upstream. - -Filesystem encryption ostensibly supported revoking a keyring key that -had been used to "unlock" encrypted files, causing those files to become -"locked" again. This was, however, buggy for several reasons, the most -severe of which was that when key revocation happened to be detected for -an inode, its fscrypt_info was immediately freed, even while other -threads could be using it for encryption or decryption concurrently. -This could be exploited to crash the kernel or worse. - -This patch fixes the use-after-free by removing the code which detects -the keyring key having been revoked, invalidated, or expired. Instead, -an encrypted inode that is "unlocked" now simply remains unlocked until -it is evicted from memory. Note that this is no worse than the case for -block device-level encryption, e.g. dm-crypt, and it still remains -possible for a privileged user to evict unused pages, inodes, and -dentries by running 'sync; echo 3 > /proc/sys/vm/drop_caches', or by -simply unmounting the filesystem. In fact, one of those actions was -already needed anyway for key revocation to work even somewhat sanely. -This change is not expected to break any applications. - -In the future I'd like to implement a real API for fscrypt key -revocation that interacts sanely with ongoing filesystem operations --- -waiting for existing operations to complete and blocking new operations, -and invalidating and sanitizing key material and plaintext from the VFS -caches. But this is a hard problem, and for now this bug must be fixed. - -This bug affected almost all versions of ext4, f2fs, and ubifs -encryption, and it was potentially reachable in any kernel configured -with encryption support (CONFIG_EXT4_ENCRYPTION=y, -CONFIG_EXT4_FS_ENCRYPTION=y, CONFIG_F2FS_FS_ENCRYPTION=y, or -CONFIG_UBIFS_FS_ENCRYPTION=y). Note that older kernels did not use the -shared fs/crypto/ code, but due to the potential security implications -of this bug, it may still be worthwhile to backport this fix to them. - -Fixes: b7236e21d55f ("ext4 crypto: reorganize how we store keys in the inode") -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o -Acked-by: Michael Halcrow -Signed-off-by: Greg Kroah-Hartman ---- - fs/ext4/crypto_key.c | 28 +++++++--------------------- - fs/ext4/ext4.h | 14 +------------- - fs/ext4/ext4_crypto.h | 1 - - fs/f2fs/crypto_key.c | 28 +++++++--------------------- - fs/f2fs/f2fs.h | 14 +------------- - fs/f2fs/f2fs_crypto.h | 1 - - 6 files changed, 16 insertions(+), 70 deletions(-) - -diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c -index 9a16d1e75a49..505f8afde57c 100644 ---- a/fs/ext4/crypto_key.c -+++ b/fs/ext4/crypto_key.c -@@ -88,8 +88,6 @@ void ext4_free_crypt_info(struct ext4_crypt_info *ci) - if (!ci) - return; - -- if (ci->ci_keyring_key) -- key_put(ci->ci_keyring_key); - crypto_free_ablkcipher(ci->ci_ctfm); - kmem_cache_free(ext4_crypt_info_cachep, ci); - } -@@ -111,7 +109,7 @@ void ext4_free_encryption_info(struct inode *inode, - ext4_free_crypt_info(ci); - } - --int _ext4_get_encryption_info(struct inode *inode) -+int ext4_get_encryption_info(struct inode *inode) - { - struct ext4_inode_info *ei = EXT4_I(inode); - struct ext4_crypt_info *crypt_info; -@@ -128,22 +126,15 @@ int _ext4_get_encryption_info(struct inode *inode) - char mode; - int res; - -+ if (ei->i_crypt_info) -+ return 0; -+ - if (!ext4_read_workqueue) { - res = ext4_init_crypto(); - if (res) - return res; - } - --retry: -- crypt_info = ACCESS_ONCE(ei->i_crypt_info); -- if (crypt_info) { -- if (!crypt_info->ci_keyring_key || -- key_validate(crypt_info->ci_keyring_key) == 0) -- return 0; -- ext4_free_encryption_info(inode, crypt_info); -- goto retry; -- } -- - res = ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION, - EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, - &ctx, sizeof(ctx)); -@@ -166,7 +157,6 @@ retry: - crypt_info->ci_data_mode = ctx.contents_encryption_mode; - crypt_info->ci_filename_mode = ctx.filenames_encryption_mode; - crypt_info->ci_ctfm = NULL; -- crypt_info->ci_keyring_key = NULL; - memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor, - sizeof(crypt_info->ci_master_key)); - if (S_ISREG(inode->i_mode)) -@@ -206,7 +196,6 @@ retry: - keyring_key = NULL; - goto out; - } -- crypt_info->ci_keyring_key = keyring_key; - if (keyring_key->type != &key_type_logon) { - printk_once(KERN_WARNING - "ext4: key type must be logon\n"); -@@ -253,16 +242,13 @@ got_key: - ext4_encryption_key_size(mode)); - if (res) - goto out; -- memzero_explicit(raw_key, sizeof(raw_key)); -- if (cmpxchg(&ei->i_crypt_info, NULL, crypt_info) != NULL) { -- ext4_free_crypt_info(crypt_info); -- goto retry; -- } -- return 0; - -+ if (cmpxchg(&ei->i_crypt_info, NULL, crypt_info) == NULL) -+ crypt_info = NULL; - out: - if (res == -ENOKEY) - res = 0; -+ key_put(keyring_key); - ext4_free_crypt_info(crypt_info); - memzero_explicit(raw_key, sizeof(raw_key)); - return res; -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index cd5914495ad7..362d59b24f1d 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -2330,23 +2330,11 @@ static inline void ext4_fname_free_filename(struct ext4_filename *fname) { } - /* crypto_key.c */ - void ext4_free_crypt_info(struct ext4_crypt_info *ci); - void ext4_free_encryption_info(struct inode *inode, struct ext4_crypt_info *ci); --int _ext4_get_encryption_info(struct inode *inode); - - #ifdef CONFIG_EXT4_FS_ENCRYPTION - int ext4_has_encryption_key(struct inode *inode); - --static inline int ext4_get_encryption_info(struct inode *inode) --{ -- struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info; -- -- if (!ci || -- (ci->ci_keyring_key && -- (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) | -- (1 << KEY_FLAG_REVOKED) | -- (1 << KEY_FLAG_DEAD))))) -- return _ext4_get_encryption_info(inode); -- return 0; --} -+int ext4_get_encryption_info(struct inode *inode); - - static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode) - { -diff --git a/fs/ext4/ext4_crypto.h b/fs/ext4/ext4_crypto.h -index ac7d4e813796..1b17b05b9f4d 100644 ---- a/fs/ext4/ext4_crypto.h -+++ b/fs/ext4/ext4_crypto.h -@@ -78,7 +78,6 @@ struct ext4_crypt_info { - char ci_filename_mode; - char ci_flags; - struct crypto_ablkcipher *ci_ctfm; -- struct key *ci_keyring_key; - char ci_master_key[EXT4_KEY_DESCRIPTOR_SIZE]; - }; - -diff --git a/fs/f2fs/crypto_key.c b/fs/f2fs/crypto_key.c -index 5de2d866a25c..18595d7a0efc 100644 ---- a/fs/f2fs/crypto_key.c -+++ b/fs/f2fs/crypto_key.c -@@ -92,7 +92,6 @@ static void f2fs_free_crypt_info(struct f2fs_crypt_info *ci) - if (!ci) - return; - -- key_put(ci->ci_keyring_key); - crypto_free_ablkcipher(ci->ci_ctfm); - kmem_cache_free(f2fs_crypt_info_cachep, ci); - } -@@ -113,7 +112,7 @@ void f2fs_free_encryption_info(struct inode *inode, struct f2fs_crypt_info *ci) - f2fs_free_crypt_info(ci); - } - --int _f2fs_get_encryption_info(struct inode *inode) -+int f2fs_get_encryption_info(struct inode *inode) - { - struct f2fs_inode_info *fi = F2FS_I(inode); - struct f2fs_crypt_info *crypt_info; -@@ -129,18 +128,12 @@ int _f2fs_get_encryption_info(struct inode *inode) - char mode; - int res; - -+ if (fi->i_crypt_info) -+ return 0; -+ - res = f2fs_crypto_initialize(); - if (res) - return res; --retry: -- crypt_info = ACCESS_ONCE(fi->i_crypt_info); -- if (crypt_info) { -- if (!crypt_info->ci_keyring_key || -- key_validate(crypt_info->ci_keyring_key) == 0) -- return 0; -- f2fs_free_encryption_info(inode, crypt_info); -- goto retry; -- } - - res = f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION, - F2FS_XATTR_NAME_ENCRYPTION_CONTEXT, -@@ -159,7 +152,6 @@ retry: - crypt_info->ci_data_mode = ctx.contents_encryption_mode; - crypt_info->ci_filename_mode = ctx.filenames_encryption_mode; - crypt_info->ci_ctfm = NULL; -- crypt_info->ci_keyring_key = NULL; - memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor, - sizeof(crypt_info->ci_master_key)); - if (S_ISREG(inode->i_mode)) -@@ -197,7 +189,6 @@ retry: - keyring_key = NULL; - goto out; - } -- crypt_info->ci_keyring_key = keyring_key; - BUG_ON(keyring_key->type != &key_type_logon); - ukp = user_key_payload(keyring_key); - if (ukp->datalen != sizeof(struct f2fs_encryption_key)) { -@@ -230,17 +221,12 @@ retry: - if (res) - goto out; - -- memzero_explicit(raw_key, sizeof(raw_key)); -- if (cmpxchg(&fi->i_crypt_info, NULL, crypt_info) != NULL) { -- f2fs_free_crypt_info(crypt_info); -- goto retry; -- } -- return 0; -- -+ if (cmpxchg(&fi->i_crypt_info, NULL, crypt_info) == NULL) -+ crypt_info = NULL; - out: - if (res == -ENOKEY && !S_ISREG(inode->i_mode)) - res = 0; -- -+ key_put(keyring_key); - f2fs_free_crypt_info(crypt_info); - memzero_explicit(raw_key, sizeof(raw_key)); - return res; -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index 9db5500d63d9..b1aeca83f4be 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -2149,7 +2149,6 @@ void f2fs_end_io_crypto_work(struct f2fs_crypto_ctx *, struct bio *); - - /* crypto_key.c */ - void f2fs_free_encryption_info(struct inode *, struct f2fs_crypt_info *); --int _f2fs_get_encryption_info(struct inode *inode); - - /* crypto_fname.c */ - bool f2fs_valid_filenames_enc_mode(uint32_t); -@@ -2170,18 +2169,7 @@ void f2fs_exit_crypto(void); - - int f2fs_has_encryption_key(struct inode *); - --static inline int f2fs_get_encryption_info(struct inode *inode) --{ -- struct f2fs_crypt_info *ci = F2FS_I(inode)->i_crypt_info; -- -- if (!ci || -- (ci->ci_keyring_key && -- (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) | -- (1 << KEY_FLAG_REVOKED) | -- (1 << KEY_FLAG_DEAD))))) -- return _f2fs_get_encryption_info(inode); -- return 0; --} -+int f2fs_get_encryption_info(struct inode *inode); - - void f2fs_fname_crypto_free_buffer(struct f2fs_str *); - int f2fs_fname_setup_filename(struct inode *, const struct qstr *, -diff --git a/fs/f2fs/f2fs_crypto.h b/fs/f2fs/f2fs_crypto.h -index c2c1c2b63b25..f113f1a1e8c1 100644 ---- a/fs/f2fs/f2fs_crypto.h -+++ b/fs/f2fs/f2fs_crypto.h -@@ -79,7 +79,6 @@ struct f2fs_crypt_info { - char ci_filename_mode; - char ci_flags; - struct crypto_ablkcipher *ci_ctfm; -- struct key *ci_keyring_key; - char ci_master_key[F2FS_KEY_DESCRIPTOR_SIZE]; - }; - --- -2.12.2 - -From 2bed5987692cb6dc3bf3ce15d8abeb79fdf4ab2a Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Tue, 24 Jan 2017 15:40:06 +0100 -Subject: [PATCH 223/251] sched/rt: Add a missing rescheduling point -Content-Length: 2699 -Lines: 74 - -commit 619bd4a71874a8fd78eb6ccf9f272c5e98bcc7b7 upstream. - -Since the change in commit: - - fd7a4bed1835 ("sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks") - -... we don't reschedule a task under certain circumstances: - -Lets say task-A, SCHED_OTHER, is running on CPU0 (and it may run only on -CPU0) and holds a PI lock. This task is removed from the CPU because it -used up its time slice and another SCHED_OTHER task is running. Task-B on -CPU1 runs at RT priority and asks for the lock owned by task-A. This -results in a priority boost for task-A. Task-B goes to sleep until the -lock has been made available. Task-A is already runnable (but not active), -so it receives no wake up. - -The reality now is that task-A gets on the CPU once the scheduler decides -to remove the current task despite the fact that a high priority task is -enqueued and waiting. This may take a long time. - -The desired behaviour is that CPU0 immediately reschedules after the -priority boost which made task-A the task with the lowest priority. - -Suggested-by: Peter Zijlstra -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Peter Zijlstra (Intel) -Cc: Linus Torvalds -Cc: Mike Galbraith -Cc: Thomas Gleixner -Fixes: fd7a4bed1835 ("sched, rt: Convert switched_{from, to}_rt() prio_changed_rt() to balance callbacks") -Link: http://lkml.kernel.org/r/20170124144006.29821-1-bigeasy@linutronix.de -Signed-off-by: Ingo Molnar -Signed-off-by: Greg Kroah-Hartman ---- - kernel/sched/deadline.c | 3 +-- - kernel/sched/rt.c | 3 +-- - 2 files changed, 2 insertions(+), 4 deletions(-) - -diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c -index 8b0a15e285f9..e984f059e5fc 100644 ---- a/kernel/sched/deadline.c -+++ b/kernel/sched/deadline.c -@@ -1771,12 +1771,11 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p) - #ifdef CONFIG_SMP - if (p->nr_cpus_allowed > 1 && rq->dl.overloaded) - queue_push_tasks(rq); --#else -+#endif - if (dl_task(rq->curr)) - check_preempt_curr_dl(rq, p, 0); - else - resched_curr(rq); --#endif - } - } - -diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c -index 8ec86abe0ea1..78ae5c1d9412 100644 ---- a/kernel/sched/rt.c -+++ b/kernel/sched/rt.c -@@ -2136,10 +2136,9 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p) - #ifdef CONFIG_SMP - if (p->nr_cpus_allowed > 1 && rq->rt.overloaded) - queue_push_tasks(rq); --#else -+#endif /* CONFIG_SMP */ - if (p->prio < rq->curr->prio) - resched_curr(rq); --#endif /* CONFIG_SMP */ - } - } - --- -2.12.2 - -From 61a4577c9a4419b99e647744923517d47255da35 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Fri, 31 Mar 2017 10:17:09 +0200 -Subject: [PATCH 224/251] Linux 4.4.59 -Status: RO -Content-Length: 301 -Lines: 18 - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index 3efe2ea99e2d..083724c6ca4d 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 4 - PATCHLEVEL = 4 --SUBLEVEL = 58 -+SUBLEVEL = 59 - EXTRAVERSION = - NAME = Blurry Fish Butt - --- -2.12.2 - -From ba46d8fab00a8e1538df241681d9161c8ec85778 Mon Sep 17 00:00:00 2001 -From: Ilya Dryomov -Date: Tue, 21 Mar 2017 13:44:28 +0100 -Subject: [PATCH 225/251] libceph: force GFP_NOIO for socket allocations -Status: RO -Content-Length: 4579 -Lines: 104 - -commit 633ee407b9d15a75ac9740ba9d3338815e1fcb95 upstream. - -sock_alloc_inode() allocates socket+inode and socket_wq with -GFP_KERNEL, which is not allowed on the writeback path: - - Workqueue: ceph-msgr con_work [libceph] - ffff8810871cb018 0000000000000046 0000000000000000 ffff881085d40000 - 0000000000012b00 ffff881025cad428 ffff8810871cbfd8 0000000000012b00 - ffff880102fc1000 ffff881085d40000 ffff8810871cb038 ffff8810871cb148 - Call Trace: - [] schedule+0x29/0x70 - [] schedule_timeout+0x1bd/0x200 - [] ? ttwu_do_wakeup+0x2c/0x120 - [] ? ttwu_do_activate.constprop.135+0x66/0x70 - [] wait_for_completion+0xbf/0x180 - [] ? try_to_wake_up+0x390/0x390 - [] flush_work+0x165/0x250 - [] ? worker_detach_from_pool+0xd0/0xd0 - [] xlog_cil_force_lsn+0x81/0x200 [xfs] - [] ? __slab_free+0xee/0x234 - [] _xfs_log_force_lsn+0x4d/0x2c0 [xfs] - [] ? lookup_page_cgroup_used+0xe/0x30 - [] ? xfs_reclaim_inode+0xa3/0x330 [xfs] - [] xfs_log_force_lsn+0x3f/0xf0 [xfs] - [] ? xfs_reclaim_inode+0xa3/0x330 [xfs] - [] xfs_iunpin_wait+0xc6/0x1a0 [xfs] - [] ? wake_atomic_t_function+0x40/0x40 - [] xfs_reclaim_inode+0xa3/0x330 [xfs] - [] xfs_reclaim_inodes_ag+0x257/0x3d0 [xfs] - [] xfs_reclaim_inodes_nr+0x33/0x40 [xfs] - [] xfs_fs_free_cached_objects+0x15/0x20 [xfs] - [] super_cache_scan+0x178/0x180 - [] shrink_slab_node+0x14e/0x340 - [] ? mem_cgroup_iter+0x16b/0x450 - [] shrink_slab+0x100/0x140 - [] do_try_to_free_pages+0x335/0x490 - [] try_to_free_pages+0xb9/0x1f0 - [] ? __alloc_pages_direct_compact+0x69/0x1be - [] __alloc_pages_nodemask+0x69a/0xb40 - [] alloc_pages_current+0x9e/0x110 - [] new_slab+0x2c5/0x390 - [] __slab_alloc+0x33b/0x459 - [] ? sock_alloc_inode+0x2d/0xd0 - [] ? inet_sendmsg+0x71/0xc0 - [] ? sock_alloc_inode+0x2d/0xd0 - [] kmem_cache_alloc+0x1a2/0x1b0 - [] sock_alloc_inode+0x2d/0xd0 - [] alloc_inode+0x26/0xa0 - [] new_inode_pseudo+0x1a/0x70 - [] sock_alloc+0x1e/0x80 - [] __sock_create+0x95/0x220 - [] sock_create_kern+0x24/0x30 - [] con_work+0xef9/0x2050 [libceph] - [] ? rbd_img_request_submit+0x4c/0x60 [rbd] - [] process_one_work+0x159/0x4f0 - [] worker_thread+0x11b/0x530 - [] ? create_worker+0x1d0/0x1d0 - [] kthread+0xc9/0xe0 - [] ? flush_kthread_worker+0x90/0x90 - [] ret_from_fork+0x58/0x90 - [] ? flush_kthread_worker+0x90/0x90 - -Use memalloc_noio_{save,restore}() to temporarily force GFP_NOIO here. - -Link: http://tracker.ceph.com/issues/19309 -Reported-by: Sergey Jerusalimov -Signed-off-by: Ilya Dryomov -Reviewed-by: Jeff Layton -Signed-off-by: Greg Kroah-Hartman ---- - net/ceph/messenger.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c -index b8d927c56494..a6b2f2138c9d 100644 ---- a/net/ceph/messenger.c -+++ b/net/ceph/messenger.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -478,11 +479,16 @@ static int ceph_tcp_connect(struct ceph_connection *con) - { - struct sockaddr_storage *paddr = &con->peer_addr.in_addr; - struct socket *sock; -+ unsigned int noio_flag; - int ret; - - BUG_ON(con->sock); -+ -+ /* sock_create_kern() allocates with GFP_KERNEL */ -+ noio_flag = memalloc_noio_save(); - ret = sock_create_kern(read_pnet(&con->msgr->net), paddr->ss_family, - SOCK_STREAM, IPPROTO_TCP, &sock); -+ memalloc_noio_restore(noio_flag); - if (ret) - return ret; - sock->sk->sk_allocation = GFP_NOFS; --- -2.12.2 - -From ef55c3df5dbd60eb3daab7797feac850bd1e6fe3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michel=20D=C3=A4nzer?= -Date: Fri, 24 Mar 2017 19:01:09 +0900 -Subject: [PATCH 239/251] drm/radeon: Override fpfn for all VRAM placements in - radeon_evict_flags -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Content-Length: 1858 -Lines: 41 - -commit ce4b4f228e51219b0b79588caf73225b08b5b779 upstream. - -We were accidentally only overriding the first VRAM placement. For BOs -with the RADEON_GEM_NO_CPU_ACCESS flag set, -radeon_ttm_placement_from_domain creates a second VRAM placment with -fpfn == 0. If VRAM is almost full, the first VRAM placement with -fpfn > 0 may not work, but the second one with fpfn == 0 always will -(the BO's current location trivially satisfies it). Because "moving" -the BO to its current location puts it back on the LRU list, this -results in an infinite loop. - -Fixes: 2a85aedd117c ("drm/radeon: Try evicting from CPU accessible to - inaccessible VRAM first") -Reported-by: Zachary Michaels -Reported-and-Tested-by: Julien Isorce -Reviewed-by: Christian König -Reviewed-by: Alex Deucher -Signed-off-by: Michel Dänzer -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman ---- - drivers/gpu/drm/radeon/radeon_ttm.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c -index 35310336dd0a..d684e2b79d2b 100644 ---- a/drivers/gpu/drm/radeon/radeon_ttm.c -+++ b/drivers/gpu/drm/radeon/radeon_ttm.c -@@ -213,8 +213,8 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, - rbo->placement.num_busy_placement = 0; - for (i = 0; i < rbo->placement.num_placement; i++) { - if (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) { -- if (rbo->placements[0].fpfn < fpfn) -- rbo->placements[0].fpfn = fpfn; -+ if (rbo->placements[i].fpfn < fpfn) -+ rbo->placements[i].fpfn = fpfn; - } else { - rbo->placement.busy_placement = - &rbo->placements[i]; --- -2.12.2 - -From 47e2fe17d14d1a7da3a405b1f364c094c271d35c Mon Sep 17 00:00:00 2001 -From: Naoya Horiguchi -Date: Fri, 31 Mar 2017 15:11:55 -0700 -Subject: [PATCH 240/251] mm, hugetlb: use pte_present() instead of - pmd_present() in follow_huge_pmd() -Content-Length: 4587 -Lines: 99 - -commit c9d398fa237882ea07167e23bcfc5e6847066518 upstream. - -I found the race condition which triggers the following bug when -move_pages() and soft offline are called on a single hugetlb page -concurrently. - - Soft offlining page 0x119400 at 0x700000000000 - BUG: unable to handle kernel paging request at ffffea0011943820 - IP: follow_huge_pmd+0x143/0x190 - PGD 7ffd2067 - PUD 7ffd1067 - PMD 0 - [61163.582052] Oops: 0000 [#1] SMP - Modules linked in: binfmt_misc ppdev virtio_balloon parport_pc pcspkr i2c_piix4 parport i2c_core acpi_cpufreq ip_tables xfs libcrc32c ata_generic pata_acpi virtio_blk 8139too crc32c_intel ata_piix serio_raw libata virtio_pci 8139cp virtio_ring virtio mii floppy dm_mirror dm_region_hash dm_log dm_mod [last unloaded: cap_check] - CPU: 0 PID: 22573 Comm: iterate_numa_mo Tainted: P OE 4.11.0-rc2-mm1+ #2 - Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 - RIP: 0010:follow_huge_pmd+0x143/0x190 - RSP: 0018:ffffc90004bdbcd0 EFLAGS: 00010202 - RAX: 0000000465003e80 RBX: ffffea0004e34d30 RCX: 00003ffffffff000 - RDX: 0000000011943800 RSI: 0000000000080001 RDI: 0000000465003e80 - RBP: ffffc90004bdbd18 R08: 0000000000000000 R09: ffff880138d34000 - R10: ffffea0004650000 R11: 0000000000c363b0 R12: ffffea0011943800 - R13: ffff8801b8d34000 R14: ffffea0000000000 R15: 000077ff80000000 - FS: 00007fc977710740(0000) GS:ffff88007dc00000(0000) knlGS:0000000000000000 - CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 - CR2: ffffea0011943820 CR3: 000000007a746000 CR4: 00000000001406f0 - Call Trace: - follow_page_mask+0x270/0x550 - SYSC_move_pages+0x4ea/0x8f0 - SyS_move_pages+0xe/0x10 - do_syscall_64+0x67/0x180 - entry_SYSCALL64_slow_path+0x25/0x25 - RIP: 0033:0x7fc976e03949 - RSP: 002b:00007ffe72221d88 EFLAGS: 00000246 ORIG_RAX: 0000000000000117 - RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fc976e03949 - RDX: 0000000000c22390 RSI: 0000000000001400 RDI: 0000000000005827 - RBP: 00007ffe72221e00 R08: 0000000000c2c3a0 R09: 0000000000000004 - R10: 0000000000c363b0 R11: 0000000000000246 R12: 0000000000400650 - R13: 00007ffe72221ee0 R14: 0000000000000000 R15: 0000000000000000 - Code: 81 e4 ff ff 1f 00 48 21 c2 49 c1 ec 0c 48 c1 ea 0c 4c 01 e2 49 bc 00 00 00 00 00 ea ff ff 48 c1 e2 06 49 01 d4 f6 45 bc 04 74 90 <49> 8b 7c 24 20 40 f6 c7 01 75 2b 4c 89 e7 8b 47 1c 85 c0 7e 2a - RIP: follow_huge_pmd+0x143/0x190 RSP: ffffc90004bdbcd0 - CR2: ffffea0011943820 - ---[ end trace e4f81353a2d23232 ]--- - Kernel panic - not syncing: Fatal exception - Kernel Offset: disabled - -This bug is triggered when pmd_present() returns true for non-present -hugetlb, so fixing the present check in follow_huge_pmd() prevents it. -Using pmd_present() to determine present/non-present for hugetlb is not -correct, because pmd_present() checks multiple bits (not only -_PAGE_PRESENT) for historical reason and it can misjudge hugetlb state. - -Fixes: e66f17ff7177 ("mm/hugetlb: take page table lock in follow_huge_pmd()") -Link: http://lkml.kernel.org/r/1490149898-20231-1-git-send-email-n-horiguchi@ah.jp.nec.com -Signed-off-by: Naoya Horiguchi -Acked-by: Hillf Danton -Cc: Hugh Dickins -Cc: Michal Hocko -Cc: "Kirill A. Shutemov" -Cc: Mike Kravetz -Cc: Christian Borntraeger -Cc: Gerald Schaefer -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman ---- - mm/hugetlb.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index ea11123a9249..7294301d8495 100644 ---- a/mm/hugetlb.c -+++ b/mm/hugetlb.c -@@ -4362,6 +4362,7 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, - { - struct page *page = NULL; - spinlock_t *ptl; -+ pte_t pte; - retry: - ptl = pmd_lockptr(mm, pmd); - spin_lock(ptl); -@@ -4371,12 +4372,13 @@ retry: - */ - if (!pmd_huge(*pmd)) - goto out; -- if (pmd_present(*pmd)) { -+ pte = huge_ptep_get((pte_t *)pmd); -+ if (pte_present(pte)) { - page = pmd_page(*pmd) + ((address & ~PMD_MASK) >> PAGE_SHIFT); - if (flags & FOLL_GET) - get_page(page); - } else { -- if (is_hugetlb_entry_migration(huge_ptep_get((pte_t *)pmd))) { -+ if (is_hugetlb_entry_migration(pte)) { - spin_unlock(ptl); - __migration_entry_wait(mm, (pte_t *)pmd, ptl); - goto retry; --- -2.12.2 - -From 6280ac931a23d3fa40cd26057576abcf90a4f22d Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 19 Jan 2017 12:28:22 +0100 -Subject: [PATCH 241/251] MIPS: Lantiq: Fix cascaded IRQ setup -Content-Length: 3014 -Lines: 101 - -commit 6c356eda225e3ee134ed4176b9ae3a76f793f4dd upstream. - -With the IRQ stack changes integrated, the XRX200 devices started -emitting a constant stream of kernel messages like this: - -[ 565.415310] Spurious IRQ: CAUSE=0x1100c300 - -This is caused by IP0 getting handled by plat_irq_dispatch() rather than -its vectored interrupt handler, which is fixed by commit de856416e714 -("MIPS: IRQ Stack: Fix erroneous jal to plat_irq_dispatch"). - -Fix plat_irq_dispatch() to handle non-vectored IPI interrupts correctly -by setting up IP2-6 as proper chained IRQ handlers and calling do_IRQ -for all MIPS CPU interrupts. - -Signed-off-by: Felix Fietkau -Acked-by: John Crispin -Cc: linux-mips@linux-mips.org -Patchwork: https://patchwork.linux-mips.org/patch/15077/ -[james.hogan@imgtec.com: tweaked commit message] -Signed-off-by: James Hogan -Signed-off-by: Amit Pundir -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/lantiq/irq.c | 38 +++++++++++++++++--------------------- - 1 file changed, 17 insertions(+), 21 deletions(-) - -diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c -index 2e7f60c9fc5d..51cdc46a87e2 100644 ---- a/arch/mips/lantiq/irq.c -+++ b/arch/mips/lantiq/irq.c -@@ -269,6 +269,11 @@ static void ltq_hw5_irqdispatch(void) - DEFINE_HWx_IRQDISPATCH(5) - #endif - -+static void ltq_hw_irq_handler(struct irq_desc *desc) -+{ -+ ltq_hw_irqdispatch(irq_desc_get_irq(desc) - 2); -+} -+ - #ifdef CONFIG_MIPS_MT_SMP - void __init arch_init_ipiirq(int irq, struct irqaction *action) - { -@@ -313,23 +318,19 @@ static struct irqaction irq_call = { - asmlinkage void plat_irq_dispatch(void) - { - unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; -- unsigned int i; -- -- if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) { -- do_IRQ(MIPS_CPU_TIMER_IRQ); -- goto out; -- } else { -- for (i = 0; i < MAX_IM; i++) { -- if (pending & (CAUSEF_IP2 << i)) { -- ltq_hw_irqdispatch(i); -- goto out; -- } -- } -+ int irq; -+ -+ if (!pending) { -+ spurious_interrupt(); -+ return; - } -- pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status()); - --out: -- return; -+ pending >>= CAUSEB_IP; -+ while (pending) { -+ irq = fls(pending) - 1; -+ do_IRQ(MIPS_CPU_IRQ_BASE + irq); -+ pending &= ~BIT(irq); -+ } - } - - static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) -@@ -354,11 +355,6 @@ static const struct irq_domain_ops irq_domain_ops = { - .map = icu_map, - }; - --static struct irqaction cascade = { -- .handler = no_action, -- .name = "cascade", --}; -- - int __init icu_of_init(struct device_node *node, struct device_node *parent) - { - struct device_node *eiu_node; -@@ -390,7 +386,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) - mips_cpu_irq_init(); - - for (i = 0; i < MAX_IM; i++) -- setup_irq(i + 2, &cascade); -+ irq_set_chained_handler(i + 2, ltq_hw_irq_handler); - - if (cpu_has_vint) { - pr_info("Setting up vectored interrupts\n"); --- -2.12.2 - -From 063d30f187f5c492aa4a6cca88b8afa08f5a170c Mon Sep 17 00:00:00 2001 -From: Alexandre Belloni -Date: Tue, 25 Oct 2016 11:37:59 +0200 -Subject: [PATCH 247/251] power: reset: at91-poweroff: timely shutdown LPDDR - memories -Content-Length: 3667 -Lines: 122 - -commit 0b0408745e7ff24757cbfd571d69026c0ddb803c upstream. - -LPDDR memories can only handle up to 400 uncontrolled power off. Ensure the -proper power off sequence is used before shutting down the platform. - -Signed-off-by: Alexandre Belloni -Signed-off-by: Sebastian Reichel -Signed-off-by: Greg Kroah-Hartman ---- - drivers/power/reset/at91-poweroff.c | 54 ++++++++++++++++++++++++++++++++++++- - 1 file changed, 53 insertions(+), 1 deletion(-) - -diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c -index e9e24df35f26..2579f025b90b 100644 ---- a/drivers/power/reset/at91-poweroff.c -+++ b/drivers/power/reset/at91-poweroff.c -@@ -14,9 +14,12 @@ - #include - #include - #include -+#include - #include - #include - -+#include -+ - #define AT91_SHDW_CR 0x00 /* Shut Down Control Register */ - #define AT91_SHDW_SHDW BIT(0) /* Shut Down command */ - #define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */ -@@ -50,6 +53,7 @@ static const char *shdwc_wakeup_modes[] = { - - static void __iomem *at91_shdwc_base; - static struct clk *sclk; -+static void __iomem *mpddrc_base; - - static void __init at91_wakeup_status(void) - { -@@ -73,6 +77,29 @@ static void at91_poweroff(void) - writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR); - } - -+static void at91_lpddr_poweroff(void) -+{ -+ asm volatile( -+ /* Align to cache lines */ -+ ".balign 32\n\t" -+ -+ /* Ensure AT91_SHDW_CR is in the TLB by reading it */ -+ " ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t" -+ -+ /* Power down SDRAM0 */ -+ " str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t" -+ /* Shutdown CPU */ -+ " str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t" -+ -+ " b .\n\t" -+ : -+ : "r" (mpddrc_base), -+ "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF), -+ "r" (at91_shdwc_base), -+ "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW) -+ : "r0"); -+} -+ - static int at91_poweroff_get_wakeup_mode(struct device_node *np) - { - const char *pm; -@@ -124,6 +151,8 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev) - static int __init at91_poweroff_probe(struct platform_device *pdev) - { - struct resource *res; -+ struct device_node *np; -+ u32 ddr_type; - int ret; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -150,12 +179,30 @@ static int __init at91_poweroff_probe(struct platform_device *pdev) - - pm_power_off = at91_poweroff; - -+ np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc"); -+ if (!np) -+ return 0; -+ -+ mpddrc_base = of_iomap(np, 0); -+ of_node_put(np); -+ -+ if (!mpddrc_base) -+ return 0; -+ -+ ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD; -+ if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) || -+ (ddr_type == AT91_DDRSDRC_MD_LPDDR3)) -+ pm_power_off = at91_lpddr_poweroff; -+ else -+ iounmap(mpddrc_base); -+ - return 0; - } - - static int __exit at91_poweroff_remove(struct platform_device *pdev) - { -- if (pm_power_off == at91_poweroff) -+ if (pm_power_off == at91_poweroff || -+ pm_power_off == at91_lpddr_poweroff) - pm_power_off = NULL; - - clk_disable_unprepare(sclk); -@@ -163,6 +210,11 @@ static int __exit at91_poweroff_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id at91_ramc_of_match[] = { -+ { .compatible = "atmel,sama5d3-ddramc", }, -+ { /* sentinel */ } -+}; -+ - static const struct of_device_id at91_poweroff_of_match[] = { - { .compatible = "atmel,at91sam9260-shdwc", }, - { .compatible = "atmel,at91sam9rl-shdwc", }, --- -2.12.2 - -From 2cbd78f4239bd28b86c6ff8e3b7867db72762f1a Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Wed, 8 Mar 2017 07:38:05 +1100 -Subject: [PATCH 248/251] blk: improve order of bio handling in - generic_make_request() -Content-Length: 5024 -Lines: 114 - -commit 79bd99596b7305ab08109a8bf44a6a4511dbf1cd upstream. - -To avoid recursion on the kernel stack when stacked block devices -are in use, generic_make_request() will, when called recursively, -queue new requests for later handling. They will be handled when the -make_request_fn for the current bio completes. - -If any bios are submitted by a make_request_fn, these will ultimately -be handled seqeuntially. If the handling of one of those generates -further requests, they will be added to the end of the queue. - -This strict first-in-first-out behaviour can lead to deadlocks in -various ways, normally because a request might need to wait for a -previous request to the same device to complete. This can happen when -they share a mempool, and can happen due to interdependencies -particular to the device. Both md and dm have examples where this happens. - -These deadlocks can be erradicated by more selective ordering of bios. -Specifically by handling them in depth-first order. That is: when the -handling of one bio generates one or more further bios, they are -handled immediately after the parent, before any siblings of the -parent. That way, when generic_make_request() calls make_request_fn -for some particular device, we can be certain that all previously -submited requests for that device have been completely handled and are -not waiting for anything in the queue of requests maintained in -generic_make_request(). - -An easy way to achieve this would be to use a last-in-first-out stack -instead of a queue. However this will change the order of consecutive -bios submitted by a make_request_fn, which could have unexpected consequences. -Instead we take a slightly more complex approach. -A fresh queue is created for each call to a make_request_fn. After it completes, -any bios for a different device are placed on the front of the main queue, followed -by any bios for the same device, followed by all bios that were already on -the queue before the make_request_fn was called. -This provides the depth-first approach without reordering bios on the same level. - -This, by itself, it not enough to remove all deadlocks. It just makes -it possible for drivers to take the extra step required themselves. - -To avoid deadlocks, drivers must never risk waiting for a request -after submitting one to generic_make_request. This includes never -allocing from a mempool twice in the one call to a make_request_fn. - -A common pattern in drivers is to call bio_split() in a loop, handling -the first part and then looping around to possibly split the next part. -Instead, a driver that finds it needs to split a bio should queue -(with generic_make_request) the second part, handle the first part, -and then return. The new code in generic_make_request will ensure the -requests to underlying bios are processed first, then the second bio -that was split off. If it splits again, the same process happens. In -each case one bio will be completely handled before the next one is attempted. - -With this is place, it should be possible to disable the -punt_bios_to_recover() recovery thread for many block devices, and -eventually it may be possible to remove it completely. - -Ref: http://www.spinics.net/lists/raid/msg54680.html -Tested-by: Jinpu Wang -Inspired-by: Lars Ellenberg -Signed-off-by: NeilBrown -Signed-off-by: Jens Axboe -[jwang: backport to 4.4] -Signed-off-by: Jack Wang -Signed-off-by: Greg Kroah-Hartman ---- - block/blk-core.c | 25 ++++++++++++++++++++----- - 1 file changed, 20 insertions(+), 5 deletions(-) - -diff --git a/block/blk-core.c b/block/blk-core.c -index 4fab5d610805..7a58a22d1595 100644 ---- a/block/blk-core.c -+++ b/block/blk-core.c -@@ -2063,18 +2063,33 @@ blk_qc_t generic_make_request(struct bio *bio) - struct request_queue *q = bdev_get_queue(bio->bi_bdev); - - if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) { -+ struct bio_list lower, same, hold; -+ -+ /* Create a fresh bio_list for all subordinate requests */ -+ hold = bio_list_on_stack; -+ bio_list_init(&bio_list_on_stack); - - ret = q->make_request_fn(q, bio); - - blk_queue_exit(q); -- -- bio = bio_list_pop(current->bio_list); -+ /* sort new bios into those for a lower level -+ * and those for the same level -+ */ -+ bio_list_init(&lower); -+ bio_list_init(&same); -+ while ((bio = bio_list_pop(&bio_list_on_stack)) != NULL) -+ if (q == bdev_get_queue(bio->bi_bdev)) -+ bio_list_add(&same, bio); -+ else -+ bio_list_add(&lower, bio); -+ /* now assemble so we handle the lowest level first */ -+ bio_list_merge(&bio_list_on_stack, &lower); -+ bio_list_merge(&bio_list_on_stack, &same); -+ bio_list_merge(&bio_list_on_stack, &hold); - } else { -- struct bio *bio_next = bio_list_pop(current->bio_list); -- - bio_io_error(bio); -- bio = bio_next; - } -+ bio = bio_list_pop(current->bio_list); - } while (bio); - current->bio_list = NULL; /* deactivate */ - --- -2.12.2 - -From 5cca175b6cda16b68b18967210872327b1cadf4f Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Fri, 10 Mar 2017 17:00:47 +1100 -Subject: [PATCH 249/251] blk: Ensure users for current->bio_list can see the - full list. -Content-Length: 7421 -Lines: 217 - -commit f5fe1b51905df7cfe4fdfd85c5fb7bc5b71a094f upstream. - -Commit 79bd99596b73 ("blk: improve order of bio handling in generic_make_request()") -changed current->bio_list so that it did not contain *all* of the -queued bios, but only those submitted by the currently running -make_request_fn. - -There are two places which walk the list and requeue selected bios, -and others that check if the list is empty. These are no longer -correct. - -So redefine current->bio_list to point to an array of two lists, which -contain all queued bios, and adjust various code to test or walk both -lists. - -Signed-off-by: NeilBrown -Fixes: 79bd99596b73 ("blk: improve order of bio handling in generic_make_request()") -Signed-off-by: Jens Axboe -[jwang: backport to 4.4] -Signed-off-by: Jack Wang -Signed-off-by: Greg Kroah-Hartman -[bwh: Restore changes in device-mapper from upstream version] -Signed-off-by: Ben Hutchings ---- - block/bio.c | 12 +++++++++--- - block/blk-core.c | 31 +++++++++++++++++++------------ - drivers/md/dm.c | 29 ++++++++++++++++------------- - drivers/md/raid1.c | 3 ++- - drivers/md/raid10.c | 3 ++- - 5 files changed, 48 insertions(+), 30 deletions(-) - -diff --git a/block/bio.c b/block/bio.c -index 46e2cc1d4016..14263fab94d3 100644 ---- a/block/bio.c -+++ b/block/bio.c -@@ -373,10 +373,14 @@ static void punt_bios_to_rescuer(struct bio_set *bs) - bio_list_init(&punt); - bio_list_init(&nopunt); - -- while ((bio = bio_list_pop(current->bio_list))) -+ while ((bio = bio_list_pop(¤t->bio_list[0]))) - bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio); -+ current->bio_list[0] = nopunt; - -- *current->bio_list = nopunt; -+ bio_list_init(&nopunt); -+ while ((bio = bio_list_pop(¤t->bio_list[1]))) -+ bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio); -+ current->bio_list[1] = nopunt; - - spin_lock(&bs->rescue_lock); - bio_list_merge(&bs->rescue_list, &punt); -@@ -464,7 +468,9 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) - * we retry with the original gfp_flags. - */ - -- if (current->bio_list && !bio_list_empty(current->bio_list)) -+ if (current->bio_list && -+ (!bio_list_empty(¤t->bio_list[0]) || -+ !bio_list_empty(¤t->bio_list[1]))) - gfp_mask &= ~__GFP_DIRECT_RECLAIM; - - p = mempool_alloc(bs->bio_pool, gfp_mask); -diff --git a/block/blk-core.c b/block/blk-core.c -index 7a58a22d1595..ef083e7a37c5 100644 ---- a/block/blk-core.c -+++ b/block/blk-core.c -@@ -2021,7 +2021,14 @@ end_io: - */ - blk_qc_t generic_make_request(struct bio *bio) - { -- struct bio_list bio_list_on_stack; -+ /* -+ * bio_list_on_stack[0] contains bios submitted by the current -+ * make_request_fn. -+ * bio_list_on_stack[1] contains bios that were submitted before -+ * the current make_request_fn, but that haven't been processed -+ * yet. -+ */ -+ struct bio_list bio_list_on_stack[2]; - blk_qc_t ret = BLK_QC_T_NONE; - - if (!generic_make_request_checks(bio)) -@@ -2038,7 +2045,7 @@ blk_qc_t generic_make_request(struct bio *bio) - * should be added at the tail - */ - if (current->bio_list) { -- bio_list_add(current->bio_list, bio); -+ bio_list_add(¤t->bio_list[0], bio); - goto out; - } - -@@ -2057,17 +2064,17 @@ blk_qc_t generic_make_request(struct bio *bio) - * bio_list, and call into ->make_request() again. - */ - BUG_ON(bio->bi_next); -- bio_list_init(&bio_list_on_stack); -- current->bio_list = &bio_list_on_stack; -+ bio_list_init(&bio_list_on_stack[0]); -+ current->bio_list = bio_list_on_stack; - do { - struct request_queue *q = bdev_get_queue(bio->bi_bdev); - - if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) { -- struct bio_list lower, same, hold; -+ struct bio_list lower, same; - - /* Create a fresh bio_list for all subordinate requests */ -- hold = bio_list_on_stack; -- bio_list_init(&bio_list_on_stack); -+ bio_list_on_stack[1] = bio_list_on_stack[0]; -+ bio_list_init(&bio_list_on_stack[0]); - - ret = q->make_request_fn(q, bio); - -@@ -2077,19 +2084,19 @@ blk_qc_t generic_make_request(struct bio *bio) - */ - bio_list_init(&lower); - bio_list_init(&same); -- while ((bio = bio_list_pop(&bio_list_on_stack)) != NULL) -+ while ((bio = bio_list_pop(&bio_list_on_stack[0])) != NULL) - if (q == bdev_get_queue(bio->bi_bdev)) - bio_list_add(&same, bio); - else - bio_list_add(&lower, bio); - /* now assemble so we handle the lowest level first */ -- bio_list_merge(&bio_list_on_stack, &lower); -- bio_list_merge(&bio_list_on_stack, &same); -- bio_list_merge(&bio_list_on_stack, &hold); -+ bio_list_merge(&bio_list_on_stack[0], &lower); -+ bio_list_merge(&bio_list_on_stack[0], &same); -+ bio_list_merge(&bio_list_on_stack[0], &bio_list_on_stack[1]); - } else { - bio_io_error(bio); - } -- bio = bio_list_pop(current->bio_list); -+ bio = bio_list_pop(&bio_list_on_stack[0]); - } while (bio); - current->bio_list = NULL; /* deactivate */ - -diff --git a/drivers/md/dm.c b/drivers/md/dm.c -index 397f0454100b..320eb3c4bb6b 100644 ---- a/drivers/md/dm.c -+++ b/drivers/md/dm.c -@@ -1481,26 +1481,29 @@ static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule) - struct dm_offload *o = container_of(cb, struct dm_offload, cb); - struct bio_list list; - struct bio *bio; -+ int i; - - INIT_LIST_HEAD(&o->cb.list); - - if (unlikely(!current->bio_list)) - return; - -- list = *current->bio_list; -- bio_list_init(current->bio_list); -- -- while ((bio = bio_list_pop(&list))) { -- struct bio_set *bs = bio->bi_pool; -- if (unlikely(!bs) || bs == fs_bio_set) { -- bio_list_add(current->bio_list, bio); -- continue; -+ for (i = 0; i < 2; i++) { -+ list = current->bio_list[i]; -+ bio_list_init(¤t->bio_list[i]); -+ -+ while ((bio = bio_list_pop(&list))) { -+ struct bio_set *bs = bio->bi_pool; -+ if (unlikely(!bs) || bs == fs_bio_set) { -+ bio_list_add(¤t->bio_list[i], bio); -+ continue; -+ } -+ -+ spin_lock(&bs->rescue_lock); -+ bio_list_add(&bs->rescue_list, bio); -+ queue_work(bs->rescue_workqueue, &bs->rescue_work); -+ spin_unlock(&bs->rescue_lock); - } -- -- spin_lock(&bs->rescue_lock); -- bio_list_add(&bs->rescue_list, bio); -- queue_work(bs->rescue_workqueue, &bs->rescue_work); -- spin_unlock(&bs->rescue_lock); - } - } - -diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c -index 515554c7365b..9be39988bf06 100644 ---- a/drivers/md/raid1.c -+++ b/drivers/md/raid1.c -@@ -877,7 +877,8 @@ static sector_t wait_barrier(struct r1conf *conf, struct bio *bio) - ((conf->start_next_window < - conf->next_resync + RESYNC_SECTORS) && - current->bio_list && -- !bio_list_empty(current->bio_list))), -+ (!bio_list_empty(¤t->bio_list[0]) || -+ !bio_list_empty(¤t->bio_list[1])))), - conf->resync_lock); - conf->nr_waiting--; - } -diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c -index a92979e704e3..e5ee4e9e0ea5 100644 ---- a/drivers/md/raid10.c -+++ b/drivers/md/raid10.c -@@ -946,7 +946,8 @@ static void wait_barrier(struct r10conf *conf) - !conf->barrier || - (conf->nr_pending && - current->bio_list && -- !bio_list_empty(current->bio_list)), -+ (!bio_list_empty(¤t->bio_list[0]) || -+ !bio_list_empty(¤t->bio_list[1]))), - conf->resync_lock); - conf->nr_waiting--; - } --- -2.12.2 - -From 8f8ee9706b0a64a3506b9d9789ace7c44f3d817d Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Sat, 8 Apr 2017 09:53:53 +0200 -Subject: [PATCH 251/251] Linux 4.4.60 -Status: RO -Content-Length: 301 -Lines: 18 - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index 083724c6ca4d..fb7c2b40753d 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 4 - PATCHLEVEL = 4 --SUBLEVEL = 59 -+SUBLEVEL = 60 - EXTRAVERSION = - NAME = Blurry Fish Butt - --- -2.12.2 - -From a80c068fbf43e22f099c0587b9e1a2337378a505 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Tue, 18 Apr 2017 07:15:37 +0200 -Subject: [PATCH 52/52] Linux 4.4.62 -Status: RO -Content-Length: 301 -Lines: 18 - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index ef5045b8201d..0309acc34472 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 4 - PATCHLEVEL = 4 --SUBLEVEL = 61 -+SUBLEVEL = 62 - EXTRAVERSION = - NAME = Blurry Fish Butt - --- -2.12.2 - -From ac0cbfbb1e4b84d426f210849492afadbc4b6bb9 Mon Sep 17 00:00:00 2001 -From: Jack Morgenstein -Date: Mon, 16 Jan 2017 18:31:38 +0200 -Subject: [PATCH 50/52] net/mlx4_core: Fix when to save some qp context flags - for dynamic VST to VGT transitions -Content-Length: 2238 -Lines: 54 - -commit 7c3945bc2073554bb2ecf983e073dee686679c53 upstream. - -Save the qp context flags byte containing the flag disabling vlan stripping -in the RESET to INIT qp transition, rather than in the INIT to RTR -transition. Per the firmware spec, the flags in this byte are active -in the RESET to INIT transition. - -As a result of saving the flags in the incorrect qp transition, when -switching dynamically from VGT to VST and back to VGT, the vlan -remained stripped (as is required for VST) and did not return to -not-stripped (as is required for VGT). - -Fixes: f0f829bf42cd ("net/mlx4_core: Add immediate activate for VGT->VST->VGT") -Signed-off-by: Jack Morgenstein -Signed-off-by: Tariq Toukan -Signed-off-by: David S. Miller -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c -index d314d96dcb1c..d1fc7fa87b05 100644 ---- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c -+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c -@@ -2955,6 +2955,9 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave, - put_res(dev, slave, srqn, RES_SRQ); - qp->srq = srq; - } -+ -+ /* Save param3 for dynamic changes from VST back to VGT */ -+ qp->param3 = qpc->param3; - put_res(dev, slave, rcqn, RES_CQ); - put_res(dev, slave, mtt_base, RES_MTT); - res_end_move(dev, slave, RES_QP, qpn); -@@ -3747,7 +3750,6 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave, - int qpn = vhcr->in_modifier & 0x7fffff; - struct res_qp *qp; - u8 orig_sched_queue; -- __be32 orig_param3 = qpc->param3; - u8 orig_vlan_control = qpc->pri_path.vlan_control; - u8 orig_fvl_rx = qpc->pri_path.fvl_rx; - u8 orig_pri_path_fl = qpc->pri_path.fl; -@@ -3789,7 +3791,6 @@ out: - */ - if (!err) { - qp->sched_queue = orig_sched_queue; -- qp->param3 = orig_param3; - qp->vlan_control = orig_vlan_control; - qp->fvl_rx = orig_fvl_rx; - qp->pri_path_fl = orig_pri_path_fl; --- -2.12.2 - -From 710f793a15de0213d4e15f123f327b2075a0c62b Mon Sep 17 00:00:00 2001 -From: Jack Morgenstein -Date: Mon, 16 Jan 2017 18:31:37 +0200 -Subject: [PATCH 49/52] net/mlx4_core: Fix racy CQ (Completion Queue) free -Content-Length: 5257 -Lines: 146 - -commit 291c566a28910614ce42d0ffe82196eddd6346f4 upstream. - -In function mlx4_cq_completion() and mlx4_cq_event(), the -radix_tree_lookup requires a rcu_read_lock. -This is mandatory: if another core frees the CQ, it could -run the radix_tree_node_rcu_free() call_rcu() callback while -its being used by the radix tree lookup function. - -Additionally, in function mlx4_cq_event(), since we are adding -the rcu lock around the radix-tree lookup, we no longer need to take -the spinlock. Also, the synchronize_irq() call for the async event -eliminates the need for incrementing the cq reference count in -mlx4_cq_event(). - -Other changes: -1. In function mlx4_cq_free(), replace spin_lock_irq with spin_lock: - we no longer take this spinlock in the interrupt context. - The spinlock here, therefore, simply protects against different - threads simultaneously invoking mlx4_cq_free() for different cq's. - -2. In function mlx4_cq_free(), we move the radix tree delete to before - the synchronize_irq() calls. This guarantees that we will not - access this cq during any subsequent interrupts, and therefore can - safely free the CQ after the synchronize_irq calls. The rcu_read_lock - in the interrupt handlers only needs to protect against corrupting the - radix tree; the interrupt handlers may access the cq outside the - rcu_read_lock due to the synchronize_irq calls which protect against - premature freeing of the cq. - -3. In function mlx4_cq_event(), we change the mlx_warn message to mlx4_dbg. - -4. We leave the cq reference count mechanism in place, because it is - still needed for the cq completion tasklet mechanism. - -Fixes: 6d90aa5cf17b ("net/mlx4_core: Make sure there are no pending async events when freeing CQ") -Fixes: 225c7b1feef1 ("IB/mlx4: Add a driver Mellanox ConnectX InfiniBand adapters") -Signed-off-by: Jack Morgenstein -Signed-off-by: Matan Barak -Signed-off-by: Tariq Toukan -Signed-off-by: David S. Miller -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/ethernet/mellanox/mlx4/cq.c | 38 +++++++++++++++++---------------- - 1 file changed, 20 insertions(+), 18 deletions(-) - -diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c -index 3348e646db70..6eba58044456 100644 ---- a/drivers/net/ethernet/mellanox/mlx4/cq.c -+++ b/drivers/net/ethernet/mellanox/mlx4/cq.c -@@ -101,13 +101,19 @@ void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn) - { - struct mlx4_cq *cq; - -+ rcu_read_lock(); - cq = radix_tree_lookup(&mlx4_priv(dev)->cq_table.tree, - cqn & (dev->caps.num_cqs - 1)); -+ rcu_read_unlock(); -+ - if (!cq) { - mlx4_dbg(dev, "Completion event for bogus CQ %08x\n", cqn); - return; - } - -+ /* Acessing the CQ outside of rcu_read_lock is safe, because -+ * the CQ is freed only after interrupt handling is completed. -+ */ - ++cq->arm_sn; - - cq->comp(cq); -@@ -118,23 +124,19 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type) - struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table; - struct mlx4_cq *cq; - -- spin_lock(&cq_table->lock); -- -+ rcu_read_lock(); - cq = radix_tree_lookup(&cq_table->tree, cqn & (dev->caps.num_cqs - 1)); -- if (cq) -- atomic_inc(&cq->refcount); -- -- spin_unlock(&cq_table->lock); -+ rcu_read_unlock(); - - if (!cq) { -- mlx4_warn(dev, "Async event for bogus CQ %08x\n", cqn); -+ mlx4_dbg(dev, "Async event for bogus CQ %08x\n", cqn); - return; - } - -+ /* Acessing the CQ outside of rcu_read_lock is safe, because -+ * the CQ is freed only after interrupt handling is completed. -+ */ - cq->event(cq, event_type); -- -- if (atomic_dec_and_test(&cq->refcount)) -- complete(&cq->free); - } - - static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, -@@ -301,9 +303,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, - if (err) - return err; - -- spin_lock_irq(&cq_table->lock); -+ spin_lock(&cq_table->lock); - err = radix_tree_insert(&cq_table->tree, cq->cqn, cq); -- spin_unlock_irq(&cq_table->lock); -+ spin_unlock(&cq_table->lock); - if (err) - goto err_icm; - -@@ -347,9 +349,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, - return 0; - - err_radix: -- spin_lock_irq(&cq_table->lock); -+ spin_lock(&cq_table->lock); - radix_tree_delete(&cq_table->tree, cq->cqn); -- spin_unlock_irq(&cq_table->lock); -+ spin_unlock(&cq_table->lock); - - err_icm: - mlx4_cq_free_icm(dev, cq->cqn); -@@ -368,15 +370,15 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq) - if (err) - mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn); - -+ spin_lock(&cq_table->lock); -+ radix_tree_delete(&cq_table->tree, cq->cqn); -+ spin_unlock(&cq_table->lock); -+ - synchronize_irq(priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq); - if (priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq != - priv->eq_table.eq[MLX4_EQ_ASYNC].irq) - synchronize_irq(priv->eq_table.eq[MLX4_EQ_ASYNC].irq); - -- spin_lock_irq(&cq_table->lock); -- radix_tree_delete(&cq_table->tree, cq->cqn); -- spin_unlock_irq(&cq_table->lock); -- - if (atomic_dec_and_test(&cq->refcount)) - complete(&cq->free); - wait_for_completion(&cq->free); --- -2.12.2 - -From f1e6b1149e497dc61ceff290c1d3db259ebf7938 Mon Sep 17 00:00:00 2001 -From: Eugenia Emantayev -Date: Thu, 29 Dec 2016 18:37:10 +0200 -Subject: [PATCH 48/52] net/mlx4_en: Fix bad WQE issue -Content-Length: 1449 -Lines: 38 - -commit 6496bbf0ec481966ef9ffe5b6660d8d1b55c60cc upstream. - -Single send WQE in RX buffer should be stamped with software -ownership in order to prevent the flow of QP in error in FW -once UPDATE_QP is called. - -Fixes: 9f519f68cfff ('mlx4_en: Not using Shared Receive Queues') -Signed-off-by: Eugenia Emantayev -Signed-off-by: Tariq Toukan -Signed-off-by: David S. Miller -Signed-off-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/ethernet/mellanox/mlx4/en_rx.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c -index 28a4b34310b2..82bf1b539d87 100644 ---- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c -+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c -@@ -439,8 +439,14 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) - ring->cqn = priv->rx_cq[ring_ind]->mcq.cqn; - - ring->stride = stride; -- if (ring->stride <= TXBB_SIZE) -+ if (ring->stride <= TXBB_SIZE) { -+ /* Stamp first unused send wqe */ -+ __be32 *ptr = (__be32 *)ring->buf; -+ __be32 stamp = cpu_to_be32(1 << STAMP_SHIFT); -+ *ptr = stamp; -+ /* Move pointer to start of rx section */ - ring->buf += TXBB_SIZE; -+ } - - ring->log_stride = ffs(ring->stride) - 1; - ring->buf_size = ring->size * ring->stride; --- -2.12.2 - -From d35f8fa0b93e61dd95b8f86928a783c4d8a32d3e Mon Sep 17 00:00:00 2001 -From: Andrey Konovalov -Date: Wed, 29 Mar 2017 16:11:20 +0200 -Subject: [PATCH 45/52] net/packet: fix overflow in check for priv area size -Content-Length: 1299 -Lines: 36 - -commit 2b6867c2ce76c596676bec7d2d525af525fdc6e2 upstream. - -Subtracting tp_sizeof_priv from tp_block_size and casting to int -to check whether one is less then the other doesn't always work -(both of them are unsigned ints). - -Compare them as is instead. - -Also cast tp_sizeof_priv to u64 before using BLK_PLUS_PRIV, as -it can overflow inside BLK_PLUS_PRIV otherwise. - -Signed-off-by: Andrey Konovalov -Acked-by: Eric Dumazet -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - net/packet/af_packet.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index 3975ac809934..d76800108ddb 100644 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -4138,8 +4138,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, - if (unlikely(!PAGE_ALIGNED(req->tp_block_size))) - goto out; - if (po->tp_version >= TPACKET_V3 && -- (int)(req->tp_block_size - -- BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0) -+ req->tp_block_size <= -+ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv)) - goto out; - if (unlikely(req->tp_frame_size < po->tp_hdrlen + - po->tp_reserve)) --- -2.12.2 - -From ba7681e4eee6739e4f23a1ba21fb7737fe4ce4f4 Mon Sep 17 00:00:00 2001 -From: Matt Redfearn -Date: Wed, 25 Jan 2017 17:00:25 +0000 -Subject: [PATCH 43/52] MIPS: IRQ Stack: Fix erroneous jal to plat_irq_dispatch -Content-Length: 1415 -Lines: 38 - -commit c25f8064c1d5731a2ce5664def890140dcdd3e5c upstream. - -Commit dda45f701c9d ("MIPS: Switch to the irq_stack in interrupts") -changed both the normal and vectored interrupt handlers. Unfortunately -the vectored version, "except_vec_vi_handler", was incorrectly modified -to unconditionally jal to plat_irq_dispatch, rather than doing a jalr to -the vectored handler that has been set up. This is ok for many platforms -which set the vectored handler to plat_irq_dispatch anyway, but will -cause problems with platforms that use other handlers. - -Fixes: dda45f701c9d ("MIPS: Switch to the irq_stack in interrupts") -Signed-off-by: Matt Redfearn -Cc: Ralf Baechle -Cc: Paul Burton -Cc: linux-mips@linux-mips.org -Patchwork: https://patchwork.linux-mips.org/patch/15110/ -Signed-off-by: James Hogan -Signed-off-by: Amit Pundir -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/kernel/genex.S | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S -index 2c7cd622673f..619e30e2c4f0 100644 ---- a/arch/mips/kernel/genex.S -+++ b/arch/mips/kernel/genex.S -@@ -330,7 +330,7 @@ NESTED(except_vec_vi_handler, 0, sp) - PTR_ADD sp, t0, t1 - - 2: -- jal plat_irq_dispatch -+ jalr v0 - - /* Restore sp */ - move sp, s1 --- -2.12.2 - -From f017e58da4aba293e4a6ab62ca5d4801f79cc929 Mon Sep 17 00:00:00 2001 -From: Matt Redfearn -Date: Mon, 19 Dec 2016 14:21:00 +0000 -Subject: [PATCH 42/52] MIPS: Select HAVE_IRQ_EXIT_ON_IRQ_STACK -Content-Length: 1117 -Lines: 33 - -commit 3cc3434fd6307d06b53b98ce83e76bf9807689b9 upstream. - -Since do_IRQ is now invoked on a separate IRQ stack, we select -HAVE_IRQ_EXIT_ON_IRQ_STACK so that softirq's may be invoked directly -from irq_exit(), rather than requiring do_softirq_own_stack. - -Signed-off-by: Matt Redfearn -Acked-by: Jason A. Donenfeld -Cc: Thomas Gleixner -Cc: linux-mips@linux-mips.org -Cc: linux-kernel@vger.kernel.org -Patchwork: https://patchwork.linux-mips.org/patch/14744/ -Signed-off-by: Ralf Baechle -Signed-off-by: Amit Pundir -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index 75bfca69e418..d5cfa937d622 100644 ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -9,6 +9,7 @@ config MIPS - select HAVE_CONTEXT_TRACKING - select HAVE_GENERIC_DMA_COHERENT - select HAVE_IDE -+ select HAVE_IRQ_EXIT_ON_IRQ_STACK - select HAVE_OPROFILE - select HAVE_PERF_EVENTS - select PERF_USE_VMALLOC --- -2.12.2 - -From b39b263816687fd71b10c31b3eb916defe8176f0 Mon Sep 17 00:00:00 2001 -From: Matt Redfearn -Date: Mon, 19 Dec 2016 14:20:59 +0000 -Subject: [PATCH 41/52] MIPS: Switch to the irq_stack in interrupts -Content-Length: 3496 -Lines: 130 - -commit dda45f701c9d7ad4ac0bb446e3a96f6df9a468d9 upstream. - -When enterring interrupt context via handle_int or except_vec_vi, switch -to the irq_stack of the current CPU if it is not already in use. - -The current stack pointer is masked with the thread size and compared to -the base or the irq stack. If it does not match then the stack pointer -is set to the top of that stack, otherwise this is a nested irq being -handled on the irq stack so the stack pointer should be left as it was. - -The in-use stack pointer is placed in the callee saved register s1. It -will be saved to the stack when plat_irq_dispatch is invoked and can be -restored once control returns here. - -Signed-off-by: Matt Redfearn -Acked-by: Jason A. Donenfeld -Cc: Thomas Gleixner -Cc: James Hogan -Cc: Paul Burton -Cc: linux-mips@linux-mips.org -Cc: linux-kernel@vger.kernel.org -Patchwork: https://patchwork.linux-mips.org/patch/14743/ -Signed-off-by: Ralf Baechle -Signed-off-by: Amit Pundir -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/kernel/genex.S | 81 +++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 76 insertions(+), 5 deletions(-) - -diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S -index baa7b6fc0a60..2c7cd622673f 100644 ---- a/arch/mips/kernel/genex.S -+++ b/arch/mips/kernel/genex.S -@@ -188,9 +188,44 @@ NESTED(handle_int, PT_SIZE, sp) - - LONG_L s0, TI_REGS($28) - LONG_S sp, TI_REGS($28) -- PTR_LA ra, ret_from_irq -- PTR_LA v0, plat_irq_dispatch -- jr v0 -+ -+ /* -+ * SAVE_ALL ensures we are using a valid kernel stack for the thread. -+ * Check if we are already using the IRQ stack. -+ */ -+ move s1, sp # Preserve the sp -+ -+ /* Get IRQ stack for this CPU */ -+ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG -+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) -+ lui k1, %hi(irq_stack) -+#else -+ lui k1, %highest(irq_stack) -+ daddiu k1, %higher(irq_stack) -+ dsll k1, 16 -+ daddiu k1, %hi(irq_stack) -+ dsll k1, 16 -+#endif -+ LONG_SRL k0, SMP_CPUID_PTRSHIFT -+ LONG_ADDU k1, k0 -+ LONG_L t0, %lo(irq_stack)(k1) -+ -+ # Check if already on IRQ stack -+ PTR_LI t1, ~(_THREAD_SIZE-1) -+ and t1, t1, sp -+ beq t0, t1, 2f -+ -+ /* Switch to IRQ stack */ -+ li t1, _IRQ_STACK_SIZE -+ PTR_ADD sp, t0, t1 -+ -+2: -+ jal plat_irq_dispatch -+ -+ /* Restore sp */ -+ move sp, s1 -+ -+ j ret_from_irq - #ifdef CONFIG_CPU_MICROMIPS - nop - #endif -@@ -263,8 +298,44 @@ NESTED(except_vec_vi_handler, 0, sp) - - LONG_L s0, TI_REGS($28) - LONG_S sp, TI_REGS($28) -- PTR_LA ra, ret_from_irq -- jr v0 -+ -+ /* -+ * SAVE_ALL ensures we are using a valid kernel stack for the thread. -+ * Check if we are already using the IRQ stack. -+ */ -+ move s1, sp # Preserve the sp -+ -+ /* Get IRQ stack for this CPU */ -+ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG -+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) -+ lui k1, %hi(irq_stack) -+#else -+ lui k1, %highest(irq_stack) -+ daddiu k1, %higher(irq_stack) -+ dsll k1, 16 -+ daddiu k1, %hi(irq_stack) -+ dsll k1, 16 -+#endif -+ LONG_SRL k0, SMP_CPUID_PTRSHIFT -+ LONG_ADDU k1, k0 -+ LONG_L t0, %lo(irq_stack)(k1) -+ -+ # Check if already on IRQ stack -+ PTR_LI t1, ~(_THREAD_SIZE-1) -+ and t1, t1, sp -+ beq t0, t1, 2f -+ -+ /* Switch to IRQ stack */ -+ li t1, _IRQ_STACK_SIZE -+ PTR_ADD sp, t0, t1 -+ -+2: -+ jal plat_irq_dispatch -+ -+ /* Restore sp */ -+ move sp, s1 -+ -+ j ret_from_irq - END(except_vec_vi_handler) - - /* --- -2.12.2 - -From 93a82f8dbef8ee421fac80a1bd0564124a8ac41c Mon Sep 17 00:00:00 2001 -From: Matt Redfearn -Date: Mon, 19 Dec 2016 14:20:58 +0000 -Subject: [PATCH 40/52] MIPS: Only change $28 to thread_info if coming from - user mode -Content-Length: 2181 -Lines: 60 - -commit 510d86362a27577f5ee23f46cfb354ad49731e61 upstream. - -The SAVE_SOME macro is used to save the execution context on all -exceptions. -If an exception occurs while executing user code, the stack is switched -to the kernel's stack for the current task, and register $28 is switched -to point to the current_thread_info, which is at the bottom of the stack -region. -If the exception occurs while executing kernel code, the stack is left, -and this change ensures that register $28 is not updated. This is the -correct behaviour when the kernel can be executing on the separate irq -stack, because the thread_info will not be at the base of it. - -With this change, register $28 is only switched to it's kernel -conventional usage of the currrent thread info pointer at the point at -which execution enters kernel space. Doing it on every exception was -redundant, but OK without an IRQ stack, but will be erroneous once that -is introduced. - -Signed-off-by: Matt Redfearn -Acked-by: Jason A. Donenfeld -Cc: Thomas Gleixner -Cc: James Hogan -Cc: Paul Burton -Cc: linux-mips@linux-mips.org -Cc: linux-kernel@vger.kernel.org -Patchwork: https://patchwork.linux-mips.org/patch/14742/ -Signed-off-by: Ralf Baechle -Signed-off-by: Amit Pundir -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/include/asm/stackframe.h | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h -index a71da576883c..5347f130f536 100644 ---- a/arch/mips/include/asm/stackframe.h -+++ b/arch/mips/include/asm/stackframe.h -@@ -216,12 +216,19 @@ - LONG_S $25, PT_R25(sp) - LONG_S $28, PT_R28(sp) - LONG_S $31, PT_R31(sp) -+ -+ /* Set thread_info if we're coming from user mode */ -+ mfc0 k0, CP0_STATUS -+ sll k0, 3 /* extract cu0 bit */ -+ bltz k0, 9f -+ - ori $28, sp, _THREAD_MASK - xori $28, _THREAD_MASK - #ifdef CONFIG_CPU_CAVIUM_OCTEON - .set mips64 - pref 0, 0($28) /* Prefetch the current pointer */ - #endif -+9: - .set pop - .endm - --- -2.12.2 - -From 3363653512853754fcc7592d2c68c4769a4825c9 Mon Sep 17 00:00:00 2001 -From: Matt Redfearn -Date: Mon, 19 Dec 2016 14:20:57 +0000 -Subject: [PATCH 39/52] MIPS: Stack unwinding while on IRQ stack -Content-Length: 2025 -Lines: 62 - -commit d42d8d106b0275b027c1e8992c42aecf933436ea upstream. - -Within unwind stack, check if the stack pointer being unwound is within -the CPU's irq_stack and if so use that page rather than the task's stack -page. - -Signed-off-by: Matt Redfearn -Acked-by: Jason A. Donenfeld -Cc: Thomas Gleixner -Cc: Adam Buchbinder -Cc: Maciej W. Rozycki -Cc: Marcin Nowakowski -Cc: Chris Metcalf -Cc: James Hogan -Cc: Paul Burton -Cc: Jiri Slaby -Cc: Andrew Morton -Cc: linux-mips@linux-mips.org -Cc: linux-kernel@vger.kernel.org -Patchwork: https://patchwork.linux-mips.org/patch/14741/ -Signed-off-by: Ralf Baechle -Signed-off-by: Amit Pundir -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/kernel/process.c | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - -diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c -index fc537d1b649d..8c26ecac930d 100644 ---- a/arch/mips/kernel/process.c -+++ b/arch/mips/kernel/process.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -552,7 +553,19 @@ EXPORT_SYMBOL(unwind_stack_by_address); - unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, - unsigned long pc, unsigned long *ra) - { -- unsigned long stack_page = (unsigned long)task_stack_page(task); -+ unsigned long stack_page = 0; -+ int cpu; -+ -+ for_each_possible_cpu(cpu) { -+ if (on_irq_stack(cpu, *sp)) { -+ stack_page = (unsigned long)irq_stack[cpu]; -+ break; -+ } -+ } -+ -+ if (!stack_page) -+ stack_page = (unsigned long)task_stack_page(task); -+ - return unwind_stack_by_address(stack_page, sp, pc, ra); - } - #endif --- -2.12.2 - -From d8b8b5528ea5a394074a91e37571bcca081b27e1 Mon Sep 17 00:00:00 2001 -From: Matt Redfearn -Date: Mon, 19 Dec 2016 14:20:56 +0000 -Subject: [PATCH 38/52] MIPS: Introduce irq_stack -Content-Length: 2919 -Lines: 95 - -commit fe8bd18ffea5327344d4ec2bf11f47951212abd0 upstream. - -Allocate a per-cpu irq stack for use within interrupt handlers. - -Also add a utility function on_irq_stack to determine if a given stack -pointer is within the irq stack for that cpu. - -Signed-off-by: Matt Redfearn -Acked-by: Jason A. Donenfeld -Cc: Thomas Gleixner -Cc: Paolo Bonzini -Cc: Chris Metcalf -Cc: Petr Mladek -Cc: James Hogan -Cc: Paul Burton -Cc: Aaron Tomlin -Cc: Andrew Morton -Cc: linux-kernel@vger.kernel.org -Cc: linux-mips@linux-mips.org -Patchwork: https://patchwork.linux-mips.org/patch/14740/ -Signed-off-by: Ralf Baechle -Signed-off-by: Amit Pundir -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/include/asm/irq.h | 12 ++++++++++++ - arch/mips/kernel/asm-offsets.c | 1 + - arch/mips/kernel/irq.c | 11 +++++++++++ - 3 files changed, 24 insertions(+) - -diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h -index 15e0fecbc300..ebb9efb02502 100644 ---- a/arch/mips/include/asm/irq.h -+++ b/arch/mips/include/asm/irq.h -@@ -17,6 +17,18 @@ - - #include - -+#define IRQ_STACK_SIZE THREAD_SIZE -+ -+extern void *irq_stack[NR_CPUS]; -+ -+static inline bool on_irq_stack(int cpu, unsigned long sp) -+{ -+ unsigned long low = (unsigned long)irq_stack[cpu]; -+ unsigned long high = low + IRQ_STACK_SIZE; -+ -+ return (low <= sp && sp <= high); -+} -+ - #ifdef CONFIG_I8259 - static inline int irq_canonicalize(int irq) - { -diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c -index 154e2039ea5e..ec053ce7bb38 100644 ---- a/arch/mips/kernel/asm-offsets.c -+++ b/arch/mips/kernel/asm-offsets.c -@@ -101,6 +101,7 @@ void output_thread_info_defines(void) - OFFSET(TI_REGS, thread_info, regs); - DEFINE(_THREAD_SIZE, THREAD_SIZE); - DEFINE(_THREAD_MASK, THREAD_MASK); -+ DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE); - BLANK(); - } - -diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c -index 8eb5af805964..dc1180a8bfa1 100644 ---- a/arch/mips/kernel/irq.c -+++ b/arch/mips/kernel/irq.c -@@ -25,6 +25,8 @@ - #include - #include - -+void *irq_stack[NR_CPUS]; -+ - /* - * 'what should we do if we get a hw irq event on an illegal vector'. - * each architecture has to answer this themselves. -@@ -55,6 +57,15 @@ void __init init_IRQ(void) - irq_set_noprobe(i); - - arch_init_irq(); -+ -+ for_each_possible_cpu(i) { -+ int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE; -+ void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages); -+ -+ irq_stack[i] = s; -+ pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i, -+ irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE); -+ } - } - - #ifdef CONFIG_DEBUG_STACKOVERFLOW --- -2.12.2 - -From 5a527d80836e9ad0dc3dceee7de72f16c817fb8b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 20 Nov 2016 16:09:30 +0100 -Subject: [PATCH 37/52] mtd: bcm47xxpart: fix parsing first block after aligned - TRX -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Content-Length: 1364 -Lines: 40 - -commit bd5d21310133921021d78995ad6346f908483124 upstream. - -After parsing TRX we should skip to the first block placed behind it. -Our code was working only with TRX with length not aligned to the -blocksize. In other cases (length aligned) it was missing the block -places right after TRX. - -This fixes calculation and simplifies the comment. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Brian Norris -Signed-off-by: Amit Pundir -Signed-off-by: Greg Kroah-Hartman ---- - drivers/mtd/bcm47xxpart.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c -index c0720c1ee4c9..5abab8800891 100644 ---- a/drivers/mtd/bcm47xxpart.c -+++ b/drivers/mtd/bcm47xxpart.c -@@ -225,12 +225,10 @@ static int bcm47xxpart_parse(struct mtd_info *master, - - last_trx_part = curr_part - 1; - -- /* -- * We have whole TRX scanned, skip to the next part. Use -- * roundown (not roundup), as the loop will increase -- * offset in next step. -- */ -- offset = rounddown(offset + trx->length, blocksize); -+ /* Jump to the end of TRX */ -+ offset = roundup(offset + trx->length, blocksize); -+ /* Next loop iteration will increase the offset */ -+ offset -= blocksize; - continue; - } - --- -2.12.2 - -From 8cfaf0ae1f566ddfcda661bd81b625a71b16459a Mon Sep 17 00:00:00 2001 -From: Chris Wilson -Date: Mon, 13 Mar 2017 17:06:17 +0000 -Subject: [PATCH 35/52] drm/i915: Stop using RP_DOWN_EI on Baytrail -Content-Length: 6512 -Lines: 177 - -commit 8f68d591d4765b2e1ce9d916ac7bc5583285c4ad upstream. - -On Baytrail, we manually calculate busyness over the evaluation interval -to avoid issues with miscaluations with RC6 enabled. However, it turns -out that the DOWN_EI interrupt generator is completely bust - it -operates in two modes, continuous or never. Neither of which are -conducive to good behaviour. Stop unmask the DOWN_EI interrupt and just -compute everything from the UP_EI which does seem to correspond to the -desired interval. - -v2: Fixup gen6_rps_pm_mask() as well -v3: Inline vlv_c0_above() to combine the now identical elapsed -calculation for up/down and simplify the threshold testing - -Fixes: 43cf3bf084ba ("drm/i915: Improved w/a for rps on Baytrail") -Signed-off-by: Chris Wilson -Cc: Mika Kuoppala -Link: http://patchwork.freedesktop.org/patch/msgid/20170309211232.28878-1-chris@chris-wilson.co.uk -Reviewed-by: Mika Kuoppala -Link: http://patchwork.freedesktop.org/patch/msgid/20170313170617.31564-1-chris@chris-wilson.co.uk -(cherry picked from commit e0e8c7cb6eb68e9256de2d8cbeb481d3701c05ac) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman ---- - drivers/gpu/drm/i915/i915_drv.h | 2 +- - drivers/gpu/drm/i915/i915_irq.c | 73 ++++++++++++++++------------------------- - drivers/gpu/drm/i915/intel_pm.c | 5 +-- - 3 files changed, 32 insertions(+), 48 deletions(-) - -diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h -index fb9f647bb5cd..5044f2257e89 100644 ---- a/drivers/gpu/drm/i915/i915_drv.h -+++ b/drivers/gpu/drm/i915/i915_drv.h -@@ -1159,7 +1159,7 @@ struct intel_gen6_power_mgmt { - struct intel_rps_client semaphores, mmioflips; - - /* manual wa residency calculations */ -- struct intel_rps_ei up_ei, down_ei; -+ struct intel_rps_ei ei; - - /* - * Protects RPS/RC6 register access and PCU communication. -diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c -index 0f42a2782afc..b7b0a38acd67 100644 ---- a/drivers/gpu/drm/i915/i915_irq.c -+++ b/drivers/gpu/drm/i915/i915_irq.c -@@ -994,68 +994,51 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv, - ei->media_c0 = I915_READ(VLV_MEDIA_C0_COUNT); - } - --static bool vlv_c0_above(struct drm_i915_private *dev_priv, -- const struct intel_rps_ei *old, -- const struct intel_rps_ei *now, -- int threshold) --{ -- u64 time, c0; -- unsigned int mul = 100; -- -- if (old->cz_clock == 0) -- return false; -- -- if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) -- mul <<= 8; -- -- time = now->cz_clock - old->cz_clock; -- time *= threshold * dev_priv->czclk_freq; -- -- /* Workload can be split between render + media, e.g. SwapBuffers -- * being blitted in X after being rendered in mesa. To account for -- * this we need to combine both engines into our activity counter. -- */ -- c0 = now->render_c0 - old->render_c0; -- c0 += now->media_c0 - old->media_c0; -- c0 *= mul * VLV_CZ_CLOCK_TO_MILLI_SEC; -- -- return c0 >= time; --} -- - void gen6_rps_reset_ei(struct drm_i915_private *dev_priv) - { -- vlv_c0_read(dev_priv, &dev_priv->rps.down_ei); -- dev_priv->rps.up_ei = dev_priv->rps.down_ei; -+ memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei)); - } - - static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) - { -+ const struct intel_rps_ei *prev = &dev_priv->rps.ei; - struct intel_rps_ei now; - u32 events = 0; - -- if ((pm_iir & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) == 0) -+ if ((pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) == 0) - return 0; - - vlv_c0_read(dev_priv, &now); - if (now.cz_clock == 0) - return 0; - -- if (pm_iir & GEN6_PM_RP_DOWN_EI_EXPIRED) { -- if (!vlv_c0_above(dev_priv, -- &dev_priv->rps.down_ei, &now, -- dev_priv->rps.down_threshold)) -- events |= GEN6_PM_RP_DOWN_THRESHOLD; -- dev_priv->rps.down_ei = now; -- } -+ if (prev->cz_clock) { -+ u64 time, c0; -+ unsigned int mul; - -- if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) { -- if (vlv_c0_above(dev_priv, -- &dev_priv->rps.up_ei, &now, -- dev_priv->rps.up_threshold)) -- events |= GEN6_PM_RP_UP_THRESHOLD; -- dev_priv->rps.up_ei = now; -+ mul = VLV_CZ_CLOCK_TO_MILLI_SEC * 100; /* scale to threshold% */ -+ if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) -+ mul <<= 8; -+ -+ time = now.cz_clock - prev->cz_clock; -+ time *= dev_priv->czclk_freq; -+ -+ /* Workload can be split between render + media, -+ * e.g. SwapBuffers being blitted in X after being rendered in -+ * mesa. To account for this we need to combine both engines -+ * into our activity counter. -+ */ -+ c0 = now.render_c0 - prev->render_c0; -+ c0 += now.media_c0 - prev->media_c0; -+ c0 *= mul; -+ -+ if (c0 > time * dev_priv->rps.up_threshold) -+ events = GEN6_PM_RP_UP_THRESHOLD; -+ else if (c0 < time * dev_priv->rps.down_threshold) -+ events = GEN6_PM_RP_DOWN_THRESHOLD; - } - -+ dev_priv->rps.ei = now; - return events; - } - -@@ -4390,7 +4373,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) - /* Let's track the enabled rps events */ - if (IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) - /* WaGsvRC0ResidencyMethod:vlv */ -- dev_priv->pm_rps_events = GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED; -+ dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; - else - dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; - -diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c -index e4031fcac4bf..fd4690ed93c0 100644 ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -4411,8 +4411,9 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) - { - u32 mask = 0; - -+ /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */ - if (val > dev_priv->rps.min_freq_softlimit) -- mask |= GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; -+ mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; - if (val < dev_priv->rps.max_freq_softlimit) - mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD; - -@@ -4516,7 +4517,7 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) - { - mutex_lock(&dev_priv->rps.hw_lock); - if (dev_priv->rps.enabled) { -- if (dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) -+ if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED) - gen6_rps_reset_ei(dev_priv); - I915_WRITE(GEN6_PMINTRMSK, - gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); --- -2.12.2 - -From cb0a2cba62d58caf6668f630858acc15ed40ee23 Mon Sep 17 00:00:00 2001 -From: Mika Kuoppala -Date: Wed, 15 Feb 2017 15:52:59 +0200 -Subject: [PATCH 34/52] drm/i915: Avoid tweaking evaluation thresholds on - Baytrail v3 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Content-Length: 3679 -Lines: 88 - -commit 34dc8993eef63681b062871413a9484008a2a78f upstream. - -Certain Baytrails, namely the 4 cpu core variants, have been -plaqued by spurious system hangs, mostly occurring with light loads. - -Multiple bisects by various people point to a commit which changes the -reclocking strategy for Baytrail to follow its bigger brethen: -commit 8fb55197e64d ("drm/i915: Agressive downclocking on Baytrail") - -There is also a review comment attached to this commit from Deepak S -on avoiding punit access on Cherryview and thus it was excluded on -common reclocking path. By taking the same approach and omitting -the punit access by not tweaking the thresholds when the hardware -has been asked to move into different frequency, considerable gains -in stability have been observed. - -With J1900 box, light render/video load would end up in system hang -in usually less than 12 hours. With this patch applied, the cumulative -uptime has now been 34 days without issues. To provoke system hang, -light loads on both render and bsd engines in parallel have been used: -glxgears >/dev/null 2>/dev/null & -mpv --vo=vaapi --hwdec=vaapi --loop=inf vid.mp4 - -So far, author has not witnessed system hang with above load -and this patch applied. Reports from the tenacious people at -kernel bugzilla are also promising. - -Considering that the punit access frequency with this patch is -considerably less, there is a possibility that this will push -the, still unknown, root cause past the triggering point on most loads. - -But as we now can reliably reproduce the hang independently, -we can reduce the pain that users are having and use a -static thresholds until a root cause is found. - -v3: don't break debugfs and simplification (Chris Wilson) - -References: https://bugzilla.kernel.org/show_bug.cgi?id=109051 -Cc: Chris Wilson -Cc: Ville Syrjälä -Cc: Len Brown -Cc: Daniel Vetter -Cc: Jani Nikula -Cc: fritsch@xbmc.org -Cc: miku@iki.fi -Cc: Ezequiel Garcia -CC: Michal Feix -Cc: Hans de Goede -Cc: Deepak S -Cc: Jarkko Nikula -Acked-by: Daniel Vetter -Acked-by: Chris Wilson -Signed-off-by: Mika Kuoppala -Link: http://patchwork.freedesktop.org/patch/msgid/1487166779-26945-1-git-send-email-mika.kuoppala@intel.com -(cherry picked from commit 6067a27d1f0184596d51decbac1c1fdc4acb012f) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman ---- - drivers/gpu/drm/i915/intel_pm.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c -index e7c18519274a..e4031fcac4bf 100644 ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -4376,6 +4376,12 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) - break; - } - -+ /* When byt can survive without system hang with dynamic -+ * sw freq adjustments, this restriction can be lifted. -+ */ -+ if (IS_VALLEYVIEW(dev_priv)) -+ goto skip_hw_write; -+ - I915_WRITE(GEN6_RP_UP_EI, - GT_INTERVAL_FROM_US(dev_priv, ei_up)); - I915_WRITE(GEN6_RP_UP_THRESHOLD, -@@ -4394,6 +4400,7 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) - GEN6_RP_UP_BUSY_AVG | - GEN6_RP_DOWN_IDLE_AVG); - -+skip_hw_write: - dev_priv->rps.power = new_power; - dev_priv->rps.up_threshold = threshold_up; - dev_priv->rps.down_threshold = threshold_down; --- -2.12.2 - -From ec5e61608ad1919c1ff3cc0369dbf1b1ede9eb88 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Wed, 12 Apr 2017 12:38:50 +0200 -Subject: [PATCH 33/52] Linux 4.4.61 -Status: RO -Content-Length: 301 -Lines: 18 - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index fb7c2b40753d..ef5045b8201d 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 4 - PATCHLEVEL = 4 --SUBLEVEL = 60 -+SUBLEVEL = 61 - EXTRAVERSION = - NAME = Blurry Fish Butt - --- -2.12.2 - -From b73d08ce20c5cb2e0cec8c019a27b9574e2c4ec2 Mon Sep 17 00:00:00 2001 -From: Chris Salls -Date: Fri, 7 Apr 2017 23:48:11 -0700 -Subject: [PATCH 32/52] mm/mempolicy.c: fix error handling in set_mempolicy and - mbind. -Content-Length: 2383 -Lines: 73 - -commit cf01fb9985e8deb25ccf0ea54d916b8871ae0e62 upstream. - -In the case that compat_get_bitmap fails we do not want to copy the -bitmap to the user as it will contain uninitialized stack data and leak -sensitive data. - -Signed-off-by: Chris Salls -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman ---- - mm/mempolicy.c | 20 ++++++++------------ - 1 file changed, 8 insertions(+), 12 deletions(-) - -diff --git a/mm/mempolicy.c b/mm/mempolicy.c -index a4217fe60dff..e09b1a0e2cfe 100644 ---- a/mm/mempolicy.c -+++ b/mm/mempolicy.c -@@ -1492,7 +1492,6 @@ COMPAT_SYSCALL_DEFINE5(get_mempolicy, int __user *, policy, - COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask, - compat_ulong_t, maxnode) - { -- long err = 0; - unsigned long __user *nm = NULL; - unsigned long nr_bits, alloc_size; - DECLARE_BITMAP(bm, MAX_NUMNODES); -@@ -1501,14 +1500,13 @@ COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask, - alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; - - if (nmask) { -- err = compat_get_bitmap(bm, nmask, nr_bits); -+ if (compat_get_bitmap(bm, nmask, nr_bits)) -+ return -EFAULT; - nm = compat_alloc_user_space(alloc_size); -- err |= copy_to_user(nm, bm, alloc_size); -+ if (copy_to_user(nm, bm, alloc_size)) -+ return -EFAULT; - } - -- if (err) -- return -EFAULT; -- - return sys_set_mempolicy(mode, nm, nr_bits+1); - } - -@@ -1516,7 +1514,6 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, compat_ulong_t, len, - compat_ulong_t, mode, compat_ulong_t __user *, nmask, - compat_ulong_t, maxnode, compat_ulong_t, flags) - { -- long err = 0; - unsigned long __user *nm = NULL; - unsigned long nr_bits, alloc_size; - nodemask_t bm; -@@ -1525,14 +1522,13 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, compat_ulong_t, len, - alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; - - if (nmask) { -- err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits); -+ if (compat_get_bitmap(nodes_addr(bm), nmask, nr_bits)) -+ return -EFAULT; - nm = compat_alloc_user_space(alloc_size); -- err |= copy_to_user(nm, nodes_addr(bm), alloc_size); -+ if (copy_to_user(nm, nodes_addr(bm), alloc_size)) -+ return -EFAULT; - } - -- if (err) -- return -EFAULT; -- - return sys_mbind(start, len, mode, nm, nr_bits+1, flags); - } - --- -2.12.2 - -From 2d1af1b7025f96c86938af7f7c54d60adb4773fe Mon Sep 17 00:00:00 2001 -From: Huacai Chen -Date: Thu, 16 Mar 2017 21:00:27 +0800 -Subject: [PATCH 31/52] MIPS: Flush wrong invalid FTLB entry for huge page -Content-Length: 3637 -Lines: 98 - -commit 0115f6cbf26663c86496bc56eeea293f85b77897 upstream. - -On VTLB+FTLB platforms (such as Loongson-3A R2), FTLB's pagesize is -usually configured the same as PAGE_SIZE. In such a case, Huge page -entry is not suitable to write in FTLB. - -Unfortunately, when a huge page is created, its page table entries -haven't created immediately. Then the TLB refill handler will fetch an -invalid page table entry which has no "HUGE" bit, and this entry may be -written to FTLB. Since it is invalid, TLB load/store handler will then -use tlbwi to write the valid entry at the same place. However, the -valid entry is a huge page entry which isn't suitable for FTLB. - -Our solution is to modify build_huge_handler_tail. Flush the invalid -old entry (whether it is in FTLB or VTLB, this is in order to reduce -branches) and use tlbwr to write the valid new entry. - -Signed-off-by: Rui Wang -Signed-off-by: Huacai Chen -Cc: John Crispin -Cc: Steven J . Hill -Cc: Fuxin Zhang -Cc: Zhangjin Wu -Cc: Huacai Chen -Cc: linux-mips@linux-mips.org -Patchwork: https://patchwork.linux-mips.org/patch/15754/ -Signed-off-by: Ralf Baechle -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/mm/tlbex.c | 25 +++++++++++++++++++++---- - 1 file changed, 21 insertions(+), 4 deletions(-) - -diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c -index 29f73e00253d..63b7d6f82d24 100644 ---- a/arch/mips/mm/tlbex.c -+++ b/arch/mips/mm/tlbex.c -@@ -757,7 +757,8 @@ static void build_huge_update_entries(u32 **p, unsigned int pte, - static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, - struct uasm_label **l, - unsigned int pte, -- unsigned int ptr) -+ unsigned int ptr, -+ unsigned int flush) - { - #ifdef CONFIG_SMP - UASM_i_SC(p, pte, 0, ptr); -@@ -766,6 +767,22 @@ static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, - #else - UASM_i_SW(p, pte, 0, ptr); - #endif -+ if (cpu_has_ftlb && flush) { -+ BUG_ON(!cpu_has_tlbinv); -+ -+ UASM_i_MFC0(p, ptr, C0_ENTRYHI); -+ uasm_i_ori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); -+ UASM_i_MTC0(p, ptr, C0_ENTRYHI); -+ build_tlb_write_entry(p, l, r, tlb_indexed); -+ -+ uasm_i_xori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); -+ UASM_i_MTC0(p, ptr, C0_ENTRYHI); -+ build_huge_update_entries(p, pte, ptr); -+ build_huge_tlb_write_entry(p, l, r, pte, tlb_random, 0); -+ -+ return; -+ } -+ - build_huge_update_entries(p, pte, ptr); - build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0); - } -@@ -2082,7 +2099,7 @@ static void build_r4000_tlb_load_handler(void) - uasm_l_tlbl_goaround2(&l, p); - } - uasm_i_ori(&p, wr.r1, wr.r1, (_PAGE_ACCESSED | _PAGE_VALID)); -- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); -+ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); - #endif - - uasm_l_nopage_tlbl(&l, p); -@@ -2137,7 +2154,7 @@ static void build_r4000_tlb_store_handler(void) - build_tlb_probe_entry(&p); - uasm_i_ori(&p, wr.r1, wr.r1, - _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); -- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); -+ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); - #endif - - uasm_l_nopage_tlbs(&l, p); -@@ -2193,7 +2210,7 @@ static void build_r4000_tlb_modify_handler(void) - build_tlb_probe_entry(&p); - uasm_i_ori(&p, wr.r1, wr.r1, - _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); -- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); -+ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 0); - #endif - - uasm_l_nopage_tlbm(&l, p); --- -2.12.2 - -From 55f67b97ca05df00c3b61123a7e9e363819c60ee Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Wed, 15 Mar 2017 23:26:42 +0100 -Subject: [PATCH 30/52] MIPS: Lantiq: fix missing xbar kernel panic -Content-Length: 1672 -Lines: 41 - -commit 6ef90877eee63a0d03e83183bb44b64229b624e6 upstream. - -Commit 08b3c894e565 ("MIPS: lantiq: Disable xbar fpi burst mode") -accidentally requested the resources from the pmu address region -instead of the xbar registers region, but the check for the return -value of request_mem_region() was wrong. Commit 98ea51cb0c8c ("MIPS: -Lantiq: Fix another request_mem_region() return code check") fixed the -check of the return value of request_mem_region() which made the kernel -panics. -This patch now makes use of the correct memory region for the cross bar. - -Fixes: 08b3c894e565 ("MIPS: lantiq: Disable xbar fpi burst mode") -Signed-off-by: Hauke Mehrtens -Cc: John Crispin -Cc: james.hogan@imgtec.com -Cc: arnd@arndb.de -Cc: sergei.shtylyov@cogentembedded.com -Cc: john@phrozen.org -Cc: linux-mips@linux-mips.org -Patchwork: https://patchwork.linux-mips.org/patch/15751 -Signed-off-by: Ralf Baechle -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/lantiq/xway/sysctrl.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c -index 3e390a4e3897..daf580ce5ca2 100644 ---- a/arch/mips/lantiq/xway/sysctrl.c -+++ b/arch/mips/lantiq/xway/sysctrl.c -@@ -467,7 +467,7 @@ void __init ltq_soc_init(void) - - if (!np_xbar) - panic("Failed to load xbar nodes from devicetree"); -- if (of_address_to_resource(np_pmu, 0, &res_xbar)) -+ if (of_address_to_resource(np_xbar, 0, &res_xbar)) - panic("Failed to get xbar resources"); - if (request_mem_region(res_xbar.start, resource_size(&res_xbar), - res_xbar.name) < 0) --- -2.12.2 - -From 768019030ab58e9622caeb6c5a06553260609327 Mon Sep 17 00:00:00 2001 -From: Paul Burton -Date: Thu, 23 Feb 2017 14:50:24 +0000 -Subject: [PATCH 29/52] MIPS: End spinlocks with .insn -Content-Length: 2774 -Lines: 73 - -commit 4b5347a24a0f2d3272032c120664b484478455de upstream. - -When building for microMIPS we need to ensure that the assembler always -knows that there is code at the target of a branch or jump. Recent -toolchains will fail to link a microMIPS kernel when this isn't the case -due to what it thinks is a branch to non-microMIPS code. - -mips-mti-linux-gnu-ld kernel/built-in.o: .spinlock.text+0x2fc: Unsupported branch between ISA modes. -mips-mti-linux-gnu-ld final link failed: Bad value - -This is due to inline assembly labels in spinlock.h not being followed -by an instruction mnemonic, either due to a .subsection pseudo-op or the -end of the inline asm block. - -Fix this with a .insn direction after such labels. - -Signed-off-by: Paul Burton -Signed-off-by: James Hogan -Reviewed-by: Maciej W. Rozycki -Cc: Ralf Baechle -Cc: Peter Zijlstra -Cc: Ingo Molnar -Cc: linux-mips@linux-mips.org -Cc: linux-kernel@vger.kernel.org -Patchwork: https://patchwork.linux-mips.org/patch/15325/ -Signed-off-by: James Hogan -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/include/asm/spinlock.h | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h -index 40196bebe849..2365ce0ad8f2 100644 ---- a/arch/mips/include/asm/spinlock.h -+++ b/arch/mips/include/asm/spinlock.h -@@ -112,7 +112,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) - " andi %[ticket], %[ticket], 0xffff \n" - " bne %[ticket], %[my_ticket], 4f \n" - " subu %[ticket], %[my_ticket], %[ticket] \n" -- "2: \n" -+ "2: .insn \n" - " .subsection 2 \n" - "4: andi %[ticket], %[ticket], 0xffff \n" - " sll %[ticket], 5 \n" -@@ -187,7 +187,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) - " sc %[ticket], %[ticket_ptr] \n" - " beqz %[ticket], 1b \n" - " li %[ticket], 1 \n" -- "2: \n" -+ "2: .insn \n" - " .subsection 2 \n" - "3: b 2b \n" - " li %[ticket], 0 \n" -@@ -367,7 +367,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) - " .set reorder \n" - __WEAK_LLSC_MB - " li %2, 1 \n" -- "2: \n" -+ "2: .insn \n" - : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) - : GCC_OFF_SMALL_ASM() (rw->lock) - : "memory"); -@@ -407,7 +407,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) - " lui %1, 0x8000 \n" - " sc %1, %0 \n" - " li %2, 1 \n" -- "2: \n" -+ "2: .insn \n" - : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), - "=&r" (ret) - : GCC_OFF_SMALL_ASM() (rw->lock) --- -2.12.2 - -From 22665fe0a60a73734889e1cfc7f8fba4036e0b9a Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sat, 25 Feb 2017 11:54:23 +0100 -Subject: [PATCH 28/52] MIPS: ralink: Fix typos in rt3883 pinctrl -Content-Length: 1801 -Lines: 40 - -commit 7c5a3d813050ee235817b0220dd8c42359a9efd8 upstream. - -There are two copy & paste errors in the definition of the 5GHz LNA and -second ethernet pinmux. - -Fixes: f576fb6a0700 ("MIPS: ralink: cleanup the soc specific pinmux data") -Signed-off-by: John Crispin -Signed-off-by: Daniel Golle -Cc: linux-mips@linux-mips.org -Patchwork: https://patchwork.linux-mips.org/patch/15328/ -Signed-off-by: James Hogan -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/ralink/rt3883.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c -index f42834c7f007..3c575093f8f1 100644 ---- a/arch/mips/ralink/rt3883.c -+++ b/arch/mips/ralink/rt3883.c -@@ -36,7 +36,7 @@ static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; - static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; - static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; - static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) }; --static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) }; -+static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna g", 0, 35, 3) }; - static struct rt2880_pmx_func pci_func[] = { - FUNC("pci-dev", 0, 40, 32), - FUNC("pci-host2", 1, 40, 32), -@@ -44,7 +44,7 @@ static struct rt2880_pmx_func pci_func[] = { - FUNC("pci-fnc", 3, 40, 32) - }; - static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) }; --static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) }; -+static struct rt2880_pmx_func ge2_func[] = { FUNC("ge2", 0, 84, 12) }; - - static struct rt2880_pmx_group rt3883_pinmux_data[] = { - GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C), --- -2.12.2 - -From 394d71b1ea24c248a8d497d10635b86dd2fccef7 Mon Sep 17 00:00:00 2001 -From: James Hogan -Date: Thu, 16 Feb 2017 12:39:01 +0000 -Subject: [PATCH 27/52] MIPS: Force o32 fp64 support on 32bit MIPS64r6 kernels -Content-Length: 1610 -Lines: 42 - -commit 2e6c7747730296a6d4fd700894286db1132598c4 upstream. - -When a 32-bit kernel is configured to support MIPS64r6 (CPU_MIPS64_R6), -MIPS_O32_FP64_SUPPORT won't be selected as it should be because -MIPS32_O32 is disabled (o32 is already the default ABI available on -32-bit kernels). - -This results in userland FP breakage as CP0_Status.FR is read-only 1 -since r6 (when an FPU is present) so __enable_fpu() will fail to clear -FR. This causes the FPU emulator to get used which will incorrectly -emulate 32-bit FPU registers. - -Force o32 fp64 support in this case by also selecting -MIPS_O32_FP64_SUPPORT from CPU_MIPS64_R6 if 32BIT. - -Fixes: 4e9d324d4288 ("MIPS: Require O32 FP64 support for MIPS64 with O32 compat") -Signed-off-by: James Hogan -Reviewed-by: Paul Burton -Cc: Ralf Baechle -Cc: linux-mips@linux-mips.org -Patchwork: https://patchwork.linux-mips.org/patch/15310/ -Signed-off-by: James Hogan -Signed-off-by: Greg Kroah-Hartman ---- - arch/mips/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index db459612de44..75bfca69e418 100644 ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -1412,7 +1412,7 @@ config CPU_MIPS32_R6 - select CPU_SUPPORTS_MSA - select GENERIC_CSUM - select HAVE_KVM -- select MIPS_O32_FP64_SUPPORT -+ select MIPS_O32_FP64_SUPPORT if 32BIT - help - Choose this option to build a kernel for release 6 or later of the - MIPS32 architecture. New MIPS processors, starting with the Warrior --- -2.12.2 - -From 435cc436a88652046b9ca89fb56acf3a4b1a44b8 Mon Sep 17 00:00:00 2001 -From: James Hogan -Date: Tue, 4 Apr 2017 08:51:34 +0100 -Subject: [PATCH 21/52] metag/usercopy: Add missing fixups -Content-Length: 4904 -Lines: 163 - -commit b884a190afcecdbef34ca508ea5ee88bb7c77861 upstream. - -The rapf copy loops in the Meta usercopy code is missing some extable -entries for HTP cores with unaligned access checking enabled, where -faults occur on the instruction immediately after the faulting access. - -Add the fixup labels and extable entries for these cases so that corner -case user copy failures don't cause kernel crashes. - -Fixes: 373cd784d0fc ("metag: Memory handling") -Signed-off-by: James Hogan -Cc: linux-metag@vger.kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - arch/metag/lib/usercopy.c | 72 +++++++++++++++++++++++++++++++---------------- - 1 file changed, 48 insertions(+), 24 deletions(-) - -diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c -index e09c95ba028c..2792fc621088 100644 ---- a/arch/metag/lib/usercopy.c -+++ b/arch/metag/lib/usercopy.c -@@ -259,27 +259,31 @@ - "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "22:\n" \ - "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -- "SUB %3, %3, #32\n" \ - "23:\n" \ -- "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -+ "SUB %3, %3, #32\n" \ - "24:\n" \ -+ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -+ "25:\n" \ - "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -+ "26:\n" \ - "SUB %3, %3, #32\n" \ - "DCACHE [%1+#-64], D0Ar6\n" \ - "BR $Lloop"id"\n" \ - \ - "MOV RAPF, %1\n" \ -- "25:\n" \ -+ "27:\n" \ - "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -- "26:\n" \ -+ "28:\n" \ - "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -+ "29:\n" \ - "SUB %3, %3, #32\n" \ -- "27:\n" \ -+ "30:\n" \ - "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -- "28:\n" \ -+ "31:\n" \ - "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -+ "32:\n" \ - "SUB %0, %0, #8\n" \ -- "29:\n" \ -+ "33:\n" \ - "SETL [%0++], D0.7, D1.7\n" \ - "SUB %3, %3, #32\n" \ - "1:" \ -@@ -311,7 +315,11 @@ - " .long 26b,3b\n" \ - " .long 27b,3b\n" \ - " .long 28b,3b\n" \ -- " .long 29b,4b\n" \ -+ " .long 29b,3b\n" \ -+ " .long 30b,3b\n" \ -+ " .long 31b,3b\n" \ -+ " .long 32b,3b\n" \ -+ " .long 33b,4b\n" \ - " .previous\n" \ - : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ - : "0" (to), "1" (from), "2" (ret), "3" (n) \ -@@ -402,47 +410,55 @@ - "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "22:\n" \ - "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -- "SUB %3, %3, #16\n" \ - "23:\n" \ -- "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -- "24:\n" \ -- "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ - "SUB %3, %3, #16\n" \ -- "25:\n" \ -+ "24:\n" \ - "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -- "26:\n" \ -+ "25:\n" \ - "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -+ "26:\n" \ - "SUB %3, %3, #16\n" \ - "27:\n" \ - "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "28:\n" \ - "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -+ "29:\n" \ -+ "SUB %3, %3, #16\n" \ -+ "30:\n" \ -+ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -+ "31:\n" \ -+ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -+ "32:\n" \ - "SUB %3, %3, #16\n" \ - "DCACHE [%1+#-64], D0Ar6\n" \ - "BR $Lloop"id"\n" \ - \ - "MOV RAPF, %1\n" \ -- "29:\n" \ -+ "33:\n" \ - "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -- "30:\n" \ -+ "34:\n" \ - "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -+ "35:\n" \ - "SUB %3, %3, #16\n" \ -- "31:\n" \ -+ "36:\n" \ - "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -- "32:\n" \ -+ "37:\n" \ - "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -+ "38:\n" \ - "SUB %3, %3, #16\n" \ -- "33:\n" \ -+ "39:\n" \ - "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -- "34:\n" \ -+ "40:\n" \ - "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -+ "41:\n" \ - "SUB %3, %3, #16\n" \ -- "35:\n" \ -+ "42:\n" \ - "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ -- "36:\n" \ -+ "43:\n" \ - "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ -+ "44:\n" \ - "SUB %0, %0, #4\n" \ -- "37:\n" \ -+ "45:\n" \ - "SETD [%0++], D0.7\n" \ - "SUB %3, %3, #16\n" \ - "1:" \ -@@ -482,7 +498,15 @@ - " .long 34b,3b\n" \ - " .long 35b,3b\n" \ - " .long 36b,3b\n" \ -- " .long 37b,4b\n" \ -+ " .long 37b,3b\n" \ -+ " .long 38b,3b\n" \ -+ " .long 39b,3b\n" \ -+ " .long 40b,3b\n" \ -+ " .long 41b,3b\n" \ -+ " .long 42b,3b\n" \ -+ " .long 43b,3b\n" \ -+ " .long 44b,3b\n" \ -+ " .long 45b,4b\n" \ - " .previous\n" \ - : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ - : "0" (to), "1" (from), "2" (ret), "3" (n) \ --- -2.12.2 - -From 3040ecd4253a4ef996e6f940801ee4b80b01c87a Mon Sep 17 00:00:00 2001 -From: James Hogan -Date: Mon, 3 Apr 2017 17:41:40 +0100 -Subject: [PATCH 20/52] metag/usercopy: Fix src fixup in from user rapf loops -Content-Length: 3332 -Lines: 85 - -commit 2c0b1df88b987a12d95ea1d6beaf01894f3cc725 upstream. - -The fixup code to rewind the source pointer in -__asm_copy_from_user_{32,64}bit_rapf_loop() always rewound the source by -a single unit (4 or 8 bytes), however this is insufficient if the fault -didn't occur on the first load in the loop, as the source pointer will -have been incremented but nothing will have been stored until all 4 -register [pairs] are loaded. - -Read the LSM_STEP field of TXSTATUS (which is already loaded into a -register), a bit like the copy_to_user versions, to determine how many -iterations of MGET[DL] have taken place, all of which need rewinding. - -Fixes: 373cd784d0fc ("metag: Memory handling") -Signed-off-by: James Hogan -Cc: linux-metag@vger.kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - arch/metag/lib/usercopy.c | 36 ++++++++++++++++++++++++++++-------- - 1 file changed, 28 insertions(+), 8 deletions(-) - -diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c -index 4422928a1746..e09c95ba028c 100644 ---- a/arch/metag/lib/usercopy.c -+++ b/arch/metag/lib/usercopy.c -@@ -687,29 +687,49 @@ EXPORT_SYMBOL(__copy_user); - * - * Rationale: - * A fault occurs while reading from user buffer, which is the -- * source. Since the fault is at a single address, we only -- * need to rewind by 8 bytes. -+ * source. - * Since we don't write to kernel buffer until we read first, - * the kernel buffer is at the right state and needn't be -- * corrected. -+ * corrected, but the source must be rewound to the beginning of -+ * the block, which is LSM_STEP*8 bytes. -+ * LSM_STEP is bits 10:8 in TXSTATUS which is already read -+ * and stored in D0Ar2 -+ * -+ * NOTE: If a fault occurs at the last operation in M{G,S}ETL -+ * LSM_STEP will be 0. ie: we do 4 writes in our case, if -+ * a fault happens at the 4th write, LSM_STEP will be 0 -+ * instead of 4. The code copes with that. - */ - #define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id) \ - __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ -- "SUB %1, %1, #8\n") -+ "LSR D0Ar2, D0Ar2, #5\n" \ -+ "ANDS D0Ar2, D0Ar2, #0x38\n" \ -+ "ADDZ D0Ar2, D0Ar2, #32\n" \ -+ "SUB %1, %1, D0Ar2\n") - - /* rewind 'from' pointer when a fault occurs - * - * Rationale: - * A fault occurs while reading from user buffer, which is the -- * source. Since the fault is at a single address, we only -- * need to rewind by 4 bytes. -+ * source. - * Since we don't write to kernel buffer until we read first, - * the kernel buffer is at the right state and needn't be -- * corrected. -+ * corrected, but the source must be rewound to the beginning of -+ * the block, which is LSM_STEP*4 bytes. -+ * LSM_STEP is bits 10:8 in TXSTATUS which is already read -+ * and stored in D0Ar2 -+ * -+ * NOTE: If a fault occurs at the last operation in M{G,S}ETL -+ * LSM_STEP will be 0. ie: we do 4 writes in our case, if -+ * a fault happens at the 4th write, LSM_STEP will be 0 -+ * instead of 4. The code copes with that. - */ - #define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id) \ - __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ -- "SUB %1, %1, #4\n") -+ "LSR D0Ar2, D0Ar2, #6\n" \ -+ "ANDS D0Ar2, D0Ar2, #0x1c\n" \ -+ "ADDZ D0Ar2, D0Ar2, #16\n" \ -+ "SUB %1, %1, D0Ar2\n") - - - /* --- -2.12.2 - -From beb0ad97ad099ac99f0354e195bd129586a60694 Mon Sep 17 00:00:00 2001 -From: James Hogan -Date: Tue, 4 Apr 2017 11:43:26 +0100 -Subject: [PATCH 19/52] metag/usercopy: Set flags before ADDZ -Content-Length: 2357 -Lines: 63 - -commit fd40eee1290ad7add7aa665e3ce6b0f9fe9734b4 upstream. - -The fixup code for the copy_to_user rapf loops reads TXStatus.LSM_STEP -to decide how far to rewind the source pointer. There is a special case -for the last execution of an MGETL/MGETD, since it leaves LSM_STEP=0 -even though the number of MGETLs/MGETDs attempted was 4. This uses ADDZ -which is conditional upon the Z condition flag, but the AND instruction -which masked the TXStatus.LSM_STEP field didn't set the condition flags -based on the result. - -Fix that now by using ANDS which does set the flags, and also marking -the condition codes as clobbered by the inline assembly. - -Fixes: 373cd784d0fc ("metag: Memory handling") -Signed-off-by: James Hogan -Cc: linux-metag@vger.kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - arch/metag/lib/usercopy.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c -index e1d553872fd7..4422928a1746 100644 ---- a/arch/metag/lib/usercopy.c -+++ b/arch/metag/lib/usercopy.c -@@ -315,7 +315,7 @@ - " .previous\n" \ - : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ - : "0" (to), "1" (from), "2" (ret), "3" (n) \ -- : "D1Ar1", "D0Ar2", "memory") -+ : "D1Ar1", "D0Ar2", "cc", "memory") - - /* rewind 'to' and 'from' pointers when a fault occurs - * -@@ -341,7 +341,7 @@ - #define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\ - __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ - "LSR D0Ar2, D0Ar2, #8\n" \ -- "AND D0Ar2, D0Ar2, #0x7\n" \ -+ "ANDS D0Ar2, D0Ar2, #0x7\n" \ - "ADDZ D0Ar2, D0Ar2, #4\n" \ - "SUB D0Ar2, D0Ar2, #1\n" \ - "MOV D1Ar1, #4\n" \ -@@ -486,7 +486,7 @@ - " .previous\n" \ - : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ - : "0" (to), "1" (from), "2" (ret), "3" (n) \ -- : "D1Ar1", "D0Ar2", "memory") -+ : "D1Ar1", "D0Ar2", "cc", "memory") - - /* rewind 'to' and 'from' pointers when a fault occurs - * -@@ -512,7 +512,7 @@ - #define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\ - __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ - "LSR D0Ar2, D0Ar2, #8\n" \ -- "AND D0Ar2, D0Ar2, #0x7\n" \ -+ "ANDS D0Ar2, D0Ar2, #0x7\n" \ - "ADDZ D0Ar2, D0Ar2, #4\n" \ - "SUB D0Ar2, D0Ar2, #1\n" \ - "MOV D1Ar1, #4\n" \ --- -2.12.2 - -From 29b5eb517c6961ea9e9b16c49b5cf7fd93860be2 Mon Sep 17 00:00:00 2001 -From: James Hogan -Date: Fri, 31 Mar 2017 11:14:02 +0100 -Subject: [PATCH 18/52] metag/usercopy: Zero rest of buffer from copy_from_user -Content-Length: 7463 -Lines: 230 - -commit 563ddc1076109f2b3f88e6d355eab7b6fd4662cb upstream. - -Currently we try to zero the destination for a failed read from userland -in fixup code in the usercopy.c macros. The rest of the destination -buffer is then zeroed from __copy_user_zeroing(), which is used for both -copy_from_user() and __copy_from_user(). - -Unfortunately we fail to zero in the fixup code as D1Ar1 is set to 0 -before the fixup code entry labels, and __copy_from_user() shouldn't even -be zeroing the rest of the buffer. - -Move the zeroing out into copy_from_user() and rename -__copy_user_zeroing() to raw_copy_from_user() since it no longer does -any zeroing. This also conveniently matches the name needed for -RAW_COPY_USER support in a later patch. - -Fixes: 373cd784d0fc ("metag: Memory handling") -Reported-by: Al Viro -Signed-off-by: James Hogan -Cc: linux-metag@vger.kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - arch/metag/include/asm/uaccess.h | 15 ++++++----- - arch/metag/lib/usercopy.c | 57 +++++++++++++--------------------------- - 2 files changed, 26 insertions(+), 46 deletions(-) - -diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h -index 273e61225c27..07238b39638c 100644 ---- a/arch/metag/include/asm/uaccess.h -+++ b/arch/metag/include/asm/uaccess.h -@@ -197,20 +197,21 @@ extern long __must_check strnlen_user(const char __user *src, long count); - - #define strlen_user(str) strnlen_user(str, 32767) - --extern unsigned long __must_check __copy_user_zeroing(void *to, -- const void __user *from, -- unsigned long n); -+extern unsigned long raw_copy_from_user(void *to, const void __user *from, -+ unsigned long n); - - static inline unsigned long - copy_from_user(void *to, const void __user *from, unsigned long n) - { -+ unsigned long res = n; - if (likely(access_ok(VERIFY_READ, from, n))) -- return __copy_user_zeroing(to, from, n); -- memset(to, 0, n); -- return n; -+ res = raw_copy_from_user(to, from, n); -+ if (unlikely(res)) -+ memset(to + (n - res), 0, res); -+ return res; - } - --#define __copy_from_user(to, from, n) __copy_user_zeroing(to, from, n) -+#define __copy_from_user(to, from, n) raw_copy_from_user(to, from, n) - #define __copy_from_user_inatomic __copy_from_user - - extern unsigned long __must_check __copy_user(void __user *to, -diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c -index 714d8562aa20..e1d553872fd7 100644 ---- a/arch/metag/lib/usercopy.c -+++ b/arch/metag/lib/usercopy.c -@@ -29,7 +29,6 @@ - COPY \ - "1:\n" \ - " .section .fixup,\"ax\"\n" \ -- " MOV D1Ar1,#0\n" \ - FIXUP \ - " MOVT D1Ar1,#HI(1b)\n" \ - " JUMP D1Ar1,#LO(1b)\n" \ -@@ -637,16 +636,14 @@ EXPORT_SYMBOL(__copy_user); - __asm_copy_user_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "2: SETB [%0++],D1Ar1\n", \ -- "3: ADD %2,%2,#1\n" \ -- " SETB [%0++],D1Ar1\n", \ -+ "3: ADD %2,%2,#1\n", \ - " .long 2b,3b\n") - - #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_user_cont(to, from, ret, \ - " GETW D1Ar1,[%1++]\n" \ - "2: SETW [%0++],D1Ar1\n" COPY, \ -- "3: ADD %2,%2,#2\n" \ -- " SETW [%0++],D1Ar1\n" FIXUP, \ -+ "3: ADD %2,%2,#2\n" FIXUP, \ - " .long 2b,3b\n" TENTRY) - - #define __asm_copy_from_user_2(to, from, ret) \ -@@ -656,32 +653,26 @@ EXPORT_SYMBOL(__copy_user); - __asm_copy_from_user_2x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "4: SETB [%0++],D1Ar1\n", \ -- "5: ADD %2,%2,#1\n" \ -- " SETB [%0++],D1Ar1\n", \ -+ "5: ADD %2,%2,#1\n", \ - " .long 4b,5b\n") - - #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_user_cont(to, from, ret, \ - " GETD D1Ar1,[%1++]\n" \ - "2: SETD [%0++],D1Ar1\n" COPY, \ -- "3: ADD %2,%2,#4\n" \ -- " SETD [%0++],D1Ar1\n" FIXUP, \ -+ "3: ADD %2,%2,#4\n" FIXUP, \ - " .long 2b,3b\n" TENTRY) - - #define __asm_copy_from_user_4(to, from, ret) \ - __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") - -- - #define __asm_copy_from_user_8x64(to, from, ret) \ - asm volatile ( \ - " GETL D0Ar2,D1Ar1,[%1++]\n" \ - "2: SETL [%0++],D0Ar2,D1Ar1\n" \ - "1:\n" \ - " .section .fixup,\"ax\"\n" \ -- " MOV D1Ar1,#0\n" \ -- " MOV D0Ar2,#0\n" \ - "3: ADD %2,%2,#8\n" \ -- " SETL [%0++],D0Ar2,D1Ar1\n" \ - " MOVT D0Ar2,#HI(1b)\n" \ - " JUMP D0Ar2,#LO(1b)\n" \ - " .previous\n" \ -@@ -721,11 +712,12 @@ EXPORT_SYMBOL(__copy_user); - "SUB %1, %1, #4\n") - - --/* Copy from user to kernel, zeroing the bytes that were inaccessible in -- userland. The return-value is the number of bytes that were -- inaccessible. */ --unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, -- unsigned long n) -+/* -+ * Copy from user to kernel. The return-value is the number of bytes that were -+ * inaccessible. -+ */ -+unsigned long raw_copy_from_user(void *pdst, const void __user *psrc, -+ unsigned long n) - { - register char *dst asm ("A0.2") = pdst; - register const char __user *src asm ("A1.2") = psrc; -@@ -738,7 +730,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - __asm_copy_from_user_1(dst, src, retn); - n--; - if (retn) -- goto copy_exception_bytes; -+ return retn + n; - } - if ((unsigned long) dst & 1) { - /* Worst case - byte copy */ -@@ -746,14 +738,14 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - __asm_copy_from_user_1(dst, src, retn); - n--; - if (retn) -- goto copy_exception_bytes; -+ return retn + n; - } - } - if (((unsigned long) src & 2) && n >= 2) { - __asm_copy_from_user_2(dst, src, retn); - n -= 2; - if (retn) -- goto copy_exception_bytes; -+ return retn + n; - } - if ((unsigned long) dst & 2) { - /* Second worst case - word copy */ -@@ -761,7 +753,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - __asm_copy_from_user_2(dst, src, retn); - n -= 2; - if (retn) -- goto copy_exception_bytes; -+ return retn + n; - } - } - -@@ -777,7 +769,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - __asm_copy_from_user_8x64(dst, src, retn); - n -= 8; - if (retn) -- goto copy_exception_bytes; -+ return retn + n; - } - } - -@@ -793,7 +785,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - __asm_copy_from_user_8x64(dst, src, retn); - n -= 8; - if (retn) -- goto copy_exception_bytes; -+ return retn + n; - } - } - #endif -@@ -803,7 +795,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - n -= 4; - - if (retn) -- goto copy_exception_bytes; -+ return retn + n; - } - - /* If we get here, there were no memory read faults. */ -@@ -829,21 +821,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - /* If we get here, retn correctly reflects the number of failing - bytes. */ - return retn; -- -- copy_exception_bytes: -- /* We already have "retn" bytes cleared, and need to clear the -- remaining "n" bytes. A non-optimized simple byte-for-byte in-line -- memset is preferred here, since this isn't speed-critical code and -- we'd rather have this a leaf-function than calling memset. */ -- { -- char *endp; -- for (endp = dst + n; dst < endp; dst++) -- *dst = 0; -- } -- -- return retn + n; - } --EXPORT_SYMBOL(__copy_user_zeroing); -+EXPORT_SYMBOL(raw_copy_from_user); - - #define __asm_clear_8x64(to, ret) \ - asm volatile ( \ --- -2.12.2 - -From dde6f22c1e122907717f45405cbc2c6227e259e5 Mon Sep 17 00:00:00 2001 -From: James Hogan -Date: Fri, 31 Mar 2017 13:35:01 +0100 -Subject: [PATCH 17/52] metag/usercopy: Add early abort to copy_to_user -Content-Length: 2525 -Lines: 99 - -commit fb8ea062a8f2e85256e13f55696c5c5f0dfdcc8b upstream. - -When copying to userland on Meta, if any faults are encountered -immediately abort the copy instead of continuing on and repeatedly -faulting, and worse potentially copying further bytes successfully to -subsequent valid pages. - -Fixes: 373cd784d0fc ("metag: Memory handling") -Reported-by: Al Viro -Signed-off-by: James Hogan -Cc: linux-metag@vger.kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - arch/metag/lib/usercopy.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c -index a6ced9691ddb..714d8562aa20 100644 ---- a/arch/metag/lib/usercopy.c -+++ b/arch/metag/lib/usercopy.c -@@ -538,23 +538,31 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, - if ((unsigned long) src & 1) { - __asm_copy_to_user_1(dst, src, retn); - n--; -+ if (retn) -+ return retn + n; - } - if ((unsigned long) dst & 1) { - /* Worst case - byte copy */ - while (n > 0) { - __asm_copy_to_user_1(dst, src, retn); - n--; -+ if (retn) -+ return retn + n; - } - } - if (((unsigned long) src & 2) && n >= 2) { - __asm_copy_to_user_2(dst, src, retn); - n -= 2; -+ if (retn) -+ return retn + n; - } - if ((unsigned long) dst & 2) { - /* Second worst case - word copy */ - while (n >= 2) { - __asm_copy_to_user_2(dst, src, retn); - n -= 2; -+ if (retn) -+ return retn + n; - } - } - -@@ -569,6 +577,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, - while (n >= 8) { - __asm_copy_to_user_8x64(dst, src, retn); - n -= 8; -+ if (retn) -+ return retn + n; - } - } - if (n >= RAPF_MIN_BUF_SIZE) { -@@ -581,6 +591,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, - while (n >= 8) { - __asm_copy_to_user_8x64(dst, src, retn); - n -= 8; -+ if (retn) -+ return retn + n; - } - } - #endif -@@ -588,11 +600,15 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, - while (n >= 16) { - __asm_copy_to_user_16(dst, src, retn); - n -= 16; -+ if (retn) -+ return retn + n; - } - - while (n >= 4) { - __asm_copy_to_user_4(dst, src, retn); - n -= 4; -+ if (retn) -+ return retn + n; - } - - switch (n) { -@@ -609,6 +625,10 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, - break; - } - -+ /* -+ * If we get here, retn correctly reflects the number of failing -+ * bytes. -+ */ - return retn; - } - EXPORT_SYMBOL(__copy_user); --- -2.12.2 - -From ae781dee56e4805311f0615ca04ea226bfbcafcd Mon Sep 17 00:00:00 2001 -From: James Hogan -Date: Fri, 31 Mar 2017 11:23:18 +0100 -Subject: [PATCH 16/52] metag/usercopy: Fix alignment error checking -Content-Length: 2038 -Lines: 57 - -commit 2257211942bbbf6c798ab70b487d7e62f7835a1a upstream. - -Fix the error checking of the alignment adjustment code in -raw_copy_from_user(), which mistakenly considers it safe to skip the -error check when aligning the source buffer on a 2 or 4 byte boundary. - -If the destination buffer was unaligned it may have started to copy -using byte or word accesses, which could well be at the start of a new -(valid) source page. This would result in it appearing to have copied 1 -or 2 bytes at the end of the first (invalid) page rather than none at -all. - -Fixes: 373cd784d0fc ("metag: Memory handling") -Signed-off-by: James Hogan -Cc: linux-metag@vger.kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - arch/metag/lib/usercopy.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c -index b4eb1f17069f..a6ced9691ddb 100644 ---- a/arch/metag/lib/usercopy.c -+++ b/arch/metag/lib/usercopy.c -@@ -717,6 +717,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - if ((unsigned long) src & 1) { - __asm_copy_from_user_1(dst, src, retn); - n--; -+ if (retn) -+ goto copy_exception_bytes; - } - if ((unsigned long) dst & 1) { - /* Worst case - byte copy */ -@@ -730,6 +732,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - if (((unsigned long) src & 2) && n >= 2) { - __asm_copy_from_user_2(dst, src, retn); - n -= 2; -+ if (retn) -+ goto copy_exception_bytes; - } - if ((unsigned long) dst & 2) { - /* Second worst case - word copy */ -@@ -741,12 +745,6 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - } - } - -- /* We only need one check after the unalignment-adjustments, -- because if both adjustments were done, either both or -- neither reference had an exception. */ -- if (retn != 0) -- goto copy_exception_bytes; -- - #ifdef USE_RAPF - /* 64 bit copy loop */ - if (!(((unsigned long) src | (unsigned long) dst) & 7)) { --- -2.12.2 - -From ce962cf480331380d7eb3c8e3c625a975e0aa38f Mon Sep 17 00:00:00 2001 -From: James Hogan -Date: Fri, 31 Mar 2017 10:37:44 +0100 -Subject: [PATCH 15/52] metag/usercopy: Drop unused macros -Content-Length: 4774 -Lines: 140 - -commit ef62a2d81f73d9cddef14bc3d9097a57010d551c upstream. - -Metag's lib/usercopy.c has a bunch of copy_from_user macros for larger -copies between 5 and 16 bytes which are completely unused. Before fixing -zeroing lets drop these macros so there is less to fix. - -Signed-off-by: James Hogan -Cc: Al Viro -Cc: linux-metag@vger.kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - arch/metag/lib/usercopy.c | 113 ---------------------------------------------- - 1 file changed, 113 deletions(-) - -diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c -index b3ebfe9c8e88..b4eb1f17069f 100644 ---- a/arch/metag/lib/usercopy.c -+++ b/arch/metag/lib/usercopy.c -@@ -651,119 +651,6 @@ EXPORT_SYMBOL(__copy_user); - #define __asm_copy_from_user_4(to, from, ret) \ - __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") - --#define __asm_copy_from_user_5(to, from, ret) \ -- __asm_copy_from_user_4x_cont(to, from, ret, \ -- " GETB D1Ar1,[%1++]\n" \ -- "4: SETB [%0++],D1Ar1\n", \ -- "5: ADD %2,%2,#1\n" \ -- " SETB [%0++],D1Ar1\n", \ -- " .long 4b,5b\n") -- --#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ -- __asm_copy_from_user_4x_cont(to, from, ret, \ -- " GETW D1Ar1,[%1++]\n" \ -- "4: SETW [%0++],D1Ar1\n" COPY, \ -- "5: ADD %2,%2,#2\n" \ -- " SETW [%0++],D1Ar1\n" FIXUP, \ -- " .long 4b,5b\n" TENTRY) -- --#define __asm_copy_from_user_6(to, from, ret) \ -- __asm_copy_from_user_6x_cont(to, from, ret, "", "", "") -- --#define __asm_copy_from_user_7(to, from, ret) \ -- __asm_copy_from_user_6x_cont(to, from, ret, \ -- " GETB D1Ar1,[%1++]\n" \ -- "6: SETB [%0++],D1Ar1\n", \ -- "7: ADD %2,%2,#1\n" \ -- " SETB [%0++],D1Ar1\n", \ -- " .long 6b,7b\n") -- --#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ -- __asm_copy_from_user_4x_cont(to, from, ret, \ -- " GETD D1Ar1,[%1++]\n" \ -- "4: SETD [%0++],D1Ar1\n" COPY, \ -- "5: ADD %2,%2,#4\n" \ -- " SETD [%0++],D1Ar1\n" FIXUP, \ -- " .long 4b,5b\n" TENTRY) -- --#define __asm_copy_from_user_8(to, from, ret) \ -- __asm_copy_from_user_8x_cont(to, from, ret, "", "", "") -- --#define __asm_copy_from_user_9(to, from, ret) \ -- __asm_copy_from_user_8x_cont(to, from, ret, \ -- " GETB D1Ar1,[%1++]\n" \ -- "6: SETB [%0++],D1Ar1\n", \ -- "7: ADD %2,%2,#1\n" \ -- " SETB [%0++],D1Ar1\n", \ -- " .long 6b,7b\n") -- --#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ -- __asm_copy_from_user_8x_cont(to, from, ret, \ -- " GETW D1Ar1,[%1++]\n" \ -- "6: SETW [%0++],D1Ar1\n" COPY, \ -- "7: ADD %2,%2,#2\n" \ -- " SETW [%0++],D1Ar1\n" FIXUP, \ -- " .long 6b,7b\n" TENTRY) -- --#define __asm_copy_from_user_10(to, from, ret) \ -- __asm_copy_from_user_10x_cont(to, from, ret, "", "", "") -- --#define __asm_copy_from_user_11(to, from, ret) \ -- __asm_copy_from_user_10x_cont(to, from, ret, \ -- " GETB D1Ar1,[%1++]\n" \ -- "8: SETB [%0++],D1Ar1\n", \ -- "9: ADD %2,%2,#1\n" \ -- " SETB [%0++],D1Ar1\n", \ -- " .long 8b,9b\n") -- --#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ -- __asm_copy_from_user_8x_cont(to, from, ret, \ -- " GETD D1Ar1,[%1++]\n" \ -- "6: SETD [%0++],D1Ar1\n" COPY, \ -- "7: ADD %2,%2,#4\n" \ -- " SETD [%0++],D1Ar1\n" FIXUP, \ -- " .long 6b,7b\n" TENTRY) -- --#define __asm_copy_from_user_12(to, from, ret) \ -- __asm_copy_from_user_12x_cont(to, from, ret, "", "", "") -- --#define __asm_copy_from_user_13(to, from, ret) \ -- __asm_copy_from_user_12x_cont(to, from, ret, \ -- " GETB D1Ar1,[%1++]\n" \ -- "8: SETB [%0++],D1Ar1\n", \ -- "9: ADD %2,%2,#1\n" \ -- " SETB [%0++],D1Ar1\n", \ -- " .long 8b,9b\n") -- --#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ -- __asm_copy_from_user_12x_cont(to, from, ret, \ -- " GETW D1Ar1,[%1++]\n" \ -- "8: SETW [%0++],D1Ar1\n" COPY, \ -- "9: ADD %2,%2,#2\n" \ -- " SETW [%0++],D1Ar1\n" FIXUP, \ -- " .long 8b,9b\n" TENTRY) -- --#define __asm_copy_from_user_14(to, from, ret) \ -- __asm_copy_from_user_14x_cont(to, from, ret, "", "", "") -- --#define __asm_copy_from_user_15(to, from, ret) \ -- __asm_copy_from_user_14x_cont(to, from, ret, \ -- " GETB D1Ar1,[%1++]\n" \ -- "10: SETB [%0++],D1Ar1\n", \ -- "11: ADD %2,%2,#1\n" \ -- " SETB [%0++],D1Ar1\n", \ -- " .long 10b,11b\n") -- --#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ -- __asm_copy_from_user_12x_cont(to, from, ret, \ -- " GETD D1Ar1,[%1++]\n" \ -- "8: SETD [%0++],D1Ar1\n" COPY, \ -- "9: ADD %2,%2,#4\n" \ -- " SETD [%0++],D1Ar1\n" FIXUP, \ -- " .long 8b,9b\n" TENTRY) -- --#define __asm_copy_from_user_16(to, from, ret) \ -- __asm_copy_from_user_16x_cont(to, from, ret, "", "", "") - - #define __asm_copy_from_user_8x64(to, from, ret) \ - asm volatile ( \ --- -2.12.2 - -From 5cc244782dabaee110ed9c3900d40cd4b481a517 Mon Sep 17 00:00:00 2001 -From: Wei Yongjun -Date: Fri, 17 Jun 2016 17:33:59 +0000 -Subject: [PATCH 14/52] ring-buffer: Fix return value check in - test_ringbuffer() -Content-Length: 1507 -Lines: 46 - -commit 62277de758b155dc04b78f195a1cb5208c37b2df upstream. - -In case of error, the function kthread_run() returns ERR_PTR() -and never returns NULL. The NULL test in the return value check -should be replaced with IS_ERR(). - -Link: http://lkml.kernel.org/r/1466184839-14927-1-git-send-email-weiyj_lk@163.com - -Fixes: 6c43e554a ("ring-buffer: Add ring buffer startup selftest") -Signed-off-by: Wei Yongjun -Signed-off-by: Steven Rostedt (VMware) -Signed-off-by: Greg Kroah-Hartman ---- - kernel/trace/ring_buffer.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index acbb0e73d3a2..7d7f99b0db47 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -4875,9 +4875,9 @@ static __init int test_ringbuffer(void) - rb_data[cpu].cnt = cpu; - rb_threads[cpu] = kthread_create(rb_test, &rb_data[cpu], - "rbtester/%d", cpu); -- if (WARN_ON(!rb_threads[cpu])) { -+ if (WARN_ON(IS_ERR(rb_threads[cpu]))) { - pr_cont("FAILED\n"); -- ret = -1; -+ ret = PTR_ERR(rb_threads[cpu]); - goto out_free; - } - -@@ -4887,9 +4887,9 @@ static __init int test_ringbuffer(void) - - /* Now create the rb hammer! */ - rb_hammer = kthread_run(rb_hammer_test, NULL, "rbhammer"); -- if (WARN_ON(!rb_hammer)) { -+ if (WARN_ON(IS_ERR(rb_hammer))) { - pr_cont("FAILED\n"); -- ret = -1; -+ ret = PTR_ERR(rb_hammer); - goto out_free; - } - ++ /* sock_create_kern() allocates with GFP_KERNEL */ ++ noio_flag = memalloc_noio_save(); + ret = sock_create_kern(read_pnet(&con->msgr->net), paddr->ss_family, + SOCK_STREAM, IPPROTO_TCP, &sock); ++ memalloc_noio_restore(noio_flag); + if (ret) + return ret; + sock->sk->sk_allocation = GFP_NOFS; -- 2.12.2 diff --git a/queue-3.18/block-allow-write_same-commands-with-the-sg_io-ioctl.patch b/queue-3.18/block-allow-write_same-commands-with-the-sg_io-ioctl.patch new file mode 100644 index 00000000000..1a17e218f9c --- /dev/null +++ b/queue-3.18/block-allow-write_same-commands-with-the-sg_io-ioctl.patch @@ -0,0 +1,79 @@ +From 25cdb64510644f3e854d502d69c73f21c6df88a9 Mon Sep 17 00:00:00 2001 +From: Mauricio Faria de Oliveira +Date: Thu, 15 Dec 2016 11:48:18 -0600 +Subject: block: allow WRITE_SAME commands with the SG_IO ioctl + +From: Mauricio Faria de Oliveira + +commit 25cdb64510644f3e854d502d69c73f21c6df88a9 upstream. + +The WRITE_SAME commands are not present in the blk_default_cmd_filter +write_ok list, and thus are failed with -EPERM when the SG_IO ioctl() +is executed without CAP_SYS_RAWIO capability (e.g., unprivileged users). +[ sg_io() -> blk_fill_sghdr_rq() > blk_verify_command() -> -EPERM ] + +The problem can be reproduced with the sg_write_same command + + # sg_write_same --num 1 --xferlen 512 /dev/sda + # + + # capsh --drop=cap_sys_rawio -- -c \ + 'sg_write_same --num 1 --xferlen 512 /dev/sda' + Write same: pass through os error: Operation not permitted + # + +For comparison, the WRITE_VERIFY command does not observe this problem, +since it is in that list: + + # capsh --drop=cap_sys_rawio -- -c \ + 'sg_write_verify --num 1 --ilen 512 --lba 0 /dev/sda' + # + +So, this patch adds the WRITE_SAME commands to the list, in order +for the SG_IO ioctl to finish successfully: + + # capsh --drop=cap_sys_rawio -- -c \ + 'sg_write_same --num 1 --xferlen 512 /dev/sda' + # + +That case happens to be exercised by QEMU KVM guests with 'scsi-block' devices +(qemu "-device scsi-block" [1], libvirt "" [2]), +which employs the SG_IO ioctl() and runs as an unprivileged user (libvirt-qemu). + +In that scenario, when a filesystem (e.g., ext4) performs its zero-out calls, +which are translated to write-same calls in the guest kernel, and then into +SG_IO ioctls to the host kernel, SCSI I/O errors may be observed in the guest: + + [...] sd 0:0:0:0: [sda] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE + [...] sd 0:0:0:0: [sda] tag#0 Sense Key : Aborted Command [current] + [...] sd 0:0:0:0: [sda] tag#0 Add. Sense: I/O process terminated + [...] sd 0:0:0:0: [sda] tag#0 CDB: Write Same(10) 41 00 01 04 e0 78 00 00 08 00 + [...] blk_update_request: I/O error, dev sda, sector 17096824 + +Links: +[1] http://git.qemu.org/?p=qemu.git;a=commit;h=336a6915bc7089fb20fea4ba99972ad9a97c5f52 +[2] https://libvirt.org/formatdomain.html#elementsDisks (see 'disk' -> 'device') + +Signed-off-by: Mauricio Faria de Oliveira +Signed-off-by: Brahadambal Srinivasan +Reported-by: Manjunatha H R +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/scsi_ioctl.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/block/scsi_ioctl.c ++++ b/block/scsi_ioctl.c +@@ -182,6 +182,9 @@ static void blk_set_cmd_filter_defaults( + __set_bit(WRITE_16, filter->write_ok); + __set_bit(WRITE_LONG, filter->write_ok); + __set_bit(WRITE_LONG_2, filter->write_ok); ++ __set_bit(WRITE_SAME, filter->write_ok); ++ __set_bit(WRITE_SAME_16, filter->write_ok); ++ __set_bit(WRITE_SAME_32, filter->write_ok); + __set_bit(ERASE, filter->write_ok); + __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok); + __set_bit(MODE_SELECT, filter->write_ok); diff --git a/queue-3.18/give-up-on-gcc-ilog2-constant-optimizations.patch b/queue-3.18/give-up-on-gcc-ilog2-constant-optimizations.patch new file mode 100644 index 00000000000..5358beafed4 --- /dev/null +++ b/queue-3.18/give-up-on-gcc-ilog2-constant-optimizations.patch @@ -0,0 +1,89 @@ +From 474c90156c8dcc2fa815e6716cc9394d7930cb9c Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Thu, 2 Mar 2017 12:17:22 -0800 +Subject: give up on gcc ilog2() constant optimizations + +From: Linus Torvalds + +commit 474c90156c8dcc2fa815e6716cc9394d7930cb9c upstream. + +gcc-7 has an "optimization" pass that completely screws up, and +generates the code expansion for the (impossible) case of calling +ilog2() with a zero constant, even when the code gcc compiles does not +actually have a zero constant. + +And we try to generate a compile-time error for anybody doing ilog2() on +a constant where that doesn't make sense (be it zero or negative). So +now gcc7 will fail the build due to our sanity checking, because it +created that constant-zero case that didn't actually exist in the source +code. + +There's a whole long discussion on the kernel mailing about how to work +around this gcc bug. The gcc people themselevs have discussed their +"feature" in + + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72785 + +but it's all water under the bridge, because while it looked at one +point like it would be solved by the time gcc7 was released, that was +not to be. + +So now we have to deal with this compiler braindamage. + +And the only simple approach seems to be to just delete the code that +tries to warn about bad uses of ilog2(). + +So now "ilog2()" will just return 0 not just for the value 1, but for +any non-positive value too. + +It's not like I can recall anybody having ever actually tried to use +this function on any invalid value, but maybe the sanity check just +meant that such code never made it out in public. + +Reported-by: Laura Abbott +Cc: John Stultz , +Cc: Thomas Gleixner +Cc: Ard Biesheuvel +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/log2.h | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +--- a/include/linux/log2.h ++++ b/include/linux/log2.h +@@ -16,12 +16,6 @@ + #include + + /* +- * deal with unrepresentable constant logarithms +- */ +-extern __attribute__((const, noreturn)) +-int ____ilog2_NaN(void); +- +-/* + * non-constant log of base 2 calculators + * - the arch may override these in asm/bitops.h if they can be implemented + * more efficiently than using fls() and fls64() +@@ -85,7 +79,7 @@ unsigned long __rounddown_pow_of_two(uns + #define ilog2(n) \ + ( \ + __builtin_constant_p(n) ? ( \ +- (n) < 1 ? ____ilog2_NaN() : \ ++ (n) < 2 ? 0 : \ + (n) & (1ULL << 63) ? 63 : \ + (n) & (1ULL << 62) ? 62 : \ + (n) & (1ULL << 61) ? 61 : \ +@@ -148,10 +142,7 @@ unsigned long __rounddown_pow_of_two(uns + (n) & (1ULL << 4) ? 4 : \ + (n) & (1ULL << 3) ? 3 : \ + (n) & (1ULL << 2) ? 2 : \ +- (n) & (1ULL << 1) ? 1 : \ +- (n) & (1ULL << 0) ? 0 : \ +- ____ilog2_NaN() \ +- ) : \ ++ 1 ) : \ + (sizeof(n) <= 4) ? \ + __ilog2_u32(n) : \ + __ilog2_u64(n) \ diff --git a/queue-3.18/metag-usercopy-add-early-abort-to-copy_to_user.patch b/queue-3.18/metag-usercopy-add-early-abort-to-copy_to_user.patch new file mode 100644 index 00000000000..d5a75f9560d --- /dev/null +++ b/queue-3.18/metag-usercopy-add-early-abort-to-copy_to_user.patch @@ -0,0 +1,103 @@ +From fb8ea062a8f2e85256e13f55696c5c5f0dfdcc8b Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Fri, 31 Mar 2017 13:35:01 +0100 +Subject: metag/usercopy: Add early abort to copy_to_user + +From: James Hogan + +commit fb8ea062a8f2e85256e13f55696c5c5f0dfdcc8b upstream. + +When copying to userland on Meta, if any faults are encountered +immediately abort the copy instead of continuing on and repeatedly +faulting, and worse potentially copying further bytes successfully to +subsequent valid pages. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Reported-by: Al Viro +Signed-off-by: James Hogan +Cc: linux-metag@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/metag/lib/usercopy.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -538,23 +538,31 @@ unsigned long __copy_user(void __user *p + if ((unsigned long) src & 1) { + __asm_copy_to_user_1(dst, src, retn); + n--; ++ if (retn) ++ return retn + n; + } + if ((unsigned long) dst & 1) { + /* Worst case - byte copy */ + while (n > 0) { + __asm_copy_to_user_1(dst, src, retn); + n--; ++ if (retn) ++ return retn + n; + } + } + if (((unsigned long) src & 2) && n >= 2) { + __asm_copy_to_user_2(dst, src, retn); + n -= 2; ++ if (retn) ++ return retn + n; + } + if ((unsigned long) dst & 2) { + /* Second worst case - word copy */ + while (n >= 2) { + __asm_copy_to_user_2(dst, src, retn); + n -= 2; ++ if (retn) ++ return retn + n; + } + } + +@@ -569,6 +577,8 @@ unsigned long __copy_user(void __user *p + while (n >= 8) { + __asm_copy_to_user_8x64(dst, src, retn); + n -= 8; ++ if (retn) ++ return retn + n; + } + } + if (n >= RAPF_MIN_BUF_SIZE) { +@@ -581,6 +591,8 @@ unsigned long __copy_user(void __user *p + while (n >= 8) { + __asm_copy_to_user_8x64(dst, src, retn); + n -= 8; ++ if (retn) ++ return retn + n; + } + } + #endif +@@ -588,11 +600,15 @@ unsigned long __copy_user(void __user *p + while (n >= 16) { + __asm_copy_to_user_16(dst, src, retn); + n -= 16; ++ if (retn) ++ return retn + n; + } + + while (n >= 4) { + __asm_copy_to_user_4(dst, src, retn); + n -= 4; ++ if (retn) ++ return retn + n; + } + + switch (n) { +@@ -609,6 +625,10 @@ unsigned long __copy_user(void __user *p + break; + } + ++ /* ++ * If we get here, retn correctly reflects the number of failing ++ * bytes. ++ */ + return retn; + } + EXPORT_SYMBOL(__copy_user); diff --git a/queue-3.18/metag-usercopy-add-missing-fixups.patch b/queue-3.18/metag-usercopy-add-missing-fixups.patch new file mode 100644 index 00000000000..f1021ca5bb9 --- /dev/null +++ b/queue-3.18/metag-usercopy-add-missing-fixups.patch @@ -0,0 +1,167 @@ +From b884a190afcecdbef34ca508ea5ee88bb7c77861 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Tue, 4 Apr 2017 08:51:34 +0100 +Subject: metag/usercopy: Add missing fixups + +From: James Hogan + +commit b884a190afcecdbef34ca508ea5ee88bb7c77861 upstream. + +The rapf copy loops in the Meta usercopy code is missing some extable +entries for HTP cores with unaligned access checking enabled, where +faults occur on the instruction immediately after the faulting access. + +Add the fixup labels and extable entries for these cases so that corner +case user copy failures don't cause kernel crashes. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Signed-off-by: James Hogan +Cc: linux-metag@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/metag/lib/usercopy.c | 72 ++++++++++++++++++++++++++++++---------------- + 1 file changed, 48 insertions(+), 24 deletions(-) + +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -259,27 +259,31 @@ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "22:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ +- "SUB %3, %3, #32\n" \ + "23:\n" \ +- "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ ++ "SUB %3, %3, #32\n" \ + "24:\n" \ ++ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ ++ "25:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "26:\n" \ + "SUB %3, %3, #32\n" \ + "DCACHE [%1+#-64], D0Ar6\n" \ + "BR $Lloop"id"\n" \ + \ + "MOV RAPF, %1\n" \ +- "25:\n" \ ++ "27:\n" \ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "26:\n" \ ++ "28:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "29:\n" \ + "SUB %3, %3, #32\n" \ +- "27:\n" \ ++ "30:\n" \ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "28:\n" \ ++ "31:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "32:\n" \ + "SUB %0, %0, #8\n" \ +- "29:\n" \ ++ "33:\n" \ + "SETL [%0++], D0.7, D1.7\n" \ + "SUB %3, %3, #32\n" \ + "1:" \ +@@ -311,7 +315,11 @@ + " .long 26b,3b\n" \ + " .long 27b,3b\n" \ + " .long 28b,3b\n" \ +- " .long 29b,4b\n" \ ++ " .long 29b,3b\n" \ ++ " .long 30b,3b\n" \ ++ " .long 31b,3b\n" \ ++ " .long 32b,3b\n" \ ++ " .long 33b,4b\n" \ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ + : "0" (to), "1" (from), "2" (ret), "3" (n) \ +@@ -402,47 +410,55 @@ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "22:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ +- "SUB %3, %3, #16\n" \ + "23:\n" \ +- "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "24:\n" \ +- "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "SUB %3, %3, #16\n" \ +- "25:\n" \ ++ "24:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "26:\n" \ ++ "25:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "26:\n" \ + "SUB %3, %3, #16\n" \ + "27:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "28:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "29:\n" \ ++ "SUB %3, %3, #16\n" \ ++ "30:\n" \ ++ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ ++ "31:\n" \ ++ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "32:\n" \ + "SUB %3, %3, #16\n" \ + "DCACHE [%1+#-64], D0Ar6\n" \ + "BR $Lloop"id"\n" \ + \ + "MOV RAPF, %1\n" \ +- "29:\n" \ ++ "33:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "30:\n" \ ++ "34:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "35:\n" \ + "SUB %3, %3, #16\n" \ +- "31:\n" \ ++ "36:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "32:\n" \ ++ "37:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "38:\n" \ + "SUB %3, %3, #16\n" \ +- "33:\n" \ ++ "39:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "34:\n" \ ++ "40:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "41:\n" \ + "SUB %3, %3, #16\n" \ +- "35:\n" \ ++ "42:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "36:\n" \ ++ "43:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "44:\n" \ + "SUB %0, %0, #4\n" \ +- "37:\n" \ ++ "45:\n" \ + "SETD [%0++], D0.7\n" \ + "SUB %3, %3, #16\n" \ + "1:" \ +@@ -482,7 +498,15 @@ + " .long 34b,3b\n" \ + " .long 35b,3b\n" \ + " .long 36b,3b\n" \ +- " .long 37b,4b\n" \ ++ " .long 37b,3b\n" \ ++ " .long 38b,3b\n" \ ++ " .long 39b,3b\n" \ ++ " .long 40b,3b\n" \ ++ " .long 41b,3b\n" \ ++ " .long 42b,3b\n" \ ++ " .long 43b,3b\n" \ ++ " .long 44b,3b\n" \ ++ " .long 45b,4b\n" \ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ + : "0" (to), "1" (from), "2" (ret), "3" (n) \ diff --git a/queue-3.18/metag-usercopy-drop-unused-macros.patch b/queue-3.18/metag-usercopy-drop-unused-macros.patch new file mode 100644 index 00000000000..c4272620bf7 --- /dev/null +++ b/queue-3.18/metag-usercopy-drop-unused-macros.patch @@ -0,0 +1,144 @@ +From ef62a2d81f73d9cddef14bc3d9097a57010d551c Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Fri, 31 Mar 2017 10:37:44 +0100 +Subject: metag/usercopy: Drop unused macros + +From: James Hogan + +commit ef62a2d81f73d9cddef14bc3d9097a57010d551c upstream. + +Metag's lib/usercopy.c has a bunch of copy_from_user macros for larger +copies between 5 and 16 bytes which are completely unused. Before fixing +zeroing lets drop these macros so there is less to fix. + +Signed-off-by: James Hogan +Cc: Al Viro +Cc: linux-metag@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/metag/lib/usercopy.c | 113 ---------------------------------------------- + 1 file changed, 113 deletions(-) + +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -651,119 +651,6 @@ EXPORT_SYMBOL(__copy_user); + #define __asm_copy_from_user_4(to, from, ret) \ + __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") + +-#define __asm_copy_from_user_5(to, from, ret) \ +- __asm_copy_from_user_4x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "4: SETB [%0++],D1Ar1\n", \ +- "5: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 4b,5b\n") +- +-#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_4x_cont(to, from, ret, \ +- " GETW D1Ar1,[%1++]\n" \ +- "4: SETW [%0++],D1Ar1\n" COPY, \ +- "5: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ +- " .long 4b,5b\n" TENTRY) +- +-#define __asm_copy_from_user_6(to, from, ret) \ +- __asm_copy_from_user_6x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_7(to, from, ret) \ +- __asm_copy_from_user_6x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "6: SETB [%0++],D1Ar1\n", \ +- "7: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 6b,7b\n") +- +-#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_4x_cont(to, from, ret, \ +- " GETD D1Ar1,[%1++]\n" \ +- "4: SETD [%0++],D1Ar1\n" COPY, \ +- "5: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ +- " .long 4b,5b\n" TENTRY) +- +-#define __asm_copy_from_user_8(to, from, ret) \ +- __asm_copy_from_user_8x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_9(to, from, ret) \ +- __asm_copy_from_user_8x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "6: SETB [%0++],D1Ar1\n", \ +- "7: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 6b,7b\n") +- +-#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_8x_cont(to, from, ret, \ +- " GETW D1Ar1,[%1++]\n" \ +- "6: SETW [%0++],D1Ar1\n" COPY, \ +- "7: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ +- " .long 6b,7b\n" TENTRY) +- +-#define __asm_copy_from_user_10(to, from, ret) \ +- __asm_copy_from_user_10x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_11(to, from, ret) \ +- __asm_copy_from_user_10x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "8: SETB [%0++],D1Ar1\n", \ +- "9: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 8b,9b\n") +- +-#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_8x_cont(to, from, ret, \ +- " GETD D1Ar1,[%1++]\n" \ +- "6: SETD [%0++],D1Ar1\n" COPY, \ +- "7: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ +- " .long 6b,7b\n" TENTRY) +- +-#define __asm_copy_from_user_12(to, from, ret) \ +- __asm_copy_from_user_12x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_13(to, from, ret) \ +- __asm_copy_from_user_12x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "8: SETB [%0++],D1Ar1\n", \ +- "9: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 8b,9b\n") +- +-#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_12x_cont(to, from, ret, \ +- " GETW D1Ar1,[%1++]\n" \ +- "8: SETW [%0++],D1Ar1\n" COPY, \ +- "9: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ +- " .long 8b,9b\n" TENTRY) +- +-#define __asm_copy_from_user_14(to, from, ret) \ +- __asm_copy_from_user_14x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_15(to, from, ret) \ +- __asm_copy_from_user_14x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "10: SETB [%0++],D1Ar1\n", \ +- "11: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 10b,11b\n") +- +-#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_12x_cont(to, from, ret, \ +- " GETD D1Ar1,[%1++]\n" \ +- "8: SETD [%0++],D1Ar1\n" COPY, \ +- "9: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ +- " .long 8b,9b\n" TENTRY) +- +-#define __asm_copy_from_user_16(to, from, ret) \ +- __asm_copy_from_user_16x_cont(to, from, ret, "", "", "") + + #define __asm_copy_from_user_8x64(to, from, ret) \ + asm volatile ( \ diff --git a/queue-3.18/metag-usercopy-fix-alignment-error-checking.patch b/queue-3.18/metag-usercopy-fix-alignment-error-checking.patch new file mode 100644 index 00000000000..b6b7c6336df --- /dev/null +++ b/queue-3.18/metag-usercopy-fix-alignment-error-checking.patch @@ -0,0 +1,61 @@ +From 2257211942bbbf6c798ab70b487d7e62f7835a1a Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Fri, 31 Mar 2017 11:23:18 +0100 +Subject: metag/usercopy: Fix alignment error checking + +From: James Hogan + +commit 2257211942bbbf6c798ab70b487d7e62f7835a1a upstream. + +Fix the error checking of the alignment adjustment code in +raw_copy_from_user(), which mistakenly considers it safe to skip the +error check when aligning the source buffer on a 2 or 4 byte boundary. + +If the destination buffer was unaligned it may have started to copy +using byte or word accesses, which could well be at the start of a new +(valid) source page. This would result in it appearing to have copied 1 +or 2 bytes at the end of the first (invalid) page rather than none at +all. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Signed-off-by: James Hogan +Cc: linux-metag@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/metag/lib/usercopy.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -717,6 +717,8 @@ unsigned long __copy_user_zeroing(void * + if ((unsigned long) src & 1) { + __asm_copy_from_user_1(dst, src, retn); + n--; ++ if (retn) ++ goto copy_exception_bytes; + } + if ((unsigned long) dst & 1) { + /* Worst case - byte copy */ +@@ -730,6 +732,8 @@ unsigned long __copy_user_zeroing(void * + if (((unsigned long) src & 2) && n >= 2) { + __asm_copy_from_user_2(dst, src, retn); + n -= 2; ++ if (retn) ++ goto copy_exception_bytes; + } + if ((unsigned long) dst & 2) { + /* Second worst case - word copy */ +@@ -741,12 +745,6 @@ unsigned long __copy_user_zeroing(void * + } + } + +- /* We only need one check after the unalignment-adjustments, +- because if both adjustments were done, either both or +- neither reference had an exception. */ +- if (retn != 0) +- goto copy_exception_bytes; +- + #ifdef USE_RAPF + /* 64 bit copy loop */ + if (!(((unsigned long) src | (unsigned long) dst) & 7)) { diff --git a/queue-3.18/metag-usercopy-fix-src-fixup-in-from-user-rapf-loops.patch b/queue-3.18/metag-usercopy-fix-src-fixup-in-from-user-rapf-loops.patch new file mode 100644 index 00000000000..194bc9e598f --- /dev/null +++ b/queue-3.18/metag-usercopy-fix-src-fixup-in-from-user-rapf-loops.patch @@ -0,0 +1,89 @@ +From 2c0b1df88b987a12d95ea1d6beaf01894f3cc725 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Mon, 3 Apr 2017 17:41:40 +0100 +Subject: metag/usercopy: Fix src fixup in from user rapf loops + +From: James Hogan + +commit 2c0b1df88b987a12d95ea1d6beaf01894f3cc725 upstream. + +The fixup code to rewind the source pointer in +__asm_copy_from_user_{32,64}bit_rapf_loop() always rewound the source by +a single unit (4 or 8 bytes), however this is insufficient if the fault +didn't occur on the first load in the loop, as the source pointer will +have been incremented but nothing will have been stored until all 4 +register [pairs] are loaded. + +Read the LSM_STEP field of TXSTATUS (which is already loaded into a +register), a bit like the copy_to_user versions, to determine how many +iterations of MGET[DL] have taken place, all of which need rewinding. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Signed-off-by: James Hogan +Cc: linux-metag@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/metag/lib/usercopy.c | 36 ++++++++++++++++++++++++++++-------- + 1 file changed, 28 insertions(+), 8 deletions(-) + +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -687,29 +687,49 @@ EXPORT_SYMBOL(__copy_user); + * + * Rationale: + * A fault occurs while reading from user buffer, which is the +- * source. Since the fault is at a single address, we only +- * need to rewind by 8 bytes. ++ * source. + * Since we don't write to kernel buffer until we read first, + * the kernel buffer is at the right state and needn't be +- * corrected. ++ * corrected, but the source must be rewound to the beginning of ++ * the block, which is LSM_STEP*8 bytes. ++ * LSM_STEP is bits 10:8 in TXSTATUS which is already read ++ * and stored in D0Ar2 ++ * ++ * NOTE: If a fault occurs at the last operation in M{G,S}ETL ++ * LSM_STEP will be 0. ie: we do 4 writes in our case, if ++ * a fault happens at the 4th write, LSM_STEP will be 0 ++ * instead of 4. The code copes with that. + */ + #define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id) \ + __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ +- "SUB %1, %1, #8\n") ++ "LSR D0Ar2, D0Ar2, #5\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x38\n" \ ++ "ADDZ D0Ar2, D0Ar2, #32\n" \ ++ "SUB %1, %1, D0Ar2\n") + + /* rewind 'from' pointer when a fault occurs + * + * Rationale: + * A fault occurs while reading from user buffer, which is the +- * source. Since the fault is at a single address, we only +- * need to rewind by 4 bytes. ++ * source. + * Since we don't write to kernel buffer until we read first, + * the kernel buffer is at the right state and needn't be +- * corrected. ++ * corrected, but the source must be rewound to the beginning of ++ * the block, which is LSM_STEP*4 bytes. ++ * LSM_STEP is bits 10:8 in TXSTATUS which is already read ++ * and stored in D0Ar2 ++ * ++ * NOTE: If a fault occurs at the last operation in M{G,S}ETL ++ * LSM_STEP will be 0. ie: we do 4 writes in our case, if ++ * a fault happens at the 4th write, LSM_STEP will be 0 ++ * instead of 4. The code copes with that. + */ + #define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id) \ + __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ +- "SUB %1, %1, #4\n") ++ "LSR D0Ar2, D0Ar2, #6\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x1c\n" \ ++ "ADDZ D0Ar2, D0Ar2, #16\n" \ ++ "SUB %1, %1, D0Ar2\n") + + + /* diff --git a/queue-3.18/metag-usercopy-set-flags-before-addz.patch b/queue-3.18/metag-usercopy-set-flags-before-addz.patch new file mode 100644 index 00000000000..b44cb3b541f --- /dev/null +++ b/queue-3.18/metag-usercopy-set-flags-before-addz.patch @@ -0,0 +1,67 @@ +From fd40eee1290ad7add7aa665e3ce6b0f9fe9734b4 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Tue, 4 Apr 2017 11:43:26 +0100 +Subject: metag/usercopy: Set flags before ADDZ + +From: James Hogan + +commit fd40eee1290ad7add7aa665e3ce6b0f9fe9734b4 upstream. + +The fixup code for the copy_to_user rapf loops reads TXStatus.LSM_STEP +to decide how far to rewind the source pointer. There is a special case +for the last execution of an MGETL/MGETD, since it leaves LSM_STEP=0 +even though the number of MGETLs/MGETDs attempted was 4. This uses ADDZ +which is conditional upon the Z condition flag, but the AND instruction +which masked the TXStatus.LSM_STEP field didn't set the condition flags +based on the result. + +Fix that now by using ANDS which does set the flags, and also marking +the condition codes as clobbered by the inline assembly. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Signed-off-by: James Hogan +Cc: linux-metag@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/metag/lib/usercopy.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -315,7 +315,7 @@ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ + : "0" (to), "1" (from), "2" (ret), "3" (n) \ +- : "D1Ar1", "D0Ar2", "memory") ++ : "D1Ar1", "D0Ar2", "cc", "memory") + + /* rewind 'to' and 'from' pointers when a fault occurs + * +@@ -341,7 +341,7 @@ + #define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\ + __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ + "LSR D0Ar2, D0Ar2, #8\n" \ +- "AND D0Ar2, D0Ar2, #0x7\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x7\n" \ + "ADDZ D0Ar2, D0Ar2, #4\n" \ + "SUB D0Ar2, D0Ar2, #1\n" \ + "MOV D1Ar1, #4\n" \ +@@ -486,7 +486,7 @@ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ + : "0" (to), "1" (from), "2" (ret), "3" (n) \ +- : "D1Ar1", "D0Ar2", "memory") ++ : "D1Ar1", "D0Ar2", "cc", "memory") + + /* rewind 'to' and 'from' pointers when a fault occurs + * +@@ -512,7 +512,7 @@ + #define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\ + __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ + "LSR D0Ar2, D0Ar2, #8\n" \ +- "AND D0Ar2, D0Ar2, #0x7\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x7\n" \ + "ADDZ D0Ar2, D0Ar2, #4\n" \ + "SUB D0Ar2, D0Ar2, #1\n" \ + "MOV D1Ar1, #4\n" \ diff --git a/queue-3.18/metag-usercopy-zero-rest-of-buffer-from-copy_from_user.patch b/queue-3.18/metag-usercopy-zero-rest-of-buffer-from-copy_from_user.patch new file mode 100644 index 00000000000..afd3b1f1aba --- /dev/null +++ b/queue-3.18/metag-usercopy-zero-rest-of-buffer-from-copy_from_user.patch @@ -0,0 +1,232 @@ +From 563ddc1076109f2b3f88e6d355eab7b6fd4662cb Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Fri, 31 Mar 2017 11:14:02 +0100 +Subject: metag/usercopy: Zero rest of buffer from copy_from_user + +From: James Hogan + +commit 563ddc1076109f2b3f88e6d355eab7b6fd4662cb upstream. + +Currently we try to zero the destination for a failed read from userland +in fixup code in the usercopy.c macros. The rest of the destination +buffer is then zeroed from __copy_user_zeroing(), which is used for both +copy_from_user() and __copy_from_user(). + +Unfortunately we fail to zero in the fixup code as D1Ar1 is set to 0 +before the fixup code entry labels, and __copy_from_user() shouldn't even +be zeroing the rest of the buffer. + +Move the zeroing out into copy_from_user() and rename +__copy_user_zeroing() to raw_copy_from_user() since it no longer does +any zeroing. This also conveniently matches the name needed for +RAW_COPY_USER support in a later patch. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Reported-by: Al Viro +Signed-off-by: James Hogan +Cc: linux-metag@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/metag/include/asm/uaccess.h | 15 +++++----- + arch/metag/lib/usercopy.c | 57 ++++++++++++--------------------------- + 2 files changed, 26 insertions(+), 46 deletions(-) + +--- a/arch/metag/include/asm/uaccess.h ++++ b/arch/metag/include/asm/uaccess.h +@@ -192,20 +192,21 @@ extern long __must_check strnlen_user(co + + #define strlen_user(str) strnlen_user(str, 32767) + +-extern unsigned long __must_check __copy_user_zeroing(void *to, +- const void __user *from, +- unsigned long n); ++extern unsigned long raw_copy_from_user(void *to, const void __user *from, ++ unsigned long n); + + static inline unsigned long + copy_from_user(void *to, const void __user *from, unsigned long n) + { ++ unsigned long res = n; + if (likely(access_ok(VERIFY_READ, from, n))) +- return __copy_user_zeroing(to, from, n); +- memset(to, 0, n); +- return n; ++ res = raw_copy_from_user(to, from, n); ++ if (unlikely(res)) ++ memset(to + (n - res), 0, res); ++ return res; + } + +-#define __copy_from_user(to, from, n) __copy_user_zeroing(to, from, n) ++#define __copy_from_user(to, from, n) raw_copy_from_user(to, from, n) + #define __copy_from_user_inatomic __copy_from_user + + extern unsigned long __must_check __copy_user(void __user *to, +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -29,7 +29,6 @@ + COPY \ + "1:\n" \ + " .section .fixup,\"ax\"\n" \ +- " MOV D1Ar1,#0\n" \ + FIXUP \ + " MOVT D1Ar1,#HI(1b)\n" \ + " JUMP D1Ar1,#LO(1b)\n" \ +@@ -637,16 +636,14 @@ EXPORT_SYMBOL(__copy_user); + __asm_copy_user_cont(to, from, ret, \ + " GETB D1Ar1,[%1++]\n" \ + "2: SETB [%0++],D1Ar1\n", \ +- "3: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ ++ "3: ADD %2,%2,#1\n", \ + " .long 2b,3b\n") + + #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_user_cont(to, from, ret, \ + " GETW D1Ar1,[%1++]\n" \ + "2: SETW [%0++],D1Ar1\n" COPY, \ +- "3: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ ++ "3: ADD %2,%2,#2\n" FIXUP, \ + " .long 2b,3b\n" TENTRY) + + #define __asm_copy_from_user_2(to, from, ret) \ +@@ -656,32 +653,26 @@ EXPORT_SYMBOL(__copy_user); + __asm_copy_from_user_2x_cont(to, from, ret, \ + " GETB D1Ar1,[%1++]\n" \ + "4: SETB [%0++],D1Ar1\n", \ +- "5: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ ++ "5: ADD %2,%2,#1\n", \ + " .long 4b,5b\n") + + #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_user_cont(to, from, ret, \ + " GETD D1Ar1,[%1++]\n" \ + "2: SETD [%0++],D1Ar1\n" COPY, \ +- "3: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ ++ "3: ADD %2,%2,#4\n" FIXUP, \ + " .long 2b,3b\n" TENTRY) + + #define __asm_copy_from_user_4(to, from, ret) \ + __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") + +- + #define __asm_copy_from_user_8x64(to, from, ret) \ + asm volatile ( \ + " GETL D0Ar2,D1Ar1,[%1++]\n" \ + "2: SETL [%0++],D0Ar2,D1Ar1\n" \ + "1:\n" \ + " .section .fixup,\"ax\"\n" \ +- " MOV D1Ar1,#0\n" \ +- " MOV D0Ar2,#0\n" \ + "3: ADD %2,%2,#8\n" \ +- " SETL [%0++],D0Ar2,D1Ar1\n" \ + " MOVT D0Ar2,#HI(1b)\n" \ + " JUMP D0Ar2,#LO(1b)\n" \ + " .previous\n" \ +@@ -721,11 +712,12 @@ EXPORT_SYMBOL(__copy_user); + "SUB %1, %1, #4\n") + + +-/* Copy from user to kernel, zeroing the bytes that were inaccessible in +- userland. The return-value is the number of bytes that were +- inaccessible. */ +-unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, +- unsigned long n) ++/* ++ * Copy from user to kernel. The return-value is the number of bytes that were ++ * inaccessible. ++ */ ++unsigned long raw_copy_from_user(void *pdst, const void __user *psrc, ++ unsigned long n) + { + register char *dst asm ("A0.2") = pdst; + register const char __user *src asm ("A1.2") = psrc; +@@ -738,7 +730,7 @@ unsigned long __copy_user_zeroing(void * + __asm_copy_from_user_1(dst, src, retn); + n--; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + if ((unsigned long) dst & 1) { + /* Worst case - byte copy */ +@@ -746,14 +738,14 @@ unsigned long __copy_user_zeroing(void * + __asm_copy_from_user_1(dst, src, retn); + n--; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + if (((unsigned long) src & 2) && n >= 2) { + __asm_copy_from_user_2(dst, src, retn); + n -= 2; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + if ((unsigned long) dst & 2) { + /* Second worst case - word copy */ +@@ -761,7 +753,7 @@ unsigned long __copy_user_zeroing(void * + __asm_copy_from_user_2(dst, src, retn); + n -= 2; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + +@@ -777,7 +769,7 @@ unsigned long __copy_user_zeroing(void * + __asm_copy_from_user_8x64(dst, src, retn); + n -= 8; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + +@@ -793,7 +785,7 @@ unsigned long __copy_user_zeroing(void * + __asm_copy_from_user_8x64(dst, src, retn); + n -= 8; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + #endif +@@ -803,7 +795,7 @@ unsigned long __copy_user_zeroing(void * + n -= 4; + + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + + /* If we get here, there were no memory read faults. */ +@@ -829,21 +821,8 @@ unsigned long __copy_user_zeroing(void * + /* If we get here, retn correctly reflects the number of failing + bytes. */ + return retn; +- +- copy_exception_bytes: +- /* We already have "retn" bytes cleared, and need to clear the +- remaining "n" bytes. A non-optimized simple byte-for-byte in-line +- memset is preferred here, since this isn't speed-critical code and +- we'd rather have this a leaf-function than calling memset. */ +- { +- char *endp; +- for (endp = dst + n; dst < endp; dst++) +- *dst = 0; +- } +- +- return retn + n; + } +-EXPORT_SYMBOL(__copy_user_zeroing); ++EXPORT_SYMBOL(raw_copy_from_user); + + #define __asm_clear_8x64(to, ret) \ + asm volatile ( \ diff --git a/queue-3.18/mips-flush-wrong-invalid-ftlb-entry-for-huge-page.patch b/queue-3.18/mips-flush-wrong-invalid-ftlb-entry-for-huge-page.patch new file mode 100644 index 00000000000..3220a15a67b --- /dev/null +++ b/queue-3.18/mips-flush-wrong-invalid-ftlb-entry-for-huge-page.patch @@ -0,0 +1,102 @@ +From 0115f6cbf26663c86496bc56eeea293f85b77897 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Thu, 16 Mar 2017 21:00:27 +0800 +Subject: MIPS: Flush wrong invalid FTLB entry for huge page + +From: Huacai Chen + +commit 0115f6cbf26663c86496bc56eeea293f85b77897 upstream. + +On VTLB+FTLB platforms (such as Loongson-3A R2), FTLB's pagesize is +usually configured the same as PAGE_SIZE. In such a case, Huge page +entry is not suitable to write in FTLB. + +Unfortunately, when a huge page is created, its page table entries +haven't created immediately. Then the TLB refill handler will fetch an +invalid page table entry which has no "HUGE" bit, and this entry may be +written to FTLB. Since it is invalid, TLB load/store handler will then +use tlbwi to write the valid entry at the same place. However, the +valid entry is a huge page entry which isn't suitable for FTLB. + +Our solution is to modify build_huge_handler_tail. Flush the invalid +old entry (whether it is in FTLB or VTLB, this is in order to reduce +branches) and use tlbwr to write the valid new entry. + +Signed-off-by: Rui Wang +Signed-off-by: Huacai Chen +Cc: John Crispin +Cc: Steven J . Hill +Cc: Fuxin Zhang +Cc: Zhangjin Wu +Cc: Huacai Chen +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15754/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/mm/tlbex.c | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) + +--- a/arch/mips/mm/tlbex.c ++++ b/arch/mips/mm/tlbex.c +@@ -754,7 +754,8 @@ static void build_huge_update_entries(u3 + static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, + struct uasm_label **l, + unsigned int pte, +- unsigned int ptr) ++ unsigned int ptr, ++ unsigned int flush) + { + #ifdef CONFIG_SMP + UASM_i_SC(p, pte, 0, ptr); +@@ -763,6 +764,22 @@ static void build_huge_handler_tail(u32 + #else + UASM_i_SW(p, pte, 0, ptr); + #endif ++ if (cpu_has_ftlb && flush) { ++ BUG_ON(!cpu_has_tlbinv); ++ ++ UASM_i_MFC0(p, ptr, C0_ENTRYHI); ++ uasm_i_ori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); ++ UASM_i_MTC0(p, ptr, C0_ENTRYHI); ++ build_tlb_write_entry(p, l, r, tlb_indexed); ++ ++ uasm_i_xori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); ++ UASM_i_MTC0(p, ptr, C0_ENTRYHI); ++ build_huge_update_entries(p, pte, ptr); ++ build_huge_tlb_write_entry(p, l, r, pte, tlb_random, 0); ++ ++ return; ++ } ++ + build_huge_update_entries(p, pte, ptr); + build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0); + } +@@ -2061,7 +2078,7 @@ static void build_r4000_tlb_load_handler + uasm_l_tlbl_goaround2(&l, p); + } + uasm_i_ori(&p, wr.r1, wr.r1, (_PAGE_ACCESSED | _PAGE_VALID)); +- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); ++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); + #endif + + uasm_l_nopage_tlbl(&l, p); +@@ -2116,7 +2133,7 @@ static void build_r4000_tlb_store_handle + build_tlb_probe_entry(&p); + uasm_i_ori(&p, wr.r1, wr.r1, + _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); +- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); ++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); + #endif + + uasm_l_nopage_tlbs(&l, p); +@@ -2172,7 +2189,7 @@ static void build_r4000_tlb_modify_handl + build_tlb_probe_entry(&p); + uasm_i_ori(&p, wr.r1, wr.r1, + _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); +- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); ++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 0); + #endif + + uasm_l_nopage_tlbm(&l, p); diff --git a/queue-3.18/mm-hugetlb-use-pte_present-instead-of-pmd_present-in-follow_huge_pmd.patch b/queue-3.18/mm-hugetlb-use-pte_present-instead-of-pmd_present-in-follow_huge_pmd.patch new file mode 100644 index 00000000000..e64a3c981e9 --- /dev/null +++ b/queue-3.18/mm-hugetlb-use-pte_present-instead-of-pmd_present-in-follow_huge_pmd.patch @@ -0,0 +1,104 @@ +From 47e2fe17d14d1a7da3a405b1f364c094c271d35c Mon Sep 17 00:00:00 2001 +From: Naoya Horiguchi +Date: Fri, 31 Mar 2017 15:11:55 -0700 +Subject: mm, hugetlb: use pte_present() instead of pmd_present() in follow_huge_pmd() + +From: Naoya Horiguchi + +commit c9d398fa237882ea07167e23bcfc5e6847066518 upstream. + +I found the race condition which triggers the following bug when +move_pages() and soft offline are called on a single hugetlb page +concurrently. + + Soft offlining page 0x119400 at 0x700000000000 + BUG: unable to handle kernel paging request at ffffea0011943820 + IP: follow_huge_pmd+0x143/0x190 + PGD 7ffd2067 + PUD 7ffd1067 + PMD 0 + [61163.582052] Oops: 0000 [#1] SMP + Modules linked in: binfmt_misc ppdev virtio_balloon parport_pc pcspkr i2c_piix4 parport i2c_core acpi_cpufreq ip_tables xfs libcrc32c ata_generic pata_acpi virtio_blk 8139too crc32c_intel ata_piix serio_raw libata virtio_pci 8139cp virtio_ring virtio mii floppy dm_mirror dm_region_hash dm_log dm_mod [last unloaded: cap_check] + CPU: 0 PID: 22573 Comm: iterate_numa_mo Tainted: P OE 4.11.0-rc2-mm1+ #2 + Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 + RIP: 0010:follow_huge_pmd+0x143/0x190 + RSP: 0018:ffffc90004bdbcd0 EFLAGS: 00010202 + RAX: 0000000465003e80 RBX: ffffea0004e34d30 RCX: 00003ffffffff000 + RDX: 0000000011943800 RSI: 0000000000080001 RDI: 0000000465003e80 + RBP: ffffc90004bdbd18 R08: 0000000000000000 R09: ffff880138d34000 + R10: ffffea0004650000 R11: 0000000000c363b0 R12: ffffea0011943800 + R13: ffff8801b8d34000 R14: ffffea0000000000 R15: 000077ff80000000 + FS: 00007fc977710740(0000) GS:ffff88007dc00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: ffffea0011943820 CR3: 000000007a746000 CR4: 00000000001406f0 + Call Trace: + follow_page_mask+0x270/0x550 + SYSC_move_pages+0x4ea/0x8f0 + SyS_move_pages+0xe/0x10 + do_syscall_64+0x67/0x180 + entry_SYSCALL64_slow_path+0x25/0x25 + RIP: 0033:0x7fc976e03949 + RSP: 002b:00007ffe72221d88 EFLAGS: 00000246 ORIG_RAX: 0000000000000117 + RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fc976e03949 + RDX: 0000000000c22390 RSI: 0000000000001400 RDI: 0000000000005827 + RBP: 00007ffe72221e00 R08: 0000000000c2c3a0 R09: 0000000000000004 + R10: 0000000000c363b0 R11: 0000000000000246 R12: 0000000000400650 + R13: 00007ffe72221ee0 R14: 0000000000000000 R15: 0000000000000000 + Code: 81 e4 ff ff 1f 00 48 21 c2 49 c1 ec 0c 48 c1 ea 0c 4c 01 e2 49 bc 00 00 00 00 00 ea ff ff 48 c1 e2 06 49 01 d4 f6 45 bc 04 74 90 <49> 8b 7c 24 20 40 f6 c7 01 75 2b 4c 89 e7 8b 47 1c 85 c0 7e 2a + RIP: follow_huge_pmd+0x143/0x190 RSP: ffffc90004bdbcd0 + CR2: ffffea0011943820 + ---[ end trace e4f81353a2d23232 ]--- + Kernel panic - not syncing: Fatal exception + Kernel Offset: disabled + +This bug is triggered when pmd_present() returns true for non-present +hugetlb, so fixing the present check in follow_huge_pmd() prevents it. +Using pmd_present() to determine present/non-present for hugetlb is not +correct, because pmd_present() checks multiple bits (not only +_PAGE_PRESENT) for historical reason and it can misjudge hugetlb state. + +Fixes: e66f17ff7177 ("mm/hugetlb: take page table lock in follow_huge_pmd()") +Link: http://lkml.kernel.org/r/1490149898-20231-1-git-send-email-n-horiguchi@ah.jp.nec.com +Signed-off-by: Naoya Horiguchi +Acked-by: Hillf Danton +Cc: Hugh Dickins +Cc: Michal Hocko +Cc: "Kirill A. Shutemov" +Cc: Mike Kravetz +Cc: Christian Borntraeger +Cc: Gerald Schaefer +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/hugetlb.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -3753,6 +3753,7 @@ follow_huge_pmd(struct mm_struct *mm, un + { + struct page *page = NULL; + spinlock_t *ptl; ++ pte_t pte; + retry: + ptl = pmd_lockptr(mm, pmd); + spin_lock(ptl); +@@ -3762,13 +3763,14 @@ retry: + */ + if (!pmd_huge(*pmd)) + goto out; +- if (pmd_present(*pmd)) { ++ pte = huge_ptep_get((pte_t *)pmd); ++ if (pte_present(pte)) { + page = pte_page(*(pte_t *)pmd) + + ((address & ~PMD_MASK) >> PAGE_SHIFT); + if (flags & FOLL_GET) + get_page(page); + } else { +- if (is_hugetlb_entry_migration(huge_ptep_get((pte_t *)pmd))) { ++ if (is_hugetlb_entry_migration(pte)) { + spin_unlock(ptl); + __migration_entry_wait(mm, (pte_t *)pmd, ptl); + goto retry; diff --git a/queue-3.18/mm-mempolicy.c-fix-error-handling-in-set_mempolicy-and-mbind.patch b/queue-3.18/mm-mempolicy.c-fix-error-handling-in-set_mempolicy-and-mbind.patch new file mode 100644 index 00000000000..1858bc755df --- /dev/null +++ b/queue-3.18/mm-mempolicy.c-fix-error-handling-in-set_mempolicy-and-mbind.patch @@ -0,0 +1,77 @@ +From cf01fb9985e8deb25ccf0ea54d916b8871ae0e62 Mon Sep 17 00:00:00 2001 +From: Chris Salls +Date: Fri, 7 Apr 2017 23:48:11 -0700 +Subject: mm/mempolicy.c: fix error handling in set_mempolicy and mbind. + +From: Chris Salls + +commit cf01fb9985e8deb25ccf0ea54d916b8871ae0e62 upstream. + +In the case that compat_get_bitmap fails we do not want to copy the +bitmap to the user as it will contain uninitialized stack data and leak +sensitive data. + +Signed-off-by: Chris Salls +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/mempolicy.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -1546,7 +1546,6 @@ COMPAT_SYSCALL_DEFINE5(get_mempolicy, in + COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask, + compat_ulong_t, maxnode) + { +- long err = 0; + unsigned long __user *nm = NULL; + unsigned long nr_bits, alloc_size; + DECLARE_BITMAP(bm, MAX_NUMNODES); +@@ -1555,14 +1554,13 @@ COMPAT_SYSCALL_DEFINE3(set_mempolicy, in + alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; + + if (nmask) { +- err = compat_get_bitmap(bm, nmask, nr_bits); ++ if (compat_get_bitmap(bm, nmask, nr_bits)) ++ return -EFAULT; + nm = compat_alloc_user_space(alloc_size); +- err |= copy_to_user(nm, bm, alloc_size); ++ if (copy_to_user(nm, bm, alloc_size)) ++ return -EFAULT; + } + +- if (err) +- return -EFAULT; +- + return sys_set_mempolicy(mode, nm, nr_bits+1); + } + +@@ -1570,7 +1568,6 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulo + compat_ulong_t, mode, compat_ulong_t __user *, nmask, + compat_ulong_t, maxnode, compat_ulong_t, flags) + { +- long err = 0; + unsigned long __user *nm = NULL; + unsigned long nr_bits, alloc_size; + nodemask_t bm; +@@ -1579,14 +1576,13 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulo + alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; + + if (nmask) { +- err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits); ++ if (compat_get_bitmap(nodes_addr(bm), nmask, nr_bits)) ++ return -EFAULT; + nm = compat_alloc_user_space(alloc_size); +- err |= copy_to_user(nm, nodes_addr(bm), alloc_size); ++ if (copy_to_user(nm, nodes_addr(bm), alloc_size)) ++ return -EFAULT; + } + +- if (err) +- return -EFAULT; +- + return sys_mbind(start, len, mode, nm, nr_bits+1, flags); + } + diff --git a/queue-3.18/mtd-bcm47xxpart-fix-parsing-first-block-after-aligned-trx.patch b/queue-3.18/mtd-bcm47xxpart-fix-parsing-first-block-after-aligned-trx.patch new file mode 100644 index 00000000000..b620abb9ced --- /dev/null +++ b/queue-3.18/mtd-bcm47xxpart-fix-parsing-first-block-after-aligned-trx.patch @@ -0,0 +1,46 @@ +From bd5d21310133921021d78995ad6346f908483124 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sun, 20 Nov 2016 16:09:30 +0100 +Subject: mtd: bcm47xxpart: fix parsing first block after aligned TRX +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rafał Miłecki + +commit bd5d21310133921021d78995ad6346f908483124 upstream. + +After parsing TRX we should skip to the first block placed behind it. +Our code was working only with TRX with length not aligned to the +blocksize. In other cases (length aligned) it was missing the block +places right after TRX. + +This fixes calculation and simplifies the comment. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Brian Norris +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/bcm47xxpart.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -183,12 +183,10 @@ static int bcm47xxpart_parse(struct mtd_ + + last_trx_part = curr_part - 1; + +- /* +- * We have whole TRX scanned, skip to the next part. Use +- * roundown (not roundup), as the loop will increase +- * offset in next step. +- */ +- offset = rounddown(offset + trx->length, blocksize); ++ /* Jump to the end of TRX */ ++ offset = roundup(offset + trx->length, blocksize); ++ /* Next loop iteration will increase the offset */ ++ offset -= blocksize; + continue; + } + diff --git a/queue-3.18/pinctrl-qcom-don-t-clear-status-bit-on-irq_unmask.patch b/queue-3.18/pinctrl-qcom-don-t-clear-status-bit-on-irq_unmask.patch new file mode 100644 index 00000000000..a8fc749e15c --- /dev/null +++ b/queue-3.18/pinctrl-qcom-don-t-clear-status-bit-on-irq_unmask.patch @@ -0,0 +1,37 @@ +From a6566710adaa4a7dd5e0d99820ff9c9c30ee5951 Mon Sep 17 00:00:00 2001 +From: Bjorn Andersson +Date: Tue, 14 Mar 2017 08:23:26 -0700 +Subject: pinctrl: qcom: Don't clear status bit on irq_unmask + +From: Bjorn Andersson + +commit a6566710adaa4a7dd5e0d99820ff9c9c30ee5951 upstream. + +Clearing the status bit on irq_unmask will discard any pending interrupt +that did arrive after the irq_ack, i.e. while the IRQ handler function +was executing. + +Fixes: f365be092572 ("pinctrl: Add Qualcomm TLMM driver") +Cc: Stephen Boyd +Reported-by: Timur Tabi +Signed-off-by: Bjorn Andersson +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pinctrl/qcom/pinctrl-msm.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/drivers/pinctrl/qcom/pinctrl-msm.c ++++ b/drivers/pinctrl/qcom/pinctrl-msm.c +@@ -616,10 +616,6 @@ static void msm_gpio_irq_unmask(struct i + + spin_lock_irqsave(&pctrl->lock, flags); + +- val = readl(pctrl->regs + g->intr_status_reg); +- val &= ~BIT(g->intr_status_bit); +- writel(val, pctrl->regs + g->intr_status_reg); +- + val = readl(pctrl->regs + g->intr_cfg_reg); + val |= BIT(g->intr_enable_bit); + writel(val, pctrl->regs + g->intr_cfg_reg); diff --git a/queue-3.18/ring-buffer-fix-return-value-check-in-test_ringbuffer.patch b/queue-3.18/ring-buffer-fix-return-value-check-in-test_ringbuffer.patch new file mode 100644 index 00000000000..0cee850c354 --- /dev/null +++ b/queue-3.18/ring-buffer-fix-return-value-check-in-test_ringbuffer.patch @@ -0,0 +1,50 @@ +From 62277de758b155dc04b78f195a1cb5208c37b2df Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Fri, 17 Jun 2016 17:33:59 +0000 +Subject: ring-buffer: Fix return value check in test_ringbuffer() + +From: Wei Yongjun + +commit 62277de758b155dc04b78f195a1cb5208c37b2df upstream. + +In case of error, the function kthread_run() returns ERR_PTR() +and never returns NULL. The NULL test in the return value check +should be replaced with IS_ERR(). + +Link: http://lkml.kernel.org/r/1466184839-14927-1-git-send-email-weiyj_lk@163.com + +Fixes: 6c43e554a ("ring-buffer: Add ring buffer startup selftest") +Signed-off-by: Wei Yongjun +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ring_buffer.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -4883,9 +4883,9 @@ static __init int test_ringbuffer(void) + rb_data[cpu].cnt = cpu; + rb_threads[cpu] = kthread_create(rb_test, &rb_data[cpu], + "rbtester/%d", cpu); +- if (WARN_ON(!rb_threads[cpu])) { ++ if (WARN_ON(IS_ERR(rb_threads[cpu]))) { + pr_cont("FAILED\n"); +- ret = -1; ++ ret = PTR_ERR(rb_threads[cpu]); + goto out_free; + } + +@@ -4895,9 +4895,9 @@ static __init int test_ringbuffer(void) + + /* Now create the rb hammer! */ + rb_hammer = kthread_run(rb_hammer_test, NULL, "rbhammer"); +- if (WARN_ON(!rb_hammer)) { ++ if (WARN_ON(IS_ERR(rb_hammer))) { + pr_cont("FAILED\n"); +- ret = -1; ++ ret = PTR_ERR(rb_hammer); + goto out_free; + } + diff --git a/queue-3.18/series b/queue-3.18/series index a20b93f256c..45e402fb218 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -105,3 +105,20 @@ xfs-clear-_xbf_pages-from-buffers-when-readahead-page.patch acpi-fix-incompatibility-with-mcount-based-function-graph-tracing.patch acpi-do-not-create-a-platform_device-for-ioapic-ioxapic.patch serial-8250_pci-detach-low-level-driver-during-pci-error-recovery.patch +uvcvideo-uvc_scan_fallback-for-webcams-with-broken-chain.patch +block-allow-write_same-commands-with-the-sg_io-ioctl.patch +virtio_balloon-init-1st-buffer-in-stats-vq.patch +pinctrl-qcom-don-t-clear-status-bit-on-irq_unmask.patch +mm-hugetlb-use-pte_present-instead-of-pmd_present-in-follow_huge_pmd.patch +mtd-bcm47xxpart-fix-parsing-first-block-after-aligned-trx.patch +mm-mempolicy.c-fix-error-handling-in-set_mempolicy-and-mbind.patch +ring-buffer-fix-return-value-check-in-test_ringbuffer.patch +mips-flush-wrong-invalid-ftlb-entry-for-huge-page.patch +metag-usercopy-drop-unused-macros.patch +metag-usercopy-fix-alignment-error-checking.patch +metag-usercopy-add-early-abort-to-copy_to_user.patch +metag-usercopy-zero-rest-of-buffer-from-copy_from_user.patch +metag-usercopy-set-flags-before-addz.patch +metag-usercopy-fix-src-fixup-in-from-user-rapf-loops.patch +metag-usercopy-add-missing-fixups.patch +give-up-on-gcc-ilog2-constant-optimizations.patch diff --git a/queue-3.18/uvcvideo-uvc_scan_fallback-for-webcams-with-broken-chain.patch b/queue-3.18/uvcvideo-uvc_scan_fallback-for-webcams-with-broken-chain.patch new file mode 100644 index 00000000000..91e1405cfd3 --- /dev/null +++ b/queue-3.18/uvcvideo-uvc_scan_fallback-for-webcams-with-broken-chain.patch @@ -0,0 +1,171 @@ +From e950267ab802c8558f1100eafd4087fd039ad634 Mon Sep 17 00:00:00 2001 +From: Henrik Ingo +Date: Sun, 29 May 2016 17:58:00 -0300 +Subject: [media] uvcvideo: uvc_scan_fallback() for webcams with broken chain + +From: Henrik Ingo + +commit e950267ab802c8558f1100eafd4087fd039ad634 upstream. + +Some devices have invalid baSourceID references, causing uvc_scan_chain() +to fail, but if we just take the entities we can find and put them +together in the most sensible chain we can think of, turns out they do +work anyway. Note: This heuristic assumes there is a single chain. + +At the time of writing, devices known to have such a broken chain are + - Acer Integrated Camera (5986:055a) + - Realtek rtl157a7 (0bda:57a7) + +Signed-off-by: Henrik Ingo +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/uvc/uvc_driver.c | 118 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 112 insertions(+), 6 deletions(-) + +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -1553,6 +1553,114 @@ static const char *uvc_print_chain(struc + return buffer; + } + ++static struct uvc_video_chain *uvc_alloc_chain(struct uvc_device *dev) ++{ ++ struct uvc_video_chain *chain; ++ ++ chain = kzalloc(sizeof(*chain), GFP_KERNEL); ++ if (chain == NULL) ++ return NULL; ++ ++ INIT_LIST_HEAD(&chain->entities); ++ mutex_init(&chain->ctrl_mutex); ++ chain->dev = dev; ++ v4l2_prio_init(&chain->prio); ++ ++ return chain; ++} ++ ++/* ++ * Fallback heuristic for devices that don't connect units and terminals in a ++ * valid chain. ++ * ++ * Some devices have invalid baSourceID references, causing uvc_scan_chain() ++ * to fail, but if we just take the entities we can find and put them together ++ * in the most sensible chain we can think of, turns out they do work anyway. ++ * Note: This heuristic assumes there is a single chain. ++ * ++ * At the time of writing, devices known to have such a broken chain are ++ * - Acer Integrated Camera (5986:055a) ++ * - Realtek rtl157a7 (0bda:57a7) ++ */ ++static int uvc_scan_fallback(struct uvc_device *dev) ++{ ++ struct uvc_video_chain *chain; ++ struct uvc_entity *iterm = NULL; ++ struct uvc_entity *oterm = NULL; ++ struct uvc_entity *entity; ++ struct uvc_entity *prev; ++ ++ /* ++ * Start by locating the input and output terminals. We only support ++ * devices with exactly one of each for now. ++ */ ++ list_for_each_entry(entity, &dev->entities, list) { ++ if (UVC_ENTITY_IS_ITERM(entity)) { ++ if (iterm) ++ return -EINVAL; ++ iterm = entity; ++ } ++ ++ if (UVC_ENTITY_IS_OTERM(entity)) { ++ if (oterm) ++ return -EINVAL; ++ oterm = entity; ++ } ++ } ++ ++ if (iterm == NULL || oterm == NULL) ++ return -EINVAL; ++ ++ /* Allocate the chain and fill it. */ ++ chain = uvc_alloc_chain(dev); ++ if (chain == NULL) ++ return -ENOMEM; ++ ++ if (uvc_scan_chain_entity(chain, oterm) < 0) ++ goto error; ++ ++ prev = oterm; ++ ++ /* ++ * Add all Processing and Extension Units with two pads. The order ++ * doesn't matter much, use reverse list traversal to connect units in ++ * UVC descriptor order as we build the chain from output to input. This ++ * leads to units appearing in the order meant by the manufacturer for ++ * the cameras known to require this heuristic. ++ */ ++ list_for_each_entry_reverse(entity, &dev->entities, list) { ++ if (entity->type != UVC_VC_PROCESSING_UNIT && ++ entity->type != UVC_VC_EXTENSION_UNIT) ++ continue; ++ ++ if (entity->num_pads != 2) ++ continue; ++ ++ if (uvc_scan_chain_entity(chain, entity) < 0) ++ goto error; ++ ++ prev->baSourceID[0] = entity->id; ++ prev = entity; ++ } ++ ++ if (uvc_scan_chain_entity(chain, iterm) < 0) ++ goto error; ++ ++ prev->baSourceID[0] = iterm->id; ++ ++ list_add_tail(&chain->list, &dev->chains); ++ ++ uvc_trace(UVC_TRACE_PROBE, ++ "Found a video chain by fallback heuristic (%s).\n", ++ uvc_print_chain(chain)); ++ ++ return 0; ++ ++error: ++ kfree(chain); ++ return -EINVAL; ++} ++ + /* + * Scan the device for video chains and register video devices. + * +@@ -1575,15 +1683,10 @@ static int uvc_scan_device(struct uvc_de + if (term->chain.next || term->chain.prev) + continue; + +- chain = kzalloc(sizeof(*chain), GFP_KERNEL); ++ chain = uvc_alloc_chain(dev); + if (chain == NULL) + return -ENOMEM; + +- INIT_LIST_HEAD(&chain->entities); +- mutex_init(&chain->ctrl_mutex); +- chain->dev = dev; +- v4l2_prio_init(&chain->prio); +- + term->flags |= UVC_ENTITY_FLAG_DEFAULT; + + if (uvc_scan_chain(chain, term) < 0) { +@@ -1597,6 +1700,9 @@ static int uvc_scan_device(struct uvc_de + list_add_tail(&chain->list, &dev->chains); + } + ++ if (list_empty(&dev->chains)) ++ uvc_scan_fallback(dev); ++ + if (list_empty(&dev->chains)) { + uvc_printk(KERN_INFO, "No valid video chain found.\n"); + return -1; diff --git a/queue-3.18/virtio_balloon-init-1st-buffer-in-stats-vq.patch b/queue-3.18/virtio_balloon-init-1st-buffer-in-stats-vq.patch new file mode 100644 index 00000000000..65c267c0936 --- /dev/null +++ b/queue-3.18/virtio_balloon-init-1st-buffer-in-stats-vq.patch @@ -0,0 +1,51 @@ +From fc8653228c8588a120f6b5dad6983b7b61ff669e Mon Sep 17 00:00:00 2001 +From: Ladi Prosek +Date: Thu, 23 Mar 2017 08:04:18 +0100 +Subject: virtio_balloon: init 1st buffer in stats vq + +From: Ladi Prosek + +commit fc8653228c8588a120f6b5dad6983b7b61ff669e upstream. + +When init_vqs runs, virtio_balloon.stats is either uninitialized or +contains stale values. The host updates its state with garbage data +because it has no way of knowing that this is just a marker buffer +used for signaling. + +This patch updates the stats before pushing the initial buffer. + +Alternative fixes: +* Push an empty buffer in init_vqs. Not easily done with the current + virtio implementation and violates the spec "Driver MUST supply the + same subset of statistics in all buffers submitted to the statsq". +* Push a buffer with invalid tags in init_vqs. Violates the same + spec clause, plus "invalid tag" is not really defined. + +Note: the spec says: + When using the legacy interface, the device SHOULD ignore all values in + the first buffer in the statsq supplied by the driver after device + initialization. Note: Historically, drivers supplied an uninitialized + buffer in the first buffer. + +Unfortunately QEMU does not seem to implement the recommendation +even for the legacy interface. + +Signed-off-by: Ladi Prosek +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/virtio/virtio_balloon.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/virtio/virtio_balloon.c ++++ b/drivers/virtio/virtio_balloon.c +@@ -355,6 +355,8 @@ static int init_vqs(struct virtio_balloo + * Prime this virtqueue with one buffer so the hypervisor can + * use it to signal us later (it can't be broken yet!). + */ ++ update_balloon_stats(vb); ++ + sg_init_one(&sg, vb->stats, sizeof vb->stats); + if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL) + < 0)