Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3057857imm; Fri, 20 Jul 2018 09:23:31 -0700 (PDT) X-Google-Smtp-Source: AAOMgpfCd/XTQz3muBdscxpfdindLQ1G7c0W9C5fmfDfIXGIa6sNaEJdUSyfxyKJvmYYB9cxw/JK X-Received: by 2002:a63:4e5f:: with SMTP id o31-v6mr2745091pgl.256.1532103811810; Fri, 20 Jul 2018 09:23:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532103811; cv=none; d=google.com; s=arc-20160816; b=UeGeZ5PkvwUxM2uL8T1iu2Dbv8uR+MMx98iCALUOkwMQWEp3OICR8gPIHNIYg1G6QK pnqWsbYVN3HqK8g2W+xVgCuRuyePu4gOb79SDo8v2l/5Dqyzk5X7sopOzHNCtnoVg6GJ n9huXzW93/Q80GvmxDNLzmgtu0YdHg0Mji+MDyp1VBBZMmzo2MEiHauOoBFuMkkDsGtQ cniM1VWoyi8Eb8+TuCwh+On+jZh0X/YHXGl5hNdTrQgbyTdDnuPF3fe01mncOGozf2so /5gdgjkpmQsM4s4L4UEyMbtZyG8x1EM5RPMGJn39hBYJl6k53tVmgzt/q+bI9JGVEJfa tPWQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=ECaXDFU87RMzvAl9n5zYKAfilu+YgBB9pVsQN1JeITs=; b=mdZ014yXHVVwfLK61ynEbD/Z3XsVTro/b0DZZCgOlkzikU1eCSIp0MOYMBgNE4NXIq PJH6TxJo3vVuLGUWbNkSnJLBC1Hdnyl79dvd8QlSQ59yE5FIk0oNCo/TFZdG1U4NZKqW HQUx7cvsWwL8Hp3sjh6eMiEongpnxk2O3BlecuoRSGWe6aVjaVdwCfQAUcEiSHbgrhO2 BQGrETuHCzQnu2hwVM0z2P2wFbAT8O5BNrJaNoNvVFhAxVttKwW9+xvv6sVhMJ95is2G MHjniqJH3DWsu2z/nn3eJVvggrC1rp61vSvhxFzYttsDDiT8HXv8TOEFTUDOy3r9sqxS DR1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail (test mode) header.i=@8bytes.org header.s=mail-1 header.b=De52EfsT; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=8bytes.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c20-v6si2249668pgg.367.2018.07.20.09.23.16; Fri, 20 Jul 2018 09:23:31 -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; dkim=fail (test mode) header.i=@8bytes.org header.s=mail-1 header.b=De52EfsT; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=8bytes.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388004AbeGTRLm (ORCPT + 99 others); Fri, 20 Jul 2018 13:11:42 -0400 Received: from 8bytes.org ([81.169.241.247]:35872 "EHLO theia.8bytes.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387907AbeGTRLl (ORCPT ); Fri, 20 Jul 2018 13:11:41 -0400 Received: by theia.8bytes.org (Postfix, from userid 1000) id 8DC184DC; Fri, 20 Jul 2018 18:22:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=8bytes.org; s=mail-1; t=1532103759; bh=93K1zGGfsATlPDUeMY+jMYCQoGo2+oe6yojp67mYLac=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=De52EfsTCLFLjZSDZWBQr4Yrl0JilstATSNZB/7acPb1kGI+GQPixdt9uM4REWWPK 8OKYzQCmfXeYNZiNBDWH+/cTGq34D1C0T9I9fe9byqJjvdVI3XytEQiGkmNN7ZXuug KKEo9jc694cVt8UO9KxL+9Kzarjk8B7VsFCN1/DOnmcsFoeRBs1Mh6J41pKq04/eXO DDNAjiddluj4oQSqz4785sXAzdqTCZqCmdMZHYpBlqTWau4kbfji5N3n6l53vPWoid yXQpVS63sNP401MgagUOoTO4rQSYAvOGTjVOIAUtLuxYOm28kpmxvjpB0o7JjuUW+a va75PEEV06NGg== From: Joerg Roedel To: Thomas Gleixner , Ingo Molnar , "H . Peter Anvin" Cc: x86@kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Linus Torvalds , Andy Lutomirski , Dave Hansen , Josh Poimboeuf , Juergen Gross , Peter Zijlstra , Borislav Petkov , Jiri Kosina , Boris Ostrovsky , Brian Gerst , David Laight , Denys Vlasenko , Eduardo Valentin , Greg KH , Will Deacon , aliguori@amazon.com, daniel.gruss@iaik.tugraz.at, hughd@google.com, keescook@google.com, Andrea Arcangeli , Waiman Long , Pavel Machek , "David H . Gutteridge" , jroedel@suse.de, Arnaldo Carvalho de Melo , Alexander Shishkin , Jiri Olsa , Namhyung Kim , joro@8bytes.org Subject: [PATCH 3/3] x86/entry/32: Copy only ptregs on paranoid entry/exit path Date: Fri, 20 Jul 2018 18:22:24 +0200 Message-Id: <1532103744-31902-4-git-send-email-joro@8bytes.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1532103744-31902-1-git-send-email-joro@8bytes.org> References: <1532103744-31902-1-git-send-email-joro@8bytes.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Joerg Roedel The code that switches from entry- to task-stack when we enter from kernel-mode copies the full entry-stack contents to the task-stack. That is because we don't trust that the entry-stack contents. But actually we can trust its contents if we are not scheduled between entry and exit. So do less copying and move only the ptregs over to the task-stack in this code-path. Suggested-by: Andy Lutomirski Signed-off-by: Joerg Roedel --- arch/x86/entry/entry_32.S | 70 +++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index 2767c62..90166b2 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -469,33 +469,48 @@ * segment registers on the way back to user-space or when the * sysenter handler runs with eflags.tf set. * - * When we switch to the task-stack here, we can't trust the - * contents of the entry-stack anymore, as the exception handler - * might be scheduled out or moved to another CPU. Therefore we - * copy the complete entry-stack to the task-stack and set a - * marker in the iret-frame (bit 31 of the CS dword) to detect - * what we've done on the iret path. + * When we switch to the task-stack here, we extend the + * stack-frame we copy to include the entry-stack %esp and a + * pseudo %ss value so that we have a full ptregs struct on the + * stack. We set a marker in the frame (bit 31 of the CS dword). * - * On the iret path we copy everything back and switch to the - * entry-stack, so that the interrupted kernel code-path - * continues on the same stack it was interrupted with. + * On the iret path we read %esp from the PT_OLDESP slot on the + * stack and copy ptregs (except oldesp and oldss) to it, when + * we find the marker set. Then we switch to the %esp we read, + * so that the interrupted kernel code-path continues on the + * same stack it was interrupted with. * * Be aware that an NMI can happen anytime in this code. * + * Register values here are: + * * %esi: Entry-Stack pointer (same as %esp) * %edi: Top of the task stack * %eax: CR3 on kernel entry */ - /* Calculate number of bytes on the entry stack in %ecx */ - movl %esi, %ecx + /* Allocate full pt_regs on task-stack */ + subl $PTREGS_SIZE, %edi + + /* Switch to task-stack */ + movl %edi, %esp - /* %ecx to the top of entry-stack */ - andl $(MASK_entry_stack), %ecx - addl $(SIZEOF_entry_stack), %ecx + /* Populate pt_regs on task-stack */ + movl $__KERNEL_DS, PT_OLDSS(%esp) /* Check: Is this needed? */ - /* Number of bytes on the entry stack to %ecx */ - sub %esi, %ecx + /* + * Save entry-stack pointer on task-stack so that we can switch back to + * it on the the iret path. + */ + movl %esi, PT_OLDESP(%esp) + + /* sizeof(pt_regs) minus space for %esp and %ss to %ecx */ + movl $(PTREGS_SIZE - 8), %ecx + + /* Copy rest */ + shrl $2, %ecx + cld + rep movsl /* Mark stackframe as coming from entry stack */ orl $CS_FROM_ENTRY_STACK, PT_CS(%esp) @@ -505,16 +520,9 @@ * so that we can switch back to it before iret. */ testl $PTI_SWITCH_MASK, %eax - jz .Lcopy_pt_regs_\@ + jz .Lend_\@ orl $CS_FROM_USER_CR3, PT_CS(%esp) - /* - * %esi and %edi are unchanged, %ecx contains the number of - * bytes to copy. The code at .Lcopy_pt_regs_\@ will allocate - * the stack-frame on task-stack and copy everything over - */ - jmp .Lcopy_pt_regs_\@ - .Lend_\@: .endm @@ -594,16 +602,14 @@ /* Clear marker from stack-frame */ andl $(~CS_FROM_ENTRY_STACK), PT_CS(%esp) - /* Copy the remaining task-stack contents to entry-stack */ + /* + * Copy the remaining 'struct ptregs' to entry-stack. Leave out + * OLDESP and OLDSS as we didn't copy that over on entry. + */ movl %esp, %esi - movl PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %edi + movl PT_OLDESP(%esp), %edi - /* Bytes on the task-stack to ecx */ - movl PER_CPU_VAR(cpu_tss_rw + TSS_sp1), %ecx - subl %esi, %ecx - - /* Allocate stack-frame on entry-stack */ - subl %ecx, %edi + movl $(PTREGS_SIZE - 8), %ecx /* * Save future stack-pointer, we must not switch until the -- 2.7.4