Message ID | 20240104193303.3175844-4-seanjc@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [GIT,PULL] KVM: x86: LAM support for 6.8 | expand |
On Thu, Jan 4, 2024 at 8:33 PM Sean Christopherson <seanjc@google.com> 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(-) >
On 1/8/2024 9:04 PM, Paolo Bonzini wrote: > On Thu, Jan 4, 2024 at 8:33 PM Sean Christopherson <seanjc@google.com> 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? The patch series is tested by the LAM kselftest cases as well as a set of test cases[1] in kvm-unit-tests. [1] https://lore.kernel.org/kvm/20230530024356.24870-1-binbin.wu@linux.intel.com/ Will send a new version with minor change to resolve a feedback soon. > > 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(-) >> >