Re: [GIT PULL] KVM: x86: LAM support for 6.8

From: Paolo Bonzini
Date: Mon Jan 08 2024 - 08:05:00 EST


On Thu, Jan 4, 2024 at 8:33 PM Sean Christopherson <seanjc@xxxxxxxxxx> wrote:
>
> LAM virtualization support. FWIW, I intended to send this in early-ish
> December as you've asked in the past, but December was basically a lost cause
> for me in terms of doing upstream work. :-/
>
> The following changes since commit e9e60c82fe391d04db55a91c733df4a017c28b2f:
>
> selftests/kvm: fix compilation on non-x86_64 platforms (2023-11-21 11:58:25 -0500)
>
> are available in the Git repository at:
>
> https://github.com/kvm-x86/linux.git tags/kvm-x86-lam-6.8
>
> for you to fetch changes up to 183bdd161c2b773a62f01d1c030f5a3a5b7c33b5:
>
> KVM: x86: Use KVM-governed feature framework to track "LAM enabled" (2023-11-28 17:54:09 -0800)

Patches are surprisingly small for this. What's the state of tests
(https://www.spinics.net/lists/kvm/msg313712.html) though?

Thanks,

Paolo

> ----------------------------------------------------------------
> KVM x86 support for virtualizing Linear Address Masking (LAM)
>
> Add KVM support for Linear Address Masking (LAM). LAM tweaks the canonicality
> checks for most virtual address usage in 64-bit mode, such that only the most
> significant bit of the untranslated address bits must match the polarity of the
> last translated address bit. This allows software to use ignored, untranslated
> address bits for metadata, e.g. to efficiently tag pointers for address
> sanitization.
>
> LAM can be enabled separately for user pointers and supervisor pointers, and
> for userspace LAM can be select between 48-bit and 57-bit masking
>
> - 48-bit LAM: metadata bits 62:48, i.e. LAM width of 15.
> - 57-bit LAM: metadata bits 62:57, i.e. LAM width of 6.
>
> For user pointers, LAM enabling utilizes two previously-reserved high bits from
> CR3 (similar to how PCID_NOFLUSH uses bit 63): LAM_U48 and LAM_U57, bits 62 and
> 61 respectively. Note, if LAM_57 is set, LAM_U48 is ignored, i.e.:
>
> - CR3.LAM_U48=0 && CR3.LAM_U57=0 == LAM disabled for user pointers
> - CR3.LAM_U48=1 && CR3.LAM_U57=0 == LAM-48 enabled for user pointers
> - CR3.LAM_U48=x && CR3.LAM_U57=1 == LAM-57 enabled for user pointers
>
> For supervisor pointers, LAM is controlled by a single bit, CR4.LAM_SUP, with
> the 48-bit versus 57-bit LAM behavior following the current paging mode, i.e.:
>
> - CR4.LAM_SUP=0 && CR4.LA57=x == LAM disabled for supervisor pointers
> - CR4.LAM_SUP=1 && CR4.LA57=0 == LAM-48 enabled for supervisor pointers
> - CR4.LAM_SUP=1 && CR4.LA57=1 == LAM-57 enabled for supervisor pointers
>
> The modified LAM canonicality checks:
> - LAM_S48 : [ 1 ][ metadata ][ 1 ]
> 63 47
> - LAM_U48 : [ 0 ][ metadata ][ 0 ]
> 63 47
> - LAM_S57 : [ 1 ][ metadata ][ 1 ]
> 63 56
> - LAM_U57 + 5-lvl paging : [ 0 ][ metadata ][ 0 ]
> 63 56
> - LAM_U57 + 4-lvl paging : [ 0 ][ metadata ][ 0...0 ]
> 63 56..47
>
> The bulk of KVM support for LAM is to emulate LAM's modified canonicality
> checks. The approach taken by KVM is to "fill" the metadata bits using the
> highest bit of the translated address, e.g. for LAM-48, bit 47 is sign-extended
> to bits 62:48. The most significant bit, 63, is *not* modified, i.e. its value
> from the raw, untagged virtual address is kept for the canonicality check. This
> untagging allows
>
> Aside from emulating LAM's canonical checks behavior, LAM has the usual KVM
> touchpoints for selectable features: enumeration (CPUID.7.1:EAX.LAM[bit 26],
> enabling via CR3 and CR4 bits, etc.
>
> ----------------------------------------------------------------
> Binbin Wu (9):
> KVM: x86: Consolidate flags for __linearize()
> KVM: x86: Add an emulation flag for implicit system access
> KVM: x86: Add X86EMUL_F_INVLPG and pass it in em_invlpg()
> KVM: x86/mmu: Drop non-PA bits when getting GFN for guest's PGD
> KVM: x86: Add & use kvm_vcpu_is_legal_cr3() to check CR3's legality
> KVM: x86: Remove kvm_vcpu_is_illegal_gpa()
> KVM: x86: Introduce get_untagged_addr() in kvm_x86_ops and call it in emulator
> KVM: x86: Untag addresses for LAM emulation where applicable
> KVM: x86: Use KVM-governed feature framework to track "LAM enabled"
>
> Robert Hoo (3):
> KVM: x86: Virtualize LAM for supervisor pointer
> KVM: x86: Virtualize LAM for user pointer
> KVM: x86: Advertise and enable LAM (user and supervisor)
>
> arch/x86/include/asm/kvm-x86-ops.h | 1 +
> arch/x86/include/asm/kvm_host.h | 5 +++-
> arch/x86/kvm/cpuid.c | 2 +-
> arch/x86/kvm/cpuid.h | 13 +++++----
> arch/x86/kvm/emulate.c | 27 ++++++++++---------
> arch/x86/kvm/governed_features.h | 1 +
> arch/x86/kvm/kvm_emulate.h | 9 +++++++
> arch/x86/kvm/mmu.h | 8 ++++++
> arch/x86/kvm/mmu/mmu.c | 2 +-
> arch/x86/kvm/mmu/mmu_internal.h | 1 +
> arch/x86/kvm/mmu/paging_tmpl.h | 2 +-
> arch/x86/kvm/svm/nested.c | 4 +--
> arch/x86/kvm/vmx/nested.c | 11 +++++---
> arch/x86/kvm/vmx/sgx.c | 1 +
> arch/x86/kvm/vmx/vmx.c | 55 ++++++++++++++++++++++++++++++++++++--
> arch/x86/kvm/vmx/vmx.h | 2 ++
> arch/x86/kvm/x86.c | 18 +++++++++++--
> arch/x86/kvm/x86.h | 2 ++
> 18 files changed, 134 insertions(+), 30 deletions(-)
>