提交 ce494a96 编写于 作者: K Kunkun Jiang

vfio-pci: Match specific devices with vendor id and device id

virt inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7QPGW
CVE: NA

------------------------------------------------------------------

In probe_vendor_drivers, all registered vendor drivers are traversed.
This is not a good idea. If a vendor driver is not implemented well
enough, it may cause the system to panic. Use the vendor id and
device id to select a proper driver.

In the pervious device registration logic, since the live migration
operation ops of the three accelerator devices is the same.
Therefore, only one driver entity will be registered. As a result,
only the first sec will be loaded successfully, while hpre and zip
cannot be loaded.

The acc live migration driver needs to be adapted.

Tips: This bugfix is consistent with the one for the olk-5.10 branch.
Signed-off-by: NLongfang Liu <liulongfang@huawei.com>
Signed-off-by: NKunkun Jiang <jiangkunkun@huawei.com>
上级 0baa9b01
......@@ -1739,6 +1739,8 @@ static void acc_vf_remove(void *vendor_data)
static struct vfio_pci_vendor_driver_ops sec_vf_mig_ops = {
.owner = THIS_MODULE,
.name = "hisi_sec2",
.vendor = PCI_VENDOR_ID_HUAWEI,
.device = PCI_DEVICE_ID_HUAWEI_SEC_VF,
.probe = acc_vf_probe,
.remove = acc_vf_remove,
.device_ops = &acc_vf_device_ops_node,
......@@ -1747,6 +1749,8 @@ static struct vfio_pci_vendor_driver_ops sec_vf_mig_ops = {
static struct vfio_pci_vendor_driver_ops hpre_vf_mig_ops = {
.owner = THIS_MODULE,
.name = "hisi_hpre",
.vendor = PCI_VENDOR_ID_HUAWEI,
.device = PCI_DEVICE_ID_HUAWEI_HPRE_VF,
.probe = acc_vf_probe,
.remove = acc_vf_remove,
.device_ops = &acc_vf_device_ops_node,
......@@ -1755,6 +1759,8 @@ static struct vfio_pci_vendor_driver_ops hpre_vf_mig_ops = {
static struct vfio_pci_vendor_driver_ops zip_vf_mig_ops = {
.owner = THIS_MODULE,
.name = "hisi_zip",
.vendor = PCI_VENDOR_ID_HUAWEI,
.device = PCI_DEVICE_ID_HUAWEI_ZIP_VF,
.probe = acc_vf_probe,
.remove = acc_vf_remove,
.device_ops = &acc_vf_device_ops_node,
......@@ -1773,7 +1779,9 @@ static int __init acc_vf_module_init(void)
static void __exit acc_vf_module_exit(void)
{
vfio_pci_unregister_vendor_driver(&acc_vf_device_ops_node);
vfio_pci_unregister_vendor_driver(&sec_vf_mig_ops);
vfio_pci_unregister_vendor_driver(&hpre_vf_mig_ops);
vfio_pci_unregister_vendor_driver(&zip_vf_mig_ops);
};
module_init(acc_vf_module_init);
module_exit(acc_vf_module_exit);
......
......@@ -2077,6 +2077,10 @@ static int probe_vendor_drivers(struct vfio_pci_device *vdev)
list_for_each_entry(driver, &vfio_pci.vendor_drivers_list, next) {
void *data;
if (vdev->pdev->vendor != driver->ops->vendor ||
vdev->pdev->device != driver->ops->device)
continue;
if (!try_module_get(driver->ops->owner))
continue;
......@@ -2604,7 +2608,8 @@ int __vfio_pci_register_vendor_driver(struct vfio_pci_vendor_driver_ops *ops)
/* Check for duplicates */
list_for_each_entry(tmp, &vfio_pci.vendor_drivers_list, next) {
if (tmp->ops->device_ops == ops->device_ops) {
if (tmp->ops->vendor == ops->vendor &&
tmp->ops->vendor == ops->device) {
mutex_unlock(&vfio_pci.vendor_drivers_lock);
kfree(driver);
return -EINVAL;
......@@ -2622,14 +2627,15 @@ int __vfio_pci_register_vendor_driver(struct vfio_pci_vendor_driver_ops *ops)
}
EXPORT_SYMBOL_GPL(__vfio_pci_register_vendor_driver);
void vfio_pci_unregister_vendor_driver(struct vfio_device_ops *device_ops)
void vfio_pci_unregister_vendor_driver(struct vfio_pci_vendor_driver_ops *ops)
{
struct vfio_pci_vendor_driver *driver, *tmp;
mutex_lock(&vfio_pci.vendor_drivers_lock);
list_for_each_entry_safe(driver, tmp,
&vfio_pci.vendor_drivers_list, next) {
if (driver->ops->device_ops == device_ops) {
if (driver->ops->vendor == ops->vendor &&
driver->ops->device == ops->device) {
list_del(&driver->next);
mutex_unlock(&vfio_pci.vendor_drivers_lock);
kfree(driver);
......
......@@ -253,12 +253,15 @@ extern int vfio_pci_set_vendor_regions(void *device_data,
struct vfio_pci_vendor_driver_ops {
char *name;
struct module *owner;
/* Used to match device */
unsigned short vendor;
unsigned short device;
void *(*probe)(struct pci_dev *pdev);
void (*remove)(void *vendor_data);
struct vfio_device_ops *device_ops;
};
int __vfio_pci_register_vendor_driver(struct vfio_pci_vendor_driver_ops *ops);
void vfio_pci_unregister_vendor_driver(struct vfio_device_ops *device_ops);
void vfio_pci_unregister_vendor_driver(struct vfio_pci_vendor_driver_ops *ops);
#define vfio_pci_register_vendor_driver(__name, __probe, __remove, \
__device_ops) \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册