From a795e6cbffd534ae1b7f994149a9c7d61683ec01 Mon Sep 17 00:00:00 2001 From: "\"Huang2, Wei\"" Date: Tue, 10 Apr 2007 10:26:31 +0100 Subject: [PATCH 01/13] [HAP] Install P2M entries in monitor table under PAE mode This patch installs P2M table entries in monitor table when Xen is running under PAE mode. Without it, hypervisor might have trouble of accessing guests' high memory. Signed-off-by: Wei Huang --- xen/arch/x86/mm/hap/hap.c | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c index 6a832990d2..2037fc6eb2 100644 --- a/xen/arch/x86/mm/hap/hap.c +++ b/xen/arch/x86/mm/hap/hap.c @@ -443,6 +443,7 @@ void hap_final_teardown(struct domain *d) hap_teardown(d); p2m_teardown(d); + ASSERT( d->arch.paging.hap.p2m_pages == 0 ); } void hap_teardown(struct domain *d) @@ -635,12 +636,60 @@ void hap_update_paging_modes(struct vcpu *v) hap_unlock(d); } +#if CONFIG_PAGING_LEVELS == 3 +static void p2m_install_entry_in_monitors(struct domain *d, l3_pgentry_t *l3e) +/* Special case, only used for external-mode domains on PAE hosts: + * update the mapping of the p2m table. Once again, this is trivial in + * other paging modes (one top-level entry points to the top-level p2m, + * no maintenance needed), but PAE makes life difficult by needing a + * copy l3es of the p2m table in eight l2h slots in the monitor table. This + * function makes fresh copies when a p2m l3e changes. */ +{ + l2_pgentry_t *ml2e; + struct vcpu *v; + unsigned int index; + + index = ((unsigned long)l3e & ~PAGE_MASK) / sizeof(l3_pgentry_t); + ASSERT(index < MACHPHYS_MBYTES>>1); + + for_each_vcpu(d, v) { + if ( pagetable_get_pfn(v->arch.monitor_table) == 0 ) + continue; + + ASSERT(paging_mode_external(v->domain)); + + if ( v == current ) /* OK to use linear map of monitor_table */ + ml2e = __linear_l2_table + l2_linear_offset(RO_MPT_VIRT_START); + else { + l3_pgentry_t *ml3e; + ml3e = hap_map_domain_page(pagetable_get_mfn(v->arch.monitor_table)); + ASSERT(l3e_get_flags(ml3e[3]) & _PAGE_PRESENT); + ml2e = hap_map_domain_page(_mfn(l3e_get_pfn(ml3e[3]))); + ml2e += l2_table_offset(RO_MPT_VIRT_START); + hap_unmap_domain_page(ml3e); + } + ml2e[index] = l2e_from_pfn(l3e_get_pfn(*l3e), __PAGE_HYPERVISOR); + if ( v != current ) + hap_unmap_domain_page(ml2e); + } +} +#endif + void hap_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p, l1_pgentry_t new, unsigned int level) { hap_lock(v->domain); safe_write_pte(p, new); +#if CONFIG_PAGING_LEVELS == 3 + /* install P2M in monitor table for PAE Xen */ + if ( level == 3 ) { + /* We have written to the p2m l3: need to sync the per-vcpu + * copies of it in the monitor tables */ + p2m_install_entry_in_monitors(v->domain, (l3_pgentry_t *)p); + + } +#endif hap_unlock(v->domain); } From 1d37a61c5280ee03923dcfb2bb074b13e42328ef Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Apr 2007 10:28:11 +0100 Subject: [PATCH 02/13] xend: Destroy information about the domain in case an error occurs during resume of a domain. Signed-off-by: Stefan Berger --- tools/python/xen/xend/XendDomainInfo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 425776ce12..9083e90e77 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -430,6 +430,7 @@ class XendDomainInfo: self._endRestore() except: log.exception('VM resume failed') + self.destroy() raise else: raise XendError('VM already running') From e2492c5e9e72ffc0ddb2765080b579200fd8f1c8 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Apr 2007 13:46:28 +0100 Subject: [PATCH 03/13] Fix PV guest restore. Signed-off-by: Keir Fraser --- tools/libxc/xc_domain_restore.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c index f424d291a6..1159776f4f 100644 --- a/tools/libxc/xc_domain_restore.c +++ b/tools/libxc/xc_domain_restore.c @@ -119,6 +119,7 @@ static int uncanonicalize_pagetable(int xc_handle, uint32_t dom, { /* Have a 'valid' PFN without a matching MFN - need to alloc */ p2m_batch[nr_mfns++] = pfn; + p2m[pfn]--; } } @@ -146,8 +147,8 @@ static int uncanonicalize_pagetable(int xc_handle, uint32_t dom, continue; pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86; - - if ( p2m[pfn] == INVALID_P2M_ENTRY ) + + if ( p2m[pfn] == (INVALID_P2M_ENTRY-1) ) p2m[pfn] = p2m_batch[nr_mfns++]; pte &= ~MADDR_MASK_X86; @@ -489,6 +490,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom, { /* Have a live PFN which hasn't had an MFN allocated */ p2m_batch[nr_mfns++] = pfn; + p2m[pfn]--; } } @@ -514,7 +516,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom, region_mfn[i] = ~0UL; /* map will fail but we don't care */ else { - if ( p2m[pfn] == INVALID_P2M_ENTRY ) + if ( p2m[pfn] == (INVALID_P2M_ENTRY-1) ) { /* We just allocated a new mfn above; update p2m */ p2m[pfn] = p2m_batch[nr_mfns++]; From 20f278002607ff5af89581ae6ce1258dcd3f282a Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Apr 2007 15:31:53 +0100 Subject: [PATCH 04/13] 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 --- .../drivers/xen/core/reboot.c | 60 ++++--- .../drivers/xen/xenbus/xenbus_dev.c | 3 +- .../drivers/xen/xenbus/xenbus_probe.c | 11 +- linux-2.6-xen-sparse/include/xen/xenbus.h | 2 +- unmodified_drivers/linux-2.6/Makefile | 2 - unmodified_drivers/linux-2.6/mkbuildtree | 2 +- .../linux-2.6/platform-pci/Kbuild | 11 +- .../linux-2.6/platform-pci/evtchn.c | 152 ++++++++++++++---- .../linux-2.6/platform-pci/machine_reboot.c | 24 +++ .../linux-2.6/platform-pci/platform-pci.c | 91 +++++------ .../linux-2.6/platform-pci/platform-pci.h | 38 ++--- unmodified_drivers/linux-2.6/util/Kbuild | 3 - unmodified_drivers/linux-2.6/util/Makefile | 3 - unmodified_drivers/linux-2.6/xenbus/Kbuild | 10 -- unmodified_drivers/linux-2.6/xenbus/Makefile | 3 - .../linux-2.6/xenbus/empty_directory | 0 16 files changed, 254 insertions(+), 161 deletions(-) create mode 100644 unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c delete mode 100644 unmodified_drivers/linux-2.6/util/Kbuild delete mode 100644 unmodified_drivers/linux-2.6/util/Makefile delete mode 100644 unmodified_drivers/linux-2.6/xenbus/Kbuild delete mode 100644 unmodified_drivers/linux-2.6/xenbus/Makefile create mode 100644 unmodified_drivers/linux-2.6/xenbus/empty_directory diff --git a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c index ffe05f47df..e8601f2394 100644 --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c @@ -34,28 +34,7 @@ static int fast_suspend; static void __shutdown_handler(void *unused); static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); -#ifdef CONFIG_XEN int __xen_suspend(int fast_suspend); -#else -extern void xenbus_suspend(void); -extern void xenbus_resume(void); -extern void platform_pci_suspend(void); -extern void platform_pci_resume(void); -int __xen_suspend(int fast_suspend) -{ - xenbus_suspend(); - platform_pci_suspend(); - - /* pvdrv sleep in this hyper-call when save */ - HYPERVISOR_shutdown(SHUTDOWN_suspend); - - platform_pci_resume(); - xenbus_resume(); - printk("PV stuff on HVM resume successfully!\n"); - - return 0; -} -#endif static int shutdown_process(void *__unused) { @@ -210,13 +189,11 @@ static struct xenbus_watch shutdown_watch = { }; static struct xenbus_watch sysrq_watch = { - .node ="control/sysrq", + .node = "control/sysrq", .callback = sysrq_handler }; -static int setup_shutdown_watcher(struct notifier_block *notifier, - unsigned long event, - void *data) +static int setup_shutdown_watcher(void) { int err; @@ -225,17 +202,29 @@ static int setup_shutdown_watcher(struct notifier_block *notifier, "%d", &fast_suspend); err = register_xenbus_watch(&shutdown_watch); - if (err) + if (err) { printk(KERN_ERR "Failed to set shutdown watcher\n"); - else - xenbus_write(XBT_NIL, "control", "feature-reboot", "1"); + return err; + } + xenbus_write(XBT_NIL, "control", "feature-reboot", "1"); err = register_xenbus_watch(&sysrq_watch); - if (err) + if (err) { printk(KERN_ERR "Failed to set sysrq watcher\n"); - else - xenbus_write(XBT_NIL, "control", "feature-sysrq", "1"); + return err; + } + xenbus_write(XBT_NIL, "control", "feature-sysrq", "1"); + return 0; +} + +#ifdef CONFIG_XEN + +static int shutdown_event(struct notifier_block *notifier, + unsigned long event, + void *data) +{ + setup_shutdown_watcher(); return NOTIFY_DONE; } @@ -250,3 +239,12 @@ static int __init setup_shutdown_event(void) } subsys_initcall(setup_shutdown_event); + +#else /* !defined(CONFIG_XEN) */ + +int xen_reboot_init(void) +{ + return setup_shutdown_watcher(); +} + +#endif /* !defined(CONFIG_XEN) */ diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c index 459f434027..854982ee15 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c @@ -394,8 +394,7 @@ static const struct file_operations xenbus_dev_file_ops = { .poll = xenbus_dev_poll, }; -int __init -xenbus_dev_init(void) +int xenbus_dev_init(void) { xenbus_dev_intf = create_xen_proc_entry("xenbus", 0400); if (xenbus_dev_intf) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index 6df439f9c1..d16d67602a 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -863,7 +863,7 @@ static int xsd_port_read(char *page, char **start, off_t off, } #endif -static int __init xenbus_probe_init(void) +static int xenbus_probe_init(void) { int err = 0; unsigned long page = 0; @@ -978,10 +978,15 @@ static int __init xenbus_probe_init(void) return err; } +#ifdef CONFIG_XEN postcore_initcall(xenbus_probe_init); - MODULE_LICENSE("Dual BSD/GPL"); - +#else +int xenbus_init(void) +{ + return xenbus_probe_init(); +} +#endif static int is_disconnected_device(struct device *dev, void *data) { diff --git a/linux-2.6-xen-sparse/include/xen/xenbus.h b/linux-2.6-xen-sparse/include/xen/xenbus.h index cbf6fe351d..f4873b2633 100644 --- a/linux-2.6-xen-sparse/include/xen/xenbus.h +++ b/linux-2.6-xen-sparse/include/xen/xenbus.h @@ -293,7 +293,7 @@ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, ...); -int __init xenbus_dev_init(void); +int xenbus_dev_init(void); const char *xenbus_strstate(enum xenbus_state state); int xenbus_dev_is_online(struct xenbus_device *dev); 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 +#include +#include "platform-pci.h" +#include + +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 #include #include +#include #include +#include #include #ifdef __ia64__ #include @@ -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; + if (rc) { + printk(KERN_INFO DRV_NAME + ": No platform pci device model found\n"); + return rc; + } - 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. + * platform-pci.h + * + * Xen platform PCI device driver + * Copyright (c) 2004, 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, @@ -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 +#ifndef _XEN_PLATFORM_PCI_H +#define _XEN_PLATFORM_PCI_H + #include -#include - -static inline 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); -} 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); -#endif +void platform_pci_suspend(void); +void platform_pci_suspend_cancel(void); +void platform_pci_resume(void); + +#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 From b9526a2fbd96221fec6ceeb010642e8ff269ffe2 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Apr 2007 15:35:37 +0100 Subject: [PATCH 05/13] linux: Fix reboot.c after PV-on-HVM changes. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/drivers/xen/core/reboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c index e8601f2394..cb95ac9326 100644 --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c @@ -231,7 +231,7 @@ static int shutdown_event(struct notifier_block *notifier, static int __init setup_shutdown_event(void) { static struct notifier_block xenstore_notifier = { - .notifier_call = setup_shutdown_watcher + .notifier_call = shutdown_event }; register_xenstore_notifier(&xenstore_notifier); From 0e20ef60f83697cf5c9e6e696e601622984db7ad Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Sun, 8 Apr 2007 23:03:16 +0100 Subject: [PATCH 06/13] Add bindings and docs for the host.dmesg_clear call. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 32 +++++++++++++++++++++++++++++++ tools/libxen/include/xen_host.h | 11 +++++++++-- tools/libxen/src/xen_host.c | 17 ++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index 01b980d8a2..2ed8ab1350 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -4915,6 +4915,38 @@ string } +dmesg string +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~dmesg\_clear} + +{\bf Overview:} +Get the host xen dmesg, and clear the buffer. + + \noindent {\bf Signature:} +\begin{verbatim} string dmesg_clear (session_id s, host ref host)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & host & The Host to query \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + dmesg string \vspace{0.3cm} \vspace{0.3cm} diff --git a/tools/libxen/include/xen_host.h b/tools/libxen/include/xen_host.h index 1fbe014325..a27c875687 100644 --- a/tools/libxen/include/xen_host.h +++ b/tools/libxen/include/xen_host.h @@ -414,7 +414,7 @@ xen_host_enable(xen_session *session, xen_host host); /** * Shutdown the host. (This function can only be called if there are no - * currently running VMs on the host and it is disabled.) + * currently running VMs on the host and it is disabled.). */ extern bool xen_host_shutdown(xen_session *session, xen_host host); @@ -422,7 +422,7 @@ xen_host_shutdown(xen_session *session, xen_host host); /** * Reboot the host. (This function can only be called if there are no - * currently running VMs on the host and it is disabled.) + * currently running VMs on the host and it is disabled.). */ extern bool xen_host_reboot(xen_session *session, xen_host host); @@ -435,6 +435,13 @@ extern bool xen_host_dmesg(xen_session *session, char **result, xen_host host); +/** + * Get the host xen dmesg, and clear the buffer. + */ +extern bool +xen_host_dmesg_clear(xen_session *session, char **result, xen_host host); + + /** * List all supported methods. */ diff --git a/tools/libxen/src/xen_host.c b/tools/libxen/src/xen_host.c index d46f061c30..2ae37fefe4 100644 --- a/tools/libxen/src/xen_host.c +++ b/tools/libxen/src/xen_host.c @@ -739,6 +739,23 @@ xen_host_dmesg(xen_session *session, char **result, xen_host host) } +bool +xen_host_dmesg_clear(xen_session *session, char **result, xen_host host) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = host } + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("host.dmesg_clear"); + return session->ok; +} + + bool xen_host_list_methods(xen_session *session, struct xen_string_set **result) { From 1a2d0aa9027d6023f3240abd23e0027a2ce25925 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Mon, 9 Apr 2007 11:39:27 +0100 Subject: [PATCH 07/13] Added bindings and documentation for host.send_debug_keys and host.get_log. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 66 +++++++++++++++++++++++++++++++ tools/libxen/include/xen_host.h | 14 +++++++ tools/libxen/src/xen_host.c | 33 ++++++++++++++++ 3 files changed, 113 insertions(+) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index 2ed8ab1350..3c38727c50 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -4948,6 +4948,72 @@ string dmesg string +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_log} + +{\bf Overview:} +Get the host's log file. + + \noindent {\bf Signature:} +\begin{verbatim} string get_log (session_id s, host ref host)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & host & The Host to query \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +The contents of the host's primary log file +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~send\_debug\_keys} + +{\bf Overview:} +Inject the given string as debugging keys into Xen. + + \noindent {\bf Signature:} +\begin{verbatim} void send_debug_keys (session_id s, host ref host, string keys)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & host & The host \\ \hline + +{\tt string } & keys & The keys to send \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} diff --git a/tools/libxen/include/xen_host.h b/tools/libxen/include/xen_host.h index a27c875687..f380f989d0 100644 --- a/tools/libxen/include/xen_host.h +++ b/tools/libxen/include/xen_host.h @@ -442,6 +442,20 @@ extern bool xen_host_dmesg_clear(xen_session *session, char **result, xen_host host); +/** + * Get the host's log file. + */ +extern bool +xen_host_get_log(xen_session *session, char **result, xen_host host); + + +/** + * Inject the given string as debugging keys into Xen. + */ +extern bool +xen_host_send_debug_keys(xen_session *session, xen_host host, char *keys); + + /** * List all supported methods. */ diff --git a/tools/libxen/src/xen_host.c b/tools/libxen/src/xen_host.c index 2ae37fefe4..a55b91e0af 100644 --- a/tools/libxen/src/xen_host.c +++ b/tools/libxen/src/xen_host.c @@ -756,6 +756,39 @@ xen_host_dmesg_clear(xen_session *session, char **result, xen_host host) } +bool +xen_host_get_log(xen_session *session, char **result, xen_host host) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = host } + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("host.get_log"); + return session->ok; +} + + +bool +xen_host_send_debug_keys(xen_session *session, xen_host host, char *keys) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = host }, + { .type = &abstract_type_string, + .u.string_val = keys } + }; + + xen_call_(session, "host.send_debug_keys", param_values, 2, NULL, NULL); + return session->ok; +} + + bool xen_host_list_methods(xen_session *session, struct xen_string_set **result) { From 668fbded84ff31d548ae5e84419b2acab88600e2 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Mon, 9 Apr 2007 12:20:35 +0100 Subject: [PATCH 08/13] Make host.sched_policy read-only. Added docs, bindings, and a test for host.cpu_configuration and host.sched_policy. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 66 +++++++++++++++++++++++++++++++ tools/libxen/include/xen_host.h | 16 ++++++++ tools/libxen/src/xen_host.c | 42 ++++++++++++++++++++ tools/libxen/test/test_bindings.c | 45 +++++++++++++++++++++ tools/python/xen/xend/XendAPI.py | 2 +- 5 files changed, 170 insertions(+), 1 deletion(-) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index 3c38727c50..d2a97b5848 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -4744,6 +4744,8 @@ $\mathit{RO}_\mathit{run}$ & {\tt API\_version/vendor\_implementation} & (strin $\mathit{RO}_\mathit{run}$ & {\tt software\_version} & (string $\rightarrow$ string) Map & version strings \\ $\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\ $\mathit{RO}_\mathit{run}$ & {\tt capabilities} & string Set & Xen capabilities \\ +$\mathit{RO}_\mathit{run}$ & {\tt cpu\_configuration} & (string $\rightarrow$ string) Map & The CPU configuration on this host. May contain keys such as ``nr\_nodes'', ``sockets\_per\_node'', ``cores\_per\_socket'', or ``threads\_per\_core'' \\ +$\mathit{RO}_\mathit{run}$ & {\tt sched\_policy} & string & Scheduler policy currently in force on this host \\ $\mathit{RO}_\mathit{run}$ & {\tt supported\_bootloaders} & string Set & a list of the bootloaders installed on the machine \\ $\mathit{RO}_\mathit{run}$ & {\tt resident\_VMs} & (VM ref) Set & list of VMs currently resident on host \\ $\mathit{RW}$ & {\tt logging} & (string $\rightarrow$ string) Map & logging configuration \\ @@ -5548,6 +5550,70 @@ string Set } +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_cpu\_configuration} + +{\bf Overview:} +Get the cpu\_configuration field of the given host. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_cpu_configuration (session_id s, host ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_sched\_policy} + +{\bf Overview:} +Get the sched\_policy field of the given host. + + \noindent {\bf Signature:} +\begin{verbatim} string get_sched_policy (session_id s, host ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + value of the field \vspace{0.3cm} \vspace{0.3cm} diff --git a/tools/libxen/include/xen_host.h b/tools/libxen/include/xen_host.h index f380f989d0..181aa5e22d 100644 --- a/tools/libxen/include/xen_host.h +++ b/tools/libxen/include/xen_host.h @@ -79,6 +79,8 @@ typedef struct xen_host_record xen_string_string_map *software_version; xen_string_string_map *other_config; struct xen_string_set *capabilities; + xen_string_string_map *cpu_configuration; + char *sched_policy; struct xen_string_set *supported_bootloaders; struct xen_vm_record_opt_set *resident_vms; xen_string_string_map *logging; @@ -260,6 +262,20 @@ extern bool xen_host_get_capabilities(xen_session *session, struct xen_string_set **result, xen_host host); +/** + * Get the cpu_configuration field of the given host. + */ +extern bool +xen_host_get_cpu_configuration(xen_session *session, xen_string_string_map **result, xen_host host); + + +/** + * Get the sched_policy field of the given host. + */ +extern bool +xen_host_get_sched_policy(xen_session *session, char **result, xen_host host); + + /** * Get the supported_bootloaders field of the given host. */ diff --git a/tools/libxen/src/xen_host.c b/tools/libxen/src/xen_host.c index a55b91e0af..bc2b1f0e8b 100644 --- a/tools/libxen/src/xen_host.c +++ b/tools/libxen/src/xen_host.c @@ -73,6 +73,12 @@ static const struct_member xen_host_record_struct_members[] = { .key = "capabilities", .type = &abstract_type_string_set, .offset = offsetof(xen_host_record, capabilities) }, + { .key = "cpu_configuration", + .type = &abstract_type_string_string_map, + .offset = offsetof(xen_host_record, cpu_configuration) }, + { .key = "sched_policy", + .type = &abstract_type_string, + .offset = offsetof(xen_host_record, sched_policy) }, { .key = "supported_bootloaders", .type = &abstract_type_string_set, .offset = offsetof(xen_host_record, supported_bootloaders) }, @@ -128,6 +134,8 @@ xen_host_record_free(xen_host_record *record) xen_string_string_map_free(record->software_version); xen_string_string_map_free(record->other_config); xen_string_set_free(record->capabilities); + xen_string_string_map_free(record->cpu_configuration); + free(record->sched_policy); xen_string_set_free(record->supported_bootloaders); xen_vm_record_opt_set_free(record->resident_vms); xen_string_string_map_free(record->logging); @@ -349,6 +357,40 @@ xen_host_get_capabilities(xen_session *session, struct xen_string_set **result, } +bool +xen_host_get_cpu_configuration(xen_session *session, xen_string_string_map **result, xen_host host) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = host } + }; + + abstract_type result_type = abstract_type_string_string_map; + + *result = NULL; + XEN_CALL_("host.get_cpu_configuration"); + return session->ok; +} + + +bool +xen_host_get_sched_policy(xen_session *session, char **result, xen_host host) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = host } + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("host.get_sched_policy"); + return session->ok; +} + + bool xen_host_get_supported_bootloaders(xen_session *session, struct xen_string_set **result, xen_host host) { diff --git a/tools/libxen/test/test_bindings.c b/tools/libxen/test/test_bindings.c index 6da442d539..df067aa438 100644 --- a/tools/libxen/test/test_bindings.c +++ b/tools/libxen/test/test_bindings.c @@ -285,6 +285,40 @@ int main(int argc, char **argv) return 1; } + xen_string_string_map *cpu_configuration; + if (!xen_host_get_cpu_configuration(session, &cpu_configuration, host)) + { + print_error(session); + free(dmesg); + xen_string_set_free(capabilities); + xen_string_set_free(supported_bootloaders); + xen_string_string_map_free(versions); + xen_host_free(host); + xen_vm_record_free(vm_record); + xen_uuid_bytes_free(vm_uuid_bytes); + xen_uuid_free(vm_uuid); + xen_vm_free(vm); + CLEANUP; + return 1; + } + + char *sched_policy; + if (!xen_host_get_sched_policy(session, &sched_policy, host)) + { + print_error(session); + xen_string_string_map_free(cpu_configuration); + xen_string_set_free(capabilities); + xen_string_set_free(supported_bootloaders); + xen_string_string_map_free(versions); + xen_host_free(host); + xen_vm_record_free(vm_record); + xen_uuid_bytes_free(vm_uuid_bytes); + xen_uuid_free(vm_uuid); + xen_vm_free(vm); + CLEANUP; + return 1; + } + printf("%s.\n", vm_uuid); printf("In bytes, the VM UUID is "); @@ -318,6 +352,15 @@ int main(int argc, char **argv) } printf("\n"); + printf("Host has the following CPU configuration:\n"); + for (size_t i = 0; i < cpu_configuration->size; i++) + { + printf(" %s -> %s.\n", cpu_configuration->contents[i].key, + cpu_configuration->contents[i].val); + } + + printf("Current scheduler policy: %s.\n\n", sched_policy); + printf("%s.\n", vm_record->uuid); printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle); @@ -334,6 +377,8 @@ int main(int argc, char **argv) free(dmesg); xen_string_set_free(supported_bootloaders); xen_string_set_free(capabilities); + xen_string_string_map_free(cpu_configuration); + free(sched_policy); print_vm_metrics(session, vm); if (!session->ok) diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index b31a00899b..c9d417c3c7 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -860,13 +860,13 @@ class XendAPI(object): 'metrics', 'capabilities', 'supported_bootloaders', + 'sched_policy', 'API_version_major', 'API_version_minor', 'API_version_vendor', 'API_version_vendor_implementation'] host_attr_rw = ['name_label', - 'sched_policy', 'name_description', 'other_config'] From 6492f2ffbf3fadb112a5e819c1afb56cd258893c Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Mon, 9 Apr 2007 17:09:21 +0100 Subject: [PATCH 09/13] Added documentation, C bindings, and a test for VM_metrics.{start_time, VCPUs_CPU,VCPUs_params}. Changed VM_metrics.start_time to be a DateTime, not an integer. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 99 ++++++++++++++++++++++++++ tools/libxen/include/xen_int_int_map.h | 53 ++++++++++++++ tools/libxen/include/xen_internal.h | 1 + tools/libxen/include/xen_vm_metrics.h | 26 +++++++ tools/libxen/src/xen_common.c | 19 +++++ tools/libxen/src/xen_int_int_map.c | 39 ++++++++++ tools/libxen/src/xen_vm_metrics.c | 63 ++++++++++++++++ tools/libxen/test/test_bindings.c | 20 ++++++ tools/python/xen/xend/XendAPI.py | 11 ++- tools/python/xen/xend/XendVMMetrics.py | 4 +- tools/python/xen/xm/main.py | 7 +- 11 files changed, 339 insertions(+), 3 deletions(-) create mode 100644 tools/libxen/include/xen_int_int_map.h create mode 100644 tools/libxen/src/xen_int_int_map.c diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index d2a97b5848..b2784e234c 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -4107,6 +4107,9 @@ $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object ref $\mathit{RO}_\mathit{run}$ & {\tt memory/actual} & int & Guest's actual memory (bytes) \\ $\mathit{RO}_\mathit{run}$ & {\tt VCPUs/number} & int & Current number of VCPUs \\ $\mathit{RO}_\mathit{run}$ & {\tt VCPUs/utilisation} & (int $\rightarrow$ float) Map & Utilisation for all of guest's current VCPUs \\ +$\mathit{RO}_\mathit{run}$ & {\tt VCPUs/CPU} & (int $\rightarrow$ int) Map & VCPU to PCPU map \\ +$\mathit{RO}_\mathit{run}$ & {\tt VCPUs/params} & (string $\rightarrow$ string) Map & The live equivalent to VM.VCPUs\_params \\ +$\mathit{RO}_\mathit{run}$ & {\tt start\_time} & datetime & Time at which this VM was last booted \\ $\mathit{RO}_\mathit{run}$ & {\tt last\_updated} & datetime & Time at which this information was last updated \\ \hline \end{longtable} @@ -4256,6 +4259,102 @@ Get the VCPUs/utilisation field of the given VM\_metrics. } +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_VCPUs\_CPU} + +{\bf Overview:} +Get the VCPUs/CPU field of the given VM\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} ((int -> int) Map) get_VCPUs_CPU (session_id s, VM_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(int $\rightarrow$ int) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_VCPUs\_params} + +{\bf Overview:} +Get the VCPUs/params field of the given VM\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_VCPUs_params (session_id s, VM_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_start\_time} + +{\bf Overview:} +Get the start\_time field of the given VM\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} datetime get_start_time (session_id s, VM_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +datetime +} + + value of the field \vspace{0.3cm} \vspace{0.3cm} diff --git a/tools/libxen/include/xen_int_int_map.h b/tools/libxen/include/xen_int_int_map.h new file mode 100644 index 0000000000..5d11e146b0 --- /dev/null +++ b/tools/libxen/include/xen_int_int_map.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2006-2007, XenSource Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef XEN_INT_INT_MAP_H +#define XEN_INT_INT_MAP_H + + +#include "xen_common.h" + + +typedef struct xen_int_int_map_contents +{ + int64_t key; + int64_t val; +} xen_int_int_map_contents; + + +typedef struct xen_int_int_map +{ + size_t size; + xen_int_int_map_contents contents[]; +} xen_int_int_map; + +/** + * Allocate a xen_int_int_map of the given size. + */ +extern xen_int_int_map * +xen_int_int_map_alloc(size_t size); + +/** + * Free the given xen_int_int_map, and all referenced values. The + * given map must have been allocated by this library. + */ +extern void +xen_int_int_map_free(xen_int_int_map *map); + + +#endif diff --git a/tools/libxen/include/xen_internal.h b/tools/libxen/include/xen_internal.h index ac50de20b2..aad061fe56 100644 --- a/tools/libxen/include/xen_internal.h +++ b/tools/libxen/include/xen_internal.h @@ -86,6 +86,7 @@ extern const abstract_type abstract_type_ref_set; extern const abstract_type abstract_type_string_string_map; extern const abstract_type abstract_type_int_float_map; +extern const abstract_type abstract_type_int_int_map; typedef struct abstract_value diff --git a/tools/libxen/include/xen_vm_metrics.h b/tools/libxen/include/xen_vm_metrics.h index d686a7c99f..4b64b5953e 100644 --- a/tools/libxen/include/xen_vm_metrics.h +++ b/tools/libxen/include/xen_vm_metrics.h @@ -21,6 +21,8 @@ #include "xen_common.h" #include "xen_int_float_map.h" +#include "xen_int_int_map.h" +#include "xen_string_string_map.h" #include "xen_vm_metrics_decl.h" @@ -66,6 +68,9 @@ typedef struct xen_vm_metrics_record int64_t memory_actual; int64_t vcpus_number; xen_int_float_map *vcpus_utilisation; + xen_int_int_map *vcpus_cpu; + xen_string_string_map *vcpus_params; + time_t start_time; time_t last_updated; } xen_vm_metrics_record; @@ -190,6 +195,27 @@ extern bool xen_vm_metrics_get_vcpus_utilisation(xen_session *session, xen_int_float_map **result, xen_vm_metrics vm_metrics); +/** + * Get the VCPUs/CPU field of the given VM_metrics. + */ +extern bool +xen_vm_metrics_get_vcpus_cpu(xen_session *session, xen_int_int_map **result, xen_vm_metrics vm_metrics); + + +/** + * Get the VCPUs/params field of the given VM_metrics. + */ +extern bool +xen_vm_metrics_get_vcpus_params(xen_session *session, xen_string_string_map **result, xen_vm_metrics vm_metrics); + + +/** + * Get the start_time field of the given VM_metrics. + */ +extern bool +xen_vm_metrics_get_start_time(xen_session *session, time_t *result, xen_vm_metrics vm_metrics); + + /** * Get the last_updated field of the given VM_metrics. */ diff --git a/tools/libxen/src/xen_common.c b/tools/libxen/src/xen_common.c index 70ecc1e4fc..6b52723d9d 100644 --- a/tools/libxen/src/xen_common.c +++ b/tools/libxen/src/xen_common.c @@ -35,6 +35,7 @@ #include "xen_host.h" #include "xen_internal.h" #include "xen_int_float_map.h" +#include "xen_int_int_map.h" #include "xen_string_string_map.h" @@ -1697,3 +1698,21 @@ const abstract_type abstract_type_int_float_map = .struct_size = sizeof(xen_int_float_map_contents), .members = int_float_members }; + +static struct struct_member int_int_members[] = +{ + { + .type = &abstract_type_int, + .offset = offsetof(xen_int_int_map_contents, key) + }, + { + .type = &abstract_type_int, + .offset = offsetof(xen_int_int_map_contents, val) + } +}; +const abstract_type abstract_type_int_int_map = + { + .typename = MAP, + .struct_size = sizeof(xen_int_int_map_contents), + .members = int_int_members + }; diff --git a/tools/libxen/src/xen_int_int_map.c b/tools/libxen/src/xen_int_int_map.c new file mode 100644 index 0000000000..b7eeba6e96 --- /dev/null +++ b/tools/libxen/src/xen_int_int_map.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2006-2007, XenSource Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "xen_common.h" +#include "xen_int_int_map.h" +#include "xen_internal.h" + + +xen_int_int_map * +xen_int_int_map_alloc(size_t size) +{ + xen_int_int_map *result = calloc(1, sizeof(xen_int_int_map) + + size * sizeof(struct xen_int_int_map_contents)); + result->size = size; + return result; +} + + +void +xen_int_int_map_free(xen_int_int_map *map) +{ + free(map); +} diff --git a/tools/libxen/src/xen_vm_metrics.c b/tools/libxen/src/xen_vm_metrics.c index 11e421282b..bd0509bfc4 100644 --- a/tools/libxen/src/xen_vm_metrics.c +++ b/tools/libxen/src/xen_vm_metrics.c @@ -22,7 +22,9 @@ #include "xen_common.h" #include "xen_int_float_map.h" +#include "xen_int_int_map.h" #include "xen_internal.h" +#include "xen_string_string_map.h" #include "xen_vm_metrics.h" @@ -49,6 +51,15 @@ static const struct_member xen_vm_metrics_record_struct_members[] = { .key = "VCPUs_utilisation", .type = &abstract_type_int_float_map, .offset = offsetof(xen_vm_metrics_record, vcpus_utilisation) }, + { .key = "VCPUs_CPU", + .type = &abstract_type_int_int_map, + .offset = offsetof(xen_vm_metrics_record, vcpus_cpu) }, + { .key = "VCPUs_params", + .type = &abstract_type_string_string_map, + .offset = offsetof(xen_vm_metrics_record, vcpus_params) }, + { .key = "start_time", + .type = &abstract_type_datetime, + .offset = offsetof(xen_vm_metrics_record, start_time) }, { .key = "last_updated", .type = &abstract_type_datetime, .offset = offsetof(xen_vm_metrics_record, last_updated) } @@ -74,6 +85,8 @@ xen_vm_metrics_record_free(xen_vm_metrics_record *record) free(record->handle); free(record->uuid); xen_int_float_map_free(record->vcpus_utilisation); + xen_int_int_map_free(record->vcpus_cpu); + xen_string_string_map_free(record->vcpus_params); free(record); } @@ -167,6 +180,56 @@ xen_vm_metrics_get_vcpus_utilisation(xen_session *session, xen_int_float_map **r } +bool +xen_vm_metrics_get_vcpus_cpu(xen_session *session, xen_int_int_map **result, xen_vm_metrics vm_metrics) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm_metrics } + }; + + abstract_type result_type = abstract_type_int_int_map; + + *result = NULL; + XEN_CALL_("VM_metrics.get_VCPUs_CPU"); + return session->ok; +} + + +bool +xen_vm_metrics_get_vcpus_params(xen_session *session, xen_string_string_map **result, xen_vm_metrics vm_metrics) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm_metrics } + }; + + abstract_type result_type = abstract_type_string_string_map; + + *result = NULL; + XEN_CALL_("VM_metrics.get_VCPUs_params"); + return session->ok; +} + + +bool +xen_vm_metrics_get_start_time(xen_session *session, time_t *result, xen_vm_metrics vm_metrics) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm_metrics } + }; + + abstract_type result_type = abstract_type_datetime; + + XEN_CALL_("VM_metrics.get_start_time"); + return session->ok; +} + + bool xen_vm_metrics_get_last_updated(xen_session *session, time_t *result, xen_vm_metrics vm_metrics) { diff --git a/tools/libxen/test/test_bindings.c b/tools/libxen/test/test_bindings.c index df067aa438..9a1ad1f9c4 100644 --- a/tools/libxen/test/test_bindings.c +++ b/tools/libxen/test/test_bindings.c @@ -757,6 +757,10 @@ static void print_vm_metrics(xen_session *session, xen_vm vm) my_strftime(time, 256, "Metrics updated at %c, local time.\n", tm); printf(time); + tm = localtime(&vm_metrics_record->start_time); + my_strftime(time, 256, "VM running since %c, local time.\n", tm); + printf(time); + for (size_t i = 0; i < vm_metrics_record->vcpus_utilisation->size; i++) { printf("%"PRId64" -> %lf.\n", @@ -764,6 +768,22 @@ static void print_vm_metrics(xen_session *session, xen_vm vm) vm_metrics_record->vcpus_utilisation->contents[i].val); } + printf("VCPU -> PCPU mapping:\n"); + for (size_t i = 0; i < vm_metrics_record->vcpus_cpu->size; i++) + { + printf(" %"PRId64" -> %"PRId64".\n", + vm_metrics_record->vcpus_cpu->contents[i].key, + vm_metrics_record->vcpus_cpu->contents[i].val); + } + + printf("Live scheduling parameters:\n"); + for (size_t i = 0; i < vm_metrics_record->vcpus_params->size; i++) + { + printf(" %s -> %s.\n", + vm_metrics_record->vcpus_params->contents[i].key, + vm_metrics_record->vcpus_params->contents[i].val); + } + xen_vm_metrics_record_free(vm_metrics_record); xen_vm_metrics_free(vm_metrics); diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index c9d417c3c7..7e67f491d5 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -87,7 +87,16 @@ def xen_api_todo(): def now(): - return xmlrpclib.DateTime(time.strftime("%Y%m%dT%H:%M:%S", time.gmtime())) + return datetime() + + +def datetime(when = None): + """Marshall the given time as a Xen-API DateTime. + + @param when The time in question, given as seconds since the epoch, UTC. + May be None, in which case the current time is used. + """ + return xmlrpclib.DateTime(time.gmtime(when)) # --------------------------------------------------- diff --git a/tools/python/xen/xend/XendVMMetrics.py b/tools/python/xen/xend/XendVMMetrics.py index c527814e5e..d32a295de5 100644 --- a/tools/python/xen/xend/XendVMMetrics.py +++ b/tools/python/xen/xend/XendVMMetrics.py @@ -138,7 +138,9 @@ class XendVMMetrics: return {} def get_start_time(self): - return self.xend_domain_instance.info.get("start_time", -1) + import xen.xend.XendAPI as XendAPI + return XendAPI.datetime( + self.xend_domain_instance.info.get("start_time", 0)) def get_last_updated(self): import xen.xend.XendAPI as XendAPI diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 5a6a5feca7..3dca2ee243 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -731,6 +731,10 @@ def xm_restore(args): server.xend.domain.restore(savefile, paused) +def datetime_to_secs(v): + return time.mktime(time.strptime(str(v) + 'UTC', '%Y%m%dT%H:%M:%S%Z')) + + def getDomains(domain_names, state, full = 0): if serverType == SERVER_XEN_API: doms_sxp = [] @@ -756,7 +760,8 @@ def getDomains(domain_names, state, full = 0): 'vcpus': dom_metrics['VCPUs_number'], 'state': state_str, 'cpu_time': dom_metrics['VCPUs_utilisation'], - 'start_time': dom_metrics['start_time']}) + 'start_time': datetime_to_secs( + dom_metrics['start_time'])}) doms_sxp.append(['domain'] + map2sxp(dom_rec)) doms_dict.append(dom_rec) From b586bb55adf9e04239129c75548d3a5467c7fee2 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Tue, 10 Apr 2007 17:01:40 +0100 Subject: [PATCH 10/13] Make date time handling slightly more permissive signed-off-by: Tom Wilkie --- tools/python/xen/xm/main.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 3dca2ee243..337d2a6a75 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -732,8 +732,10 @@ def xm_restore(args): def datetime_to_secs(v): - return time.mktime(time.strptime(str(v) + 'UTC', '%Y%m%dT%H:%M:%S%Z')) - + unwanted = ":-." + for c in unwanted: + v = str(v).replace(c, "") + return time.mktime(time.strptime(v[0:14], '%Y%m%dT%H%M%S')) def getDomains(domain_names, state, full = 0): if serverType == SERVER_XEN_API: From eb0639b38e60d4563cd2d49df2ca940ce1768a53 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Tue, 10 Apr 2007 17:26:45 +0100 Subject: [PATCH 11/13] Avoid using the multicol package. Signed-off-by: Ewan Mellor --- docs/xen-api/coversheet.tex | 27 +++++++++++---------------- docs/xen-api/xenapi.tex | 1 - 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/docs/xen-api/coversheet.tex b/docs/xen-api/coversheet.tex index 134af2472c..5a9478d20f 100644 --- a/docs/xen-api/coversheet.tex +++ b/docs/xen-api/coversheet.tex @@ -41,22 +41,17 @@ Date: \datestring{} \end{center} \vspace{.5cm} \begin{large} -\textbf{Contributors:} -\begin{multicols}{2}{ -Stefan Berger, IBM \\ -Daniel Berrang\'e, Red Hat \\ -Gareth Bestor, IBM \\ -Hollis Blanchard, IBM \\ -Mike Day, IBM \\ -Jim Fehlig, Novell \\ -Jon Harrop, XenSource \\ -Vincent Hanquez, XenSource \\ -John Levon, Sun Microsystems \\ -Jon Ludlam, XenSource \\ -Alastair Tse, XenSource \\ -Daniel Veillard, Red Hat \\ -Tom Wilkie, University of Cambridge} -\end{multicols} +\textbf{Contributors:} \\ +\\ +\begin{tabular}{p{0.5\textwidth}l} +Stefan Berger, IBM & Vincent Hanquez, XenSource \\ +Daniel Berrang\'e, Red Hat & John Levon, Sun Microsystems \\ +Gareth Bestor, IBM & Jon Ludlam, XenSource \\ +Hollis Blanchard, IBM & Alastair Tse, XenSource \\ +Mike Day, IBM & Daniel Veillard, Red Hat \\ +Jim Fehlig, Novell & Tom Wilkie, University of Cambridge \\ +Jon Harrop, XenSource & \\ +\end{tabular} \end{large} \vfill diff --git a/docs/xen-api/xenapi.tex b/docs/xen-api/xenapi.tex index 20ee6ec227..bc1abfee9d 100644 --- a/docs/xen-api/xenapi.tex +++ b/docs/xen-api/xenapi.tex @@ -17,7 +17,6 @@ \usepackage{graphics} \usepackage{longtable} \usepackage{fancyhdr} -\usepackage{multicol} \setlength\topskip{0cm} \setlength\topmargin{0cm} From 9853a49dd9feb3180ecfa9b9b5c3339af8f3442c Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Tue, 10 Apr 2007 17:29:16 +0100 Subject: [PATCH 12/13] Added docs and bindings for VM.{send_trigger,send_sysrq}. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 75 +++++++++++++++++++++++++++++++ tools/libxen/include/xen_vm.h | 17 +++++++ tools/libxen/src/xen_vm.c | 32 +++++++++++++ 3 files changed, 124 insertions(+) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index b2784e234c..d152bcc469 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -1558,6 +1558,81 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} +\subsubsection{RPC name:~send\_sysrq} + +{\bf Overview:} +Send the given key as a sysrq to this VM. The key is specified as a single +character (a String of length 1). This can only be called when the +specified VM is in the Running state. + + \noindent {\bf Signature:} +\begin{verbatim} void send_sysrq (session_id s, VM ref vm, string key)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & vm & The VM \\ \hline + +{\tt string } & key & The key to send \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} + +\noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE} + +\vspace{0.6cm} +\subsubsection{RPC name:~send\_trigger} + +{\bf Overview:} +Send the named trigger to this VM. This can only be called when the +specified VM is in the Running state. + + \noindent {\bf Signature:} +\begin{verbatim} void send_trigger (session_id s, VM ref vm, string trigger)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & vm & The VM \\ \hline + +{\tt string } & trigger & The trigger to send \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} + +\noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE} + +\vspace{0.6cm} \subsubsection{RPC name:~get\_all} {\bf Overview:} diff --git a/tools/libxen/include/xen_vm.h b/tools/libxen/include/xen_vm.h index 4b338088df..0f5c440c16 100644 --- a/tools/libxen/include/xen_vm.h +++ b/tools/libxen/include/xen_vm.h @@ -837,6 +837,23 @@ extern bool xen_vm_set_vcpus_number_live(xen_session *session, xen_vm self, int64_t nvcpu); +/** + * Send the given key as a sysrq to this VM. The key is specified as a + * single character (a String of length 1). This can only be called when the + * specified VM is in the Running state. + */ +extern bool +xen_vm_send_sysrq(xen_session *session, xen_vm vm, char *key); + + +/** + * Send the named trigger to this VM. This can only be called when the + * specified VM is in the Running state. + */ +extern bool +xen_vm_send_trigger(xen_session *session, xen_vm vm, char *trigger); + + /** * Return a list of all the VMs known to the system. */ diff --git a/tools/libxen/src/xen_vm.c b/tools/libxen/src/xen_vm.c index c0ac17c9d5..5f5aa72b9a 100644 --- a/tools/libxen/src/xen_vm.c +++ b/tools/libxen/src/xen_vm.c @@ -1609,6 +1609,38 @@ xen_vm_set_vcpus_number_live(xen_session *session, xen_vm self, int64_t nvcpu) } +bool +xen_vm_send_sysrq(xen_session *session, xen_vm vm, char *key) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + { .type = &abstract_type_string, + .u.string_val = key } + }; + + xen_call_(session, "VM.send_sysrq", param_values, 2, NULL, NULL); + return session->ok; +} + + +bool +xen_vm_send_trigger(xen_session *session, xen_vm vm, char *trigger) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + { .type = &abstract_type_string, + .u.string_val = trigger } + }; + + xen_call_(session, "VM.send_trigger", param_values, 2, NULL, NULL); + return session->ok; +} + + bool xen_vm_get_all(xen_session *session, struct xen_vm_set **result) { From 38ad8d2a5cddeaa0204616d1fd7766a818b8d539 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Apr 2007 18:49:20 +0100 Subject: [PATCH 13/13] linux: Fix IRQ disable/enable logic across save/restore. stop_machine_run() executes our callback function with interrupts disabled. Signed-off-by: Keir Fraser --- .../drivers/xen/core/machine_reboot.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c index 5f2e8cdee4..aa40702eed 100644 --- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c @@ -127,8 +127,10 @@ static int take_machine_down(void *p_fast_suspend) extern void time_resume(void); if (fast_suspend) { - preempt_disable(); + BUG_ON(!irqs_disabled()); } else { + BUG_ON(irqs_disabled()); + for (;;) { err = smp_suspend(); if (err) @@ -143,11 +145,11 @@ static int take_machine_down(void *p_fast_suspend) preempt_enable(); xenbus_suspend_cancel(); } + + local_irq_disable(); } mm_pin_all(); - local_irq_disable(); - preempt_enable(); gnttab_suspend(); pre_suspend(); @@ -178,7 +180,9 @@ static int take_machine_down(void *p_fast_suspend) #endif } time_resume(); - local_irq_enable(); + + if (!fast_suspend) + local_irq_enable(); return suspend_cancelled; }