Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 
0003 ======================
0004 VFIO AP Locks Overview
0005 ======================
0006 This document describes the locks that are pertinent to the secure operation
0007 of the vfio_ap device driver. Throughout this document, the following variables
0008 will be used to denote instances of the structures herein described:
0009 
0010 .. code-block:: c
0011 
0012   struct ap_matrix_dev *matrix_dev;
0013   struct ap_matrix_mdev *matrix_mdev;
0014   struct kvm *kvm;
0015 
0016 The Matrix Devices Lock (drivers/s390/crypto/vfio_ap_private.h)
0017 ---------------------------------------------------------------
0018 
0019 .. code-block:: c
0020 
0021   struct ap_matrix_dev {
0022         ...
0023         struct list_head mdev_list;
0024         struct mutex mdevs_lock;
0025         ...
0026   }
0027 
0028 The Matrix Devices Lock (matrix_dev->mdevs_lock) is implemented as a global
0029 mutex contained within the single object of struct ap_matrix_dev. This lock
0030 controls access to all fields contained within each matrix_mdev
0031 (matrix_dev->mdev_list). This lock must be held while reading from, writing to
0032 or using the data from a field contained within a matrix_mdev instance
0033 representing one of the vfio_ap device driver's mediated devices.
0034 
0035 The KVM Lock (include/linux/kvm_host.h)
0036 ---------------------------------------
0037 
0038 .. code-block:: c
0039 
0040   struct kvm {
0041         ...
0042         struct mutex lock;
0043         ...
0044   }
0045 
0046 The KVM Lock (kvm->lock) controls access to the state data for a KVM guest. This
0047 lock must be held by the vfio_ap device driver while one or more AP adapters,
0048 domains or control domains are being plugged into or unplugged from the guest.
0049 
0050 The KVM pointer is stored in the in the matrix_mdev instance
0051 (matrix_mdev->kvm = kvm) containing the state of the mediated device that has
0052 been attached to the KVM guest.
0053 
0054 The Guests Lock (drivers/s390/crypto/vfio_ap_private.h)
0055 -----------------------------------------------------------
0056 
0057 .. code-block:: c
0058 
0059   struct ap_matrix_dev {
0060         ...
0061         struct list_head mdev_list;
0062         struct mutex guests_lock;
0063         ...
0064   }
0065 
0066 The Guests Lock (matrix_dev->guests_lock) controls access to the
0067 matrix_mdev instances (matrix_dev->mdev_list) that represent mediated devices
0068 that hold the state for the mediated devices that have been attached to a
0069 KVM guest. This lock must be held:
0070 
0071 1. To control access to the KVM pointer (matrix_mdev->kvm) while the vfio_ap
0072    device driver is using it to plug/unplug AP devices passed through to the KVM
0073    guest.
0074 
0075 2. To add matrix_mdev instances to or remove them from matrix_dev->mdev_list.
0076    This is necessary to ensure the proper locking order when the list is perused
0077    to find an ap_matrix_mdev instance for the purpose of plugging/unplugging
0078    AP devices passed through to a KVM guest.
0079 
0080    For example, when a queue device is removed from the vfio_ap device driver,
0081    if the adapter is passed through to a KVM guest, it will have to be
0082    unplugged. In order to figure out whether the adapter is passed through,
0083    the matrix_mdev object to which the queue is assigned will have to be
0084    found. The KVM pointer (matrix_mdev->kvm) can then be used to determine if
0085    the mediated device is passed through (matrix_mdev->kvm != NULL) and if so,
0086    to unplug the adapter.
0087 
0088 It is not necessary to take the Guests Lock to access the KVM pointer if the
0089 pointer is not used to plug/unplug devices passed through to the KVM guest;
0090 however, in this case, the Matrix Devices Lock (matrix_dev->mdevs_lock) must be
0091 held in order to access the KVM pointer since it is set and cleared under the
0092 protection of the Matrix Devices Lock. A case in point is the function that
0093 handles interception of the PQAP(AQIC) instruction sub-function. This handler
0094 needs to access the KVM pointer only for the purposes of setting or clearing IRQ
0095 resources, so only the matrix_dev->mdevs_lock needs to be held.
0096 
0097 The PQAP Hook Lock (arch/s390/include/asm/kvm_host.h)
0098 -----------------------------------------------------
0099 
0100 .. code-block:: c
0101 
0102   typedef int (*crypto_hook)(struct kvm_vcpu *vcpu);
0103 
0104   struct kvm_s390_crypto {
0105         ...
0106         struct rw_semaphore pqap_hook_rwsem;
0107         crypto_hook *pqap_hook;
0108         ...
0109   };
0110 
0111 The PQAP Hook Lock is a r/w semaphore that controls access to the function
0112 pointer of the handler ``(*kvm->arch.crypto.pqap_hook)`` to invoke when the
0113 PQAP(AQIC) instruction sub-function is intercepted by the host. The lock must be
0114 held in write mode when pqap_hook value is set, and in read mode when the
0115 pqap_hook function is called.