1. Apr 21, 2023
    • Marc Zyngier's avatar
      Merge branch kvm-arm64/selftest/lpa into kvmarm-master/next · e2e321a7
      Marc Zyngier authored
      
      
      * kvm-arm64/selftest/lpa:
        : .
        : Selftest fixes addressing PTE and TTBR0_EL1 encodings for
        : 52bit PAs
        : .
        KVM: selftests: arm64: Fix ttbr0_el1 encoding for PA bits > 48
        KVM: selftests: arm64: Fix pte encode/decode for PA bits > 48
        KVM: selftests: Fixup config fragment for access_tracking_perf_test
      
      Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
      e2e321a7
    • Marc Zyngier's avatar
      Merge branch kvm-arm64/timer-vm-offsets into kvmarm-master/next · b22498c4
      Marc Zyngier authored
      
      
      * kvm-arm64/timer-vm-offsets: (21 commits)
        : .
        : This series aims at satisfying multiple goals:
        :
        : - allow a VMM to atomically restore a timer offset for a whole VM
        :   instead of updating the offset each time a vcpu get its counter
        :   written
        :
        : - allow a VMM to save/restore the physical timer context, something
        :   that we cannot do at the moment due to the lack of offsetting
        :
        : - provide a framework that is suitable for NV support, where we get
        :   both global and per timer, per vcpu offsetting, and manage
        :   interrupts in a less braindead way.
        :
        : Conflict resolution involves using the new per-vcpu config lock instead
        : of the home-grown timer lock.
        : .
        KVM: arm64: Handle 32bit CNTPCTSS traps
        KVM: arm64: selftests: Augment existing timer test to handle variable offset
        KVM: arm64: selftests: Deal with spurious timer interrupts
        KVM: arm64: selftests: Add physical timer registers to the sysreg list
        KVM: arm64: nv: timers: Support hyp timer emulation
        KVM: arm64: nv: timers: Add a per-timer, per-vcpu offset
        KVM: arm64: Document KVM_ARM_SET_CNT_OFFSETS and co
        KVM: arm64: timers: Abstract the number of valid timers per vcpu
        KVM: arm64: timers: Fast-track CNTPCT_EL0 trap handling
        KVM: arm64: Elide kern_hyp_va() in VHE-specific parts of the hypervisor
        KVM: arm64: timers: Move the timer IRQs into arch_timer_vm_data
        KVM: arm64: timers: Abstract per-timer IRQ access
        KVM: arm64: timers: Rationalise per-vcpu timer init
        KVM: arm64: timers: Allow save/restoring of the physical timer
        KVM: arm64: timers: Allow userspace to set the global counter offset
        KVM: arm64: Expose {un,}lock_all_vcpus() to the rest of KVM
        KVM: arm64: timers: Allow physical offset without CNTPOFF_EL2
        KVM: arm64: timers: Use CNTPOFF_EL2 to offset the physical timer
        arm64: Add HAS_ECV_CNTPOFF capability
        arm64: Add CNTPOFF_EL2 register definition
        ...
      
      Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
      b22498c4
    • Marc Zyngier's avatar
      Merge branch kvm-arm64/lock-inversion into kvmarm-master/next · ef5f97e9
      Marc Zyngier authored
      
      
      * kvm-arm64/lock-inversion:
        : .
        : vm/vcpu lock inversion fixes, courtesy of Oliver Upton, plus a few
        : extra fixes from both Oliver and Reiji Watanabe.
        :
        : From the initial cover letter:
        :
        : As it so happens, lock ordering in KVM/arm64 is completely backwards.
        : There's a significant amount of VM-wide state that needs to be accessed
        : from the context of a vCPU. Until now, this was accomplished by
        : acquiring the kvm->lock, but that cannot be nested within vcpu->mutex.
        :
        : This series fixes the issue with some fine-grained locking for MP state
        : and a new, dedicated mutex that can nest with both kvm->lock and
        : vcpu->mutex.
        : .
        KVM: arm64: Have kvm_psci_vcpu_on() use WRITE_ONCE() to update mp_state
        KVM: arm64: Acquire mp_state_lock in kvm_arch_vcpu_ioctl_vcpu_init()
        KVM: arm64: vgic: Don't acquire its_lock before config_lock
        KVM: arm64: Use config_lock to protect vgic state
        KVM: arm64: Use config_lock to protect data ordered against KVM_RUN
        KVM: arm64: Avoid lock inversion when setting the VM register width
        KVM: arm64: Avoid vcpu->mutex v. kvm->lock inversion in CPU_ON
      
      Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
      ef5f97e9
  2. Apr 20, 2023
  3. Apr 13, 2023
  4. Apr 12, 2023
  5. Mar 31, 2023
  6. Mar 29, 2023
    • Oliver Upton's avatar
      KVM: arm64: Use config_lock to protect vgic state · f0032773
      Oliver Upton authored
      
      
      Almost all of the vgic state is VM-scoped but accessed from the context
      of a vCPU. These accesses were serialized on the kvm->lock which cannot
      be nested within a vcpu->mutex critical section.
      
      Move over the vgic state to using the config_lock. Tweak the lock
      ordering where necessary to ensure that the config_lock is acquired
      after the vcpu->mutex. Acquire the config_lock in kvm_vgic_create() to
      avoid a race between the converted flows and GIC creation. Where
      necessary, continue to acquire kvm->lock to avoid a race with vCPU
      creation (i.e. flows that use lock_all_vcpus()).
      
      Finally, promote the locking expectations in comments to lockdep
      assertions and update the locking documentation for the config_lock as
      well as vcpu->mutex.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
      Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
      Link: https://lore.kernel.org/r/20230327164747.2466958-5-oliver.upton@linux.dev
      f0032773
    • Oliver Upton's avatar
      KVM: arm64: Use config_lock to protect data ordered against KVM_RUN · 4bba7f7d
      Oliver Upton authored
      
      
      There are various bits of VM-scoped data that can only be configured
      before the first call to KVM_RUN, such as the hypercall bitmaps and
      the PMU. As these fields are protected by the kvm->lock and accessed
      while holding vcpu->mutex, this is yet another example of lock
      inversion.
      
      Change out the kvm->lock for kvm->arch.config_lock in all of these
      instances. Opportunistically simplify the locking mechanics of the
      PMU configuration by holding the config_lock for the entirety of
      kvm_arm_pmu_v3_set_attr().
      
      Note that this also addresses a couple of bugs. There is an unguarded
      read of the PMU version in KVM_ARM_VCPU_PMU_V3_FILTER which could race
      with KVM_ARM_VCPU_PMU_V3_SET_PMU. Additionally, until now writes to the
      per-vCPU vPMU irq were not serialized VM-wide, meaning concurrent calls
      to KVM_ARM_VCPU_PMU_V3_IRQ could lead to a false positive in
      pmu_irq_is_valid().
      
      Cc: stable@vger.kernel.org
      Tested-by: default avatarJeremy Linton <jeremy.linton@arm.com>
      Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
      Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
      Link: https://lore.kernel.org/r/20230327164747.2466958-4-oliver.upton@linux.dev
      4bba7f7d
    • Oliver Upton's avatar
      KVM: arm64: Avoid lock inversion when setting the VM register width · c43120af
      Oliver Upton authored
      kvm->lock must be taken outside of the vcpu->mutex. Of course, the
      locking documentation for KVM makes this abundantly clear. Nonetheless,
      the locking order in KVM/arm64 has been wrong for quite a while; we
      acquire the kvm->lock while holding the vcpu->mutex all over the shop.
      
      All was seemingly fine until commit 42a90008
      
       ("KVM: Ensure lockdep
      knows about kvm->lock vs. vcpu->mutex ordering rule") caught us with our
      pants down, leading to lockdep barfing:
      
       ======================================================
       WARNING: possible circular locking dependency detected
       6.2.0-rc7+ #19 Not tainted
       ------------------------------------------------------
       qemu-system-aar/859 is trying to acquire lock:
       ffff5aa69269eba0 (&host_kvm->lock){+.+.}-{3:3}, at: kvm_reset_vcpu+0x34/0x274
      
       but task is already holding lock:
       ffff5aa68768c0b8 (&vcpu->mutex){+.+.}-{3:3}, at: kvm_vcpu_ioctl+0x8c/0xba0
      
       which lock already depends on the new lock.
      
      Add a dedicated lock to serialize writes to VM-scoped configuration from
      the context of a vCPU. Protect the register width flags with the new
      lock, thus avoiding the need to grab the kvm->lock while holding
      vcpu->mutex in kvm_reset_vcpu().
      
      Cc: stable@vger.kernel.org
      Reported-by: default avatarJeremy Linton <jeremy.linton@arm.com>
      Link: https://lore.kernel.org/kvmarm/f6452cdd-65ff-34b8-bab0-5c06416da5f6@arm.com/
      
      
      Tested-by: default avatarJeremy Linton <jeremy.linton@arm.com>
      Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
      Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
      Link: https://lore.kernel.org/r/20230327164747.2466958-3-oliver.upton@linux.dev
      c43120af
    • Oliver Upton's avatar
      KVM: arm64: Avoid vcpu->mutex v. kvm->lock inversion in CPU_ON · 0acc7239
      Oliver Upton authored
      
      
      KVM/arm64 had the lock ordering backwards on vcpu->mutex and kvm->lock
      from the very beginning. One such example is the way vCPU resets are
      handled: the kvm->lock is acquired while handling a guest CPU_ON PSCI
      call.
      
      Add a dedicated lock to serialize writes to kvm_vcpu_arch::{mp_state,
      reset_state}. Promote all accessors of mp_state to {READ,WRITE}_ONCE()
      as readers do not acquire the mp_state_lock. While at it, plug yet
      another race by taking the mp_state_lock in the KVM_SET_MP_STATE ioctl
      handler.
      
      As changes to MP state are now guarded with a dedicated lock, drop the
      kvm->lock acquisition from the PSCI CPU_ON path. Similarly, move the
      reader of reset_state outside of the kvm->lock and instead protect it
      with the mp_state_lock. Note that writes to reset_state::reset have been
      demoted to regular stores as both readers and writers acquire the
      mp_state_lock.
      
      While the kvm->lock inversion still exists in kvm_reset_vcpu(), at least
      now PSCI CPU_ON no longer depends on it for serializing vCPU reset.
      
      Cc: stable@vger.kernel.org
      Tested-by: default avatarJeremy Linton <jeremy.linton@arm.com>
      Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
      Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
      Link: https://lore.kernel.org/r/20230327164747.2466958-2-oliver.upton@linux.dev
      0acc7239
  7. Mar 27, 2023