mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
4.3 KiB
115 lines
4.3 KiB
.. SPDX-License-Identifier: GPL-2.0 |
|
|
|
====================== |
|
VFIO AP Locks Overview |
|
====================== |
|
This document describes the locks that are pertinent to the secure operation |
|
of the vfio_ap device driver. Throughout this document, the following variables |
|
will be used to denote instances of the structures herein described: |
|
|
|
.. code-block:: c |
|
|
|
struct ap_matrix_dev *matrix_dev; |
|
struct ap_matrix_mdev *matrix_mdev; |
|
struct kvm *kvm; |
|
|
|
The Matrix Devices Lock (drivers/s390/crypto/vfio_ap_private.h) |
|
--------------------------------------------------------------- |
|
|
|
.. code-block:: c |
|
|
|
struct ap_matrix_dev { |
|
... |
|
struct list_head mdev_list; |
|
struct mutex mdevs_lock; |
|
... |
|
} |
|
|
|
The Matrix Devices Lock (matrix_dev->mdevs_lock) is implemented as a global |
|
mutex contained within the single object of struct ap_matrix_dev. This lock |
|
controls access to all fields contained within each matrix_mdev |
|
(matrix_dev->mdev_list). This lock must be held while reading from, writing to |
|
or using the data from a field contained within a matrix_mdev instance |
|
representing one of the vfio_ap device driver's mediated devices. |
|
|
|
The KVM Lock (include/linux/kvm_host.h) |
|
--------------------------------------- |
|
|
|
.. code-block:: c |
|
|
|
struct kvm { |
|
... |
|
struct mutex lock; |
|
... |
|
} |
|
|
|
The KVM Lock (kvm->lock) controls access to the state data for a KVM guest. This |
|
lock must be held by the vfio_ap device driver while one or more AP adapters, |
|
domains or control domains are being plugged into or unplugged from the guest. |
|
|
|
The KVM pointer is stored in the in the matrix_mdev instance |
|
(matrix_mdev->kvm = kvm) containing the state of the mediated device that has |
|
been attached to the KVM guest. |
|
|
|
The Guests Lock (drivers/s390/crypto/vfio_ap_private.h) |
|
----------------------------------------------------------- |
|
|
|
.. code-block:: c |
|
|
|
struct ap_matrix_dev { |
|
... |
|
struct list_head mdev_list; |
|
struct mutex guests_lock; |
|
... |
|
} |
|
|
|
The Guests Lock (matrix_dev->guests_lock) controls access to the |
|
matrix_mdev instances (matrix_dev->mdev_list) that represent mediated devices |
|
that hold the state for the mediated devices that have been attached to a |
|
KVM guest. This lock must be held: |
|
|
|
1. To control access to the KVM pointer (matrix_mdev->kvm) while the vfio_ap |
|
device driver is using it to plug/unplug AP devices passed through to the KVM |
|
guest. |
|
|
|
2. To add matrix_mdev instances to or remove them from matrix_dev->mdev_list. |
|
This is necessary to ensure the proper locking order when the list is perused |
|
to find an ap_matrix_mdev instance for the purpose of plugging/unplugging |
|
AP devices passed through to a KVM guest. |
|
|
|
For example, when a queue device is removed from the vfio_ap device driver, |
|
if the adapter is passed through to a KVM guest, it will have to be |
|
unplugged. In order to figure out whether the adapter is passed through, |
|
the matrix_mdev object to which the queue is assigned will have to be |
|
found. The KVM pointer (matrix_mdev->kvm) can then be used to determine if |
|
the mediated device is passed through (matrix_mdev->kvm != NULL) and if so, |
|
to unplug the adapter. |
|
|
|
It is not necessary to take the Guests Lock to access the KVM pointer if the |
|
pointer is not used to plug/unplug devices passed through to the KVM guest; |
|
however, in this case, the Matrix Devices Lock (matrix_dev->mdevs_lock) must be |
|
held in order to access the KVM pointer since it is set and cleared under the |
|
protection of the Matrix Devices Lock. A case in point is the function that |
|
handles interception of the PQAP(AQIC) instruction sub-function. This handler |
|
needs to access the KVM pointer only for the purposes of setting or clearing IRQ |
|
resources, so only the matrix_dev->mdevs_lock needs to be held. |
|
|
|
The PQAP Hook Lock (arch/s390/include/asm/kvm_host.h) |
|
----------------------------------------------------- |
|
|
|
.. code-block:: c |
|
|
|
typedef int (*crypto_hook)(struct kvm_vcpu *vcpu); |
|
|
|
struct kvm_s390_crypto { |
|
... |
|
struct rw_semaphore pqap_hook_rwsem; |
|
crypto_hook *pqap_hook; |
|
... |
|
}; |
|
|
|
The PQAP Hook Lock is a r/w semaphore that controls access to the function |
|
pointer of the handler ``(*kvm->arch.crypto.pqap_hook)`` to invoke when the |
|
PQAP(AQIC) instruction sub-function is intercepted by the host. The lock must be |
|
held in write mode when pqap_hook value is set, and in read mode when the |
|
pqap_hook function is called.
|
|
|