From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753336AbeAMTF5 (ORCPT + 1 other); Sat, 13 Jan 2018 14:05:57 -0500 Received: from mail-io0-f195.google.com ([209.85.223.195]:38921 "EHLO mail-io0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751126AbeAMTFz (ORCPT ); Sat, 13 Jan 2018 14:05:55 -0500 X-Google-Smtp-Source: ACJfBotRotnqYOjmfxJ1Lfe06fhephitWrhqS787hMmbc6NX/Y1b7sWL2/fqADK8m6JzDIXtUvjRCRsVSRp9TYFLDv4= MIME-Version: 1.0 In-Reply-To: <151586748981.5820.14559543798744763404.stgit@dwillia2-desk3.amr.corp.intel.com> References: <151586744180.5820.13215059696964205856.stgit@dwillia2-desk3.amr.corp.intel.com> <151586748981.5820.14559543798744763404.stgit@dwillia2-desk3.amr.corp.intel.com> From: Linus Torvalds Date: Sat, 13 Jan 2018 11:05:54 -0800 X-Google-Sender-Auth: a5MHqP90nMk4MGBe_BNuxdGULoQ Message-ID: Subject: Re: [PATCH v3 8/9] x86: use __uaccess_begin_nospec and ASM_IFENCE in get_user paths To: Dan Williams Cc: Linux Kernel Mailing List , linux-arch@vger.kernel.org, Andi Kleen , Kees Cook , kernel-hardening@lists.openwall.com, Greg Kroah-Hartman , "the arch/x86 maintainers" , Ingo Molnar , Al Viro , "H. Peter Anvin" , Thomas Gleixner , Andrew Morton , Alan Cox Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: On Sat, Jan 13, 2018 at 10:18 AM, Dan Williams wrote: > diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S > index c97d935a29e8..85f400b8ee7c 100644 > --- a/arch/x86/lib/getuser.S > +++ b/arch/x86/lib/getuser.S > @@ -41,6 +41,7 @@ ENTRY(__get_user_1) > cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX > jae bad_get_user > ASM_STAC > + ASM_IFENCE > 1: movzbl (%_ASM_AX),%edx > xor %eax,%eax > ASM_CLAC So I really would like to know from somebody (preferably somebody with real microarchitectural knowledge) just how expensive that "lfence" ends up being. Because since we could just generate the masking of the address from the exact same condition code that we already generate, the "lfence" really can be replaced by just two ALU instructions instead: diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S index c97d935a29e8..4c378b485399 100644 --- a/arch/x86/lib/getuser.S +++ b/arch/x86/lib/getuser.S @@ -40,6 +40,8 @@ ENTRY(__get_user_1) mov PER_CPU_VAR(current_task), %_ASM_DX cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user + sbb %_ASM_DX,%_ASM_DX + and %_ASM_DX,%_ASM_AX ASM_STAC 1: movzbl (%_ASM_AX),%edx xor %eax,%eax which looks like it should have a fairly low maximum overhead (ok, the above is totally untested, maybe I got the condition the wrong way around _again_). I _know_ that lfence is expensive as hell on P4, for example. Yes, yes, "sbb" is often more expensive than most ALU instructions, and Agner Fog says it has a 10-cycle latency on Prescott (which is outrageous, but being one or two cycles more due to the flags generation is normal). So the sbb/and may certainly add a few cycles to the critical path, but on Prescott "lfence" is *50* cycles according to those same tables by Agner Fog. Is there anybody who is willing to say one way or another wrt the "sbb/and" sequence vs "lfence". Linus From mboxrd@z Thu Jan 1 00:00:00 1970 MIME-Version: 1.0 Sender: linus971@gmail.com In-Reply-To: <151586748981.5820.14559543798744763404.stgit@dwillia2-desk3.amr.corp.intel.com> References: <151586744180.5820.13215059696964205856.stgit@dwillia2-desk3.amr.corp.intel.com> <151586748981.5820.14559543798744763404.stgit@dwillia2-desk3.amr.corp.intel.com> From: Linus Torvalds Date: Sat, 13 Jan 2018 11:05:54 -0800 Message-ID: Content-Type: text/plain; charset="UTF-8" Subject: [kernel-hardening] Re: [PATCH v3 8/9] x86: use __uaccess_begin_nospec and ASM_IFENCE in get_user paths To: Dan Williams Cc: Linux Kernel Mailing List , linux-arch@vger.kernel.org, Andi Kleen , Kees Cook , kernel-hardening@lists.openwall.com, Greg Kroah-Hartman , the arch/x86 maintainers , Ingo Molnar , Al Viro , "H. Peter Anvin" , Thomas Gleixner , Andrew Morton , Alan Cox List-ID: On Sat, Jan 13, 2018 at 10:18 AM, Dan Williams wrote: > diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S > index c97d935a29e8..85f400b8ee7c 100644 > --- a/arch/x86/lib/getuser.S > +++ b/arch/x86/lib/getuser.S > @@ -41,6 +41,7 @@ ENTRY(__get_user_1) > cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX > jae bad_get_user > ASM_STAC > + ASM_IFENCE > 1: movzbl (%_ASM_AX),%edx > xor %eax,%eax > ASM_CLAC So I really would like to know from somebody (preferably somebody with real microarchitectural knowledge) just how expensive that "lfence" ends up being. Because since we could just generate the masking of the address from the exact same condition code that we already generate, the "lfence" really can be replaced by just two ALU instructions instead: diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S index c97d935a29e8..4c378b485399 100644 --- a/arch/x86/lib/getuser.S +++ b/arch/x86/lib/getuser.S @@ -40,6 +40,8 @@ ENTRY(__get_user_1) mov PER_CPU_VAR(current_task), %_ASM_DX cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user + sbb %_ASM_DX,%_ASM_DX + and %_ASM_DX,%_ASM_AX ASM_STAC 1: movzbl (%_ASM_AX),%edx xor %eax,%eax which looks like it should have a fairly low maximum overhead (ok, the above is totally untested, maybe I got the condition the wrong way around _again_). I _know_ that lfence is expensive as hell on P4, for example. Yes, yes, "sbb" is often more expensive than most ALU instructions, and Agner Fog says it has a 10-cycle latency on Prescott (which is outrageous, but being one or two cycles more due to the flags generation is normal). So the sbb/and may certainly add a few cycles to the critical path, but on Prescott "lfence" is *50* cycles according to those same tables by Agner Fog. Is there anybody who is willing to say one way or another wrt the "sbb/and" sequence vs "lfence". Linus