From: Gleb Natapov <gleb@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org,
Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>,
Jun Nakajima <jun.nakajima@intel.com>,
Yang Zhang <yang.z.zhang@intel.com>
Subject: Re: [PATCH v4 09/13] nEPT: Add nEPT violation/misconfigration support
Date: Mon, 29 Jul 2013 15:34:11 +0300 [thread overview]
Message-ID: <20130729123410.GI18009@redhat.com> (raw)
In-Reply-To: <51F65A98.2040002@redhat.com>
On Mon, Jul 29, 2013 at 02:05:44PM +0200, Paolo Bonzini wrote:
> Il 29/07/2013 13:43, Gleb Natapov ha scritto:
> > On Mon, Jul 29, 2013 at 12:59:54PM +0200, Paolo Bonzini wrote:
> >> Il 29/07/2013 12:52, Gleb Natapov ha scritto:
> >>> On Mon, Jul 29, 2013 at 10:59:31AM +0200, Paolo Bonzini wrote:
> >>>> Il 25/07/2013 12:59, Gleb Natapov ha scritto:
> >>>>> +#if PTTYPE == PTTYPE_EPT
> >>>>> +#define CHECK_BAD_MT_XWR(G) mmu->bad_mt_xwr & (1ull << ((G) & 0x3f));
> >>>>> +#else
> >>>>> +#define CHECK_BAD_MT_XWR(G) 0;
> >>
> >> No semicolons here, BTW.
> >>
> >>>>> +#endif
> >>>>> +
> >>>>> static bool FNAME(is_rsvd_bits_set)(struct kvm_mmu *mmu, u64 gpte, int level)
> >>>>> {
> >>>>> int bit7;
> >>>>>
> >>>>> bit7 = (gpte >> 7) & 1;
> >>>>> - return (gpte & mmu->rsvd_bits_mask[bit7][level-1]) != 0;
> >>>>> + return ((gpte & mmu->rsvd_bits_mask[bit7][level-1]) != 0) ||
> >>>>> + CHECK_BAD_MT_XWR(gpte);
> >>>>> }
> >>>>>
> >>>>> +#undef CHECK_BAD_MT_XWR
> >>>>
> >>>> Instead of a macro, you can do
> >>>>
> >>>> if (...)
> >>>> return true;
> >>>> #if PTTYPE == PTTYPE_EPT
> >>>> if (...)
> >>>> return true;
> >>>> #endif
> >>>> return false;
> >>>>
> >>>> The compiler should be smart enough to generate the same code for
> >>>> non-EPT PTTYPE.
> >>>>
> >>> The idea behind this rsvd_bits_mask trickery is to produce code that
> >>> does not have conditional branches.
> >>
> >> If you want to have no conditional branches, you need to use "|" not
> >> "||" (and you also need an "!= 0" in CHECK_BAD_MT_XWR). As you wrote
> >> it, the compiler is most likely to generate exactly the same code that I
> >> suggested.
> > OK. I can add that :) I still prefer to have ifdefs outside the
> > function, not inside.
> >
> >>
> >> But I think what you _really_ want is not avoiding conditional branches.
> > The idea is that it is hard for branch prediction to predict correct
> > result when correct result depends on guest's page table that can
> > contain anything, so in some places shadow paging code uses boolean
> > logic to avoid branches, in this case it is hard to avoid if() anyway
> > since the function invocation is in the if().
>
> Yes, I get the idea, but is_rsvd_bits_set should be predicted unlikely,
> no? If the guest has to run, it must use mostly valid ptes. :)
>
You see, you are confused and you want branch prediction not to be? :)
If your guest is KVM is_rsvd_bits_set() will be likely much more then
unlikely because KVM misconfigures EPT entries to cache MMIO addresses,
so all the "unlikely" cases will be fixed by shadow pages and will not
reappear (until shadow pages are zapped), but misconfigured entries will
continue to produces violations.
> Especially if you change prefetch_invalid_gpte to do the reserved bits
> test after the present test (so that is_rsvd_bits_set is only called on
> present pagetables), is_rsvd_bits_set's result should be really
> well-predicted.
Nope, for ept page tables present is not a single bit, it is three bits
which by themselves can have invalid values. For regular paging you are
probably right.
> At this point (and especially since function invocation
> is always in "if"s), using boolean logic to avoid branches does not make
> much sense anymore for this function.
That's true.
>
> The compiler may still use setCC and boolean logic, even if you write it
> as "if"s; and in simple cases like this, after inlining and seeing an
> "if" the compiler may undo all your careful choice of "|" vs. "||". So
> it's better anyway to ensure is_rsvd_bits_set is called only when it's
> unlikely.
>
> Paolo
--
Gleb.
next prev parent reply other threads:[~2013-07-29 12:34 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-25 10:59 [PATCH v4 00/13] Nested EPT Gleb Natapov
2013-07-25 10:59 ` [PATCH v4 01/13] nEPT: Support LOAD_IA32_EFER entry/exit controls for L1 Gleb Natapov
2013-07-29 8:32 ` Paolo Bonzini
2013-07-29 13:12 ` Gleb Natapov
2013-07-29 14:13 ` Paolo Bonzini
2013-07-25 10:59 ` [PATCH v4 02/13] nEPT: Fix cr3 handling in nested exit and entry Gleb Natapov
2013-07-25 10:59 ` [PATCH v4 03/13] nEPT: Fix wrong test in kvm_set_cr3 Gleb Natapov
2013-07-29 8:36 ` Paolo Bonzini
2013-07-29 10:43 ` Gleb Natapov
2013-07-31 8:02 ` Xiao Guangrong
2013-07-25 10:59 ` [PATCH v4 04/13] nEPT: Move common code to paging_tmpl.h Gleb Natapov
2013-07-31 8:02 ` Xiao Guangrong
2013-07-31 8:36 ` Gleb Natapov
2013-07-25 10:59 ` [PATCH v4 05/13] nEPT: make guest's A/D bits depends on guest's paging mode Gleb Natapov
2013-07-25 10:59 ` [PATCH v4 06/13] nEPT: Add EPT tables support to paging_tmpl.h Gleb Natapov
2013-07-29 9:48 ` Paolo Bonzini
2013-07-29 11:33 ` Gleb Natapov
2013-07-29 11:55 ` Paolo Bonzini
2013-07-29 12:24 ` Gleb Natapov
2013-07-29 13:19 ` Paolo Bonzini
2013-07-29 13:27 ` Gleb Natapov
2013-07-29 14:15 ` Paolo Bonzini
2013-07-29 16:14 ` Gleb Natapov
2013-07-29 16:28 ` Paolo Bonzini
2013-07-29 16:43 ` Gleb Natapov
2013-07-29 17:06 ` Paolo Bonzini
2013-07-29 17:11 ` Gleb Natapov
2013-07-30 10:03 ` Paolo Bonzini
2013-07-30 11:56 ` Gleb Natapov
2013-07-30 12:13 ` Paolo Bonzini
2013-07-30 14:22 ` Gleb Natapov
2013-07-30 14:36 ` Gleb Natapov
2013-07-25 10:59 ` [PATCH v4 07/13] nEPT: Redefine EPT-specific link_shadow_page() Gleb Natapov
2013-07-25 10:59 ` [PATCH v4 08/13] nEPT: Nested INVEPT Gleb Natapov
2013-07-25 10:59 ` [PATCH v4 09/13] nEPT: Add nEPT violation/misconfigration support Gleb Natapov
2013-07-29 8:59 ` Paolo Bonzini
2013-07-29 10:52 ` Gleb Natapov
2013-07-29 10:59 ` Paolo Bonzini
2013-07-29 11:43 ` Gleb Natapov
2013-07-29 12:05 ` Paolo Bonzini
2013-07-29 12:34 ` Gleb Natapov [this message]
2013-07-29 13:11 ` Paolo Bonzini
2013-07-29 13:20 ` Gleb Natapov
2013-07-29 14:12 ` Paolo Bonzini
2013-07-29 16:24 ` Gleb Natapov
2013-07-29 16:36 ` Paolo Bonzini
2013-07-29 16:54 ` Gleb Natapov
2013-07-25 10:59 ` [PATCH v4 10/13] nEPT: MMU context for nested EPT Gleb Natapov
2013-07-25 10:59 ` [PATCH v4 11/13] nEPT: Advertise EPT to L1 Gleb Natapov
2013-07-29 9:21 ` Paolo Bonzini
2013-07-29 11:11 ` Gleb Natapov
2013-07-29 11:33 ` Paolo Bonzini
2013-07-29 11:35 ` Gleb Natapov
2013-07-25 11:00 ` [PATCH v4 12/13] nEPT: Some additional comments Gleb Natapov
2013-07-25 11:00 ` [PATCH v4 13/13] nEPT: Miscelleneous cleanups Gleb Natapov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130729123410.GI18009@redhat.com \
--to=gleb@redhat.com \
--cc=jun.nakajima@intel.com \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=xiaoguangrong@linux.vnet.ibm.com \
--cc=yang.z.zhang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox