Re: [PATCH v11 19/23] KVM: x86: Enable CET virtualization for VMX and advertise to userspace
From: Mathias Krause
Date: Tue Jul 22 2025 - 01:49:40 EST
On 21.07.25 19:45, Sean Christopherson wrote:
> On Mon, Jul 21, 2025, Mathias Krause wrote:
>> Can we please make CR4.CET a guest-owned bit as well (sending a patch in
>> a second)? It's a logical continuation to making CR0.WP a guest-owned
>> bit just that it's even easier this time, as no MMU role bits are
>> involved and it still makes a big difference, at least for grsecurity
>> guest kernels.
>
> Out of curiosity, what's the use case for toggling CR4.CET at runtime?
Plain and simple: architectural requirements to be able to toggle CR0.WP.
>> Using the old test from [1] gives the following numbers (perf stat -r 5
>> ssdd 10 50000):
>>
>> * grsec guest on linux-6.16-rc5 + cet patches:
>> 2.4647 +- 0.0706 seconds time elapsed ( +- 2.86% )
>>
>> * grsec guest on linux-6.16-rc5 + cet patches + CR4.CET guest-owned:
>> 1.5648 +- 0.0240 seconds time elapsed ( +- 1.53% )
>>
>> Not only is it ~35% faster, it's also more stable, less fluctuation due
>> to less VMEXITs, I believe.
Above test exercises the "pain path" by single-stepping a process and
constantly switching between tracer and tracee. The scheduling part
involves a CR0.WP toggle in grsecurity to be able to write to r/o
memory, which now requires toggling CR4.CET as well.
>>
>> Thanks,
>> Mathias
>>
>> [1]
>> https://lore.kernel.org/kvm/20230322013731.102955-1-minipli@xxxxxxxxxxxxxx/
>
>> From 14ef5d8b952744c46c32f16fea3b29184cde3e65 Mon Sep 17 00:00:00 2001
>> From: Mathias Krause <minipli@xxxxxxxxxxxxxx>
>> Date: Mon, 21 Jul 2025 13:45:55 +0200
>> Subject: [PATCH] KVM: VMX: Make CR4.CET a guest owned bit
>>
>> There's no need to intercept changes of CR4.CET, make it a guest-owned
>> bit where possible.
>
> In the changelog, please elaborate on the assertion that CR4.CET doesn't need to
> be intercepted, and include the motiviation and perf numbers. KVM's "rule" is
> to disable interception of something if and only if there is a good reason for
> doing so, because generally speaking intercepting is safer. E.g. KVM bugs are
> less likely to put the host at risk. "Because we can" isn't not a good reason :-)
Understood, will extend the changelog accordingly.
>
> E.g. at one point CR4.LA57 was a guest-owned bit, and the code was buggy. Fixing
> things took far more effort than it should have there was no justification for
> the logic (IIRC, it was done purely on the whims of the original developer).
>
> KVM has had many such cases, where some weird behavior was never documented/justified,
> and I really, really want to avoid committing the same sins that have caused me
> so much pain :-)
I totally understand your reasoning, "just because" shouldn't be the
justification. In this case, however, not making it a guest-owned bit
has a big performance impact for grsecurity, we would like to address.
The defines and asserts regarding KVM_MMU_CR4_ROLE_BITS and
KVM_POSSIBLE_CR4_GUEST_BITS (and KVM_MMU_CR0_ROLE_BITS /
KVM_POSSIBLE_CR0_GUEST_BITS too) should catch future attempts on
involving CR4.CET in any MMU-related decisions and I found no other use
of the (nested) guest's CR4.CET value beside for sanity checks to
prevent invalid architectural state (CR4.CET=1 but CR0.WP=0).
That is, imho, existing documentation regarding the expectations on
guest-owned bits and, even better, with BUILD_BUG_ON()s enforcing these.
Thanks,
Mathias