[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |