From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752376AbbC1JLR (ORCPT ); Sat, 28 Mar 2015 05:11:17 -0400 Received: from mail-wi0-f178.google.com ([209.85.212.178]:34016 "EHLO mail-wi0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751156AbbC1JLM (ORCPT ); Sat, 28 Mar 2015 05:11:12 -0400 Date: Sat, 28 Mar 2015 10:11:06 +0100 From: Ingo Molnar To: Denys Vlasenko Cc: Brian Gerst , Andy Lutomirski , Borislav Petkov , the arch/x86 maintainers , Linux Kernel Mailing List , Linus Torvalds Subject: Re: [PATCH] x86/asm/entry/64: better check for canonical address Message-ID: <20150328091106.GA5361@gmail.com> References: <1427373731-13056-1-git-send-email-dvlasenk@redhat.com> <20150327081141.GA9526@gmail.com> <551534B1.6090908@redhat.com> <20150327111738.GA8749@gmail.com> <20150327113430.GC14778@gmail.com> <551549AF.50808@redhat.com> <20150327121645.GC15631@gmail.com> <55154DB3.9000008@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <55154DB3.9000008@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org * Denys Vlasenko wrote: > On 03/27/2015 01:16 PM, Ingo Molnar wrote: > >>> Indeed, an IRET ought to be pretty cheap for same-ring interrupt > >>> returns in any case. > >> > >> Unfortunately, it is not. Try attached program. > >> > >> On this CPU, 1 ns ~= 3 cycles. > >> > >> $ ./timing_test64 callret > >> 10000 loops in 0.00008s = 7.87 nsec/loop for callret > >> 100000 loops in 0.00076s = 7.56 nsec/loop for callret > >> 1000000 loops in 0.00548s = 5.48 nsec/loop for callret > >> 10000000 loops in 0.02882s = 2.88 nsec/loop for callret > >> 100000000 loops in 0.18334s = 1.83 nsec/loop for callret > >> 200000000 loops in 0.36051s = 1.80 nsec/loop for callret > >> 400000000 loops in 0.71632s = 1.79 nsec/loop for callret > >> > >> Near call + near ret = 5 cycles > >> > >> $ ./timing_test64 lret > >> 10000 loops in 0.00034s = 33.95 nsec/loop for lret > >> 100000 loops in 0.00328s = 32.83 nsec/loop for lret > >> 1000000 loops in 0.04541s = 45.41 nsec/loop for lret > >> 10000000 loops in 0.32130s = 32.13 nsec/loop for lret > >> 20000000 loops in 0.64191s = 32.10 nsec/loop for lret > >> > >> push my_cs + push next_label + far ret = ~90 cycles > >> > >> $ ./timing_test64 iret > >> 10000 loops in 0.00344s = 343.90 nsec/loop for iret > >> 100000 loops in 0.01890s = 188.97 nsec/loop for iret > >> 1000000 loops in 0.08228s = 82.28 nsec/loop for iret > >> 10000000 loops in 0.77910s = 77.91 nsec/loop for iret > >> > >> This is the "same-ring interrupt return". ~230 cycles! :( > > > > Ugh, that's really expensive! Why is that so? Same-ring irqs are > > supposedly a lot simpler. > > Descriptor checks for restored CS and SS, > checking canonical-ness of RIP, > supporting "return to TSS" (flags.NT bit), > "return to VM86" (flags.VM bit), > complex logic around restoring RFLAGS > ("don't allow CPL3 to be able to disable interrupts... > ...unless their flags.IOPL is 3." Gasp) > return to 16-bit code ("do not touch high 16 bits") > > All of this is a giant PITA to encode in microcode. I guess they could optimize it by adding a single "I am a modern OS executing regular userspace" flag to the descriptor [or expressing the same as a separate instruction], to avoid all that legacy crap that won't trigger on like 99.999999% of systems ... Thanks, Ingo