123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- .. 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.
|