Re: [PATCH v4 0/9] Linear Address Masking (LAM) KVM Enabling

Binbin Wu
2023-02-13T09:03:19Z

On 2/9/2023 10:40 AM, Robert Hoo wrote:
> ===Feature Introduction===
>
> Linear-address masking (LAM) [1], modifies the checking that is applied to
> *64-bit* linear addresses, allowing software to use of the untranslated
> address (upper) bits for metadata.
> As for which upper bits of linear address can be borrowed, LAM has 2 modes:
> LAM_48 (bits 62:48, i.e. LAM width of 15) and LAM_57 (bits 62:57, i.e. LAM
> width of 6), controlled by these new bits: CR3[62] (LAM_U48), CR3[61]
> (LAM_U57), and CR4[28] (LAM_SUP).
>
> * LAM_U48 and LAM_U57 bits controls LAM for user mode address. I.e. if
> CR3.LAM_U57 = 1, LAM57 is applied; if CR3.LAM_U48 = 1 and CR3.LAM_U57 = 0,
> LAM48 is applied.
> * LAM_SUP bit, combined with paging mode (4-level or 5-level), determines
> LAM status for supervisor mode address. I.e. when CR4.LAM_SUP =1, 4-level
> paging mode will have LAM48 for supervisor mode address while 5-level paging
> will have LAM57.
>
> Note:
> 1. LAM applies to only data address, not to instructions.
> 2. LAM identification of an address as user or supervisor is based solely on the
> value of pointer bit 63 and does not, for the purposes of LAM, depend on the CPL.
> 3. For user mode address, it is possible that 5-level paging and LAM_U48 are both
> set, in this case, the effective usable linear address width is 48, i.e. bit
> 56:47 is reserved by LAM. [2]

How to understand "reserved by LAM"?

According to the spec, bits 56:48 of the pointer contained metadata.

> 4. When VM exit, the problematic address saved in VMCS field is clean, i.e.
> metadata cleared with canonical form.
>
>
> ===LAM KVM Design===
>
> Intercept CR4.LAM_SUP by KVM, to avoid read VMCS field every time, with
> expectation that guest won't toggle this bit frequently.
>
> Under EPT mode, CR3 is fully under guest control, guest LAM is thus transparent to
> KVM. Nothing more need to do.
>
> For Shadow paging (EPT = off), KVM need to handle guest CR3.LAM_U48 and CR3.LAM_U57
> toggles.
>
> [1] ISE Chap10 https://cdrdv2.intel.com/v1/dl/getContent/671368 (Section 10.6 VMX interaction)
> [2] Thus currently, Kernel enabling patch only enables LAM_U57. https://lore.kernel.org/lkml/20230123220500.21077-1-kirill.shutemov@linux.intel.com/
>
> ---
> Changelog
> v3 --> v4:
> Drop unrelated Patch 1 in v3 (Binbin, Sean, Xiaoyao)
> Intercept CR4.LAM_SUP instead of pass through to guest (Sean)
> Just filter out CR3.LAM_{U48, U57}, instead of all reserved high bits
> (Sean, Yuan)
> Use existing __canonical_address() helper instead write a new one (Weijiang)
> Add LAM handling in KVM emulation (Yu, Yuan)
> Add Jingqi's reviwed-by on Patch 7
> Rebased to Kirill's latest code, which is 6.2-rc1 base.
>
> v2 --> v3:
> As LAM Kernel patches are in tip tree now, rebase to it.
> https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/
>
> v1 --> v2:
> 1. Fixes i386-allyesconfig build error on get_pgd(), where
> CR3_HIGH_RSVD_MASK isn't applicable.
> (Reported-by: kernel test robot <lkp@intel.com>)
> 2. In kvm_set_cr3(), be conservative on skip tlb flush when only LAM bits
> toggles. (Kirill)
>
>
> Robert Hoo (9):
> KVM: x86: Intercept CR4.LAM_SUP when LAM feature is enabled in guest
> KVM: x86: MMU: Clear CR3 LAM bits when allocate shadow root
> [Trivial] KVM: x86: MMU: Commets update
> KVM: x86: MMU: Integrate LAM bits when build guest CR3
> KVM: x86: Untag LAM bits when applicable
> KVM: x86: When judging setting CR3 valid or not, consider LAM bits
> KVM: x86: When guest set CR3, handle LAM bits semantics
> KVM: x86: LAM: Expose LAM CPUID to user space VMM
> KVM: x86: emulation: Apply LAM when emulating data access
>
> arch/x86/include/asm/kvm_host.h | 3 ++-
> arch/x86/kvm/cpuid.c | 2 +-
> arch/x86/kvm/emulate.c | 6 +++++
> arch/x86/kvm/mmu.h | 5 ++++
> arch/x86/kvm/mmu/mmu.c | 11 ++++++--
> arch/x86/kvm/vmx/vmx.c | 6 ++++-
> arch/x86/kvm/x86.c | 38 ++++++++++++++++++++++----
> arch/x86/kvm/x86.h | 47 +++++++++++++++++++++++++++++++++
> 8 files changed, 108 insertions(+), 10 deletions(-)
>
> base-commit: 03334443640f226f56f71b5dfa3b1be6d4a1a1bc
> (https://git.kernel.org/pub/scm/linux/kernel/git/kas/linux.git lam)