diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 0b6989f92041b4a2be7cc7f422368aa2925d29c9..9b700b4a987a1457b127a224bfdca6e47b17499d 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -109,34 +109,22 @@ config XEN_PCIDEV_BACKEND
 	tristate "Xen PCI-device backend driver"
 	depends on PCI && X86 && XEN
 	depends on XEN_BACKEND
+	default m
 	help
 	  The PCI device backend driver allows the kernel to export arbitrary
 	  PCI devices to other guests. If you select this to be a module, you
 	  will need to make sure no other driver has bound to the device(s)
 	  you want to make visible to other guests.
 
-choice
-	prompt "PCI Backend Mode"
-	depends on XEN_PCIDEV_BACKEND
-
-config XEN_PCIDEV_BACKEND_VPCI
-	bool "Virtual PCI"
-	help
-	  This PCI Backend hides the true PCI topology and makes the frontend
-	  think there is a single PCI bus with only the exported devices on it.
-	  For example, a device at 03:05.0 will be re-assigned to 00:00.0. A
-	  second device at 02:1a.1 will be re-assigned to 00:01.1.
-
-config XEN_PCIDEV_BACKEND_PASS
-	bool "Passthrough"
-	help
-	  This PCI Backend provides a real view of the PCI topology to the
-	  frontend (for example, a device at 06:01.b will still appear at
-	  06:01.b to the frontend). This is similar to how Xen 2.0.x exposed
-	  PCI devices to its driver domains. This may be required for drivers
-	  which depend on finding their hardward in certain bus/slot
-	  locations.
+	  The parameter "passthrough" allows you specify how you want the PCI
+	  devices to appear in the guest. You can choose the default (0) where
+	  PCI topology starts at 00.00.0, or (1) for passthrough if you want
+	  the PCI devices topology appear the same as in the host.
 
-endchoice
+	  The "hide" parameter (only applicable if backend driver is compiled
+	  into the kernel) allows you to bind the PCI devices to this module
+	  from the default device drivers. The argument is the list of PCI BDFs:
+	  xen-pciback.hide=(03:00.0)(04:00.0)
 
+	  If in doubt, say m.
 endmenu
diff --git a/drivers/xen/xen-pciback/Makefile b/drivers/xen/xen-pciback/Makefile
index 290396766f07194faafcd9e199147880027c217e..ffe0ad3438bd4c944cbf69ddb36b64cb72c29afd 100644
--- a/drivers/xen/xen-pciback/Makefile
+++ b/drivers/xen/xen-pciback/Makefile
@@ -3,6 +3,5 @@ obj-$(CONFIG_XEN_PCIDEV_BACKEND) += xen-pciback.o
 xen-pciback-y := pci_stub.o pciback_ops.o xenbus.o
 xen-pciback-y += conf_space.o conf_space_header.o \
 		 conf_space_capability.o \
-		 conf_space_quirks.o
-xen-pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o
-xen-pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o
+		 conf_space_quirks.o vpci.o \
+		 passthrough.o
diff --git a/drivers/xen/xen-pciback/passthrough.c b/drivers/xen/xen-pciback/passthrough.c
index b451cb8dd2fff9a89bc45f6743b46eb22e741598..1d32a9a42c0116c6685c1028f2c799632259e90d 100644
--- a/drivers/xen/xen-pciback/passthrough.c
+++ b/drivers/xen/xen-pciback/passthrough.c
@@ -16,9 +16,10 @@ struct passthrough_dev_data {
 	spinlock_t lock;
 };
 
-struct pci_dev *xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
-				      unsigned int domain, unsigned int bus,
-				      unsigned int devfn)
+static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
+					       unsigned int domain,
+					       unsigned int bus,
+					       unsigned int devfn)
 {
 	struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
 	struct pci_dev_entry *dev_entry;
@@ -41,8 +42,9 @@ struct pci_dev *xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
 	return dev;
 }
 
-int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, struct pci_dev *dev,
-			  int devid, publish_pci_dev_cb publish_cb)
+static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
+				   struct pci_dev *dev,
+				   int devid, publish_pci_dev_cb publish_cb)
 {
 	struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
 	struct pci_dev_entry *dev_entry;
@@ -68,8 +70,8 @@ int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, struct pci_dev *dev,
 	return err;
 }
 
