mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
s390/Docs: new doc describing lock usage by the vfio_ap device driver
Introduces a new document describing the locks used by the vfio_ap device driver and how to use them so as to avoid lockdep reports and deadlock situations. Signed-off-by: Tony Krowiak <akrowiak@linux.ibm.com> Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
This commit is contained in:
parent
cb269e0aba
commit
e32d3827f3
105
Documentation/s390/vfio-ap-locking.rst
Normal file
105
Documentation/s390/vfio-ap-locking.rst
Normal file
@ -0,0 +1,105 @@
|
||||
.. 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:
|
||||
|
||||
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)
|
||||
--------------------------------------------------------------
|
||||
|
||||
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)
|
||||
---------------------------------------
|
||||
|
||||
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)
|
||||
-----------------------------------------------------------
|
||||
|
||||
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)
|
||||
-----------------------------------------------------
|
||||
|
||||
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.
|
Loading…
Reference in New Issue
Block a user