Received: by 2002:a4a:311b:0:0:0:0:0 with SMTP id k27-v6csp4781690ooa; Tue, 14 Aug 2018 10:27:53 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyWlsB5zHqjmcxWu79jFLKHasDoamwHywzkTCgPHpCQz0TXxnWPL9qZWj6lbp4uxDJp0v2N X-Received: by 2002:a62:4704:: with SMTP id u4-v6mr24148172pfa.76.1534267673746; Tue, 14 Aug 2018 10:27:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534267673; cv=none; d=google.com; s=arc-20160816; b=iLb+dlGRmFVr22S+rhpGIEqOXQo/N1TpbUNdP/tUlCTxRAhM+7wRcCQ4B3yZZlFMI5 57pwTNAw2pttfFth/ImifIX/7ODTZqWqxRsuAcyfavmWjfCu8O7zDbX8oLdfk0T2AWhY XDZ0rj9x/s0ltf1JNHieLU6YMdjBTc1mebVtQb5tcsA7r8ahE72af0czxrAUqQaSWE+k WZIqC+brh7NrWvbCC827hYfywyFUwZj62phlBOi1In8fv8vvk5p3Ycelz0clGYZV4MeS hQzFbr/BRVWO6HJHKtB7a+g2z7CZpXjA6jJ8H4xRGE33EkY8oJAJFuoutwFAMUFlGCVY xVqA== 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=yqSxOx9WdcEnPREAGo0NKIahNXdhVwvCl0uGRXl/1JM=; b=DjW+cO6C0wM9/qQUNqLI6q+HxGk9BRLhecb1emz7Pid1b9rObcUGpXyfVL79i1I36U 7al/5LEQSC3wtKpNHf88Up7egdOKd3+YBLjC5VPpVGeX7r/1rDDkjSt2BLGUbvwFGzyc MC9c/v+S5PYro5RYycuQJDpaHyzFFTGh7WI59qx7aKFUUPPlXtvZ4PS2uJQjyhlFLFll bEwQbwwuZ87AINf/FsDT7wRsCD/szeLrRYvmlLqODwT93DGSN6Ew7UqlRufxgEqM439m oWoxb+pVxvacjttfx6ofn+A3JmcodTCzlZ2dhNmoQ8p4FrPi1ykc6Z5Y9WOvolvJXJbV w2GQ== 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 o12-v6si18784292pgn.556.2018.08.14.10.27.38; Tue, 14 Aug 2018 10:27:53 -0700 (PDT) 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 S2388227AbeHNUNi (ORCPT + 99 others); Tue, 14 Aug 2018 16:13:38 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:51730 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733240AbeHNUNi (ORCPT ); Tue, 14 Aug 2018 16:13:38 -0400 Received: from localhost (unknown [194.244.16.108]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 8AF74C5C; Tue, 14 Aug 2018 17:25:31 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Linus Torvalds , Andi Kleen , Thomas Gleixner , Josh Poimboeuf , Michal Hocko , Vlastimil Babka , Dave Hansen Subject: [PATCH 4.18 07/79] x86/speculation/l1tf: Protect swap entries against L1TF Date: Tue, 14 Aug 2018 19:16:26 +0200 Message-Id: <20180814171337.079739604@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814171336.799314117@linuxfoundation.org> References: <20180814171336.799314117@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.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Linus Torvalds With L1 terminal fault the CPU speculates into unmapped PTEs, and resulting side effects allow to read the memory the PTE is pointing too, if its values are still in the L1 cache. For swapped out pages Linux uses unmapped PTEs and stores a swap entry into them. To protect against L1TF it must be ensured that the swap entry is not pointing to valid memory, which requires setting higher bits (between bit 36 and bit 45) that are inside the CPUs physical address space, but outside any real memory. To do this invert the offset to make sure the higher bits are always set, as long as the swap file is not too big. Note there is no workaround for 32bit !PAE, or on systems which have more than MAX_PA/2 worth of memory. The later case is very unlikely to happen on real systems. [AK: updated description and minor tweaks by. Split out from the original patch ] Signed-off-by: Linus Torvalds Signed-off-by: Andi Kleen Signed-off-by: Thomas Gleixner Tested-by: Andi Kleen Reviewed-by: Josh Poimboeuf Acked-by: Michal Hocko Acked-by: Vlastimil Babka Acked-by: Dave Hansen Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/pgtable_64.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -273,7 +273,7 @@ static inline int pgd_large(pgd_t pgd) { * * | ... | 11| 10| 9|8|7|6|5| 4| 3|2| 1|0| <- bit number * | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U| W|P| <- bit names - * | TYPE (59-63) | OFFSET (9-58) |0|0|X|X| X| X|X|SD|0| <- swp entry + * | TYPE (59-63) | ~OFFSET (9-58) |0|0|X|X| X| X|X|SD|0| <- swp entry * * G (8) is aliased and used as a PROT_NONE indicator for * !present ptes. We need to start storing swap entries above @@ -286,6 +286,9 @@ static inline int pgd_large(pgd_t pgd) { * * Bit 7 in swp entry should be 0 because pmd_present checks not only P, * but also L and G. + * + * The offset is inverted by a binary not operation to make the high + * physical bits set. */ #define SWP_TYPE_BITS 5 @@ -300,13 +303,15 @@ static inline int pgd_large(pgd_t pgd) { #define __swp_type(x) ((x).val >> (64 - SWP_TYPE_BITS)) /* Shift up (to get rid of type), then down to get value */ -#define __swp_offset(x) ((x).val << SWP_TYPE_BITS >> SWP_OFFSET_SHIFT) +#define __swp_offset(x) (~(x).val << SWP_TYPE_BITS >> SWP_OFFSET_SHIFT) /* * Shift the offset up "too far" by TYPE bits, then down again + * The offset is inverted by a binary not operation to make the high + * physical bits set. */ #define __swp_entry(type, offset) ((swp_entry_t) { \ - ((unsigned long)(offset) << SWP_OFFSET_SHIFT >> SWP_TYPE_BITS) \ + (~(unsigned long)(offset) << SWP_OFFSET_SHIFT >> SWP_TYPE_BITS) \ | ((unsigned long)(type) << (64-SWP_TYPE_BITS)) }) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) })