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

[Xen-devel] [PATCH 1/3] linux-2.6.18/pciback: support wild cards in slot specifications


  • To: "xen-devel" <xen-devel@xxxxxxxxxxxxx>
  • From: "Jan Beulich" <JBeulich@xxxxxxxx>
  • Date: Mon, 24 Sep 2012 16:54:06 +0100
  • Delivery-date: Mon, 24 Sep 2012 15:54:25 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>

Particularly for hiding sets of SR-IOV devices, specifying them all
individually is rather cumbersome. Therefore, allow function and slot
numbers to be replaced by a wildcard character ('*').

Unfortunately this gets complicated by the in-kernel sscanf()
implementation not being really standard conformant - matching of
plain text tails cannot be checked by the caller (a patch to overcome
this will be sent shortly, and a follow-up patch for simplifying the
code is planned to be sent when that fixed went upstream).

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/drivers/xen/pciback/pci_stub.c
+++ b/drivers/xen/pciback/pci_stub.c
@@ -861,17 +861,41 @@ static inline int str_to_slot(const char
                              int *slot, int *func)
 {
        int err;
+       char wc = '*';
 
        err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func);
-       if (err == 4)
+       switch (err) {
+       case 3:
+               *func = -1;
+               err = sscanf(buf, " %x:%x:%x.%c", domain, bus, slot, &wc);
+               break;
+       case 2:
+               *slot = *func = -1;
+               err = sscanf(buf, " %x:%x:*.%c", domain, bus, &wc);
+               if (err >= 2)
+                       ++err;
+               break;
+       }
+       if (err == 4 && wc == '*')
                return 0;
        else if (err < 0)
                return -EINVAL;
 
        /* try again without domain */
        *domain = 0;
+       wc = '*';
        err = sscanf(buf, " %x:%x.%x", bus, slot, func);
-       if (err == 3)
+       switch (err) {
+       case 2:
+               *func = -1;
+               err = sscanf(buf, " %x:%x.%c", bus, slot, &wc);
+               break;
+       case 1:
+               *slot = *func = -1;
+               err = sscanf(buf, " %x:*.%c", bus, &wc) + 1;
+               break;
+       }
+       if (err == 3 && wc == '*')
                return 0;
 
        return -EINVAL;
@@ -894,6 +918,19 @@ static int pcistub_device_id_add(int dom
 {
        struct pcistub_device_id *pci_dev_id;
        unsigned long flags;
+       int rc = 0;
+
+       if (slot < 0) {
+               for (slot = 0; !rc && slot < 32; ++slot)
+                       rc = pcistub_device_id_add(domain, bus, slot, func);
+               return rc;
+       }
+
+       if (func < 0) {
+               for (func = 0; !rc && func < 8; ++func)
+                       rc = pcistub_device_id_add(domain, bus, slot, func);
+               return rc;
+       }
 
        pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
        if (!pci_dev_id)
@@ -916,15 +953,15 @@ static int pcistub_device_id_add(int dom
 static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
 {
        struct pcistub_device_id *pci_dev_id, *t;
-       int devfn = PCI_DEVFN(slot, func);
        int err = -ENOENT;
        unsigned long flags;
 
        spin_lock_irqsave(&device_ids_lock, flags);
        list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids, slot_list) 
{
 
-               if (pci_dev_id->domain == domain
-                   && pci_dev_id->bus == bus && pci_dev_id->devfn == devfn) {
+               if (pci_dev_id->domain == domain && pci_dev_id->bus == bus
+                   && (slot < 0 || PCI_SLOT(pci_dev_id->devfn) == slot)
+                   && (func < 0 || PCI_FUNC(pci_dev_id->devfn) == func)) {
                        /* Don't break; here because it's possible the same
                         * slot could be in the list more than once
                         */
@@ -1117,6 +1154,10 @@ static ssize_t permissive_add(struct dev
        err = str_to_slot(buf, &domain, &bus, &slot, &func);
        if (err)
                goto out;
+       if (slot < 0 || func < 0) {
+               err = -EINVAL;
+               goto out;
+       }
        psdev = pcistub_device_find(domain, bus, slot, func);
        if (!psdev) {
                err = -ENODEV;
@@ -1211,17 +1252,51 @@ static int __init pcistub_init(void)
 
        if (pci_devs_to_hide && *pci_devs_to_hide) {
                do {
+                       char wc = '*';
+
                        parsed = 0;
 
                        err = sscanf(pci_devs_to_hide + pos,
                                     " (%x:%x:%x.%x) %n",
                                     &domain, &bus, &slot, &func, &parsed);
-                       if (err != 4) {
+                       switch (err) {
+                       case 3:
+                               func = -1;
+                               err = sscanf(pci_devs_to_hide + pos,
+                                            " (%x:%x:%x.%c) %n",
+                                            &domain, &bus, &slot, &wc,
+                                            &parsed);
+                               break;
+                       case 2:
+                               slot = func = -1;
+                               err = sscanf(pci_devs_to_hide + pos,
+                                            " (%x:%x:*.%c) %n",
+                                            &domain, &bus, &wc, &parsed) + 1;
+                               break;
+                       }
+
+                       if (err != 4 || wc != '*') {
                                domain = 0;
+                               wc = '*';
                                err = sscanf(pci_devs_to_hide + pos,
                                             " (%x:%x.%x) %n",
                                             &bus, &slot, &func, &parsed);
-                               if (err != 3)
+                               switch (err) {
+                               case 2:
+                                       func = -1;
+                                       err = sscanf(pci_devs_to_hide + pos,
+                                                    " (%x:%x.%c) %n",
+                                                    &bus, &slot, &wc,
+                                                    &parsed);
+                                       break;
+                               case 1:
+                                       slot = func = -1;
+                                       err = sscanf(pci_devs_to_hide + pos,
+                                                    " (%x:*.%c) %n",
+                                                    &bus, &wc, &parsed) + 1;
+                                       break;
+                               }
+                               if (err != 3 || wc != '*')
                                        goto parse_error;
                        }
 


Attachment: xen-pciback-wildcard.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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