Commit Graph

347 Commits

Author SHA1 Message Date
Keir Fraser d6045efc66 FROMLIST: KVM: arm64: vgic-init: Remove vgic_ready() macro
It is now used only within kvm_vgic_map_resources(). vgic_dist::ready
is already written directly by this function, so it is clearer to
bypass the macro for reads as well.

Bug: 395485007
Bug: 357781595
Link: https://lore.kernel.org/all/20250624092256.1105524-2-keirf@google.com/

Change-Id: I924de8c4a02ed5d3af39b798af12d015d577d2f7
Signed-off-by: Keir Fraser <keirf@google.com>
2025-07-11 03:09:09 -07:00
Quentin Perret 6cb1db877d ANDROID: KVM: arm64: Pad more pKVM structs
Pad the remanining pKVM-related structs before KMI freeze.

Bug: 360102915
Change-Id: I47a9469a1115d3289427368ac076e64e7f798105
Signed-off-by: Quentin Perret <qperret@google.com>
2025-05-16 12:17:59 +00:00
Mostafa Saleh 38ab8e61f9 ANDROID: KVM: arm64: pviommu: Add alloc/free_domain() HVC ops
Guests doens't have a separate domain space as the host, but they share
the upper half of the domain ids, so they would ask for a domain and
get a domain_id as a return.

Also as the guests doesn't know about the IOMMU topology, add
KVM_IOMMU_DOMAIN_ANY_TYPE, which would be used for guests, and the
IOMMU driver should choose the proper type for it.

Allocating a domain for guest, this HVC can need memory for:
- PGD for the domain page table.
- Domain struct for hyp.

For both we return to host to fill the guest iommu memcache.

The HVC returns the ID allocated for this domain, which the guest
can use later for map/unmap.

Bug: 357781595
Bug: 348382247
Bug: 236685427
Change-Id: I2ee84938b60337bee38f2227db53c832878140d0
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2025-04-16 13:39:55 +00:00
Mostafa Saleh 540b4b9ce3 ANDROID: KVM: arm64: iommu: Add owner to domains
Add an owner to each domain either host or a VM which is set at alloc
time, and all other IOMMU operations would be allowed only from the
domain owner.
The new vm member is protected by kvm_iommu_domain_lock while
set/cleared in alloc/free, and the check is done only after the domain
refcount is elevated to avoid racing with alloc.

Bug: 357781595
Bug: 348382247
Bug: 236685427
Change-Id: Ie23379d958922368ec3be2127ba90393709a77bb
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2025-04-16 13:39:55 +00:00
Mostafa Saleh 42a42417a6 ANDROID: KVM: arm64: Add getters for SMCCC args 4-6
SMCCCv1.1 can have up to 6 args, but there were no getters for args 4-6.
This patch adds the missing getters.

Bug: 357781595
Bug: 348382247
Bug: 236685427
Change-Id: I99d06bd7a91da102f62355e373475a906384c87b
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2025-04-16 13:39:55 +00:00
Mostafa Saleh 2e19490f3f ANDROID: KVM: arm64: iommu: Use same type for kernel/hyp
Although hyp_spinlock_t and u32 have the same size, that makes the build
system duplicate the type for EL1/EL2 builds impacting KMI.

Use a single type for lock, and cast it when used at EL2.

Bug: 350677978
Bug: 357781595
Bug: 384432312
Change-Id: I13b7330dcf5c5340e3bad35eab9808388e9a84a3
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2025-02-11 04:01:05 -08:00
Mostafa Saleh 44f9c10361 ANDROID: KVM: arm64: devices: Add reset handler for devices
Many devices must be reset before and after assignment, and as the
host can't be trusted to do this, we have to do it from the
hypervisor, and as we only deal with MMIO(platform) devices, which
has not standard interface, we provide a function to register
reset handler to modules, that can be registered with the MMIO base
address of the device with pkvm_device_register_reset.

Bug: 357781595
Bug: 348382247
Change-Id: Ie700aacf440caa6f1ffee85086a1edecdc104a5a
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2025-02-07 05:50:52 -08:00
Mostafa Saleh b86926ac85 ANDROID: KVM: arm64: devices: Check host ownership for IOMMU calls
As currently we support pVMs, host shouldn't be able to attach or
detach any device owned by a pVM.

Bug: 357781595
Bug: 348382247
Change-Id: If3f2233b7163cb8630140882a8e30e09cdd2ac24
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2025-02-07 05:50:52 -08:00
Mostafa Saleh 2cb178cea5 ANDROID: KVM: arm64: devices: Add initial device definitions
In preparation for supporting device assignment in pKVM, the
hypervisor should be able to authenticate assigned devices by
providing HVCs to the guest to get trusted description about the
device.

