Received: by 10.223.185.116 with SMTP id b49csp1046979wrg; Fri, 23 Feb 2018 10:57:52 -0800 (PST) X-Google-Smtp-Source: AH8x226GZHGww1YYDs8aMaOpwE0JaSqm+GSkDAN+IDEWaURhpqvPNWfanUi3DRGjib5lZA+jTMGY X-Received: by 2002:a17:902:367:: with SMTP id 94-v6mr2633785pld.140.1519412272795; Fri, 23 Feb 2018 10:57:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519412272; cv=none; d=google.com; s=arc-20160816; b=HeJJeHYEPh3iTLwYoUr5B+MFs8z43jqDbYS1PLWAWU4DBLK1T2B1LJRvsDzrtfdAdD jm/Tq1k1uWTZuNtEn9GuOhD90qA3bLUNYIdKh3p9JKedTvmEft25govKnSwUVCh4zx6j YIrfY8F3qMr+5rABLID44kI8qYvlVwPCfwFUiuxzV8llFS/oBZAwRvbNh1Ak8e4UNmcB WzBhXFi31SusMzIajVFQNKAmvIXNc1S4fELnixufDdKezIVvJI5gLU4FTvckTRtzte+U p7bPLmOLUew9qF3TgKna6+nTmT8cs8V9DxGKMkbq51RmVAFZW3EUmqVMIOrEzK88+C3R SqsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=AqjO7q8vzlqakhM/YU2L42myq/51gIKu/Mm5opxfZ8k=; b=YeURfEIiJBLkvD2ui5BWhz/bGTJT0zzJgxfQXSvSG+T9FY3AGcDr7CkA4eYWI3uCH0 wy3pKbDoSXXPyBNx93KPUCk+X8yBXrYIMjCl3O7kG1EtsAFSHULekOiNhCh1TPX+uduc Z7k1/r31CQNshglLw3e+c6D0AjdHIwFXRV+EG1QJhx29jan7Z35ci9Xwsv2ZFks034EY 38C0ypd8R0jBJXoGwTc/EFec/aWT//nZs3XeLVBwXDw6f2gse7Bryqeqsk744TOuZGcF yVDuRhGHJqRoNjdMAR07N2wi5J2ddnKCyydCEM2LOWaP74WLAO5FRCCyuKTCGpSpQU0g CHvw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 33-v6si2144964ply.512.2018.02.23.10.57.38; Fri, 23 Feb 2018 10:57:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965268AbeBWS4N (ORCPT + 99 others); Fri, 23 Feb 2018 13:56:13 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:48542 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965199AbeBWS4K (ORCPT ); Fri, 23 Feb 2018 13:56:10 -0500 Received: from localhost (LFbn-1-12258-90.w90-92.abo.wanadoo.fr [90.92.71.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id AE4BE129C; Fri, 23 Feb 2018 18:56:09 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Lyude , Karol Herbst , Pekka Paalanen , Linus Torvalds , Peter Zijlstra , Steven Rostedt , Thomas Gleixner , nouveau@lists.freedesktop.org, Ingo Molnar , Sasha Levin Subject: [PATCH 4.14 148/159] x86/mm/kmmio: Fix mmiotrace for page unaligned addresses Date: Fri, 23 Feb 2018 19:27:36 +0100 Message-Id: <20180223170800.883691621@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180223170743.086611315@linuxfoundation.org> References: <20180223170743.086611315@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Karol Herbst [ Upstream commit 6d60ce384d1d5ca32b595244db4077a419acc687 ] If something calls ioremap() with an address not aligned to PAGE_SIZE, the returned address might be not aligned as well. This led to a probe registered on exactly the returned address, but the entire page was armed for mmiotracing. On calling iounmap() the address passed to unregister_kmmio_probe() was PAGE_SIZE aligned by the caller leading to a complete freeze of the machine. We should always page align addresses while (un)registerung mappings, because the mmiotracer works on top of pages, not mappings. We still keep track of the probes based on their real addresses and lengths though, because the mmiotrace still needs to know what are mapped memory regions. Also move the call to mmiotrace_iounmap() prior page aligning the address, so that all probes are unregistered properly, otherwise the kernel ends up failing memory allocations randomly after disabling the mmiotracer. Tested-by: Lyude Signed-off-by: Karol Herbst Acked-by: Pekka Paalanen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Steven Rostedt Cc: Thomas Gleixner Cc: nouveau@lists.freedesktop.org Link: http://lkml.kernel.org/r/20171127075139.4928-1-kherbst@redhat.com Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- arch/x86/mm/ioremap.c | 4 ++-- arch/x86/mm/kmmio.c | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -349,11 +349,11 @@ void iounmap(volatile void __iomem *addr return; } + mmiotrace_iounmap(addr); + addr = (volatile void __iomem *) (PAGE_MASK & (unsigned long __force)addr); - mmiotrace_iounmap(addr); - /* Use the vm area unlocked, assuming the caller ensures there isn't another iounmap for the same address in parallel. Reuse of the virtual address is prevented by --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -435,17 +435,18 @@ int register_kmmio_probe(struct kmmio_pr unsigned long flags; int ret = 0; unsigned long size = 0; + unsigned long addr = p->addr & PAGE_MASK; const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK); unsigned int l; pte_t *pte; spin_lock_irqsave(&kmmio_lock, flags); - if (get_kmmio_probe(p->addr)) { + if (get_kmmio_probe(addr)) { ret = -EEXIST; goto out; } - pte = lookup_address(p->addr, &l); + pte = lookup_address(addr, &l); if (!pte) { ret = -EINVAL; goto out; @@ -454,7 +455,7 @@ int register_kmmio_probe(struct kmmio_pr kmmio_count++; list_add_rcu(&p->list, &kmmio_probes); while (size < size_lim) { - if (add_kmmio_fault_page(p->addr + size)) + if (add_kmmio_fault_page(addr + size)) pr_err("Unable to set page fault.\n"); size += page_level_size(l); } @@ -528,19 +529,20 @@ void unregister_kmmio_probe(struct kmmio { unsigned long flags; unsigned long size = 0; + unsigned long addr = p->addr & PAGE_MASK; const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK); struct kmmio_fault_page *release_list = NULL; struct kmmio_delayed_release *drelease; unsigned int l; pte_t *pte; - pte = lookup_address(p->addr, &l); + pte = lookup_address(addr, &l); if (!pte) return; spin_lock_irqsave(&kmmio_lock, flags); while (size < size_lim) { - release_kmmio_fault_page(p->addr + size, &release_list); + release_kmmio_fault_page(addr + size, &release_list); size += page_level_size(l); } list_del_rcu(&p->list);