PCI: Hide remove and rescan sysfs interfaces for SR-IOV virtual functions
authorJiang Liu <liuj97@gmail.com>
Fri, 31 May 2013 04:21:31 +0000 (12:21 +0800)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 5 Jun 2013 18:18:50 +0000 (12:18 -0600)
PCI devices for SR-IOV virtual functions should only be created/
destroyed by pci_enable_sriov()/pci_disable_sriov() because special
data structures are associated with SR-IOV virtual functions.
So hide hotplug related sysfs interfaces "remove" and "rescan" for
SR-IOV virtual functions, otherwise it may cause memory leakage
and other issues.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Donald Dutile <ddutile@redhat.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Ram Pai <linuxram@us.ibm.com>
drivers/pci/pci-sysfs.c

index 5b4a9d9cd200dd5a6ee32c3d343bbae0cf2ff8ac..403da60cd983eb3f74634c388e33839357748bf1 100644 (file)
@@ -325,6 +325,8 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr,
        }
        return count;
 }
+struct device_attribute dev_rescan_attr = __ATTR(rescan, (S_IWUSR|S_IWGRP),
+                                                NULL, dev_rescan_store);
 
 static void remove_callback(struct device *dev)
 {
@@ -354,6 +356,8 @@ remove_store(struct device *dev, struct device_attribute *dummy,
                count = ret;
        return count;
 }
+struct device_attribute dev_remove_attr = __ATTR(remove, (S_IWUSR|S_IWGRP),
+                                                NULL, remove_store);
 
 static ssize_t
 dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
@@ -504,8 +508,6 @@ struct device_attribute pci_dev_attrs[] = {
        __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
                broken_parity_status_show,broken_parity_status_store),
        __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
-       __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
-       __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store),
 #if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI)
        __ATTR(d3cold_allowed, 0644, d3cold_allowed_show, d3cold_allowed_store),
 #endif
@@ -1463,6 +1465,29 @@ static umode_t pci_dev_attrs_are_visible(struct kobject *kobj,
        return a->mode;
 }
 
+static struct attribute *pci_dev_hp_attrs[] = {
+       &dev_remove_attr.attr,
+       &dev_rescan_attr.attr,
+       NULL,
+};
+
+static umode_t pci_dev_hp_attrs_are_visible(struct kobject *kobj,
+                                               struct attribute *a, int n)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct pci_dev *pdev = to_pci_dev(dev);
+
+       if (pdev->is_virtfn)
+               return 0;
+
+       return a->mode;
+}
+
+static struct attribute_group pci_dev_hp_attr_group = {
+       .attrs = pci_dev_hp_attrs,
+       .is_visible = pci_dev_hp_attrs_are_visible,
+};
+
 #ifdef CONFIG_PCI_IOV
 static struct attribute *sriov_dev_attrs[] = {
        &sriov_totalvfs_attr.attr,
@@ -1494,6 +1519,7 @@ static struct attribute_group pci_dev_attr_group = {
 
 static const struct attribute_group *pci_dev_attr_groups[] = {
        &pci_dev_attr_group,
+       &pci_dev_hp_attr_group,
 #ifdef CONFIG_PCI_IOV
        &sriov_dev_attr_group,
 #endif