To be able to do this the hypervisor should get assignable devices
description at boot when the kernel is still trusted.

Bug: 357781595
Bug: 348382247
Change-Id: I8bf38c253786eb56cbb1368531b2a3dea048ae88
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2025-02-06 04:30:59 -08:00
Mostafa Saleh d4772b152b ANDROID: KVM: arm64: Pad IOMMU structs for KMI
KMI is going to be frozen soon, so add padding in IOMMU structs as
it can be helpful to update the driver without changing the ABI.

The updated structs are:
kvm_iommu_ops: kvm_iommu_driver: reserve 8 qwords, this is only
instantiated once, and the most likely one to change, as it
implements the callbacks between the IOMMU code and the hypervisor module.

kvm_iommu_driver: reserve 8 qwords, this is only instantiated once,
this implements the callbacks between the IOMMU code and the kernel module.

kvm_hyp_iommu: reserve 4 qwords, instantiated once per-iommu.

kvm_hyp_iommu_domain: reserve 2 qwords, this is the most instantiated
struct, so we don’t add a lot of padding.

iommu_iotlb_gather: reserve 2 qwords, in case we need to add hypervisor
specific logic in the future.

io_pgtable_ops: reserve 4 qwords, instantiated once per iommu domain.

Bug: 357781595
Bug: 384432312
Change-Id: I1c5c9e0dd4fe1b422c8a20e23df6b9e10f646071
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2025-01-21 13:09:26 +00:00
Mostafa Saleh b2e3ad4708 ANDROID: KVM: arm64: iommu: Snapshot host stage-2
Snapshot the host stage-2 in the idmapped domain, this is done
differently from the Android14:

- Instead of assuming that the page table maps all the memory and
  the snapshot function would only unmap the donated pages, now the
  polarity is the opposite, where the page table is assumed to be
  empty and the snapshot function would map all host memory, so this
  slower, but done only once at boot, and that won't require the
  module to know the memory map.

- Instead of calling snapshot at init, now it is exported to modules,
  as some IOMMUs as SMMUv3 doens't know the format of the page table
  until the device is attached.

Bug: 357781595
Bug: 384432312
Change-Id: I82dbf273eebc4e5c588c230a3a9bb18ef7b468ea
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-24 10:39:44 +00:00
Mostafa Saleh 6ff074eb95 ANDROID: KVM: arm64: Remove HYP_SPIN_LOCK from generated code
As HYP_SPIN_LOCK is used by modules, we can't include internal header
for it. Instead we assume its 4, then assert this at runtime.

Bug: 357781595
Bug: 384432312
Change-Id: I6d7b0c8fa8000c4e32c65fd8c98533e6ed17563f
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-24 10:39:43 +00:00
Mostafa Saleh f4d03430a2 ANDROID: iommu/arm-smmu-v3-kvm: Move files out of KVM
In Preparation of having SMMUv3 driver as an EL2 module move its
files to drivers/iommu/...

No functional change intended.

Bug: 357781595
Bug: 384432312
Change-Id: I7c62d287103c6b2461d65d2cbe799a465ebd54f7
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-24 10:39:42 +00:00
Mostafa Saleh 6a5ce6eabe BACKPORT: FROMLIST: KVM: arm64: smmu-v3: Add attach_dev
Add attach_dev HVC code which handles both stage-1 and stage-2.

Link: https://lore.kernel.org/all/20241212180423.1578358-36-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: I3f45b6baf0a2dceca786543190b1ee5fc83f3534
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-20 03:25:14 -08:00
Mostafa Saleh 5d885dc270 BACKPORT: FROMLIST: KVM: arm64: smmu-v3: Add {alloc/free}_domain
Add SMMUv3 alloc/free domain, as this operations are not
tied to the IOMMU, we can't do much with the io-pgtable
allocation or configuration.

Link: https://lore.kernel.org/all/20241212180423.1578358-33-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: I06af7cbf5868e86f4cf8ebcc44d689fa8d36c567
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-20 03:25:14 -08:00
Mostafa Saleh c7d7c29253 BACKPORT: FROMLIST: KVM: arm64: smmu-v3: Setup stream table
Map the stream table allocated by the host into the hypervisor address
space. When the host mappings are finalized, the table is unmapped from
the host. Depending on the host configuration, the stream table may have
one or two levels. Populate the level-2 stream table lazily.

Also, add accessors for STEs.

