Received: by 10.223.185.116 with SMTP id b49csp1095464wrg; Fri, 23 Feb 2018 11:51:39 -0800 (PST) X-Google-Smtp-Source: AH8x225exJGQFXiFD3F+KWHWV9Ibz2dasw+U6L5bVosT58egCMM78A/Fhv1dqRQ5l18R/3AXsivI X-Received: by 10.99.96.206 with SMTP id u197mr2179559pgb.261.1519415499096; Fri, 23 Feb 2018 11:51:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519415499; cv=none; d=google.com; s=arc-20160816; b=tviFlN95srREN0zYQ+tAb/lVb1NCOCbfiPxysIxgN2nuDgaOKAcEHEO5+XkVZ8UsPF wVZ/dI8+R3CDgo3dmzbzxSWlfyG8jeKZCMi/1YytaVS+ZfvV2mH11P1xw0jjSzNfMVC5 Pp5UWMj4EYC6FfyaRBgz3/e6YH5bGHvu4bZlj14T+flTepjEAkKeCzeIZvn6Eza7b85Z Yz0d+IdnzH29GHb4SUcgpsVgfWd3/JrbhWJZZvW017YZjjtbBoHWyfBgcBZl7fzvapNM qCQNCfrc8T0xVmGTiKZh3LS4oRPOgIEWQSGY7B2NQGvzWyhYxW6lL8yy7Nboa3UTz5bj RNkw== 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=rwtTyhvVVeJ/BgfBbZJ956gYrU5NUu+NBz0HV7VrlxU=; b=uWmH315j7w7wql8SXQ8Sw6B2dVHI4ujFcz8h6qxvedi1Gqjs3ugknLNRTDmd0EwaEG 4a864kDopNv/lwxmgaIRJnoVETjObWEitg0S3OQt21y7fFHu4NVPcCsi7lYCg6C5h5TX Ai82rnfoCr0KLlrM1jRwyKeuzay8qlngxZNx+bpsuVK+vyDWvJw9lfyKLw9NU99qyCDB 3wL7Ao5yWciP027D36Argkj6JzqwCU9w2CydmCf1t7oivvnJjE4IEtiwXfaYtujK0Bfz d64s8xLlplEnCHxS5oxmtmgjrV6FuIE3zwWqcHK5qjuOZ4uLXoIkgM2BzQ3HyQ3mdR2d COCw== 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 q11-v6si2175590pll.379.2018.02.23.11.51.25; Fri, 23 Feb 2018 11:51:39 -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 S933992AbeBWSqT (ORCPT + 99 others); Fri, 23 Feb 2018 13:46:19 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:43636 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933975AbeBWSqP (ORCPT ); Fri, 23 Feb 2018 13:46:15 -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 B664612CB; Fri, 23 Feb 2018 18:46:14 +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.9 083/145] x86/mm/kmmio: Fix mmiotrace for page unaligned addresses Date: Fri, 23 Feb 2018 19:26:29 +0100 Message-Id: <20180223170735.466154379@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180223170724.669759283@linuxfoundation.org> References: <20180223170724.669759283@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.9-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 @@ -347,11 +347,11 @@ void iounmap(volatile void __iomem *addr (void __force *)addr < phys_to_virt(ISA_END_ADDRESS)) 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 @@ -434,17 +434,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; @@ -453,7 +454,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); } @@ -527,19 +528,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);