-void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
-			       struct pci_dev *dev)
+static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
+					struct pci_dev *dev)
 {
 	struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
 	struct pci_dev_entry *dev_entry, *t;
@@ -92,7 +94,7 @@ void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
 		pcistub_put_pci_dev(found_dev);
 }
 
-int xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
+static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
 {
 	struct passthrough_dev_data *dev_data;
 
@@ -109,8 +111,8 @@ int xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
 	return 0;
 }
 
-int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
-				publish_pci_root_cb publish_root_cb)
+static int __xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
+					 publish_pci_root_cb publish_root_cb)
 {
 	int err = 0;
 	struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
@@ -154,7 +156,7 @@ int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
 	return err;
 }
 
-void xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
+static void __xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
 {
 	struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
 	struct pci_dev_entry *dev_entry, *t;
@@ -169,13 +171,24 @@ void xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
 	pdev->pci_dev_data = NULL;
 }
 
-int xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
-			       struct xen_pcibk_device *pdev,
-			       unsigned int *domain, unsigned int *bus,
-			       unsigned int *devfn)
+static int __xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
+					struct xen_pcibk_device *pdev,
+					unsigned int *domain, unsigned int *bus,
+					unsigned int *devfn)
 {
 	*domain = pci_domain_nr(pcidev->bus);
 	*bus = pcidev->bus->number;
 	*devfn = pcidev->devfn;
 	return 1;
 }
+
+struct xen_pcibk_backend xen_pcibk_passthrough_backend = {
+	.name           = "passthrough",
+	.init           = __xen_pcibk_init_devices,
+	.free		= __xen_pcibk_release_devices,
+	.find           = __xen_pcibk_get_pcifront_dev,
+	.publish        = __xen_pcibk_publish_pci_roots,
+	.release        = __xen_pcibk_release_pci_dev,
+	.add            = __xen_pcibk_add_pci_dev,
+	.get            = __xen_pcibk_get_pci_dev,
+};
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h
index 427b7fd01356916e7b09fad8b967fb82200e1d12..a0e131a815030d5ed95536b1ea89f9ec5ef93b3a 100644
--- a/drivers/xen/xen-pciback/pciback.h
+++ b/drivers/xen/xen-pciback/pciback.h
@@ -83,30 +83,90 @@ typedef int (*publish_pci_dev_cb) (struct xen_pcibk_device *pdev,
 				   unsigned int devfn, unsigned int devid);
 typedef int (*publish_pci_root_cb) (struct xen_pcibk_device *pdev,
 				    unsigned int domain, unsigned int bus);
-int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, struct pci_dev *dev,
-			  int devid, publish_pci_dev_cb publish_cb);
-void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
-			       struct pci_dev *dev);
-struct pci_dev *xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
-				      unsigned int domain, unsigned int bus,
-				      unsigned int devfn);
 
+/* Backend registration for the two types of BDF representation:
+ *  vpci - BDFs start at 00
+ *  passthrough - BDFs are exactly like in the host.
+ */
+struct xen_pcibk_backend {
+	char *name;
+	int (*init)(struct xen_pcibk_device *pdev);
+	void (*free)(struct xen_pcibk_device *pdev);
+	int (*find)(struct pci_dev *pcidev, struct xen_pcibk_device *pdev,
+		    unsigned int *domain, unsigned int *bus,
+		    unsigned int *devfn);
+	int (*publish)(struct xen_pcibk_device *pdev, publish_pci_root_cb cb);
+	void (*release)(struct xen_pcibk_device *pdev, struct pci_dev *dev);
+	int (*add)(struct xen_pcibk_device *pdev, struct pci_dev *dev,
+		   int devid, publish_pci_dev_cb publish_cb);
+	struct pci_dev *(*get)(struct xen_pcibk_device *pdev,
+			       unsigned int domain, unsigned int bus,
+			       unsigned int devfn);
+};
+
+extern struct xen_pcibk_backend xen_pcibk_vpci_backend;
+extern struct xen_pcibk_backend xen_pcibk_passthrough_backend;
+extern struct xen_pcibk_backend *xen_pcibk_backend;
+
+static inline int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
+					struct pci_dev *dev,
+					int devid,
+					publish_pci_dev_cb publish_cb)
+{
+	if (xen_pcibk_backend && xen_pcibk_backend->add)
+		return xen_pcibk_backend->add(pdev, dev, devid, publish_cb);
+	return -1;
+};
+static inline void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
+					     struct pci_dev *dev)
+{
+	if (xen_pcibk_backend && xen_pcibk_backend->free)
+		return xen_pcibk_backend->release(pdev, dev);
+};
+
+static inline struct pci_dev *
+xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev, unsigned int domain,
+		      unsigned int bus, unsigned int devfn)
+{
+	if (xen_pcibk_backend && xen_pcibk_backend->get)
+		return xen_pcibk_backend->get(pdev, domain, bus, devfn);
+	return NULL;
+};
 /**
 * Add for domain0 PCIE-AER handling. Get guest domain/bus/devfn in xen_pcibk
 * before sending aer request to pcifront, so that guest could identify
 * device, coopearte with xen_pcibk to finish aer recovery job if device driver
 * has the capability
 */
