1.. SPDX-License-Identifier: GPL-2.0 2 3============== 4KVM pvIOMMU 5============== 6 7pvIOMMU is a paravirtual IOMMU interface exposed to guests. 8 9This is mainly needed for protected virtual machines (pVM), with device 10assignment, as the host can't map memory for the guest kernel in the IOMMU 11(as it is not trusted). 12 13So the host kernel would create a pvIOMMU device and attach it to a guest VM 14while providing a virtual (pvIOMMU, virtual SID(vsid)) mapping to 15the physical device (IOMMU, SID) to the hypervisor to translate guest requests. 16 17The interface as described below, mainly follows the Linux IOMMU ops 18({attach, detach}_dev, {alloc, free}_domain, {map, unmap}_pages) which 19makes the guest driver trivial to implement. 20 21pvIOMMU ID, is chosen by the host and described to the guest in a platform 22specific way, in pKVM reference implementation this is done through the device 23tree. 24 25The pvIOMMU exposes on hypercall ``ARM_SMCCC_VENDOR_HYP_KVM_PVIOMMU_OP_FUNC_ID`` 26where arg1 defines the operation requested as follows: 27 28 29``KVM_PVIOMMU_OP_ATTACH_DEV`` 30-------------------------------------- 31 32Attach a device to a domain, previously allocated from ``KVM_PVIOMMU_OP_ALLOC_DOMAIN`` 33 34+---------------------+-------------------------------------------------------------+ 35| Presence: | Optional; pKVM protected guests only | 36+---------------------+-------------------------------------------------------------+ 37| Calling convention: | HVC64 | 38+---------------------+----------+--------------------------------------------------+ 39| Function ID: | (uint32) | 0xC6000003E | 40+---------------------+----------+----+---------------------------------------------+ 41| Arguments: | (uint64) | R1 | 0x0 | 42| +----------+----+---------------------------------------------+ 43| | (uint64) | R2 | pvIOMMU ID | 44| +----------+----+---------------------------------------------+ 45| | (uint64) | R3 | vSID (virtual SID) | 46| +----------+----+---------------------------------------------+ 47| | (uint64) | R4 | PASID (or 0) | 48| +----------+----+---------------------------------------------+ 49| | (uint64) | R5 | Domain ID | 50| +----------+----+---------------------------------------------+ 51| | (uint32) | R6 | PASID_bits, the pasid space. | 52+---------------------+----------+----+---------------------------------------------+ 53| Return Values: | (int64) | R0 | ``SUCCESS (0)`` | 54| | | +---------------------------------------------+ 55| | | | ``INVALID_PARAMETER (-3)`` | 56+---------------------+----------+----+---------------------------------------------+ 57 58``KVM_PVIOMMU_OP_DETACH_DEV`` 59-------------------------------------- 60 61Detach a device from a domain, previously attached with ``KVM_PVIOMMU_OP_ATTACH_DEV`` 62 63+---------------------+-------------------------------------------------------------+ 64| Presence: | Optional; pKVM protected guests only | 65+---------------------+-------------------------------------------------------------+ 66| Calling convention: | HVC64 | 67+---------------------+----------+--------------------------------------------------+ 68| Function ID: | (uint32) | 0xC6000003E | 69+---------------------+----------+----+---------------------------------------------+ 70| Arguments: | (uint64) | R1 | 0x1 | 71| +----------+----+---------------------------------------------+ 72| | (uint64) | R2 | pvIOMMU ID | 73| +----------+----+---------------------------------------------+ 74| | (uint64) | R3 | vSID (virtual SID) | 75| +----------+----+---------------------------------------------+ 76| | (uint64) | R4 | PASID (or 0) | 77| +----------+----+---------------------------------------------+ 78| | (uint64) | R5 | Domain ID | 79| +----------+----+---------------------------------------------+ 80| | (uint64) | R6 | Reserved / Must be zero | 81+---------------------+----------+----+---------------------------------------------+ 82| Return Values: | (int64) | R0 | ``SUCCESS (0)`` | 83| | | +---------------------------------------------+ 84| | | | ``INVALID_PARAMETER (-3)`` | 85+---------------------+----------+----+---------------------------------------------+ 86 87``KVM_PVIOMMU_OP_ALLOC_DOMAIN`` 88-------------------------------------- 89 90Allocate a translation regime, which can hold IOMMU mappings and used (attached) 91by one or more devices. 92 93After a domain is successfully created from this operation, it can be passed to 94``KVM_PVIOMMU_OP_MAP_PAGES`` and ``KVM_PVIOMMU_OP_UNMAP_PAGES`` ops to add IOVA to 95IPA mappins inside yet. 96And can be used in ``KVM_PVIOMMU_OP_ATTACH_DEV`` and ``KVM_PVIOMMU_OP_DETACH_DEV`` 97to attach/detach devices to this translation regime. 98 99+---------------------+-------------------------------------------------------------+ 100| Presence: | Optional; pKVM protected guests only | 101+---------------------+-------------------------------------------------------------+ 102| Calling convention: | HVC64 | 103+---------------------+----------+--------------------------------------------------+ 104| Function ID: | (uint32) | 0xC6000003E | 105+---------------------+----------+----+---------------------------------------------+ 106| Arguments: | (uint64) | R1 | 0x2 | 107| +----------+----+---------------------------------------------+ 108| | (uint64) | R2 | Reserved / Must be zero | 109| +----------+----+---------------------------------------------+ 110| | (uint64) | R3 | Reserved / Must be zero | 111| +----------+----+---------------------------------------------+ 112| | (uint64) | R4 | Reserved / Must be zero | 113| +----------+----+---------------------------------------------+ 114| | (uint64) | R5 | Reserved / Must be zero | 115| +----------+----+---------------------------------------------+ 116| | (uint64) | R6 | Reserved / Must be zero | 117+---------------------+----------+----+---------------------------------------------+ 118| Return Values: | (int64) | R0 | ``SUCCESS (0)`` | 119| | | +---------------------------------------------+ 120| | | | ``INVALID_PARAMETER (-3)`` | 121| +----------+----+---------------------------------------------+ 122| | (uint32) | R1 | Domain ID in case of ``SUCCESS`` | 123+---------------------+----------+----+---------------------------------------------+ 124 125``KVM_PVIOMMU_OP_FREE_DOMAIN`` 126-------------------------------------- 127 128Free a domain, previously allocated from ``KVM_PVIOMMU_OP_ALLOC_DOMAIN`` 129All device previously attached to this domain (``KVM_PVIOMMU_OP_ATTACH_DEV``) 130MUST be detached first (``KVM_PVIOMMU_OP_DETACH_DEV``) before calling this. 131 132+---------------------+-------------------------------------------------------------+ 133| Presence: | Optional; pKVM protected guests only | 134+---------------------+-------------------------------------------------------------+ 135| Calling convention: | HVC64 | 136+---------------------+----------+--------------------------------------------------+ 137| Function ID: | (uint32) | 0xC6000003E | 138+---------------------+----------+----+---------------------------------------------+ 139| Arguments: | (uint64) | R1 | 0x3 | 140| +----------+----+---------------------------------------------+ 141| | (uint64) | R2 | Domain ID | 142| +----------+----+---------------------------------------------+ 143| | (uint64) | R3 | Reserved / Must be zero | 144| +----------+----+---------------------------------------------+ 145| | (uint64) | R4 | Reserved / Must be zero | 146| +----------+----+---------------------------------------------+ 147| | (uint64) | R5 | Reserved / Must be zero | 148| +----------+----+---------------------------------------------+ 149| | (uint64) | R6 | Reserved / Must be zero | 150+---------------------+----------+----+---------------------------------------------+ 151| Return Values: | (int64) | R0 | ``SUCCESS (0)`` | 152| | | +---------------------------------------------+ 153| | | | ``INVALID_PARAMETER (-3)`` | 154+---------------------+----------+----+---------------------------------------------+ 155 156``KVM_PVIOMMU_OP_MAP_PAGES`` 157-------------------------------------- 158 159Map pages in a domain. 160 161IOVA and IPA and size must all be aligned to memory protection granule according to 162``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO`` 163 164prot(R6) encoded as a bitmask as follows: 165- ARM_SMCCC_KVM_PVIOMMU_READ (1 << 0) 166- ARM_SMCCC_KVM_PVIOMMU_WRITE (1 << 1) 167- ARM_SMCCC_KVM_PVIOMMU_CACHE (1 << 2) 168- ARM_SMCCC_KVM_PVIOMMU_NOEXEC (1 << 3) 169- ARM_SMCCC_KVM_PVIOMMU_MMIO (1 << 4) 170- ARM_SMCCC_KVM_PVIOMMU_PRIV (1 << 5) 171 172+---------------------+-------------------------------------------------------------+ 173| Presence: | Optional. | 174+---------------------+-------------------------------------------------------------+ 175| Calling convention: | HVC64 | 176+---------------------+----------+--------------------------------------------------+ 177| Function ID: | (uint32) | 0xC6000003E | 178+---------------------+----------+----+---------------------------------------------+ 179| Arguments: | (uint64) | R1 | 0x4 | 180| +----------+----+---------------------------------------------+ 181| | (uint64) | R2 | Domain ID | 182| +----------+----+---------------------------------------------+ 183| | (uint64) | R3 | IOVA | 184| +----------+----+---------------------------------------------+ 185| | (uint64) | R4 | IPA | 186| +----------+----+---------------------------------------------+ 187| | (uint64) | R5 | Size | 188| +----------+----+---------------------------------------------+ 189| | (uint64) | R6 | Protection | 190+---------------------+----------+----+---------------------------------------------+ 191| Return Values: | (int64) | R0 | ``SUCCESS (0)`` | 192| | | +---------------------------------------------+ 193| | | | ``INVALID_PARAMETER (-3)`` | 194+---------------------+----------+----+---------------------------------------------+ 195| | (uint64) | R1 | Number of mapped pages | 196+---------------------+----------+----+---------------------------------------------+ 197 198``KVM_PVIOMMU_OP_UNMAP_PAGES`` 199-------------------------------------- 200 201Unmap pages from a domain. 202 203+---------------------+-------------------------------------------------------------+ 204| Presence: | Optional. | 205+---------------------+-------------------------------------------------------------+ 206| Calling convention: | HVC64 | 207+---------------------+----------+--------------------------------------------------+ 208| Function ID: | (uint32) | 0xC6000003E | 209+---------------------+----------+----+---------------------------------------------+ 210| Arguments: | (uint64) | R1 | 0x5 | 211| +----------+----+---------------------------------------------+ 212| | (uint64) | R2 | Domain ID | 213| +----------+----+---------------------------------------------+ 214| | (uint64) | R3 | IOVA | 215| +----------+----+---------------------------------------------+ 216| | (uint64) | R4 | Size | 217| +----------+----+---------------------------------------------+ 218| | (uint64) | R5 | Reserved / Must be zero | 219| +----------+----+---------------------------------------------+ 220| | (uint64) | R6 | Reserved / Must be zero | 221+---------------------+----------+----+---------------------------------------------+ 222| Return Values: | (int64) | R0 | ``SUCCESS (0)`` | 223| | | +---------------------------------------------+ 224| | | | ``INVALID_PARAMETER (-3)`` | 225+---------------------+----------+----+---------------------------------------------+ 226| | (uint64) | R1 | Number of unmapped pages | 227+---------------------+----------+----+---------------------------------------------+ 228 229``ARM_SMCCC_KVM_FUNC_DEV_REQ_DMA`` 230-------------------------------------- 231 232Verify a device IOMMU matches what the host describes in the firmware 233(ex: device tree) for a physical device passthrough to a protected 234virtual machine. 235 236Called per IOMMU endpoint (pvIOMMU ID + vSID). 237 238Returns a token(128 bit) that can be used to verify the resource 239matching a trusted firmware description with the same token, which 240passed is through a platform specific way. 241 242Must be called before any IOMMU access for protected virtual machines. 243 244Ideally called from protected vm firmware. 245 246+---------------------+-------------------------------------------------------------+ 247| Presence: | Optional. | 248+---------------------+-------------------------------------------------------------+ 249| Calling convention: | HVC64 | 250+---------------------+----------+--------------------------------------------------+ 251| Function ID: | (uint32) | 0xC6000003D | 252+---------------------+----------+----+---------------------------------------------+ 253| Arguments: | (uint64) | R1 | pvIOMMU ID | 254| +----------+----+---------------------------------------------+ 255| | (uint64) | R2 | vSID | 256| +----------+----+---------------------------------------------+ 257| | (uint64) | R3 | Reserved / Must be zero | 258| +----------+----+---------------------------------------------+ 259| | (uint64) | R4 | Reserved / Must be zero | 260| +----------+----+---------------------------------------------+ 261| | (uint64) | R5 | Reserved / Must be zero | 262| +----------+----+---------------------------------------------+ 263| | (uint64) | R6 | Reserved / Must be zero | 264+---------------------+----------+----+---------------------------------------------+ 265| Return Values: | (int64) | R0 | ``SUCCESS (0)`` | 266| | | +---------------------------------------------+ 267| | | | ``INVALID_PARAMETER (-3)`` | 268+---------------------+----------+----+---------------------------------------------+ 269| | (uint64) | R1 | Token1 in case of ``SUCCESS`` | 270+---------------------+----------+----+---------------------------------------------+ 271| | (uint64) | R2 | Token2 in case of ``SUCCESS`` | 272+---------------------+----------+----+---------------------------------------------+ 273