[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2/5] pciback: per-device permissive flag



This patch includes the per-device permissive flag as described by its
original author, Ryan:

"The permissive flag was added to the PCI Backend to disable the PCI
Backend's "read-only by default" stance to allow devices in driver
domains to write to registers within a device's configuration space.
This flag was global for all devices controlled by the PCI Backend in
all domains. This patch removes the global flag and instead adds a
per-device flag. Permissive mode for a particular device can be enabled
by writing the device's slot number to a sysfs attribute
(/sys/bus/pci/drivers/pciback/permissive). That sysfs node can also be
read to list all devices for which permissive mode is enabled. However,
once enabled, this patch provides no interface to turn permissive mode
off for a device. Please unbind the device from the backend and re-bind
it if you need that capability for now."

NB: This patch provides a feature that is independent of preceding
patch, however because the two affect the same areas it is important to
either apply patch 1/5 first (if you want both patches) OR manually
extract and apply the changes from this patch (if you want just the
per-device patch).

Signed-off-by: Chris Bookholt <hap10@xxxxxxxxxxxxxx>
diff -r 46eb52cd64e3 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c     Thu Jul 13 
13:32:11 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c     Thu Jul 13 
13:35:51 2006 -0400
@@ -14,9 +14,6 @@
 #include "pciback.h"
 #include "conf_space.h"
 #include "conf_space_quirks.h"
-
-static int permissive = 0;
-module_param(permissive, bool, 0644);
 
 #define DEFINE_PCI_CONFIG(op,size,type)                        \
 int pciback_##op##_config_##size                               \
@@ -258,7 +255,7 @@ int pciback_config_write(struct pci_dev 
                 * This means that some fields may still be read-only because
                 * they have entries in the config_field list that intercept
                 * the write and do nothing. */
-               if (permissive) {
+               if (dev_data->permissive) {
                        switch (size) {
                        case 1:
                                err = pci_write_config_byte(dev, offset,
diff -r 46eb52cd64e3 linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c       Thu Jul 13 
13:32:11 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c       Thu Jul 13 
13:35:51 2006 -0400
@@ -739,6 +739,72 @@ static ssize_t pcistub_quirk_show(struct
 
 DRIVER_ATTR(quirks, S_IRUSR | S_IWUSR, pcistub_quirk_show, pcistub_quirk_add);
 
+static ssize_t permissive_add(struct device_driver *drv, const char *buf,
+                             size_t count)
+{
+       int domain, bus, slot, func;
+       int err;
+       struct pcistub_device *psdev;
+       struct pciback_dev_data *dev_data;
+       err = str_to_slot(buf, &domain, &bus, &slot, &func);
+       if (err)
+               goto out;
+       psdev = pcistub_device_find(domain, bus, slot, func);
+       if (!psdev) {
+               err = -ENODEV;
+               goto out;
+       }
+       if (!psdev->dev) {
+               err = -ENODEV;
+               goto release;
+       }
+       dev_data = pci_get_drvdata(psdev->dev);
+       /* the driver data for a device should never be null at this point */
+       if (!dev_data) {
+               err = -ENXIO;
+               goto release;
+       }
+       if (!dev_data->permissive) {
+               dev_data->permissive = 1;
+               /* Let user know that what they're doing could be unsafe */
+               dev_warn(&psdev->dev->dev,
+                        "enabling permissive mode configuration space 
accesses!\n");
+               dev_warn(&psdev->dev->dev,
+                        "permissive mode is potentially unsafe!\n");
+       }
+      release:
+       pcistub_device_put(psdev);
+      out:
+       if (!err)
+               err = count;
+       return err;
+}
+
+static ssize_t permissive_show(struct device_driver *drv, char *buf)
+{
+       struct pcistub_device *psdev;
+       struct pciback_dev_data *dev_data;
+       size_t count = 0;
+       unsigned long flags;
+       spin_lock_irqsave(&pcistub_devices_lock, flags);
+       list_for_each_entry(psdev, &pcistub_devices, dev_list) {
+               if (count >= PAGE_SIZE)
+                       break;
+               if (!psdev->dev)
+                       continue;
+               dev_data = pci_get_drvdata(psdev->dev);
+               if (!dev_data || !dev_data->permissive)
+                       continue;
+               count +=
+                   scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
+                             pci_name(psdev->dev));
+       }
+       spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+       return count;
+}
+
+DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
+
 static int __init pcistub_init(void)
 {
        int pos = 0;
@@ -784,6 +850,7 @@ static int __init pcistub_init(void)
                           &driver_attr_remove_slot);
        driver_create_file(&pciback_pci_driver.driver, &driver_attr_slots);
        driver_create_file(&pciback_pci_driver.driver, &driver_attr_quirks);
+       driver_create_file(&pciback_pci_driver.driver, &driver_attr_permissive);
 
       out:
        return err;
@@ -834,6 +901,7 @@ static void __exit pciback_cleanup(void)
                           &driver_attr_remove_slot);
        driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
        driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
+       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
 
        pci_unregister_driver(&pciback_pci_driver);
 }
diff -r 46eb52cd64e3 linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h        Thu Jul 13 
13:32:11 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h        Thu Jul 13 
13:35:51 2006 -0400
@@ -44,6 +44,7 @@ struct pciback_device {
 
 struct pciback_dev_data {
        struct list_head config_fields;
+       int permissive;
        int warned_on_write;
 };
 
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.