From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754560AbdKKEFn (ORCPT ); Fri, 10 Nov 2017 23:05:43 -0500 Received: from mail.kernel.org ([198.145.29.99]:52346 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751134AbdKKEFh (ORCPT ); Fri, 10 Nov 2017 23:05:37 -0500 DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5B4502197C Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=luto@kernel.org From: Andy Lutomirski To: X86 ML Cc: Borislav Petkov , "linux-kernel@vger.kernel.org" , Brian Gerst , Dave Hansen , Linus Torvalds , Andy Lutomirski Subject: [RFC 5/7] x86/asm: Rearrange struct cpu_tss to enlarge SYSENTER_stack and fix alignment Date: Fri, 10 Nov 2017 20:05:24 -0800 Message-Id: <2a675c72e35f737156c98ccad5cc3c73c3aa9d72.1510371795.git.luto@kernel.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The Intel SDM says (Volume 3, 7.2.1): Avoid placing a page boundary in the part of the TSS that the processor reads during a task switch (the first 104 bytes). The processor may not correctly perform address translations if a boundary occurs in this area. During a task switch, the processor reads and writes into the first 104 bytes of each TSS (using contiguous physical addresses beginning with the physical address of the first byte of the TSS). So, after TSS access begins, if part of the 104 bytes is not physically contiguous, the processor will access incorrect information without generating a page-fault exception. Merely cacheline-aligning the TSS doesn't actually guarantee that the hardware TSS doesn't span a page. Instead, page-align the structure that contains it. Signed-off-by: Andy Lutomirski --- arch/x86/include/asm/processor.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 301d41ca1fa1..97ded6e3edd3 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -326,6 +326,16 @@ struct x86_hw_tss { struct tss_struct { /* + * Space for the temporary SYSENTER stack. Used for the entry + * trampoline as well. Size it such that tss_struct ends up + * as a multiple of PAGE_SIZE. This calculation assumes that + * io_bitmap is a multiple of PAGE_SIZE (8192 bytes) plus one + * long. + */ + unsigned long SYSENTER_stack_canary; + unsigned long SYSENTER_stack[(PAGE_SIZE - sizeof(struct x86_hw_tss)) / sizeof(unsigned long) - 2]; + + /* * The hardware state: */ struct x86_hw_tss x86_tss; @@ -337,15 +347,9 @@ struct tss_struct { * be within the limit. */ unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; - - /* - * Space for the temporary SYSENTER stack. - */ - unsigned long SYSENTER_stack_canary; - unsigned long SYSENTER_stack[64]; } ____cacheline_aligned; -DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss); +DECLARE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss); /* * sizeof(unsigned long) coming from an extra "long" at the end -- 2.13.6