Link: https://lore.kernel.org/all/20241212180423.1578358-29-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: I017d009d7e3c36ef114b70840979348c7813c20b
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
2024-12-20 03:25:14 -08:00
Jean-Philippe Brucker bd15feb317 BACKPORT: FROMLIST: KVM: arm64: smmu-v3: Setup command queue
Map the command queue allocated by the host into the hypervisor address
space. When the host mappings are finalized, the queue is unmapped from
the host.

Link: https://lore.kernel.org/all/20241212180423.1578358-28-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: I191e9d99c02943f594c03bfaba69b1da3405a674
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-20 03:25:14 -08:00
Jean-Philippe Brucker b414161ca3 BACKPORT: FROMLIST: KVM: arm64: smmu-v3: Initialize registers
Ensure all writable registers are properly initialized. We do not touch
registers that will not be read by the SMMU due to disabled features.

Link: https://lore.kernel.org/all/20241212180423.1578358-27-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: I2f8ed283765c3b9fe577239be96b84164a6a23f1
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-20 03:25:14 -08:00
Jean-Philippe Brucker c16a84d8e6 BACKPORT: FROMLIST: KVM: arm64: iommu: Add SMMUv3 driver
Add the skeleton for an Arm SMMUv3 driver at EL2.

Link: https://lore.kernel.org/all/20241212180423.1578358-26-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: I605da2ed3075054b142eac6f6a7922f140244ca8
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-20 03:25:14 -08:00
Jean-Philippe Brucker 09b0f24506 BACKPORT: FROMLIST: KVM: arm64: iommu: Support power management
Add power domain ops to the hypervisor IOMMU driver. We currently make
these assumptions:

* The register state is retained across power off.
* The TLBs are clean on power on.
* Another privileged software (EL3 or SCP FW) handles dependencies
  between SMMU and endpoints.

So we just need to make sure that the CPU does not touch the SMMU
registers while it is powered off.

Link: https://lore.kernel.org/all/20241212180423.1578358-24-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: Iefe6f06b40510cbd5945cc8acf2bba7bd82a4564
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-20 03:25:14 -08:00
Jean-Philippe Brucker 220be80770 BACKPORT: FROMLIST: KVM: arm64: pkvm: Support SCMI power domain
The hypervisor needs to catch power domain changes for devices it owns,
such as the SMMU. Possible reasons:

* Ensure that software and hardware states are consistent. The driver
  does not attempt to modify the state while the device is off.
* Save and restore the device state.
* Enforce dependency between consumers and suppliers. For example ensure
  that endpoints are off before turning the SMMU off, in case a powered
  off SMMU lets DMA through. However this is normally enforced by
  firmware.

Add a SCMI power domain, as the standard method for device power
management on Arm. Other methods can be added to kvm_power_domain later.

Link: https://lore.kernel.org/all/20241212180423.1578358-23-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: I6c9ee841b92644114e5fabca23200c41fe12526a
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-20 03:25:14 -08:00
Mostafa Saleh 2e3d19be3e BACKPORT: FROMLIST: KVM: arm64: Support power domains
Unfortunately, as power management is not widely standardized we have
to work around that.

One implementation we can support is HOST_HVC, where the host
is in control of the power management and it notifies the
hypervisor about the updates.

This adds extra constraints to the IOMMUs, as they must reset to
blocking DMA traffic to be able to use this PD interface.

Unfortunately again, for SMMUv3 which is the only IOMMU currently
supported, there is no architectural way to discover this, so we
rely on enabling this driver when it fits the constraints, also
the driver sets GBPA and assumes that the SMMU retains across
power cycling.

In the next patch SCMI support is added.

Link: https://lore.kernel.org/all/20241212180423.1578358-21-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: I99e71fc44b67ca8e69a043f3d19e2f5c3c69206e
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
2024-12-20 03:25:14 -08:00
Mostafa Saleh 14364a71d0 BACKPORT: FROMLIST: KVM: arm64: iommu: Add {attach, detach}_dev
Add attach/detach dev operations which are forwarded to the driver.

To avoid racing between alloc/free domain and attach/detach dev,
the refcount is used.

Although, as IOMMU attach/detach are per-IOMMU and would require
some sort of locking, nothing in the IOMMU core code need the lock
so delegate that to the driver to use locks when needed and the
hypervisor only guarantees no races between alloc/free domain.

Also, add a new function kvm_iommu_init_device() to initialise common
fields of the IOMMU struct, which is only the lock at the moment.
The IOMMU core code will need to use the lock next for power
management.

