aboutsummaryrefslogtreecommitdiffstats
path: root/unmodified_drivers
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-04-10 15:31:53 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-04-10 15:31:53 +0100
commit20f278002607ff5af89581ae6ce1258dcd3f282a (patch)
treed1e461baa2c13863d3d172f0c2047270d386dfea /unmodified_drivers
parente2492c5e9e72ffc0ddb2765080b579200fd8f1c8 (diff)
downloadxen-20f278002607ff5af89581ae6ce1258dcd3f282a.tar.gz
xen-20f278002607ff5af89581ae6ce1258dcd3f282a.tar.bz2
xen-20f278002607ff5af89581ae6ce1258dcd3f282a.zip
PV-on-HVM: Fixes for save/restore. Also gets rid of separate modules
reboot.ko and xenbus.ko. These are now part of xen-platform-pci.ko. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'unmodified_drivers')
-rw-r--r--unmodified_drivers/linux-2.6/Makefile2
-rwxr-xr-xunmodified_drivers/linux-2.6/mkbuildtree2
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/Kbuild11
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/evtchn.c152
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c24
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/platform-pci.c91
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/platform-pci.h38
-rw-r--r--unmodified_drivers/linux-2.6/util/Kbuild3
-rw-r--r--unmodified_drivers/linux-2.6/util/Makefile3
-rw-r--r--unmodified_drivers/linux-2.6/xenbus/Kbuild10
-rw-r--r--unmodified_drivers/linux-2.6/xenbus/Makefile3
-rw-r--r--unmodified_drivers/linux-2.6/xenbus/empty_directory0
12 files changed, 215 insertions, 124 deletions
diff --git a/unmodified_drivers/linux-2.6/Makefile b/unmodified_drivers/linux-2.6/Makefile
index 6722df5ac6..c548aa9f65 100644
--- a/unmodified_drivers/linux-2.6/Makefile
+++ b/unmodified_drivers/linux-2.6/Makefile
@@ -1,8 +1,6 @@
include $(M)/overrides.mk
obj-m += platform-pci/
-obj-m += xenbus/
obj-m += balloon/
obj-m += blkfront/
obj-m += netfront/
-obj-m += util/
diff --git a/unmodified_drivers/linux-2.6/mkbuildtree b/unmodified_drivers/linux-2.6/mkbuildtree
index b12da9b086..b09acf92e8 100755
--- a/unmodified_drivers/linux-2.6/mkbuildtree
+++ b/unmodified_drivers/linux-2.6/mkbuildtree
@@ -25,7 +25,7 @@ done
ln -sf ${XL}/drivers/xen/core/gnttab.c platform-pci
ln -sf ${XL}/drivers/xen/core/features.c platform-pci
ln -sf ${XL}/drivers/xen/core/xen_proc.c xenbus
-ln -sf ${XL}/drivers/xen/core/reboot.c util
+ln -sf ${XL}/drivers/xen/core/reboot.c platform-pci
mkdir -p include/asm include/xen
diff --git a/unmodified_drivers/linux-2.6/platform-pci/Kbuild b/unmodified_drivers/linux-2.6/platform-pci/Kbuild
index a44e50e94c..baf8e3b8bf 100644
--- a/unmodified_drivers/linux-2.6/platform-pci/Kbuild
+++ b/unmodified_drivers/linux-2.6/platform-pci/Kbuild
@@ -4,7 +4,16 @@ obj-m := xen-platform-pci.o
EXTRA_CFLAGS += -I$(M)/platform-pci
-xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o features.o platform-compat.o
+xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o
+xen-platform-pci-objs += features.o platform-compat.o
+xen-platform-pci-objs += reboot.o machine_reboot.o
+
+xen-platform-pci-objs += ../xenbus/xenbus_comms.o
+xen-platform-pci-objs += ../xenbus/xenbus_xs.o
+xen-platform-pci-objs += ../xenbus/xenbus_probe.o
+xen-platform-pci-objs += ../xenbus/xenbus_dev.o
+xen-platform-pci-objs += ../xenbus/xenbus_client.o
+xen-platform-pci-objs += ../xenbus/xen_proc.o
# Can we do better ?
ifeq ($(ARCH),ia64)
diff --git a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c
index 0c19cf5cda..5e7a3dfcde 100644
--- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c
+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c
@@ -41,16 +41,42 @@
void *shared_info_area;
-#define MAX_EVTCHN 256
+static DEFINE_MUTEX(irq_evtchn_mutex);
+
+#define is_valid_evtchn(x) ((x) != 0)
+#define evtchn_from_irq(x) (irq_evtchn[irq].evtchn)
+
static struct {
irqreturn_t(*handler) (int, void *, struct pt_regs *);
void *dev_id;
- int close; /* close on unbind_from_irqhandler()? */
-} evtchns[MAX_EVTCHN];
+ int evtchn;
+ int close:1; /* close on unbind_from_irqhandler()? */
+ int inuse:1;
+} irq_evtchn[256];
+static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
+ [0 ... NR_EVENT_CHANNELS-1] = -1 };
+
+static int find_unbound_irq(void)
+{
+ static int warned;
+ int irq;
+
+ for (irq = 0; irq < ARRAY_SIZE(irq_evtchn); irq++)
+ if (!irq_evtchn[irq].inuse)
+ return irq;
+
+ if (!warned) {
+ warned = 1;
+ printk(KERN_WARNING "No available IRQ to bind to: "
+ "increase irq_evtchn[] size in evtchn.c.\n");
+ }
+
+ return -ENOSPC;
+}
int irq_to_evtchn_port(int irq)
{
- return irq;
+ return irq_evtchn[irq].evtchn;
}
EXPORT_SYMBOL(irq_to_evtchn_port);
@@ -107,21 +133,37 @@ int bind_listening_port_to_irqhandler(
void *dev_id)
{
struct evtchn_alloc_unbound alloc_unbound;
- int err;
+ int err, irq;
+
+ mutex_lock(&irq_evtchn_mutex);
+
+ irq = find_unbound_irq();
+ if (irq < 0) {
+ mutex_unlock(&irq_evtchn_mutex);
+ return irq;
+ }
alloc_unbound.dom = DOMID_SELF;
alloc_unbound.remote_dom = remote_domain;
-
err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
&alloc_unbound);
- if (err)
+ if (err) {
+ mutex_unlock(&irq_evtchn_mutex);
return err;
+ }
+
+ irq_evtchn[irq].handler = handler;
+ irq_evtchn[irq].dev_id = dev_id;
+ irq_evtchn[irq].evtchn = alloc_unbound.port;
+ irq_evtchn[irq].close = 1;
+ irq_evtchn[irq].inuse = 1;
+
+ evtchn_to_irq[alloc_unbound.port] = irq;
- evtchns[alloc_unbound.port].handler = handler;
- evtchns[alloc_unbound.port].dev_id = dev_id;
- evtchns[alloc_unbound.port].close = 1;
unmask_evtchn(alloc_unbound.port);
- return alloc_unbound.port;
+
+ mutex_unlock(&irq_evtchn_mutex);
+ return irq;
}
EXPORT_SYMBOL(bind_listening_port_to_irqhandler);
@@ -132,35 +174,59 @@ int bind_caller_port_to_irqhandler(
const char *devname,
void *dev_id)
{
- if (caller_port >= MAX_EVTCHN)
- return -EINVAL;
- evtchns[caller_port].handler = handler;
- evtchns[caller_port].dev_id = dev_id;
- evtchns[caller_port].close = 0;
+ int irq;
+
+ mutex_lock(&irq_evtchn_mutex);
+
+ irq = find_unbound_irq();
+ if (irq < 0) {
+ mutex_unlock(&irq_evtchn_mutex);
+ return irq;
+ }
+
+ irq_evtchn[irq].handler = handler;
+ irq_evtchn[irq].dev_id = dev_id;
+ irq_evtchn[irq].evtchn = caller_port;
+ irq_evtchn[irq].close = 0;
+ irq_evtchn[irq].inuse = 1;
+
+ evtchn_to_irq[caller_port] = irq;
+
unmask_evtchn(caller_port);
- return caller_port;
+
+ mutex_unlock(&irq_evtchn_mutex);
+ return irq;
}
EXPORT_SYMBOL(bind_caller_port_to_irqhandler);
-void unbind_from_irqhandler(unsigned int evtchn, void *dev_id)
+void unbind_from_irqhandler(unsigned int irq, void *dev_id)
{
- if (evtchn >= MAX_EVTCHN)
- return;
+ int evtchn = evtchn_from_irq(irq);
- mask_evtchn(evtchn);
- evtchns[evtchn].handler = NULL;
+ mutex_lock(&irq_evtchn_mutex);
- if (evtchns[evtchn].close) {
- struct evtchn_close close = { .port = evtchn };
- HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+ if (is_valid_evtchn(evtchn)) {
+ evtchn_to_irq[irq] = -1;
+ mask_evtchn(evtchn);
+ if (irq_evtchn[irq].close) {
+ struct evtchn_close close = { .port = evtchn };
+ HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+ }
}
+
+ irq_evtchn[irq].handler = NULL;
+ irq_evtchn[irq].evtchn = 0;
+ irq_evtchn[irq].inuse = 0;
+
+ mutex_unlock(&irq_evtchn_mutex);
}
EXPORT_SYMBOL(unbind_from_irqhandler);
void notify_remote_via_irq(int irq)
{
- int evtchn = irq;
- notify_remote_via_evtchn(evtchn);
+ int evtchn = evtchn_from_irq(irq);
+ if (is_valid_evtchn(evtchn))
+ notify_remote_via_evtchn(evtchn);
}
EXPORT_SYMBOL(notify_remote_via_irq);
@@ -183,9 +249,10 @@ irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
while ((l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i])) {
port = (l1i * BITS_PER_LONG) + __ffs(l2);
synch_clear_bit(port, &s->evtchn_pending[0]);
- if ((handler = evtchns[port].handler) != NULL)
- handler(port, evtchns[port].dev_id,
- regs);
+ irq = evtchn_to_irq[port];
+ if ((irq >= 0) &&
+ ((handler = irq_evtchn[irq].handler) != NULL))
+ handler(irq, irq_evtchn[irq].dev_id, regs);
else
printk(KERN_WARNING "unexpected event channel "
"upcall on port %d!\n", port);
@@ -200,3 +267,28 @@ void force_evtchn_callback(void)
(void)HYPERVISOR_xen_version(0, NULL);
}
EXPORT_SYMBOL(force_evtchn_callback);
+
+void irq_suspend(void)
+{
+ mutex_lock(&irq_evtchn_mutex);
+}
+
+void irq_suspend_cancel(void)
+{
+ mutex_unlock(&irq_evtchn_mutex);
+}
+
+void irq_resume(void)
+{
+ int evtchn, irq;
+
+ for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) {
+ mask_evtchn(evtchn);
+ evtchn_to_irq[evtchn] = -1;
+ }
+
+ for (irq = 0; irq < ARRAY_SIZE(irq_evtchn); irq++)
+ irq_evtchn[irq].evtchn = 0;
+
+ mutex_unlock(&irq_evtchn_mutex);
+}
diff --git a/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c b/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c
new file mode 100644
index 0000000000..d14bdbf1d9
--- /dev/null
+++ b/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c
@@ -0,0 +1,24 @@
+#include <linux/config.h>
+#include <xen/xenbus.h>
+#include "platform-pci.h"
+#include <asm/hypervisor.h>
+
+int __xen_suspend(int fast_suspend)
+{
+ int suspend_cancelled;
+
+ xenbus_suspend();
+ platform_pci_suspend();
+
+ suspend_cancelled = HYPERVISOR_shutdown(SHUTDOWN_suspend);
+
+ if (suspend_cancelled) {
+ platform_pci_suspend_cancel();
+ xenbus_suspend_cancel();
+ } else {
+ platform_pci_resume();
+ xenbus_resume();
+ }
+
+ return 0;
+}
diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
index 2451b7c6ce..8dc2f73153 100644
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
@@ -1,7 +1,9 @@
/******************************************************************************
* platform-pci.c
+ *
* Xen platform PCI device driver
- * Copyright (C) 2005, Intel Corporation.
+ * Copyright (c) 2005, Intel Corporation.
+ * Copyright (c) 2007, XenSource Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -35,7 +37,9 @@
#include <asm/hypervisor.h>
#include <asm/pgtable.h>
#include <xen/interface/memory.h>
+#include <xen/interface/hvm/params.h>
#include <xen/features.h>
+#include <xen/evtchn.h>
#include <xen/gnttab.h>
#ifdef __ia64__
#include <asm/xen/xencomm.h>
@@ -54,14 +58,10 @@
char *hypercall_stubs;
EXPORT_SYMBOL(hypercall_stubs);
-// Used to be xiaofeng.ling@intel.com
MODULE_AUTHOR("ssmith@xensource.com");
MODULE_DESCRIPTION("Xen platform PCI device");
MODULE_LICENSE("GPL");
-unsigned long *phys_to_machine_mapping;
-EXPORT_SYMBOL(phys_to_machine_mapping);
-
static unsigned long shared_info_frame;
static uint64_t callback_via;
@@ -89,30 +89,11 @@ static int __devinit init_xen_info(void)
if (shared_info_area == NULL)
panic("can't map shared info\n");
- phys_to_machine_mapping = NULL;
-
gnttab_init();
return 0;
}
-static void __devexit platform_pci_remove(struct pci_dev *pdev)
-{
- long ioaddr, iolen;
- long mmio_addr, mmio_len;
-
- ioaddr = pci_resource_start(pdev, 0);
- iolen = pci_resource_len(pdev, 0);
- mmio_addr = pci_resource_start(pdev, 1);
- mmio_len = pci_resource_len(pdev, 1);
-
- release_region(ioaddr, iolen);
- release_mem_region(mmio_addr, mmio_len);
-
- pci_set_drvdata(pdev, NULL);
- free_irq(pdev->irq, pdev);
-}
-
static unsigned long platform_mmio;
static unsigned long platform_mmio_alloc;
static unsigned long platform_mmiolen;
@@ -208,6 +189,19 @@ static uint64_t get_callback_via(struct pci_dev *pdev)
((uint64_t)(pin - 1) & 3));
}
+static int set_callback_via(uint64_t via)
+{
+ struct xen_hvm_param a;
+
+ a.domid = DOMID_SELF;
+ a.index = HVM_PARAM_CALLBACK_IRQ;
+ a.value = via;
+ return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
+}
+
+int xenbus_init(void);
+int xen_reboot_init(void);
+
static int __devinit platform_pci_init(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -232,15 +226,13 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
return -ENOENT;
}
- if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL)
- {
+ if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL) {
printk(KERN_ERR ":MEM I/O resource 0x%lx @ 0x%lx busy\n",
mmio_addr, mmio_len);
return -EBUSY;
}
- if (request_region(ioaddr, iolen, DRV_NAME) == NULL)
- {
+ if (request_region(ioaddr, iolen, DRV_NAME) == NULL) {
printk(KERN_ERR DRV_NAME ":I/O resource 0x%lx @ 0x%lx busy\n",
iolen, ioaddr);
release_mem_region(mmio_addr, mmio_len);
@@ -265,6 +257,12 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
if ((ret = set_callback_via(callback_via)))
goto out;
+ if ((ret = xenbus_init()))
+ goto out;
+
+ if ((ret = xen_reboot_init()))
+ goto out;
+
out:
if (ret) {
release_mem_region(mmio_addr, mmio_len);
@@ -289,7 +287,6 @@ MODULE_DEVICE_TABLE(pci, platform_pci_tbl);
static struct pci_driver platform_driver = {
name: DRV_NAME,
probe: platform_pci_init,
- remove: __devexit_p(platform_pci_remove),
id_table: platform_pci_tbl,
};
@@ -298,13 +295,18 @@ static int pci_device_registered;
void platform_pci_suspend(void)
{
gnttab_suspend();
+ irq_suspend();
+}
+
+void platform_pci_suspend_cancel(void)
+{
+ irq_suspend_cancel();
+ gnttab_resume();
}
-EXPORT_SYMBOL_GPL(platform_pci_suspend);
void platform_pci_resume(void)
{
struct xen_add_to_physmap xatp;
- phys_to_machine_mapping = NULL;
/* do 2 things for PV driver restore on HVM
* 1: rebuild share info
@@ -317,34 +319,27 @@ void platform_pci_resume(void)
if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
BUG();
- if (( set_callback_via(callback_via)))
+ irq_resume();
+
+ if (set_callback_via(callback_via))
printk("platform_pci_resume failure!\n");
gnttab_resume();
}
-EXPORT_SYMBOL_GPL(platform_pci_resume);
static int __init platform_pci_module_init(void)
{
int rc;
rc = pci_module_init(&platform_driver);
- if (rc)
- printk(KERN_INFO DRV_NAME ":No platform pci device model found\n");
- else
- pci_device_registered = 1;
-
- return rc;
-}
+ if (rc) {
+ printk(KERN_INFO DRV_NAME
+ ": No platform pci device model found\n");
+ return rc;
+ }
-static void __exit platform_pci_module_cleanup(void)
-{
- printk(KERN_INFO DRV_NAME ":Do platform module cleanup\n");
- /* disable hypervisor for callback irq */
- set_callback_via(0);
- if (pci_device_registered)
- pci_unregister_driver(&platform_driver);
+ pci_device_registered = 1;
+ return 0;
}
module_init(platform_pci_module_init);
-module_exit(platform_pci_module_cleanup);
diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h
index ca65358599..098db4525b 100644
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h
@@ -1,7 +1,9 @@
/******************************************************************************
- * evtchn-pci.h
- * module driver support in unmodified Linux
- * Copyright (C) 2004, Intel Corporation. <xiaofeng.ling@intel.com>
+ * platform-pci.h
+ *
+ * Xen platform PCI device driver
+ * Copyright (c) 2004, Intel Corporation. <xiaofeng.ling@intel.com>
+ * Copyright (c) 2007, XenSource Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -15,31 +17,21 @@
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
- *
*/
-#ifndef __XEN_SUPPORT_H
-#define __XEN_SUPPORT_H
-#include <linux/version.h>
-#include <linux/interrupt.h>
-#include <xen/interface/hvm/params.h>
-
-static inline int set_callback_via(uint64_t via)
-{
- struct xen_hvm_param a;
+#ifndef _XEN_PLATFORM_PCI_H
+#define _XEN_PLATFORM_PCI_H
- a.domid = DOMID_SELF;
- a.index = HVM_PARAM_CALLBACK_IRQ;
- a.value = via;
- return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
-}
+#include <linux/interrupt.h>
unsigned long alloc_xen_mmio(unsigned long len);
-
int gnttab_init(void);
-
-void setup_xen_features(void);
-
irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+void irq_suspend(void);
+void irq_suspend_cancel(void);
+
+void platform_pci_suspend(void);
+void platform_pci_suspend_cancel(void);
+void platform_pci_resume(void);
-#endif
+#endif /* _XEN_PLATFORM_PCI_H */
diff --git a/unmodified_drivers/linux-2.6/util/Kbuild b/unmodified_drivers/linux-2.6/util/Kbuild
deleted file mode 100644
index 35495d8194..0000000000
--- a/unmodified_drivers/linux-2.6/util/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-include $(M)/overrides.mk
-
-obj-m := reboot.o
diff --git a/unmodified_drivers/linux-2.6/util/Makefile b/unmodified_drivers/linux-2.6/util/Makefile
deleted file mode 100644
index 64e7acd194..0000000000
--- a/unmodified_drivers/linux-2.6/util/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-ifneq ($(KERNELRELEASE),)
-include $(src)/Kbuild
-endif
diff --git a/unmodified_drivers/linux-2.6/xenbus/Kbuild b/unmodified_drivers/linux-2.6/xenbus/Kbuild
deleted file mode 100644
index 1a463ab6e3..0000000000
--- a/unmodified_drivers/linux-2.6/xenbus/Kbuild
+++ /dev/null
@@ -1,10 +0,0 @@
-include $(M)/overrides.mk
-
-obj-m += xenbus.o
-xenbus-objs =
-xenbus-objs += xenbus_comms.o
-xenbus-objs += xenbus_xs.o
-xenbus-objs += xenbus_probe.o
-xenbus-objs += xenbus_dev.o
-xenbus-objs += xenbus_client.o
-xenbus-objs += xen_proc.o
diff --git a/unmodified_drivers/linux-2.6/xenbus/Makefile b/unmodified_drivers/linux-2.6/xenbus/Makefile
deleted file mode 100644
index 64e7acd194..0000000000
--- a/unmodified_drivers/linux-2.6/xenbus/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-ifneq ($(KERNELRELEASE),)
-include $(src)/Kbuild
-endif
diff --git a/unmodified_drivers/linux-2.6/xenbus/empty_directory b/unmodified_drivers/linux-2.6/xenbus/empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/unmodified_drivers/linux-2.6/xenbus/empty_directory