VFIO AP 锁概述

本文档描述了与 vfio_ap 设备驱动程序的安全操作相关的锁。在本文档中,将使用以下变量来表示此处描述的结构的实例

struct ap_matrix_dev *matrix_dev;
struct ap_matrix_mdev *matrix_mdev;
struct kvm *kvm;

矩阵设备锁(drivers/s390/crypto/vfio_ap_private.h)

struct ap_matrix_dev {
      ...
      struct list_head mdev_list;
      struct mutex mdevs_lock;
      ...
}

矩阵设备锁 (matrix_dev->mdevs_lock) 被实现为包含在结构 ap_matrix_dev 的单个对象中的全局互斥锁。此锁控制对每个 matrix_mdev (matrix_dev->mdev_list) 中包含的所有字段的访问。从表示 vfio_ap 设备驱动程序的调解设备的 matrix_mdev 实例中读取、写入或使用数据时,必须持有此锁。

KVM 锁 (include/linux/kvm_host.h)

struct kvm {
      ...
      struct mutex lock;
      ...
}

KVM 锁 (kvm->lock) 控制对 KVM 客户机的状态数据的访问。当一个或多个 AP 适配器、域或控制域被插入或从客户机拔出时,vfio_ap 设备驱动程序必须持有此锁。

KVM 指针存储在 matrix_mdev 实例 (matrix_mdev->kvm = kvm) 中,该实例包含已附加到 KVM 客户机的调解设备的状态。

客户机锁 (drivers/s390/crypto/vfio_ap_private.h)

struct ap_matrix_dev {
      ...
      struct list_head mdev_list;
      struct mutex guests_lock;
      ...
}

客户机锁 (matrix_dev->guests_lock) 控制对 matrix_mdev 实例 (matrix_dev->mdev_list) 的访问,这些实例表示保存已附加到 KVM 客户机的调解设备的状态的调解设备。必须持有此锁

  1. 为了在 vfio_ap 设备驱动程序使用它将传递到 KVM 客户机的 AP 设备插入/拔出时控制对 KVM 指针 (matrix_mdev->kvm) 的访问。

  2. 要将 matrix_mdev 实例添加到 matrix_dev->mdev_list 或从中删除它们。当浏览列表以查找 ap_matrix_mdev 实例以用于插入/拔出传递到 KVM 客户机的 AP 设备时,这对于确保正确的锁定顺序是必要的。

    例如,当从 vfio_ap 设备驱动程序中删除队列设备时,如果适配器已传递到 KVM 客户机,则必须将其拔出。为了弄清楚是否传递了适配器,必须找到队列分配到的 matrix_mdev 对象。然后可以使用 KVM 指针 (matrix_mdev->kvm) 来确定是否传递了调解设备 (matrix_mdev->kvm != NULL),如果已传递,则拔出适配器。

如果 KVM 指针不用于插入/拔出传递到 KVM 客户机的设备,则无需获取客户机锁来访问 KVM 指针;但是,在这种情况下,必须持有矩阵设备锁 (matrix_dev->mdevs_lock) 才能访问 KVM 指针,因为它是在矩阵设备锁的保护下设置和清除的。一个典型的例子是处理 PQAP(AQIC) 指令子函数拦截的函数。此处理程序仅需要访问 KVM 指针来设置或清除 IRQ 资源,因此只需要持有 matrix_dev->mdevs_lock。

PQAP 钩子锁 (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;
      ...
};

PQAP 钩子锁是一个 r/w 信号量,用于控制对处理程序的函数指针 (*kvm->arch.crypto.pqap_hook) 的访问,当主机拦截 PQAP(AQIC) 指令子函数时调用该函数。当设置 pqap_hook 值时,必须在写入模式下持有该锁,当调用 pqap_hook 函数时,必须在读取模式下持有该锁。