# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1204302031 25200
# Node ID 68e78169679ed2681fa24c8603f40a82266b8223
# Parent ee7015727bd15e80e17e725f70c0a5336e45607a
# Parent 49ffe9ef67d420bde98e7ead29c9b9bfc5b026ba
merge with linux-2.6.18-xen.hg
---
arch/i386/kernel/machine_kexec.c | 15 ++++++
arch/i386/pci/irq-xen.c | 10 +++-
arch/ia64/kernel/machine_kexec.c | 59 ++++++++++++++++++++++++++
arch/ia64/kernel/setup.c | 6 +-
arch/x86_64/kernel/machine_kexec.c | 15 ++++++
drivers/xen/core/machine_kexec.c | 17 ++++---
drivers/xen/core/machine_reboot.c | 25 +++++++----
drivers/xen/core/reboot.c | 82 ++++++++++++++++++++++++-------------
drivers/xen/fbfront/xenkbd.c | 6 +-
drivers/xen/netfront/accel.c | 12 ++++-
drivers/xen/pcifront/xenbus.c | 2
drivers/xen/xenbus/xenbus_dev.c | 2
include/xen/interface/io/kbdif.h | 2
include/xen/interface/kexec.h | 15 +++++-
14 files changed, 208 insertions(+), 60 deletions(-)
diff -r ee7015727bd1 -r 68e78169679e arch/i386/kernel/machine_kexec.c
--- a/arch/i386/kernel/machine_kexec.c Fri Feb 29 09:14:21 2008 -0700
+++ b/arch/i386/kernel/machine_kexec.c Fri Feb 29 09:20:31 2008 -0700
@@ -64,6 +64,21 @@ void machine_kexec_setup_load_arg(xen_ke
}
+int __init machine_kexec_setup_resources(struct resource *hypervisor,
+ struct resource *phys_cpus,
+ int nr_phys_cpus)
+{
+ int k;
+
+ /* The per-cpu crash note resources belong to the hypervisor resource */
+ for (k = 0; k < nr_phys_cpus; k++)
+ request_resource(hypervisor, phys_cpus + k);
+
+ return 0;
+}
+
+void machine_kexec_register_resources(struct resource *res) { ; }
+
#endif /* CONFIG_XEN */
/*
diff -r ee7015727bd1 -r 68e78169679e arch/i386/pci/irq-xen.c
--- a/arch/i386/pci/irq-xen.c Fri Feb 29 09:14:21 2008 -0700
+++ b/arch/i386/pci/irq-xen.c Fri Feb 29 09:20:31 2008 -0700
@@ -259,13 +259,13 @@ static int pirq_via_set(struct pci_dev *
*/
static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int
pirq)
{
- static const unsigned int pirqmap[4] = { 3, 2, 5, 1 };
+ static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
}
static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int
pirq, int irq)
{
- static const unsigned int pirqmap[4] = { 3, 2, 5, 1 };
+ static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
return 1;
}
@@ -547,6 +547,12 @@ static __init int intel_router_probe(str
case PCI_DEVICE_ID_INTEL_ICH8_2:
case PCI_DEVICE_ID_INTEL_ICH8_3:
case PCI_DEVICE_ID_INTEL_ICH8_4:
+ case PCI_DEVICE_ID_INTEL_ICH9_0:
+ case PCI_DEVICE_ID_INTEL_ICH9_1:
+ case PCI_DEVICE_ID_INTEL_ICH9_2:
+ case PCI_DEVICE_ID_INTEL_ICH9_3:
+ case PCI_DEVICE_ID_INTEL_ICH9_4:
+ case PCI_DEVICE_ID_INTEL_ICH9_5:
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
r->set = pirq_piix_set;
diff -r ee7015727bd1 -r 68e78169679e arch/ia64/kernel/machine_kexec.c
--- a/arch/ia64/kernel/machine_kexec.c Fri Feb 29 09:14:21 2008 -0700
+++ b/arch/ia64/kernel/machine_kexec.c Fri Feb 29 09:20:31 2008 -0700
@@ -142,4 +142,63 @@ void machine_kexec_setup_load_arg(xen_ke
xki->reboot_code_buffer =
kexec_page_to_pfn(image->control_code_page) << PAGE_SHIFT;
}
+
+static struct resource xen_hypervisor_heap_res;
+
+int __init machine_kexec_setup_resources(struct resource *hypervisor,
+ struct resource *phys_cpus,
+ int nr_phys_cpus)
+{
+ xen_kexec_range_t range;
+ int k;
+
+ /* fill in xen_hypervisor_heap_res with hypervisor heap
+ * machine address range
+ */
+
+ memset(&range, 0, sizeof(range));
+ range.range = KEXEC_RANGE_MA_XENHEAP;
+
+ if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
+ return -1;
+
+ xen_hypervisor_heap_res.name = "Hypervisor heap";
+ xen_hypervisor_heap_res.start = range.start;
+ xen_hypervisor_heap_res.end = range.start + range.size - 1;
+ xen_hypervisor_heap_res.flags = IORESOURCE_BUSY | IORESOURCE_MEM;
+
+ /* The per-cpu crash note resources belong inside the
+ * hypervisor heap resource */
+ for (k = 0; k < nr_phys_cpus; k++)
+ request_resource(&xen_hypervisor_heap_res, phys_cpus + k);
+
+ /* fill in efi_memmap_res with EFI memmap machine address range */
+
+ memset(&range, 0, sizeof(range));
+ range.range = KEXEC_RANGE_MA_EFI_MEMMAP;
+
+ if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
+ return -1;
+
+ efi_memmap_res.start = range.start;
+ efi_memmap_res.end = range.start + range.size - 1;
+
+ /* fill in boot_param_res with boot parameter machine address range */
+
+ memset(&range, 0, sizeof(range));
+ range.range = KEXEC_RANGE_MA_BOOT_PARAM;
+
+ if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
+ return -1;
+
+ boot_param_res.start = range.start;
+ boot_param_res.end = range.start + range.size - 1;
+
+ return 0;
+}
+
+void machine_kexec_register_resources(struct resource *res)
+{
+ request_resource(res, &xen_hypervisor_heap_res);
+}
#endif /* CONFIG_XEN */
diff -r ee7015727bd1 -r 68e78169679e arch/ia64/kernel/setup.c
--- a/arch/ia64/kernel/setup.c Fri Feb 29 09:14:21 2008 -0700
+++ b/arch/ia64/kernel/setup.c Fri Feb 29 09:20:31 2008 -0700
@@ -336,15 +336,15 @@ reserve_memory (void)
}
}
}
-#ifdef CONFIG_XEN
- }
-#endif
efi_memmap_res.start = ia64_boot_param->efi_memmap;
efi_memmap_res.end = efi_memmap_res.start +
ia64_boot_param->efi_memmap_size;
boot_param_res.start = kexec_virt_to_phys(ia64_boot_param);
boot_param_res.end = boot_param_res.start +
sizeof(*ia64_boot_param);
+#ifdef CONFIG_XEN
+ }
+#endif
}
#endif
/* end of memory marker */
diff -r ee7015727bd1 -r 68e78169679e arch/x86_64/kernel/machine_kexec.c
--- a/arch/x86_64/kernel/machine_kexec.c Fri Feb 29 09:14:21 2008 -0700
+++ b/arch/x86_64/kernel/machine_kexec.c Fri Feb 29 09:20:31 2008 -0700
@@ -103,6 +103,21 @@ void machine_kexec_setup_load_arg(xen_ke
xki->page_list[PA_PTE_0] = __ma(kexec_pte0);
xki->page_list[PA_PTE_1] = __ma(kexec_pte1);
}
+
+int __init machine_kexec_setup_resources(struct resource *hypervisor,
+ struct resource *phys_cpus,
+ int nr_phys_cpus)
+{
+ int k;
+
+ /* The per-cpu crash note resources belong to the hypervisor resource */
+ for (k = 0; k < nr_phys_cpus; k++)
+ request_resource(hypervisor, phys_cpus + k);
+
+ return 0;
+}
+
+void machine_kexec_register_resources(struct resource *res) { ; }
#else /* CONFIG_XEN */
diff -r ee7015727bd1 -r 68e78169679e drivers/xen/core/machine_kexec.c
--- a/drivers/xen/core/machine_kexec.c Fri Feb 29 09:14:21 2008 -0700
+++ b/drivers/xen/core/machine_kexec.c Fri Feb 29 09:20:31 2008 -0700
@@ -10,6 +10,10 @@
extern void machine_kexec_setup_load_arg(xen_kexec_image_t *xki,
struct kimage *image);
+extern int machine_kexec_setup_resources(struct resource *hypervisor,
+ struct resource *phys_cpus,
+ int nr_phys_cpus);
+extern void machine_kexec_register_resources(struct resource *res);
static int __initdata xen_max_nr_phys_cpus;
static struct resource xen_hypervisor_res;
@@ -85,12 +89,16 @@ void __init xen_machine_kexec_setup_reso
range.range = KEXEC_RANGE_MA_CRASH;
if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
- return;
+ goto err;
if (range.size) {
crashk_res.start = range.start;
crashk_res.end = range.start + range.size - 1;
}
+
+ if (machine_kexec_setup_resources(&xen_hypervisor_res, xen_phys_cpus,
+ xen_max_nr_phys_cpus))
+ goto err;
return;
@@ -106,13 +114,8 @@ void __init xen_machine_kexec_setup_reso
void __init xen_machine_kexec_register_resources(struct resource *res)
{
- int k;
-
request_resource(res, &xen_hypervisor_res);
-
- for (k = 0; k < xen_max_nr_phys_cpus; k++)
- request_resource(&xen_hypervisor_res, xen_phys_cpus + k);
-
+ machine_kexec_register_resources(res);
}
static void setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
diff -r ee7015727bd1 -r 68e78169679e drivers/xen/core/machine_reboot.c
--- a/drivers/xen/core/machine_reboot.c Fri Feb 29 09:14:21 2008 -0700
+++ b/drivers/xen/core/machine_reboot.c Fri Feb 29 09:20:31 2008 -0700
@@ -129,13 +129,18 @@ static void post_suspend(int suspend_can
#endif
-static int take_machine_down(void *p_fast_suspend)
-{
- int fast_suspend = *(int *)p_fast_suspend;
+struct suspend {
+ int fast_suspend;
+ void (*resume_notifier)(void);
+};
+
+static int take_machine_down(void *_suspend)
+{
+ struct suspend *suspend = _suspend;
int suspend_cancelled, err;
extern void time_resume(void);
- if (fast_suspend) {
+ if (suspend->fast_suspend) {
BUG_ON(!irqs_disabled());
} else {
BUG_ON(irqs_disabled());
@@ -168,6 +173,7 @@ static int take_machine_down(void *p_fas
*/
suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
+ suspend->resume_notifier();
post_suspend(suspend_cancelled);
gnttab_resume();
if (!suspend_cancelled) {
@@ -178,7 +184,7 @@ static int take_machine_down(void *p_fas
* We do it here just in case, but there's no need if we are
* in fast-suspend mode as that implies a new enough Xen.
*/
- if (!fast_suspend) {
+ if (!suspend->fast_suspend) {
struct mmuext_op op;
op.cmd = MMUEXT_NEW_USER_BASEPTR;
op.arg1.mfn = pfn_to_mfn(__pa(__user_pgd(
@@ -190,15 +196,16 @@ static int take_machine_down(void *p_fas
}
time_resume();
- if (!fast_suspend)
+ if (!suspend->fast_suspend)
local_irq_enable();
return suspend_cancelled;
}
-int __xen_suspend(int fast_suspend)
+int __xen_suspend(int fast_suspend, void (*resume_notifier)(void))
{
int err, suspend_cancelled;
+ struct suspend suspend = { fast_suspend, resume_notifier };
BUG_ON(smp_processor_id() != 0);
BUG_ON(in_interrupt());
@@ -217,11 +224,11 @@ int __xen_suspend(int fast_suspend)
if (fast_suspend) {
xenbus_suspend();
- err = stop_machine_run(take_machine_down, &fast_suspend, 0);
+ err = stop_machine_run(take_machine_down, &suspend, 0);
if (err < 0)
xenbus_suspend_cancel();
} else {
- err = take_machine_down(&fast_suspend);
+ err = take_machine_down(&suspend);
}
if (err < 0)
diff -r ee7015727bd1 -r 68e78169679e drivers/xen/core/reboot.c
--- a/drivers/xen/core/reboot.c Fri Feb 29 09:14:21 2008 -0700
+++ b/drivers/xen/core/reboot.c Fri Feb 29 09:20:31 2008 -0700
@@ -20,11 +20,7 @@ MODULE_LICENSE("Dual BSD/GPL");
#define SHUTDOWN_INVALID -1
#define SHUTDOWN_POWEROFF 0
#define SHUTDOWN_SUSPEND 2
-/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
- * report a crash, not be instructed to crash!
- * HALT is the same as POWEROFF, as far as we're concerned. The tools use
- * the distinction when we return the reason code to them.
- */
+#define SHUTDOWN_RESUMING 3
#define SHUTDOWN_HALT 4
/* Ignore multiple shutdown requests. */
@@ -36,7 +32,7 @@ static void __shutdown_handler(void *unu
static void __shutdown_handler(void *unused);
static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
-int __xen_suspend(int fast_suspend);
+int __xen_suspend(int fast_suspend, void (*resume_notifier)(void));
static int shutdown_process(void *__unused)
{
@@ -65,23 +61,49 @@ static int shutdown_process(void *__unus
return 0;
}
+static void xen_resume_notifier(void)
+{
+ int old_state = xchg(&shutting_down, SHUTDOWN_RESUMING);
+ BUG_ON(old_state != SHUTDOWN_SUSPEND);
+}
+
static int xen_suspend(void *__unused)
{
- int err;
+ int err, old_state;
daemonize("suspend");
err = set_cpus_allowed(current, cpumask_of_cpu(0));
if (err) {
printk(KERN_ERR "Xen suspend can't run on CPU0 (%d)\n", err);
- goto out;
- }
-
- err = __xen_suspend(fast_suspend);
- if (err)
- printk(KERN_ERR "Xen suspend failed (%d)\n", err);
-
- out:
- shutting_down = SHUTDOWN_INVALID;
+ goto fail;
+ }
+
+ do {
+ err = __xen_suspend(fast_suspend, xen_resume_notifier);
+ if (err) {
+ printk(KERN_ERR "Xen suspend failed (%d)\n", err);
+ goto fail;
+ }
+ old_state = cmpxchg(
+ &shutting_down, SHUTDOWN_RESUMING, SHUTDOWN_INVALID);
+ } while (old_state == SHUTDOWN_SUSPEND);
+
+ switch (old_state) {
+ case SHUTDOWN_INVALID:
+ case SHUTDOWN_SUSPEND:
+ BUG();
+ case SHUTDOWN_RESUMING:
+ break;
+ default:
+ schedule_work(&shutdown_work);
+ break;
+ }
+
+ return 0;
+
+ fail:
+ old_state = xchg(&shutting_down, SHUTDOWN_INVALID);
+ BUG_ON(old_state != SHUTDOWN_SUSPEND);
return 0;
}
@@ -106,9 +128,10 @@ static void shutdown_handler(struct xenb
extern void ctrl_alt_del(void);
char *str;
struct xenbus_transaction xbt;
- int err;
-
- if (shutting_down != SHUTDOWN_INVALID)
+ int err, old_state, new_state = SHUTDOWN_INVALID;
+
+ if ((shutting_down != SHUTDOWN_INVALID) &&
+ (shutting_down != SHUTDOWN_RESUMING))
return;
again:
@@ -132,20 +155,23 @@ static void shutdown_handler(struct xenb
}
if (strcmp(str, "poweroff") == 0)
- shutting_down = SHUTDOWN_POWEROFF;
+ new_state = SHUTDOWN_POWEROFF;
else if (strcmp(str, "reboot") == 0)
ctrl_alt_del();
else if (strcmp(str, "suspend") == 0)
- shutting_down = SHUTDOWN_SUSPEND;
+ new_state = SHUTDOWN_SUSPEND;
else if (strcmp(str, "halt") == 0)
- shutting_down = SHUTDOWN_HALT;
- else {
+ new_state = SHUTDOWN_HALT;
+ else
printk("Ignoring shutdown request: %s\n", str);
- shutting_down = SHUTDOWN_INVALID;
- }
-
- if (shutting_down != SHUTDOWN_INVALID)
- schedule_work(&shutdown_work);
+
+ if (new_state != SHUTDOWN_INVALID) {
+ old_state = xchg(&shutting_down, new_state);
+ if (old_state == SHUTDOWN_INVALID)
+ schedule_work(&shutdown_work);
+ else
+ BUG_ON(old_state != SHUTDOWN_RESUMING);
+ }
kfree(str);
}
diff -r ee7015727bd1 -r 68e78169679e drivers/xen/fbfront/xenkbd.c
--- a/drivers/xen/fbfront/xenkbd.c Fri Feb 29 09:14:21 2008 -0700
+++ b/drivers/xen/fbfront/xenkbd.c Fri Feb 29 09:20:31 2008 -0700
@@ -66,7 +66,7 @@ static irqreturn_t input_handler(int rq,
case XENKBD_TYPE_MOTION:
if (event->motion.rel_z)
input_report_rel(dev, REL_WHEEL,
- 0 - event->motion.rel_z);
+ -event->motion.rel_z);
input_report_rel(dev, REL_X, event->motion.rel_x);
input_report_rel(dev, REL_Y, event->motion.rel_y);
break;
@@ -84,9 +84,9 @@ static irqreturn_t input_handler(int rq,
event->key.keycode);
break;
case XENKBD_TYPE_POS:
- if (event->pos.abs_z)
+ if (event->pos.rel_z)
input_report_rel(dev, REL_WHEEL,
- 0 - event->pos.abs_z);
+ -event->pos.rel_z);
input_report_abs(dev, ABS_X, event->pos.abs_x);
input_report_abs(dev, ABS_Y, event->pos.abs_y);
break;
diff -r ee7015727bd1 -r 68e78169679e drivers/xen/netfront/accel.c
--- a/drivers/xen/netfront/accel.c Fri Feb 29 09:14:21 2008 -0700
+++ b/drivers/xen/netfront/accel.c Fri Feb 29 09:20:31 2008 -0700
@@ -60,6 +60,9 @@ static struct list_head accelerators_lis
/* Lock to protect access to accelerators_list */
static spinlock_t accelerators_lock;
+/* Workqueue to process acceleration configuration changes */
+struct workqueue_struct *accel_watch_workqueue;
+
/* Mutex to prevent concurrent loads and suspends, etc. */
DEFINE_MUTEX(accelerator_mutex);
@@ -67,12 +70,17 @@ void netif_init_accel(void)
{
INIT_LIST_HEAD(&accelerators_list);
spin_lock_init(&accelerators_lock);
+
+ accel_watch_workqueue = create_workqueue("accel_watch");
}
void netif_exit_accel(void)
{
struct netfront_accelerator *accelerator, *tmp;
unsigned long flags;
+
+ flush_workqueue(accel_watch_workqueue);
+ destroy_workqueue(accel_watch_workqueue);
spin_lock_irqsave(&accelerators_lock, flags);
@@ -156,7 +164,7 @@ static void accel_watch_changed(struct x
struct netfront_accel_vif_state *vif_state =
container_of(watch, struct netfront_accel_vif_state,
accel_watch);
- schedule_work(&vif_state->accel_work);
+ queue_work(accel_watch_workqueue, &vif_state->accel_work);
}
@@ -191,7 +199,7 @@ void netfront_accelerator_remove_watch(s
kfree(vif_state->accel_watch.node);
vif_state->accel_watch.node = NULL;
- flush_scheduled_work();
+ flush_workqueue(accel_watch_workqueue);
/* Clean up any state left from watch */
if (vif_state->accel_frontend != NULL) {
diff -r ee7015727bd1 -r 68e78169679e drivers/xen/pcifront/xenbus.c
--- a/drivers/xen/pcifront/xenbus.c Fri Feb 29 09:14:21 2008 -0700
+++ b/drivers/xen/pcifront/xenbus.c Fri Feb 29 09:20:31 2008 -0700
@@ -17,7 +17,7 @@ static struct pcifront_device *alloc_pde
{
struct pcifront_device *pdev;
- pdev = kmalloc(sizeof(struct pcifront_device), GFP_KERNEL);
+ pdev = kzalloc(sizeof(struct pcifront_device), GFP_KERNEL);
if (pdev == NULL)
goto out;
diff -r ee7015727bd1 -r 68e78169679e drivers/xen/xenbus/xenbus_dev.c
--- a/drivers/xen/xenbus/xenbus_dev.c Fri Feb 29 09:14:21 2008 -0700
+++ b/drivers/xen/xenbus/xenbus_dev.c Fri Feb 29 09:20:31 2008 -0700
@@ -278,7 +278,7 @@ static ssize_t xenbus_dev_write(struct f
token++;
if (msg_type == XS_WATCH) {
- watch = kmalloc(sizeof(*watch), GFP_KERNEL);
+ watch = kzalloc(sizeof(*watch), GFP_KERNEL);
watch->watch.node = kmalloc(strlen(path)+1,
GFP_KERNEL);
strcpy((char *)watch->watch.node, path);
diff -r ee7015727bd1 -r 68e78169679e include/xen/interface/io/kbdif.h
--- a/include/xen/interface/io/kbdif.h Fri Feb 29 09:14:21 2008 -0700
+++ b/include/xen/interface/io/kbdif.h Fri Feb 29 09:20:31 2008 -0700
@@ -65,7 +65,7 @@ struct xenkbd_position
uint8_t type; /* XENKBD_TYPE_POS */
int32_t abs_x; /* absolute X position (in FB pixels) */
int32_t abs_y; /* absolute Y position (in FB pixels) */
- int32_t abs_z; /* absolute Z position (wheel) */
+ int32_t rel_z; /* relative Z motion (wheel) */
};
#define XENKBD_IN_EVENT_SIZE 40
diff -r ee7015727bd1 -r 68e78169679e include/xen/interface/kexec.h
--- a/include/xen/interface/kexec.h Fri Feb 29 09:14:21 2008 -0700
+++ b/include/xen/interface/kexec.h Fri Feb 29 09:20:31 2008 -0700
@@ -126,9 +126,18 @@ typedef struct xen_kexec_load {
xen_kexec_image_t image;
} xen_kexec_load_t;
-#define KEXEC_RANGE_MA_CRASH 0 /* machine address and size of crash area */
-#define KEXEC_RANGE_MA_XEN 1 /* machine address and size of Xen itself */
-#define KEXEC_RANGE_MA_CPU 2 /* machine address and size of a CPU note */
+#define KEXEC_RANGE_MA_CRASH 0 /* machine address and size of crash area
*/
+#define KEXEC_RANGE_MA_XEN 1 /* machine address and size of Xen itself
*/
+#define KEXEC_RANGE_MA_CPU 2 /* machine address and size of a CPU note
*/
+#define KEXEC_RANGE_MA_XENHEAP 3 /* machine address and size of xenheap
+ * Note that although this is adjacent
+ * to Xen it exists in a separate EFI
+ * region on ia64, and thus needs to be
+ * inserted into iomem_machine separately */
+#define KEXEC_RANGE_MA_BOOT_PARAM 4 /* machine address and size of
+ * the ia64_boot_param */
+#define KEXEC_RANGE_MA_EFI_MEMMAP 5 /* machine address and size of
+ * of the EFI Memory Map */
/*
* Find the address and size of certain memory areas
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|