]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
driver: Factor out PCI related services
authorJan Kiszka <jan.kiszka@siemens.com>
Mon, 9 Mar 2015 08:09:11 +0000 (09:09 +0100)
committerJan Kiszka <jan.kiszka@siemens.com>
Fri, 20 Mar 2015 06:10:39 +0000 (07:10 +0100)
This moves all PCI-related functions in a separate module. Consequently,
the module is only built if PCI is enabled. Encapsulation also
simplifies to include PCI-related fields of struct cell only when used.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
driver/Makefile
driver/cell.h
driver/main.c
driver/pci.c [new file with mode: 0644]
driver/pci.h [new file with mode: 0644]

index 1a94928d7d258164ae4af1c64a97bf8b56cd4f52..d33112d623d743d40e42087066a150e387941723 100644 (file)
@@ -17,5 +17,6 @@ ccflags-y := -I$(src)/../hypervisor/arch/$(SRCARCH)/include \
             -I$(src)/../hypervisor/include
 
 jailhouse-y := main.o
+jailhouse-$(CONFIG_PCI) += pci.o
 
 $(obj)/main.o: $(obj)/../hypervisor/include/generated/version.h
index 0d780895a9e19f97fe2806fbd81225f848829089..db78d125f8227ddf9f6bff0783ffb239518a273f 100644 (file)
@@ -25,9 +25,11 @@ struct cell {
        unsigned int id;
        cpumask_t cpus_assigned;
        u32 num_memory_regions;
-       u32 num_pci_devices;
        struct jailhouse_memory *memory_regions;
+#ifdef CONFIG_PCI
+       u32 num_pci_devices;
        struct jailhouse_pci_device *pci_devices;
+#endif /* CONFIG_PCI */
 };
 
 #endif /* !_JAILHOUSE_DRIVER_CELL_H */
index 8b377d1b32c35c13f4c742f543876ab48892b3c6..12cf2eba3e0b03ca70aad7945703e6e8cd26b79e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Jailhouse, a Linux-based partitioning hypervisor
  *
- * Copyright (c) Siemens AG, 2013, 2014
+ * Copyright (c) Siemens AG, 2013-2015
  * Copyright (c) Valentine Sinitsyn, 2014
  *
  * Authors:
 #include <linux/reboot.h>
 #include <linux/vmalloc.h>
 #include <linux/io.h>
-#include <linux/pci.h>
 #include <asm/smp.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
 #include "cell.h"
 #include "jailhouse.h"
+#include "pci.h"
 
 #include <jailhouse/header.h>
 #include <jailhouse/hypercall.h>
@@ -129,59 +129,6 @@ static void init_hypercall(void)
 }
 #endif
 
