From patchwork Thu Aug 30 12:52:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Juerg Haefliger X-Patchwork-Id: 963860 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 421Mq13XRhz9s0n; Thu, 30 Aug 2018 22:53:01 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1fvMRQ-0003xr-MO; Thu, 30 Aug 2018 12:52:52 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1fvMRL-0003tC-AP for kernel-team@lists.ubuntu.com; Thu, 30 Aug 2018 12:52:47 +0000 Received: from mail-ed1-f71.google.com ([209.85.208.71]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1fvMRL-0000cW-2o for kernel-team@lists.ubuntu.com; Thu, 30 Aug 2018 12:52:47 +0000 Received: by mail-ed1-f71.google.com with SMTP id m9-v6so3581312eds.17 for ; Thu, 30 Aug 2018 05:52:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=W74nh2PU5G1enQawqxPrE+p10rAYXS3j9a5cFBp7qsE=; b=kCfmQD20hvjo5MfTG3HqTK2ojpPO2qRh76/GQDvVK9PzdkKJnNDl2gGLWAtAWON8q6 gt8UknyTsdt4ECH+HcnAw/kQF9v5JhhNYQ4E6voz0qp7H85SOuJJg1LcVQ4elusATl6C CSg5FprgGGiFEeoEZJnwkhBylxWYRNB0J41C9TMl+BB9A1Ke6uo5QJu3B7mz8ktsCIV6 XmXH+vXQjyTbtD1qRNOYPf9xN3t0Z5Yy3tbBDQL4PE4HyOoWdUnqC2sI5R+LJZPozO9+ H03/F0qTJfoNp4yBtMrBCkFUy6PhBAEG+B2WtRk+7NJ6YrW1tZ0LvLN4jrX/L441qGHq Koug== X-Gm-Message-State: APzg51BNPqoVrcq5v+usyK/21hX4d8fkKNw+YSJ9O5fG/MGCFGtWYmqP SvFZXkAOwQEGywH2dQmtq/NVeNZPJrkbP4HBSrwSQUkrQ+p5hrRohp4VkqwoLiCXwwVyL090H0R D1eFZdjqsUGBCmeU7Q1HP8WphkcRGFuw+06m+mzVThw== X-Received: by 2002:a50:afa3:: with SMTP id h32-v6mr12621594edd.129.1535633566595; Thu, 30 Aug 2018 05:52:46 -0700 (PDT) X-Google-Smtp-Source: ANB0Vda8OOU/7FsQuyXpnHJm08CGps72vh60ErtBeXFlS90YSlN6lWLTJ9SywNuFn/fVTIEU0AgYig== X-Received: by 2002:a50:afa3:: with SMTP id h32-v6mr12621575edd.129.1535633566422; Thu, 30 Aug 2018 05:52:46 -0700 (PDT) Received: from localhost.localdomain ([81.221.205.149]) by smtp.gmail.com with ESMTPSA id y27-v6sm2953550edb.20.2018.08.30.05.52.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 30 Aug 2018 05:52:45 -0700 (PDT) From: Juerg Haefliger X-Google-Original-From: Juerg Haefliger To: kernel-team@lists.ubuntu.com Subject: [SRU][Trusty][PATCH v2 5/7] x86/mm: Fix regression with huge pages on PAE Date: Thu, 30 Aug 2018 14:52:37 +0200 Message-Id: <20180830125239.16775-6-juergh@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180830125239.16775-1-juergh@canonical.com> References: <20180822064021.17216-1-juergh@canonical.com> <20180830125239.16775-1-juergh@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: juergh@canonical.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: "Kirill A. Shutemov" Recent PAT patchset has caused issue on 32-bit PAE machines: page:eea45000 count:0 mapcount:-128 mapping: (null) index:0x0 flags: 0x40000000() page dumped because: VM_BUG_ON_PAGE(page_mapcount(page) < 0) ------------[ cut here ]------------ kernel BUG at /home/build/linux-boris/mm/huge_memory.c:1485! invalid opcode: 0000 [#1] SMP [...] Call Trace: unmap_single_vma ? __wake_up unmap_vmas unmap_region do_munmap vm_munmap SyS_munmap do_fast_syscall_32 ? __do_page_fault sysenter_past_esp Code: ... EIP: [] zap_huge_pmd+0x240/0x260 SS:ESP 0068:f6459d98 The problem is in pmd_pfn_mask() and pmd_flags_mask(). These helpers use PMD_PAGE_MASK to calculate resulting mask. PMD_PAGE_MASK is 'unsigned long', not 'unsigned long long' as phys_addr_t is on 32-bit PAE (ARCH_PHYS_ADDR_T_64BIT). As a result, the upper bits of resulting mask get truncated. pud_pfn_mask() and pud_flags_mask() aren't problematic since we don't have PUD page table level on 32-bit systems, but it's reasonable to keep them consistent with PMD counterpart. Introduce PHYSICAL_PMD_PAGE_MASK and PHYSICAL_PUD_PAGE_MASK in addition to existing PHYSICAL_PAGE_MASK and reworks helpers to use them. Reported-and-Tested-by: Boris Ostrovsky Signed-off-by: Kirill A. Shutemov [ Fix -Woverflow warnings from the realmode code. ] Signed-off-by: Borislav Petkov Reviewed-by: Toshi Kani Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Jürgen Gross Cc: Linus Torvalds Cc: Mel Gorman Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: elliott@hpe.com Cc: konrad.wilk@oracle.com Cc: linux-mm Fixes: f70abb0fc3da ("x86/asm: Fix pud/pmd interfaces to handle large PAT bit") Link: http://lkml.kernel.org/r/1448878233-11390-2-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar Signed-off-by: Ingo Molnar CVE-2018-3620 CVE-2018-3646 (backported from commit 70f1528747651b20c7769d3516ade369f9963237) [juergh: Adjusted context.] Signed-off-by: Juerg Haefliger --- arch/x86/boot/boot.h | 1 - arch/x86/boot/video-mode.c | 2 ++ arch/x86/boot/video.c | 2 ++ arch/x86/include/asm/page_types.h | 7 ++----- arch/x86/include/asm/pgtable_types.h | 14 ++++---------- arch/x86/include/asm/x86_init.h | 1 - 6 files changed, 10 insertions(+), 17 deletions(-) diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index ef72baeff484..9e3281aa02f9 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "bitops.h" #include diff --git a/arch/x86/boot/video-mode.c b/arch/x86/boot/video-mode.c index 748e8d06290a..a0bb0ada348d 100644 --- a/arch/x86/boot/video-mode.c +++ b/arch/x86/boot/video-mode.c @@ -19,6 +19,8 @@ #include "video.h" #include "vesa.h" +#include + /* * Common variables */ diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c index 43eda284d27f..ef69e889bab1 100644 --- a/arch/x86/boot/video.c +++ b/arch/x86/boot/video.c @@ -13,6 +13,8 @@ * Select video mode */ +#include + #include "boot.h" #include "video.h" #include "vesa.h" diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 80678a8775c2..9d0de079af48 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h @@ -12,8 +12,8 @@ #define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT) #define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1)) -#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) -#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) +#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) +#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) #define __PHYSICAL_MASK ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1)) #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) @@ -25,9 +25,6 @@ #define PHYSICAL_PMD_PAGE_MASK (((signed long)PMD_PAGE_MASK) & __PHYSICAL_MASK) #define PHYSICAL_PUD_PAGE_MASK (((signed long)PUD_PAGE_MASK) & __PHYSICAL_MASK) -#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) -#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) - #define HPAGE_SHIFT PMD_SHIFT #define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) #define HPAGE_MASK (~(HPAGE_SIZE - 1)) diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 00a871c5d0af..1f8c0f1cf925 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -331,17 +331,14 @@ static inline pmdval_t native_pmd_val(pmd_t pmd) static inline pudval_t pud_pfn_mask(pud_t pud) { if (native_pud_val(pud) & _PAGE_PSE) - return PUD_PAGE_MASK & PHYSICAL_PAGE_MASK; + return PHYSICAL_PUD_PAGE_MASK; else return PTE_PFN_MASK; } static inline pudval_t pud_flags_mask(pud_t pud) { - if (native_pud_val(pud) & _PAGE_PSE) - return ~(PUD_PAGE_MASK & (pudval_t)PHYSICAL_PAGE_MASK); - else - return ~PTE_PFN_MASK; + return ~pud_pfn_mask(pud); } static inline pudval_t pud_flags(pud_t pud) @@ -352,17 +349,14 @@ static inline pudval_t pud_flags(pud_t pud) static inline pmdval_t pmd_pfn_mask(pmd_t pmd) { if (native_pmd_val(pmd) & _PAGE_PSE) - return PMD_PAGE_MASK & PHYSICAL_PAGE_MASK; + return PHYSICAL_PMD_PAGE_MASK; else return PTE_PFN_MASK; } static inline pmdval_t pmd_flags_mask(pmd_t pmd) { - if (native_pmd_val(pmd) & _PAGE_PSE) - return ~(PMD_PAGE_MASK & (pmdval_t)PHYSICAL_PAGE_MASK); - else - return ~PTE_PFN_MASK; + return ~pmd_pfn_mask(pmd); } static inline pmdval_t pmd_flags(pmd_t pmd) diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index 0f1be11e43d2..666e0bd02be7 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -1,7 +1,6 @@ #ifndef _ASM_X86_PLATFORM_H #define _ASM_X86_PLATFORM_H -#include #include struct mpc_bus;