-
-int xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
-			       struct xen_pcibk_device *pdev,
-			       unsigned int *domain, unsigned int *bus,
-			       unsigned int *devfn);
-int xen_pcibk_init_devices(struct xen_pcibk_device *pdev);
-int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
-				publish_pci_root_cb cb);
-void xen_pcibk_release_devices(struct xen_pcibk_device *pdev);
-
+static inline int xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
+					     struct xen_pcibk_device *pdev,
+					     unsigned int *domain,
+					     unsigned int *bus,
+					     unsigned int *devfn)
+{
+	if (xen_pcibk_backend && xen_pcibk_backend->find)
+		return xen_pcibk_backend->find(pcidev, pdev, domain, bus,
+					       devfn);
+	return -1;
+};
+static inline int xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
+{
+	if (xen_pcibk_backend && xen_pcibk_backend->init)
+		return xen_pcibk_backend->init(pdev);
+	return -1;
+};
+static inline int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
+					      publish_pci_root_cb cb)
+{
+	if (xen_pcibk_backend && xen_pcibk_backend->publish)
+		return xen_pcibk_backend->publish(pdev, cb);
+	return -1;
+};
+static inline void xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
+{
+	if (xen_pcibk_backend && xen_pcibk_backend->free)
+		return xen_pcibk_backend->free(pdev);
+};
 /* Handles events from front-end */
 irqreturn_t xen_pcibk_handle_event(int irq, void *dev_id);
 void xen_pcibk_do_op(struct work_struct *data);
diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c
index 7d5c192a150588023b6ce62c6817e4ef06aa4399..4a42cfb0959d4f5dbcf6268e19e0b0a61388b9e0 100644
--- a/drivers/xen/xen-pciback/vpci.c
+++ b/drivers/xen/xen-pciback/vpci.c
@@ -25,9 +25,10 @@ static inline struct list_head *list_first(struct list_head *head)
 	return head->next;
 }
 
-struct pci_dev *xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
-				      unsigned int domain, unsigned int bus,
-				      unsigned int devfn)
+static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
+					       unsigned int domain,
+					       unsigned int bus,
+					       unsigned int devfn)
 {
 	struct pci_dev_entry *entry;
 	struct pci_dev *dev = NULL;
@@ -63,8 +64,9 @@ static inline int match_slot(struct pci_dev *l, struct pci_dev *r)
 	return 0;
 }
 
-int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, struct pci_dev *dev,
-			  int devid, publish_pci_dev_cb publish_cb)
+static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
+				   struct pci_dev *dev, int devid,
+				   publish_pci_dev_cb publish_cb)
 {
 	int err = 0, slot, func = -1;
 	struct pci_dev_entry *t, *dev_entry;
@@ -137,8 +139,8 @@ int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, struct pci_dev *dev,
 	return err;
 }
 
-void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
-			       struct pci_dev *dev)
+static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
+					struct pci_dev *dev)
 {
 	int slot;
 	struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
@@ -167,7 +169,7 @@ void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
 		pcistub_put_pci_dev(found_dev);
 }
 