-enum { JAILHOUSE_PCI_ACTION_ADD, JAILHOUSE_PCI_ACTION_DEL };
-
-#ifdef CONFIG_PCI
-static void jailhouse_pci_add_device(const struct jailhouse_pci_device *dev)
-{
-       int num;
-       struct pci_bus *bus;
-
-       bus = pci_find_bus(dev->domain, PCI_BUS_NUM(dev->bdf));
-       if (bus) {
-               num = pci_scan_slot(bus, dev->bdf & 0xff);
-               if (num) {
-                       pci_lock_rescan_remove();
-                       pci_bus_assign_resources(bus);
-                       pci_bus_add_devices(bus);
-                       pci_unlock_rescan_remove();
-               }
-       }
-}
-
-static void jailhouse_pci_remove_device(const struct jailhouse_pci_device *dev)
-{
-       struct pci_dev *l_dev;
-
-       l_dev = pci_get_bus_and_slot(PCI_BUS_NUM(dev->bdf), dev->bdf & 0xff);
-       if (l_dev)
-               pci_stop_and_remove_bus_device_locked(l_dev);
-}
-
-static void jailhouse_pci_do_all_devices(struct cell *cell, unsigned int type,
-                                        unsigned int action)
-{
-       unsigned int n;
-       const struct jailhouse_pci_device *dev;
-
-       dev = cell->pci_devices;
-       for (n = cell->num_pci_devices; n > 0; n--) {
-               if (dev->type == type) {
-                       if (action == JAILHOUSE_PCI_ACTION_ADD)
-                               jailhouse_pci_add_device(dev);
-                       else if (action == JAILHOUSE_PCI_ACTION_DEL)
-                               jailhouse_pci_remove_device(dev);
-               }
-               dev++;
-       }
-}
-#else /* CONFIG_PCI */
-static void jailhouse_pci_do_all_devices(struct cell *cell, unsigned int type,
-                                        unsigned int action)
-{
-}
-#endif /* CONFIG_PCI */
-
 struct jailhouse_cpu_stats_attr {
        struct kobj_attribute kattr;
        unsigned int code;
@@ -349,8 +296,8 @@ static void cell_kobj_release(struct kobject *kobj)
 {
        struct cell *cell = container_of(kobj, struct cell, kobj);
 
+       jailhouse_pci_cell_cleanup(cell);
        vfree(cell->memory_regions);
-       vfree(cell->pci_devices);
        kfree(cell);
 }
 
@@ -385,26 +332,14 @@ static struct cell *create_cell(const struct jailhouse_cell_desc *cell_desc)
 
        memcpy(cell->memory_regions, jailhouse_cell_mem_regions(cell_desc),
               sizeof(struct jailhouse_memory) * cell->num_memory_regions);
-#ifdef CONFIG_PCI
-       cell->num_pci_devices = cell_desc->num_pci_devices;
-       cell->pci_devices = NULL;
-
-       if (cell->num_pci_devices > 0) {
-               cell->pci_devices =
-                       vmalloc(sizeof(struct jailhouse_pci_device) *
-                               cell->num_pci_devices);
-               if (!cell->pci_devices) {
-                       vfree(cell->memory_regions);
-                       kfree(cell);
-                       return ERR_PTR(-ENOMEM);
-               }
 
-               memcpy(cell->pci_devices,
-                      jailhouse_cell_pci_devices(cell_desc),
-                      sizeof(struct jailhouse_pci_device) *
-                      cell->num_pci_devices);
+       err = jailhouse_pci_cell_setup(cell, cell_desc);
+       if (err) {
+               vfree(cell->memory_regions);
+               kfree(cell);
+               return ERR_PTR(err);
        }
-#endif
+
        err = kobject_init_and_add(&cell->kobj, &cell_type, cells_dir, "%s",
                                   cell_desc->name);
        if (err) {
diff --git a/driver/pci.c b/driver/pci.c
new file mode 100644 (file)
index 0000000..24ac2c0
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2014-2015
+ *
+ * Authors:
+ *  Jan Kiszka <jan.kiszka@siemens.com>
+ *  Henning Schild <henning.schild@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <linux/pci.h>
+
+#include "pci.h"
+
+static void jailhouse_pci_add_device(const struct jailhouse_pci_device *dev)
+{
+       int num;
+       struct pci_bus *bus;
+
+       bus = pci_find_bus(dev->domain, PCI_BUS_NUM(dev->bdf));
+       if (bus) {
+               num = pci_scan_slot(bus, dev->bdf & 0xff);
+               if (num) {
+                       pci_lock_rescan_remove();
+                       pci_bus_assign_resources(bus);
+                       pci_bus_add_devices(bus);
+                       pci_unlock_rescan_remove();
+               }
+       }
+}
+
+static void jailhouse_pci_remove_device(const struct jailhouse_pci_device *dev)
+{
+       struct pci_dev *l_dev;
+
+       l_dev = pci_get_bus_and_slot(PCI_BUS_NUM(dev->bdf), dev->bdf & 0xff);
+       if (l_dev)
+               pci_stop_and_remove_bus_device_locked(l_dev);
+}
+
+void jailhouse_pci_do_all_devices(struct cell *cell, unsigned int type,
+                                 unsigned int action)
+{
+       unsigned int n;
+       const struct jailhouse_pci_device *dev;
+
+       dev = cell->pci_devices;
+       for (n = cell->num_pci_devices; n > 0; n--) {
+               if (dev->type == type) {
+                       if (action == JAILHOUSE_PCI_ACTION_ADD)
+                               jailhouse_pci_add_device(dev);
+                       else if (action == JAILHOUSE_PCI_ACTION_DEL)
+                               jailhouse_pci_remove_device(dev);
+               }
+               dev++;
+       }
+}
+
+int jailhouse_pci_cell_setup(struct cell *cell,
+                            const struct jailhouse_cell_desc *cell_desc)
+{
+       if (cell_desc->num_pci_devices == 0)
+               /* cell is zero-initialized, no need to set pci fields */
+               return 0;
+
+       cell->num_pci_devices = cell_desc->num_pci_devices;
+       cell->pci_devices = vmalloc(sizeof(struct jailhouse_pci_device) *
+                                   cell->num_pci_devices);
+       if (!cell->pci_devices)
+               return -ENOMEM;
+
+       memcpy(cell->pci_devices,
+              jailhouse_cell_pci_devices(cell_desc),
+              sizeof(struct jailhouse_pci_device) * cell->num_pci_devices);
+
+       return 0;
+}
+
+void jailhouse_pci_cell_cleanup(struct cell *cell)
+{
+       vfree(cell->pci_devices);
+}
diff --git a/driver/pci.h b/driver/pci.h
new file mode 100644 (file)
index 0000000..c98eddc
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2014-2015
+ *
+ * Authors:
+ *  Jan Kiszka <jan.kiszka@siemens.com>
+ *  Henning Schild <henning.schild@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "cell.h"
+
+enum { JAILHOUSE_PCI_ACTION_ADD, JAILHOUSE_PCI_ACTION_DEL };
+
+#ifdef CONFIG_PCI
+
+void jailhouse_pci_do_all_devices(struct cell *cell, unsigned int type,
+                                 unsigned int action);
+int jailhouse_pci_cell_setup(struct cell *cell,
+                            const struct jailhouse_cell_desc *cell_desc);
+void jailhouse_pci_cell_cleanup(struct cell *cell);
+
+#else /* !CONFIG_PCI */
+
+static inline void
+jailhouse_pci_do_all_devices(struct cell *cell, unsigned int type,
+                            unsigned int action)
+{
+}
+
+static inline int
+jailhouse_pci_cell_setup(struct cell *cell,
+                        const struct jailhouse_cell_desc *cell_desc)
+{
+       return 0;
+}
+
+static inline void jailhouse_pci_cell_cleanup(struct cell *cell)
+{
+}
+
+#endif /* !CONFIG_PCI */