Link: https://lore.kernel.org/all/20241212180423.1578358-18-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: I969762bda4ab2e5229a2a86942336896b9e8f066
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
2024-12-20 03:25:14 -08:00
Mostafa Saleh 50286c4984 BACKPORT: FROMLIST: KVM: arm64: iommu: Add domains
The IOMMU domain abstraction allows to share the same page tables
between multiple devices. That may be necessary due to hardware
constraints, if multiple devices cannot be isolated by the IOMMU
(conventional PCI bus for example). It may also help with optimizing
resource or TLB use. For pKVM in particular, it may be useful to reduce
the amount of memory required for page tables. All devices owned by the
host kernel could be attached to the same domain (though that requires
host changes).

There is one shared domain space with all IOMMUs holding up to 2^16
domains.

Link: https://lore.kernel.org/all/20241212180423.1578358-17-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: Ic5b0b9511e878e02bea47dc15fbdca4bc9d9af1b
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
2024-12-20 03:25:14 -08:00
Fuad Tabba 1b55dd706a ANDROID: KVM: arm64: Move some kvm_psci functions to a shared header
Move some PSCI functions and macros to a shared header to be used
by hyp in protected mode.

No functional change intended.

Bug: 357781595
Change-Id: Ibe84564f423cd0281f3dc33d9801b474fe8f2db9
Signed-off-by: Fuad Tabba <tabba@google.com>
2024-11-14 15:18:50 +00:00
Rob Herring (Arm) 2f62701fa5 KVM: arm64: Refine PMU defines for number of counters
There are 2 defines for the number of PMU counters:
ARMV8_PMU_MAX_COUNTERS and ARMPMU_MAX_HWEVENTS. Both are the same
currently, but Armv9.4/8.9 increases the number of possible counters
from 32 to 33. With this change, the maximum number of counters will
differ for KVM's PMU emulation which is PMUv3.4. Give KVM PMU emulation
its own define to decouple it from the rest of the kernel's number PMU
counters.

The VHE PMU code needs to match the PMU driver, so switch it to use
ARMPMU_MAX_HWEVENTS instead.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Tested-by: James Clark <james.clark@linaro.org>
Link: https://lore.kernel.org/r/20240731-arm-pmu-3-9-icntr-v3-6-280a8d7ff465@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
2024-08-16 13:09:12 +01:00
Rob Herring (Arm) 126d7d7cce arm64: perf/kvm: Use a common PMU cycle counter define
The PMUv3 and KVM code each have a define for the PMU cycle counter
index. Move KVM's define to a shared location and use it for PMUv3
driver.

Reviewed-by: Marc Zyngier <maz@kernel.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Tested-by: James Clark <james.clark@linaro.org>
Link: https://lore.kernel.org/r/20240731-arm-pmu-3-9-icntr-v3-5-280a8d7ff465@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
2024-08-16 13:09:12 +01:00
Rob Herring (Arm) a4a6e2078d perf: arm_pmuv3: Prepare for more than 32 counters
Various PMUv3 registers which are a mask of counters are 64-bit
registers, but the accessor functions take a u32. This has been fine as
the upper 32-bits have been RES0 as there has been a maximum of 32
counters prior to Armv9.4/8.9. With Armv9.4/8.9, a 33rd counter is
added. Update the accessor functions to use a u64 instead.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Tested-by: James Clark <james.clark@linaro.org>
Link: https://lore.kernel.org/r/20240731-arm-pmu-3-9-icntr-v3-2-280a8d7ff465@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
2024-08-16 13:09:12 +01:00
Marc Zyngier e28157060c Merge branch kvm-arm64/misc-6.10 into kvmarm-master/next
* kvm-arm64/misc-6.10:
  : .
  : Misc fixes and updates targeting 6.10
  :
  : - Improve boot-time diagnostics when the sysreg tables
  :   are not correctly sorted
  :
  : - Allow FFA_MSG_SEND_DIRECT_REQ in the FFA proxy
  :
  : - Fix duplicate XNX field in the ID_AA64MMFR1_EL1
  :   writeable mask
  :
  : - Allocate PPIs and SGIs outside of the vcpu structure, allowing
  :   for smaller EL2 mapping and some flexibility in implementing
  :   more or less than 32 private IRQs.
  :
  : - Use bitmap_gather() instead of its open-coded equivalent
  :
  : - Make protected mode use hVHE if available
  :
  : - Purge stale mpidr_data if a vcpu is created after the MPIDR
  :   map has been created
  : .
  KVM: arm64: Destroy mpidr_data for 'late' vCPU creation
  KVM: arm64: Use hVHE in pKVM by default on CPUs with VHE support
  KVM: arm64: Fix hvhe/nvhe early alias parsing
  KVM: arm64: Convert kvm_mpidr_index() to bitmap_gather()
  KVM: arm64: vgic: Allocate private interrupts on demand
  KVM: arm64: Remove duplicated AA64MMFR1_EL1 XNX
  KVM: arm64: Remove FFA_MSG_SEND_DIRECT_REQ from the denylist
  KVM: arm64: Improve out-of-order sysreg table diagnostics

Signed-off-by: Marc Zyngier <maz@kernel.org>
2024-05-08 16:41:50 +01:00
Marc Zyngier 8540bd1b99 Merge branch kvm-arm64/pkvm-6.10 into kvmarm-master/next
* kvm-arm64/pkvm-6.10: (25 commits)
  : .
  : At last, a bunch of pKVM patches, courtesy of Fuad Tabba.
  : From the cover letter:
  :
  : "This series is a bit of a bombay-mix of patches we've been
  : carrying. There's no one overarching theme, but they do improve
  : the code by fixing existing bugs in pKVM, refactoring code to
  : make it more readable and easier to re-use for pKVM, or adding
  : functionality to the existing pKVM code upstream."
  : .
  KVM: arm64: Force injection of a data abort on NISV MMIO exit
  KVM: arm64: Restrict supported capabilities for protected VMs
  KVM: arm64: Refactor setting the return value in kvm_vm_ioctl_enable_cap()
  KVM: arm64: Document the KVM/arm64-specific calls in hypercalls.rst
  KVM: arm64: Rename firmware pseudo-register documentation file
  KVM: arm64: Reformat/beautify PTP hypercall documentation
  KVM: arm64: Clarify rationale for ZCR_EL1 value restored on guest exit
  KVM: arm64: Introduce and use predicates that check for protected VMs
  KVM: arm64: Add is_pkvm_initialized() helper
  KVM: arm64: Simplify vgic-v3 hypercalls
  KVM: arm64: Move setting the page as dirty out of the critical section
  KVM: arm64: Change kvm_handle_mmio_return() return polarity
  KVM: arm64: Fix comment for __pkvm_vcpu_init_traps()
  KVM: arm64: Prevent kmemleak from accessing .hyp.data
  KVM: arm64: Do not map the host fpsimd state to hyp in pKVM
  KVM: arm64: Rename __tlb_switch_to_{guest,host}() in VHE
  KVM: arm64: Support TLB invalidation in guest context
  KVM: arm64: Avoid BBM when changing only s/w bits in Stage-2 PTE
  KVM: arm64: Check for PTE validity when checking for executable/cacheable
  KVM: arm64: Avoid BUG-ing from the host abort path
  ...

Signed-off-by: Marc Zyngier <maz@kernel.org>
2024-05-03 11:39:52 +01:00
Marc Zyngier 03b3d00a70 KVM: arm64: vgic: Allocate private interrupts on demand
Private interrupts are currently part of the CPU interface structure
that is part of each and every vcpu we create.

Currently, we have 32 of them per vcpu, resulting in a per-vcpu array
that is just shy of 4kB. On its own, that's no big deal, but it gets
in the way of other things:

- each vcpu gets mapped at EL2 on nVHE/hVHE configurations. This
  requires memory that is physically contiguous. However, the EL2
  code has no purpose looking at the interrupt structures and
  could do without them being mapped.

- supporting features such as EPPIs, which extend the number of
  private interrupts past the 32 limit would make the array
  even larger, even for VMs that do not use the EPPI feature.

Address these issues by moving the private interrupt array outside
of the vcpu, and replace it with a simple pointer. We take this
opportunity to make it obvious what gets initialised when, as
that path was remarkably opaque, and tighten the locking.

Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240502154545.3012089-1-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
2024-05-03 11:33:50 +01:00
Marc Zyngier 948e1a53c2 KVM: arm64: Simplify vgic-v3 hypercalls
Consolidate the GICv3 VMCR accessor hypercalls into the APR save/restore
hypercalls so that all of the EL2 GICv3 state is covered by a single pair
of hypercalls.

Signed-off-by: Fuad Tabba <tabba@google.com>
Acked-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240423150538.2103045-17-tabba@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
2024-05-01 16:48:14 +01:00
Oliver Upton 481c9ee846 KVM: arm64: vgic-its: Get rid of the lpi_list_lock
The last genuine use case for the lpi_list_lock was the global LPI
translation cache, which has been removed in favor of a per-ITS xarray.
Remove a layer from the locking puzzle by getting rid of it.

vgic_add_lpi() still has a critical section that needs to protect
against the insertion of other LPIs; change it to take the LPI xarray's
xa_lock to retain this property.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240422200158.2606761-13-oliver.upton@linux.dev
Signed-off-by: Marc Zyngier <maz@kernel.org>
2024-04-25 13:19:56 +01:00
Oliver Upton ec39bbfd55 KVM: arm64: vgic-its: Rip out the global translation cache
The MSI injection fast path has been transitioned away from the global
translation cache. Rip it out.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240422200158.2606761-12-oliver.upton@linux.dev
Signed-off-by: Marc Zyngier <maz@kernel.org>
2024-04-25 13:19:56 +01:00
Oliver Upton 8201d1028c KVM: arm64: vgic-its: Maintain a translation cache per ITS
Within the context of a single ITS, it is possible to use an xarray to
cache the device ID & event ID translation to a particular irq
descriptor. Take advantage of this to build a translation cache capable
of fitting all valid translations for a given ITS.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240422200158.2606761-9-oliver.upton@linux.dev
Signed-off-by: Marc Zyngier <maz@kernel.org>
2024-04-25 13:19:55 +01:00
Oliver Upton 30a0ce9c49 KVM: arm64: vgic-its: Get rid of vgic_copy_lpi_list()
The last user has been transitioned to walking the LPI xarray directly.
Cut the wart off, and get rid of the now unneeded lpi_count while doing
so.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240422200158.2606761-7-oliver.upton@linux.dev
Signed-off-by: Marc Zyngier <maz@kernel.org>
2024-04-25 13:19:55 +01:00
Oliver Upton 85d3ccc8b7 KVM: arm64: vgic-debug: Use an xarray mark for debug iterator
The vgic debug iterator is the final user of vgic_copy_lpi_list(), but
is a bit more complicated to transition to something else. Use a mark
in the LPI xarray to record the indices 'known' to the debug iterator.
Protect against the LPIs from being freed by associating an additional
reference with the xarray mark.

Rework iter_next() to let the xarray walk 'drive' the iteration after
visiting all of the SGIs, PPIs, and SPIs.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240422200158.2606761-6-oliver.upton@linux.dev
Signed-off-by: Marc Zyngier <maz@kernel.org>
2024-04-25 13:19:55 +01:00
Oliver Upton e89c928bed KVM: arm64: Fix host-programmed guest events in nVHE
Programming PMU events in the host that count during guest execution is
a feature supported by perf, e.g.

  perf stat -e cpu_cycles:G ./lkvm run

While this works for VHE, the guest/host event bitmaps are not carried
through to the hypervisor in the nVHE configuration. Make
kvm_pmu_update_vcpu_events() conditional on whether or not _hardware_
supports PMUv3 rather than if the vCPU as vPMU enabled.

Cc: stable@vger.kernel.org
Fixes: 84d751a019 ("KVM: arm64: Pass pmu events to hyp via vcpu")
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240305184840.636212-3-oliver.upton@linux.dev
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2024-03-26 01:51:44 -07:00
Oliver Upton 8dbc41105e Merge branch kvm-arm64/lpi-xarray into kvmarm/next
* kvm-arm64/lpi-xarray:
  : xarray-based representation of vgic LPIs
  :
  : KVM's linked-list of LPI state has proven to be a bottleneck in LPI
  : injection paths, due to lock serialization when acquiring / releasing a
  : reference on an IRQ.
  :
  : Start the tedious process of reworking KVM's LPI injection by replacing
  : the LPI linked-list with an xarray, leveraging this to allow RCU readers
  : to walk it outside of the spinlock.
  KVM: arm64: vgic: Don't acquire the lpi_list_lock in vgic_put_irq()
  KVM: arm64: vgic: Ensure the irq refcount is nonzero when taking a ref
  KVM: arm64: vgic: Rely on RCU protection in vgic_get_lpi()
  KVM: arm64: vgic: Free LPI vgic_irq structs in an RCU-safe manner
  KVM: arm64: vgic: Use atomics to count LPIs
  KVM: arm64: vgic: Get rid of the LPI linked-list
  KVM: arm64: vgic-its: Walk the LPI xarray in vgic_copy_lpi_list()
  KVM: arm64: vgic-v3: Iterate the xarray to find pending LPIs
  KVM: arm64: vgic: Use xarray to find LPI in vgic_get_lpi()
  KVM: arm64: vgic: Store LPIs in an xarray

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2024-03-07 00:55:53 +00:00
Oliver Upton a5c7f011cb KVM: arm64: vgic: Free LPI vgic_irq structs in an RCU-safe manner
Free the vgic_irq structs in an RCU-safe manner to allow reads of the
LPI configuration data to happen in parallel with the release of LPIs.

Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240221054253.3848076-8-oliver.upton@linux.dev
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2024-02-23 21:46:02 +00:00
Oliver Upton 05f4d4f5d4 KVM: arm64: vgic: Use atomics to count LPIs
Switch to using atomics for LPI accounting, allowing vgic_irq references
to be dropped in parallel.

Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240221054253.3848076-7-oliver.upton@linux.dev
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2024-02-23 21:46:02 +00:00
Oliver Upton 9880835af7 KVM: arm64: vgic: Get rid of the LPI linked-list
All readers of LPI configuration have been transitioned to use the LPI
xarray. Get rid of the linked-list altogether.

Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240221054253.3848076-6-oliver.upton@linux.dev
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2024-02-23 21:46:02 +00:00
Oliver Upton 1d6f83f60f KVM: arm64: vgic: Store LPIs in an xarray
Using a linked-list for LPIs is less than ideal as it of course requires
iterative searches to find a particular entry. An xarray is a better
data structure for this use case, as it provides faster searches and can
still handle a potentially sparse range of INTID allocations.

Start by storing LPIs in an xarray, punting usage of the xarray to a
subsequent change. The observant among you will notice that we added yet
another lock to the chain of locking order rules; document the ordering
of the xa_lock. Don't worry, we'll get rid of the lpi_list_lock one
day...

Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240221054253.3848076-2-oliver.upton@linux.dev
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2024-02-23 21:46:01 +00:00
Marc Zyngier c62d7a23b9 KVM: arm64: Add feature checking helpers
In order to make it easier to check whether a particular feature
is exposed to a guest, add a new set of helpers, with kvm_has_feat()
being the most useful.

Let's start making use of them in the PMU code (courtesy of Oliver).
Follow-up changes will introduce additional use patterns.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Co-developed--by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240214131827.2856277-3-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2024-02-19 17:12:59 +00:00
Paolo Bonzini 45b890f768 Merge tag 'kvmarm-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm64 updates for 6.7

 - Generalized infrastructure for 'writable' ID registers, effectively
   allowing userspace to opt-out of certain vCPU features for its guest

 - Optimization for vSGI injection, opportunistically compressing MPIDR
   to vCPU mapping into a table

 - Improvements to KVM's PMU emulation, allowing userspace to select
   the number of PMCs available to a VM

 - Guest support for memory operation instructions (FEAT_MOPS)

 - Cleanups to handling feature flags in KVM_ARM_VCPU_INIT, squashing
   bugs and getting rid of useless code

 - Changes to the way the SMCCC filter is constructed, avoiding wasted
   memory allocations when not in use

 - Load the stage-2 MMU context at vcpu_load() for VHE systems, reducing
   the overhead of errata mitigations

 - Miscellaneous kernel and selftest fixes
