Re: [PATCH RFC 2/7] kvm: x86: Introduce XFD MSRs as passthrough to guest

From: Liu, Jing2
Date: Tue Jun 01 2021 - 23:13:14 EST




On 5/25/2021 5:43 AM, Sean Christopherson wrote:
On Sun, Feb 07, 2021, Jing Liu wrote:
Passthrough both MSRs to let guest access and write without vmexit.
Why? Except for read-only MSRs, e.g. MSR_CORE_C1_RES, passthrough MSRs are
costly to support because KVM must context switch the MSR (which, by the by, is
completely missing from the patch).

In other words, if these MSRs are full RW passthrough, guests with XFD enabled
will need to load the guest value on entry, save the guest value on exit, and
load the host value on exit. That's in the neighborhood of a 40% increase in
latency for a single VM-Enter/VM-Exit roundtrip (~1500 cycles => >2000 cycles).

I'm not saying these can't be passhthrough, but there needs to be strong
justification for letting the guest read/write them directly.
For IA32_XFD, it's per task and switched during task switch(if different). Meanwhile,
hardware uses IA32_XFD to prevent any instruction per task touching AMX state at the
first time and generate #NM. This means if vcpu running with AMX enabled, hardware
IA32_XFD should keep a guest value, and once guest #NM handler finished, the bit
should not be set anymore for this task.
No matter passthrough or not, IA32_XFD need be restored to guest value when vm-enter,
and load host value on exit (or load zero to prevent losing guest AMX in use state).
And passthrough makes guest IA32_XFD switch during task switch without trapped.

For IA32_XFD_ERR, hardware automatically set the bit once #NM fault. #NM handler
detect and clear the bit.
No matter passthrough or not, KVM doesn't know if guest has #NM, it need read and save
IA32_XFD_ERR when vmexit to prevent preemption task from clearing bit.
Emulating need not restore guest non-zero IA32_XFD_ERR when vmenter and effort is guest
#NM handler takes extra trap(s). But restoring a non-zero IA32_XFD_ERR only occurs for
the vmexit case: between task's first AMX instruction(causing #NM) and end of clearing
in guest #NM handler.

Thanks,
Jing