Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 May 2025 15:10:01 +0000 (08:10 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 May 2025 15:10:01 +0000 (08:10 -0700)
Pull kvm updates from Paolo Bonzini:
 "As far as x86 goes this pull request "only" includes TDX host support.

  Quotes are appropriate because (at 6k lines and 100+ commits) it is
  much bigger than the rest, which will come later this week and
  consists mostly of bugfixes and selftests. s390 changes will also come
  in the second batch.

  ARM:

   - Add large stage-2 mapping (THP) support for non-protected guests
     when pKVM is enabled, clawing back some performance.

   - Enable nested virtualisation support on systems that support it,
     though it is disabled by default.

   - Add UBSAN support to the standalone EL2 object used in nVHE/hVHE
     and protected modes.

   - Large rework of the way KVM tracks architecture features and links
     them with the effects of control bits. While this has no functional
     impact, it ensures correctness of emulation (the data is
     automatically extracted from the published JSON files), and helps
     dealing with the evolution of the architecture.

   - Significant changes to the way pKVM tracks ownership of pages,
     avoiding page table walks by storing the state in the hypervisor's
     vmemmap. This in turn enables the THP support described above.

   - New selftest checking the pKVM ownership transition rules

   - Fixes for FEAT_MTE_ASYNC being accidentally advertised to guests
     even if the host didn't have it.

   - Fixes for the address translation emulation, which happened to be
     rather buggy in some specific contexts.

   - Fixes for the PMU emulation in NV contexts, decoupling PMCR_EL0.N
     from the number of counters exposed to a guest and addressing a
     number of issues in the process.

   - Add a new selftest for the SVE host state being corrupted by a
     guest.

   - Keep HCR_EL2.xMO set at all times for systems running with the
     kernel at EL2, ensuring that the window for interrupts is slightly
     bigger, and avoiding a pretty bad erratum on the AmpereOne HW.

   - Add workaround for AmpereOne's erratum AC04_CPU_23, which suffers
     from a pretty bad case of TLB corruption unless accesses to HCR_EL2
     are heavily synchronised.

   - Add a per-VM, per-ITS debugfs entry to dump the state of the ITS
     tables in a human-friendly fashion.

   - and the usual random cleanups.

  LoongArch:

   - Don't flush tlb if the host supports hardware page table walks.

   - Add KVM selftests support.

  RISC-V:

   - Add vector registers to get-reg-list selftest

   - VCPU reset related improvements

   - Remove scounteren initialization from VCPU reset

   - Support VCPU reset from userspace using set_mpstate() ioctl

  x86:

   - Initial support for TDX in KVM.

     This finally makes it possible to use the TDX module to run
     confidential guests on Intel processors. This is quite a large
     series, including support for private page tables (managed by the
     TDX module and mirrored in KVM for efficiency), forwarding some
     TDVMCALLs to userspace, and handling several special VM exits from
     the TDX module.

     This has been in the works for literally years and it's not really
     possible to describe everything here, so I'll defer to the various
     merge commits up to and including commit 7bcf7246c42a ('Merge
     branch 'kvm-tdx-finish-initial' into HEAD')"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (248 commits)
  x86/tdx: mark tdh_vp_enter() as __flatten
  Documentation: virt/kvm: remove unreferenced footnote
  RISC-V: KVM: lock the correct mp_state during reset
  KVM: arm64: Fix documentation for vgic_its_iter_next()
  KVM: arm64: np-guest CMOs with PMD_SIZE fixmap
  KVM: arm64: Stage-2 huge mappings for np-guests
  KVM: arm64: Add a range to pkvm_mappings
  KVM: arm64: Convert pkvm_mappings to interval tree
  KVM: arm64: Add a range to __pkvm_host_test_clear_young_guest()
  KVM: arm64: Add a range to __pkvm_host_wrprotect_guest()
  KVM: arm64: Add a range to __pkvm_host_unshare_guest()
  KVM: arm64: Add a range to __pkvm_host_share_guest()
  KVM: arm64: Introduce for_each_hyp_page
  KVM: arm64: Handle huge mappings for np-guest CMOs
  KVM: arm64: nv: Release faulted-in VNCR page from mmu_lock critical section
  KVM: arm64: nv: Handle TLBI S1E2 for VNCR invalidation with mmu_lock held
  KVM: arm64: nv: Hold mmu_lock when invalidating VNCR SW-TLB before translating
  RISC-V: KVM: add KVM_CAP_RISCV_MP_STATE_RESET
  RISC-V: KVM: Remove scounteren initialization
  KVM: RISC-V: remove unnecessary SBI reset state
  ...

16 files changed:
1  2 
MAINTAINERS
arch/arm64/Kconfig
arch/arm64/include/asm/el2_setup.h
arch/arm64/include/asm/esr.h
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/image-vars.h
arch/arm64/kernel/vmlinux.lds.S
arch/x86/include/asm/kvm_host.h
arch/x86/kernel/traps.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/pmu_intel.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c
scripts/Makefile.ubsan

diff --cc MAINTAINERS
Simple merge
Simple merge
        mov     x0, xzr
        mrs     x1, id_aa64pfr1_el1
        ubfx    x1, x1, #ID_AA64PFR1_EL1_SME_SHIFT, #4
 -      cbz     x1, .Lskip_debug_fgt_\@
 +      cbz     x1, .Lskip_sme_fgt_\@
  
        /* Disable nVHE traps of TPIDR2 and SMPRI */
-       orr     x0, x0, #HFGxTR_EL2_nSMPRI_EL1_MASK
-       orr     x0, x0, #HFGxTR_EL2_nTPIDR2_EL0_MASK
+       orr     x0, x0, #HFGRTR_EL2_nSMPRI_EL1_MASK
+       orr     x0, x0, #HFGRTR_EL2_nTPIDR2_EL0_MASK
  
 -.Lskip_debug_fgt_\@:
 +.Lskip_sme_fgt_\@:
        mrs_s   x1, SYS_ID_AA64MMFR3_EL1
        ubfx    x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
        cbz     x1, .Lskip_pie_fgt_\@
        /* GCS depends on PIE so we don't check it if PIE is absent */
        mrs_s   x1, SYS_ID_AA64PFR1_EL1
        ubfx    x1, x1, #ID_AA64PFR1_EL1_GCS_SHIFT, #4
 -      cbz     x1, .Lset_fgt_\@
 +      cbz     x1, .Lskip_gce_fgt_\@
  
        /* Disable traps of access to GCS registers at EL0 and EL1 */
-       orr     x0, x0, #HFGxTR_EL2_nGCS_EL1_MASK
-       orr     x0, x0, #HFGxTR_EL2_nGCS_EL0_MASK
+       orr     x0, x0, #HFGRTR_EL2_nGCS_EL1_MASK
+       orr     x0, x0, #HFGRTR_EL2_nGCS_EL0_MASK
  
 +.Lskip_gce_fgt_\@:
 +
  .Lset_fgt_\@:
        msr_s   SYS_HFGRTR_EL2, x0
        msr_s   SYS_HFGWTR_EL2, x0
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1337,10 -1337,10 +1339,10 @@@ void vmx_prepare_switch_to_guest(struc
                savesegment(fs, fs_sel);
                savesegment(gs, gs_sel);
                fs_base = read_msr(MSR_FS_BASE);
-               vmx->msr_host_kernel_gs_base = read_msr(MSR_KERNEL_GS_BASE);
+               vt->msr_host_kernel_gs_base = read_msr(MSR_KERNEL_GS_BASE);
        }
  
 -      wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
 +      wrmsrq(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
  #else
        savesegment(fs, fs_sel);
        savesegment(gs, gs_sel);
@@@ -1384,10 -1384,10 +1386,10 @@@ static void vmx_prepare_switch_to_host(
  #endif
        invalidate_tss_limit();
  #ifdef CONFIG_X86_64
-       wrmsrq(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
 -      wrmsrl(MSR_KERNEL_GS_BASE, vmx->vt.msr_host_kernel_gs_base);
++      wrmsrq(MSR_KERNEL_GS_BASE, vmx->vt.msr_host_kernel_gs_base);
  #endif
        load_fixmap_gdt(raw_smp_processor_id());
-       vmx->guest_state_loaded = false;
+       vmx->vt.guest_state_loaded = false;
        vmx->guest_uret_msrs_loaded = false;
  }
  
  static u64 vmx_read_guest_kernel_gs_base(struct vcpu_vmx *vmx)
  {
        preempt_disable();
-       if (vmx->guest_state_loaded)
+       if (vmx->vt.guest_state_loaded)
 -              rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
 +              rdmsrq(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
        preempt_enable();
        return vmx->msr_guest_kernel_gs_base;
  }
  static void vmx_write_guest_kernel_gs_base(struct vcpu_vmx *vmx, u64 data)
  {
        preempt_disable();
-       if (vmx->guest_state_loaded)
+       if (vmx->vt.guest_state_loaded)
 -              wrmsrl(MSR_KERNEL_GS_BASE, data);
 +              wrmsrq(MSR_KERNEL_GS_BASE, data);
        preempt_enable();
        vmx->msr_guest_kernel_gs_base = data;
  }
@@@ -9771,11 -9794,13 +9794,13 @@@ int kvm_x86_vendor_init(struct kvm_x86_
                kvm_host.xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
                kvm_caps.supported_xcr0 = kvm_host.xcr0 & KVM_SUPPORTED_XCR0;
        }
+       kvm_caps.supported_quirks = KVM_X86_VALID_QUIRKS;
+       kvm_caps.inapplicable_quirks = KVM_X86_CONDITIONAL_QUIRKS;
  
 -      rdmsrl_safe(MSR_EFER, &kvm_host.efer);
 +      rdmsrq_safe(MSR_EFER, &kvm_host.efer);
  
        if (boot_cpu_has(X86_FEATURE_XSAVES))
 -              rdmsrl(MSR_IA32_XSS, kvm_host.xss);
 +              rdmsrq(MSR_IA32_XSS, kvm_host.xss);
  
        kvm_init_pmu_capability(ops->pmu_ops);
  
@@@ -10976,9 -11006,10 +11006,10 @@@ static int vcpu_enter_guest(struct kvm_
                switch_fpu_return();
  
        if (vcpu->arch.guest_fpu.xfd_err)
 -              wrmsrl(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err);
 +              wrmsrq(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err);
  
-       if (unlikely(vcpu->arch.switch_db_regs)) {
+       if (unlikely(vcpu->arch.switch_db_regs &&
+                    !(vcpu->arch.switch_db_regs & KVM_DEBUGREG_AUTO_SWITCH))) {
                set_debugreg(0, 7);
                set_debugreg(vcpu->arch.eff_db[0], 0);
                set_debugreg(vcpu->arch.eff_db[1], 1);
Simple merge