On Fri, Oct 29, 2021 at 11:00 PM Jim Mattson <jmattson@xxxxxxxxxx> wrote: > > On Fri, Oct 29, 2021 at 3:48 PM Sean Christopherson <seanjc@xxxxxxxxxx> wrote: > > > > On Fri, Oct 29, 2021, Aaron Lewis wrote: > > > Rather than assuming which PTE the SMEP test is running on, look it up > > > to ensure we have the correct entry. If this test were to run on a > > > different page table (ie: run in an L2 test) the wrong PTE would be set. > > > Switch to looking up the PTE to avoid this from happening. > > > > > > Signed-off-by: Aaron Lewis <aaronlewis@xxxxxxxxxx> > > > --- > > > x86/access.c | 9 ++++++--- > > > x86/cstart64.S | 1 - > > > 2 files changed, 6 insertions(+), 4 deletions(-) > > > > > > diff --git a/x86/access.c b/x86/access.c > > > index 4725bbd..a4d72d9 100644 > > > --- a/x86/access.c > > > +++ b/x86/access.c > > > @@ -204,7 +204,7 @@ static void set_cr0_wp(int wp) > > > static unsigned set_cr4_smep(int smep) > > > { > > > unsigned long cr4 = shadow_cr4; > > > - extern u64 ptl2[]; > > > + pteval_t *pte; > > > unsigned r; > > > > > > cr4 &= ~CR4_SMEP_MASK; > > > @@ -213,11 +213,14 @@ static unsigned set_cr4_smep(int smep) > > > if (cr4 == shadow_cr4) > > > return 0; > > > > > > + pte = get_pte(phys_to_virt(read_cr3()), set_cr4_smep); > > > > What guarantees are there that set_cr4_smep() and the rest of the test are mapped > > by the same PTE? I 100% agree the current code is ugly, e.g. I can't remember how > > ptl2[2] is guaranteed to be used, but if we're going to fix it then we should aim > > for a more robust solution. > > One possible solution is to put labels around the code that has to run > with SMEP and then to implement a function to modify the PTEs for a > range of addresses, using gcc's double-ampersand syntax to get the > addresses of the labels. > Would it be safer to just mark the start and end of the text section, then I could remove the PT_USER_MASK flags from that whole range? > > > + assert(pte); > > > + > > > if (smep) > > > - ptl2[2] &= ~PT_USER_MASK; > > > + *pte &= ~PT_USER_MASK; > > > r = write_cr4_checking(cr4); > > > if (r || !smep) { > > > - ptl2[2] |= PT_USER_MASK; > > > + *pte |= PT_USER_MASK; > > > > > > /* Flush to avoid spurious #PF */ > > > invlpg((void *)(2 << 21)); > > > > This invlpg() should be updated as well. Good catch. I'll update this. > > > > > diff --git a/x86/cstart64.S b/x86/cstart64.S > > > index 5c6ad38..4ba9943 100644 > > > --- a/x86/cstart64.S > > > +++ b/x86/cstart64.S > > > @@ -26,7 +26,6 @@ ring0stacktop: > > > .data > > > > > > .align 4096 > > > -.globl ptl2 > > > ptl2: > > > i = 0 > > > .rept 512 * 4 > > > -- > > > 2.33.1.1089.g2158813163f-goog > > >