2023-10-31 16:37:07 -04:00
Oliver Upton 123f42f0ad Merge branch kvm-arm64/pmu_pmcr_n into kvmarm/next
* kvm-arm64/pmu_pmcr_n:
  : User-defined PMC limit, courtesy Raghavendra Rao Ananta
  :
  : Certain VMMs may want to reserve some PMCs for host use while running a
  : KVM guest. This was a bit difficult before, as KVM advertised all
  : supported counters to the guest. Userspace can now limit the number of
  : advertised PMCs by writing to PMCR_EL0.N, as KVM's sysreg and PMU
  : emulation enforce the specified limit for handling guest accesses.
  KVM: selftests: aarch64: vPMU test for validating user accesses
  KVM: selftests: aarch64: vPMU register test for unimplemented counters
  KVM: selftests: aarch64: vPMU register test for implemented counters
  KVM: selftests: aarch64: Introduce vpmu_counter_access test
  tools: Import arm_pmuv3.h
  KVM: arm64: PMU: Allow userspace to limit PMCR_EL0.N for the guest
  KVM: arm64: Sanitize PM{C,I}NTEN{SET,CLR}, PMOVS{SET,CLR} before first run
  KVM: arm64: Add {get,set}_user for PM{C,I}NTEN{SET,CLR}, PMOVS{SET,CLR}
  KVM: arm64: PMU: Set PMCR_EL0.N for vCPU based on the associated PMU
  KVM: arm64: PMU: Add a helper to read a vCPU's PMCR_EL0
  KVM: arm64: Select default PMU in KVM_ARM_VCPU_INIT handler
  KVM: arm64: PMU: Introduce helpers to set the guest's PMU

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2023-10-30 20:24:19 +00:00
Oliver Upton 54b44ad26c Merge branch kvm-arm64/sgi-injection into kvmarm/next
* kvm-arm64/sgi-injection:
  : vSGI injection improvements + fixes, courtesy Marc Zyngier
  :
  : Avoid linearly searching for vSGI targets using a compressed MPIDR to
  : index a cache. While at it, fix some egregious bugs in KVM's mishandling
  : of vcpuid (user-controlled value) and vcpu_idx.
  KVM: arm64: Clarify the ordering requirements for vcpu/RD creation
  KVM: arm64: vgic-v3: Optimize affinity-based SGI injection
  KVM: arm64: Fast-track kvm_mpidr_to_vcpu() when mpidr_data is available
  KVM: arm64: Build MPIDR to vcpu index cache at runtime
  KVM: arm64: Simplify kvm_vcpu_get_mpidr_aff()
  KVM: arm64: Use vcpu_idx for invalidation tracking
  KVM: arm64: vgic: Use vcpu_idx for the debug information
  KVM: arm64: vgic-v2: Use cpuid from userspace as vcpu_id
  KVM: arm64: vgic-v3: Refactor GICv3 SGI generation
  KVM: arm64: vgic-its: Treat the collection target address as a vcpu_id
  KVM: arm64: vgic: Make kvm_vgic_inject_irq() take a vcpu pointer

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2023-10-30 20:19:13 +00:00
Oliver Upton 7ff7dfe946 Merge branch kvm-arm64/pmevtyper-filter into kvmarm/next
* kvm-arm64/pmevtyper-filter:
  : Fixes to KVM's handling of the PMUv3 exception level filtering bits
  :
  :  - NSH (count at EL2) and M (count at EL3) should be stateful when the
  :    respective EL is advertised in the ID registers but have no effect on
  :    event counting.
  :
  :  - NSU and NSK modify the event filtering of EL0 and EL1, respectively.
  :    Though the kernel may not use these bits, other KVM guests might.
  :    Implement these bits exactly as written in the pseudocode if EL3 is
  :    advertised.
  KVM: arm64: Add PMU event filter bits required if EL3 is implemented
  KVM: arm64: Make PMEVTYPER<n>_EL0.NSH RES0 if EL2 isn't advertised

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2023-10-30 20:18:23 +00:00
Raghavendra Rao Ananta 27131b199f KVM: arm64: Sanitize PM{C,I}NTEN{SET,CLR}, PMOVS{SET,CLR} before first run
For unimplemented counters, the registers PM{C,I}NTEN{SET,CLR}
and PMOVS{SET,CLR} are expected to have the corresponding bits RAZ.
Hence to ensure correct KVM's PMU emulation, mask out the RES0 bits.
Defer this work to the point that userspace can no longer change the
number of advertised PMCs.

Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20231020214053.2144305-7-rananta@google.com
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2023-10-24 22:59:30 +00:00
Raghavendra Rao Ananta 4d20debf9c KVM: arm64: PMU: Set PMCR_EL0.N for vCPU based on the associated PMU
The number of PMU event counters is indicated in PMCR_EL0.N.
For a vCPU with PMUv3 configured, the value is set to the same
value as the current PE on every vCPU reset.  Unless the vCPU is
pinned to PEs that has the PMU associated to the guest from the
initial vCPU reset, the value might be different from the PMU's
PMCR_EL0.N on heterogeneous PMU systems.

Fix this by setting the vCPU's PMCR_EL0.N to the PMU's PMCR_EL0.N
value. Track the PMCR_EL0.N per guest, as only one PMU can be set
for the guest (PMCR_EL0.N must be the same for all vCPUs of the
guest), and it is convenient for updating the value.

To achieve this, the patch introduces a helper,
kvm_arm_pmu_get_max_counters(), that reads the maximum number of
counters from the arm_pmu associated to the VM. Make the function
global as upcoming patches will be interested to know the value
while setting the PMCR.N of the guest from userspace.

KVM does not yet support userspace modifying PMCR_EL0.N.
The following patch will add support for that.

Reviewed-by: Sebastian Ott <sebott@redhat.com>
Co-developed-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Reiji Watanabe <reijiw@google.com>
Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
Link: https://lore.kernel.org/r/20231020214053.2144305-5-rananta@google.com
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2023-10-24 22:59:30 +00:00