Re: [PATCH 2/2] KVM: SVM: Set/clear CR8 write interception when AVIC is (de)activated
From: Tom Lendacky
Date: Tue Mar 10 2026 - 18:34:11 EST
On 3/10/26 16:58, Sean Christopherson wrote:
> On Tue, Mar 10, 2026, Tom Lendacky wrote:
>> On 3/10/26 13:35, Sean Christopherson wrote:
>>> On Tue, Mar 10, 2026, Tom Lendacky wrote:
>>>> I'm just saying that the unconditional trap for CR8_WRITE isn't flawed
>>>> for SEV-ES+ because AVIC can't work with SEV, so there isn't any time
>>>> that CR8 writes shouldn't be trapped.
>>>
>>> Yeah, I forgot that (obviously).
>>>
>>> But sync_cr8_to_lapic() is very broken, no? INTERCEPT_CR8_WRITE will never be
>>> set, and svm->vmcb->control.int_ctl will become stale as soon as the VMSA is
>>> live, and so in all likelihood KVM is crushing CR8 to zero for SEV-ES guests.
>>
>> I don't think so. V_TPR is written on #VMEXIT even for SEV-ES+ guests,
>> and since it is a trap, CR8 is set and so V_TPR should have that value.
>> That would imply sync_cr8_to_lapic() should do the right thing.
>
> But isn't svm->vmcb->control.int_ctl stale? Oh. "control", not "save". /facepalm
>
> Ah, and I assume Secure AVIC hides vTPR from the host? Or at least prevents the
> host from setting it?
Secure AVIC will prevent the host from setting it since the backing page
lives in guest memory and is encrypted/private.
>
>> After attempting to verify this behavior it turns out that writes to CR8
>> (and CR2) are, in fact, not trapped, but the APM was not updated with
>> this information (I'll send a patch to remove that code). KVM's CR8
>> value is, however, synced with the proper value through
>> sync_cr8_to_lapic() because V_TPR in the VMCB is updated on #VMEXIT.
>
> Oh. Huh. So doesn't that mean that supporting Windows (or any other guest that
> uses TPR to mask interrupts) as an SEV-ES guest is practically impossible? Because
> while KVM can observe and manipulate guest CR8, KVM won't be able to precisely
> detect when TPR drops below a pending IRQ.
Could we do something with virtual interrupt support? Today KVM uses the
virtual interrupt control to detect when an IRQ window opens. We could
do something similar by setting up the virtual interrupt priority,
V_INTR_PRIO, at the level of the current TPR/CR8 level. When the TPR
drops, that would trigger a #VMEXIT and allow the pending IRQ to be
injected. Thoughts?
Thanks,
Tom
>