-int xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
+static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
 {
 	int slot;
 	struct vpci_dev_data *vpci_dev;
@@ -186,14 +188,14 @@ int xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
 	return 0;
 }
 
-int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
-				publish_pci_root_cb publish_cb)
+static int __xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
+					 publish_pci_root_cb publish_cb)
 {
 	/* The Virtual PCI bus has only one root */
 	return publish_cb(pdev, 0, 0);
 }
 
-void xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
+static void __xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
 {
 	int slot;
 	struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
@@ -212,10 +214,10 @@ void xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
 	pdev->pci_dev_data = NULL;
 }
 
-int xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
-			       struct xen_pcibk_device *pdev,
-			       unsigned int *domain, unsigned int *bus,
-			       unsigned int *devfn)
+static int __xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
+					struct xen_pcibk_device *pdev,
+					unsigned int *domain, unsigned int *bus,
+					unsigned int *devfn)
 {
 	struct pci_dev_entry *entry;
 	struct pci_dev *dev = NULL;
@@ -244,3 +246,14 @@ int xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
 	spin_unlock_irqrestore(&vpci_dev->lock, flags);
 	return found;
 }
+
+struct xen_pcibk_backend xen_pcibk_vpci_backend = {
+	.name		= "vpci",
+	.init		= __xen_pcibk_init_devices,
+	.free		= __xen_pcibk_release_devices,
+	.find		= __xen_pcibk_get_pcifront_dev,
+	.publish	= __xen_pcibk_publish_pci_roots,
+	.release	= __xen_pcibk_release_pci_dev,
+	.add		= __xen_pcibk_add_pci_dev,
+	.get		= __xen_pcibk_get_pci_dev,
+};
diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c
index 1e5ba85c0d33f64b48f78d315ff8ff4e6deb17e4..206c4ce030bc98c9b2e5f66caca50ed27c459848 100644
--- a/drivers/xen/xen-pciback/xenbus.c
+++ b/drivers/xen/xen-pciback/xenbus.c
@@ -18,6 +18,21 @@
 #define INVALID_EVTCHN_IRQ  (-1)
 struct workqueue_struct *xen_pcibk_wq;
 
+static int __read_mostly passthrough;
+module_param(passthrough, bool, S_IRUGO);
+MODULE_PARM_DESC(passthrough,
+	"Option to specify how to export PCI topology to guest:\n"\
+	" 0 - (default) Hide the true PCI topology and makes the frontend\n"\
+	"   there is a single PCI bus with only the exported devices on it.\n"\
+	"   For example, a device at 03:05.0 will be re-assigned to 00:00.0\n"\
+	"   while second device at 02:1a.1 will be re-assigned to 00:01.1.\n"\
+	" 1 - Passthrough provides a real view of the PCI topology to the\n"\
+	"   frontend (for example, a device at 06:01.b will still appear at\n"\
+	"   06:01.b to the frontend). This is similar to how Xen 2.0.x\n"\
+	"   exposed PCI devices to its driver domains. This may be required\n"\
+	"   for drivers which depend on finding their hardward in certain\n"\
+	"   bus/slot locations.");
+
 static struct xen_pcibk_device *alloc_pdev(struct xenbus_device *xdev)
 {
 	struct xen_pcibk_device *pdev;
@@ -710,6 +725,8 @@ static struct xenbus_driver xenbus_xen_pcibk_driver = {
 	.otherend_changed	= xen_pcibk_frontend_changed,
 };
 
+struct xen_pcibk_backend *xen_pcibk_backend;
+
 int __init xen_pcibk_xenbus_register(void)
 {
 	xen_pcibk_wq = create_workqueue("xen_pciback_workqueue");
@@ -718,6 +735,10 @@ int __init xen_pcibk_xenbus_register(void)
 			"xen_pciback_workqueue failed\n", __func__);
 		return -EFAULT;
 	}
+	xen_pcibk_backend = &xen_pcibk_vpci_backend;
+	if (passthrough)
+		xen_pcibk_backend = &xen_pcibk_passthrough_backend;
+	pr_info(DRV_NAME ": backend is %s\n", xen_pcibk_backend->name);
 	return xenbus_register_backend(&xenbus_xen_pcibk_driver);
 }