All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Mathias Krause <minipli@grsecurity.net>
Cc: kvm@vger.kernel.org, Chao Gao <chao.gao@intel.com>,
	 Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [kvm-unit-tests PATCH v3 01/17] x86/run_in_user: Add an "end branch" marker on the user_mode destination
Date: Fri, 14 Nov 2025 12:46:47 -0800	[thread overview]
Message-ID: <aReVN65Tgaanqd_l@google.com> (raw)
In-Reply-To: <dbe12f67-79d0-4d92-b510-56f32401e330@grsecurity.net>

On Fri, Nov 14, 2025, Mathias Krause wrote:
> On 14.11.25 01:12, Sean Christopherson wrote:
> > Add an endbr64 at the user_mode "entry point" so that run_in_user() can be
> > used when CET's Indirect Branch Tracking is enabled.
> 
> I don't think that's needed, as 'user_mode' is branched to via IRETQ and
> that isn't covered by IBT -- nor is any other RET instruction.
> 
> > 
> > Signed-off-by: Sean Christopherson <seanjc@google.com>
> > ---
> >  lib/x86/usermode.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/lib/x86/usermode.c b/lib/x86/usermode.c
> > index c3ec0ad7..f4ba0af4 100644
> > --- a/lib/x86/usermode.c
> > +++ b/lib/x86/usermode.c
> > @@ -68,6 +68,9 @@ uint64_t run_in_user(usermode_func func, unsigned int fault_vector,
> >  			"iretq\n"
> >  
> >  			"user_mode:\n\t"
> > +#ifdef __x86_64__
> > +			"endbr64\n\t"
> > +#endif
> 
> The thing is, this ENDBR64 is actually masking a missing cleanup step in
> the IBT tests. The first failing IBT test will make the CET_U IBT
> tracker state get stuck in the WAIT_FOR_ENDBRANCH state. This means,
> every time we return to userland (and thereby implicitly switching to
> the CET_U state again), it wants to see an ENDBR64 first or it will
> directly trigger a #CP(3) again. This ENDBR64 will please that demand
> and make it transition to IDLE and allow executing the test. However,
> it's really the old test that should have fixed the tracker state and
> not a blanket ENDBR64 when entering usermode.
> 
> Attached is a patch on top of [1] that does that but is, admitted, a
> little hacky and evolved. However, it shows that above ENDBR64 is, in
> fact, not needed.

You say hacky, I say clever and correct. :-)

> diff --git a/x86/cet.c b/x86/cet.c
> index 801d8da6e929..bcf1ca6d740a 100644
> --- a/x86/cet.c
> +++ b/x86/cet.c
> @@ -1,4 +1,3 @@
> -
>  #include "libcflat.h"
>  #include "x86/desc.h"
>  #include "x86/processor.h"
> @@ -192,6 +191,10 @@ static uint64_t cet_ibt_emulation(void)
>  #define CET_ENABLE_SHSTK	BIT(0)
>  #define CET_ENABLE_IBT		BIT(2)
>  #define CET_ENABLE_NOTRACK	BIT(4)
> +#define CET_IBT_SUPPRESS	BIT(10)
> +#define CET_IBT_TRACKER_STATE	BIT(11)
> +#define     IBT_TRACKER_IDLE			0
> +#define     IBT_TRACKER_WAIT_FOR_ENDBRANCH	BIT(11)

For this, I think it makes sense to diverge slightly from the SDM and just do

  #define CET_IBT_TRACKER_WAIT_FOR_ENDBRANCH	BIT(11)

because...

>  static void test_shstk(void)
>  {
> @@ -244,6 +247,22 @@ static void test_shstk(void)
>  	report(vector == GP_VECTOR, "MSR_IA32_PL3_SSP alignment test.");
>  }
>  
> +static void ibt_tracker_fixup(struct ex_regs *regs)
> +{
> +	u64 cet_u = rdmsr(MSR_IA32_U_CET);
> +
> +	/*
> +	 * Switch the IBT tracker state to IDLE to have a clean state for
> +	 * following tests.
> +	 */
> +	if ((cet_u & CET_IBT_TRACKER_STATE) == IBT_TRACKER_WAIT_FOR_ENDBRANCH) {
> +		cet_u &= ~IBT_TRACKER_WAIT_FOR_ENDBRANCH;

...this is quite weird/confusing.  It relies on CET_IBT_TRACKER_STATE being a
single bit, and "(x & y) == z)" is very un-idiomatic for a single bit.

> +		printf("CET: suppressing IBT WAIT_FOR_ENDBRANCH state at RIP: %lx\n",
> +		       regs->rip);
> +		wrmsr(MSR_IA32_U_CET, cet_u);
> +	}
> +}

  reply	other threads:[~2025-11-14 20:46 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-14  0:12 [kvm-unit-tests PATCH v3 00/17] x86: Improve CET tests Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 01/17] x86/run_in_user: Add an "end branch" marker on the user_mode destination Sean Christopherson
2025-11-14 15:51   ` Mathias Krause
2025-11-14 20:46     ` Sean Christopherson [this message]
2025-11-15  5:09       ` Mathias Krause
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 02/17] x86: cet: Pass virtual addresses to invlpg Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 03/17] x86: cet: Remove unnecessary memory zeroing for shadow stack Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 04/17] x86: cet: Directly check for #CP exception in run_in_user() Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 05/17] x86: cet: Validate #CP error code Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 06/17] x86: cet: Use report_skip() Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 07/17] x86: cet: Drop unnecessary casting Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 08/17] x86: cet: Validate writing unaligned values to SSP MSR causes #GP Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 09/17] x86: cet: Validate CET states during VMX transitions Sean Christopherson
2025-11-14  8:10   ` Mathias Krause
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 10/17] x86: cet: Make shadow stack less fragile Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 11/17] x86: cet: Simplify IBT test Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 12/17] x86: cet: Use symbolic values for the #CP error codes Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 13/17] x86: cet: Test far returns too Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 14/17] x86: Avoid top-most page for vmalloc on x86-64 Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 15/17] x86/cet: Run SHSTK and IBT tests as appropriate if either feature is supported Sean Christopherson
2025-11-14  8:59   ` Mathias Krause
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 16/17] x86/cet: Drop the "intel_" prefix from the CET testcase Sean Christopherson
2025-11-14  0:12 ` [kvm-unit-tests PATCH v3 17/17] x86/cet: Add testcases to verify KVM rejects emulation of CET instructions Sean Christopherson
2025-11-14 15:19   ` Mathias Krause
2025-11-14 20:42     ` Sean Christopherson

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=aReVN65Tgaanqd_l@google.com \
    --to=seanjc@google.com \
    --cc=chao.gao@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=minipli@grsecurity.net \
    --cc=pbonzini@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.