From cd0d1464b9ddc46aba34a2fddef40e9e8bc8e73f Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 30 Mar 2009 16:48:26 +0100 Subject: [PATCH 01/76] x86 acpi: Delete unnecessary and broken RSDP-scanning code. Signed-off-by: Keir Fraser --- xen/arch/ia64/linux-xen/acpi.c | 4 --- xen/arch/x86/acpi/boot.c | 49 ---------------------------------- xen/include/xen/acpi.h | 1 - 3 files changed, 54 deletions(-) diff --git a/xen/arch/ia64/linux-xen/acpi.c b/xen/arch/ia64/linux-xen/acpi.c index cc6ac3575a..7c15f07dfa 100644 --- a/xen/arch/ia64/linux-xen/acpi.c +++ b/xen/arch/ia64/linux-xen/acpi.c @@ -76,11 +76,7 @@ unsigned int acpi_cpei_phys_cpuid; unsigned long acpi_wakeup_address = 0; #ifdef CONFIG_IA64_GENERIC -#ifndef XEN static unsigned long __init acpi_find_rsdp(void) -#else -unsigned long __init acpi_find_rsdp(void) -#endif { unsigned long rsdp_phys = 0; diff --git a/xen/arch/x86/acpi/boot.c b/xen/arch/x86/acpi/boot.c index 2ae8cc4157..95e7fff467 100644 --- a/xen/arch/x86/acpi/boot.c +++ b/xen/arch/x86/acpi/boot.c @@ -283,25 +283,6 @@ acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end #endif /* CONFIG_X86_IO_APIC */ -static unsigned long __init -acpi_scan_rsdp(unsigned long start, unsigned long length) -{ - unsigned long offset = 0; - unsigned long sig_len = sizeof("RSD PTR ") - 1; - - /* - * Scan all 16-byte boundaries of the physical memory region for the - * RSDP signature. - */ - for (offset = 0; offset < length; offset += 16) { - if (strncmp((char *)(start + offset), "RSD PTR ", sig_len)) - continue; - return (start + offset); - } - - return 0; -} - static int __init acpi_parse_sbf(struct acpi_table_header *table) { struct acpi_table_boot *sb; @@ -371,16 +352,9 @@ extern u32 pmtmr_ioport; static void __init acpi_fadt_parse_sleep_info(struct acpi_table_fadt *fadt) { - struct acpi_table_rsdp *rsdp; - unsigned long rsdp_phys; struct acpi_table_facs *facs = NULL; uint64_t facs_pa; - rsdp_phys = acpi_find_rsdp(); - if (!rsdp_phys || acpi_disabled) - goto bad; - rsdp = __va(rsdp_phys); - acpi_fadt_copy_address(pm1a_cnt, pm1a_control, pm1_control); acpi_fadt_copy_address(pm1b_cnt, pm1b_control, pm1_control); acpi_fadt_copy_address(pm1a_evt, pm1a_event, pm1_event); @@ -483,29 +457,6 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table) return 0; } -unsigned long __init acpi_find_rsdp(void) -{ - unsigned long rsdp_phys = 0; - -#if 0 - if (efi_enabled) { - if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) - return efi.acpi20; - else if (efi.acpi != EFI_INVALID_TABLE_ADDR) - return efi.acpi; - } -#endif - /* - * Scan memory looking for the RSDP signature. First search EBDA (low - * memory) paragraphs and then search upper memory (E0000-FFFFF). - */ - rsdp_phys = acpi_scan_rsdp(0, 0x400); - if (!rsdp_phys) - rsdp_phys = acpi_scan_rsdp(0xE0000, 0x20000); - - return rsdp_phys; -} - #ifdef CONFIG_X86_LOCAL_APIC /* * Parse LAPIC entries in MADT diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h index e08a1a5612..cbf795aeaf 100644 --- a/xen/include/xen/acpi.h +++ b/xen/include/xen/acpi.h @@ -282,7 +282,6 @@ typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, co unsigned int acpi_get_processor_id (unsigned int cpu); char * __acpi_map_table (unsigned long phys_addr, unsigned long size); -unsigned long acpi_find_rsdp (void); int acpi_boot_init (void); int acpi_boot_table_init (void); int acpi_numa_init (void); From c55103c52618dc9b704f7552084f4704e9c60685 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:10:06 +0100 Subject: [PATCH 02/76] intel mce: Small fixes. Signed-off-by: Frank van der Linden --- xen/arch/x86/cpu/mcheck/mce_intel.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c index fb04a5b3ec..27f1f58f92 100644 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c @@ -426,7 +426,7 @@ static void severity_scan(void) * recovered, we need to RESET for avoiding DOM0 LOG missing */ for ( i = 0; i < nr_mce_banks; i++) { - rdmsrl(MSR_IA32_MC0_STATUS + 4 * i , status); + mca_rdmsrl(MSR_IA32_MC0_STATUS + 4 * i , status); if ( !(status & MCi_STATUS_VAL) ) continue; /* MCE handler only handles UC error */ @@ -434,7 +434,12 @@ static void severity_scan(void) continue; if ( !(status & MCi_STATUS_EN) ) continue; - if (status & MCi_STATUS_PCC) + /* + * If this was an injected error, keep going, since the + * interposed value will be lost at reboot. + */ + if (status & MCi_STATUS_PCC && intpose_lookup(smp_processor_id(), + MSR_IA32_MC0_STATUS + 4 * i, NULL) == NULL) mc_panic("pcc = 1, cpu unable to continue\n"); } @@ -519,8 +524,8 @@ static void intel_machine_check(struct cpu_user_regs * regs, long error_code) /* Pick one CPU to clear MCIP */ if (!test_and_set_bool(mce_process_lock)) { - rdmsrl(MSR_IA32_MCG_STATUS, gstatus); - wrmsrl(MSR_IA32_MCG_STATUS, gstatus & ~MCG_STATUS_MCIP); + mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus); + mca_wrmsrl(MSR_IA32_MCG_STATUS, gstatus & ~MCG_STATUS_MCIP); if (worst >= 3) { printk(KERN_WARNING "worst=3 should have caused RESET\n"); From 92f9c55a94519ce3f175dc4bec98078799d9e6aa Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:12:39 +0100 Subject: [PATCH 03/76] xend: Disallow bogus MAC addresses when creating new VIF devices Signed-off-by: Michal Novotny --- tools/python/xen/xend/XendDomainInfo.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index ea68657c88..91be00e729 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -723,6 +723,13 @@ class XendDomainInfo: dev_config_dict = self.info['devices'][dev_uuid][1] log.debug("XendDomainInfo.device_create: %s" % scrub_password(dev_config_dict)) + if dev_type == 'vif': + for x in dev_config: + if x != 'vif' and x[0] == 'mac': + if not re.match('^([0-9a-f]{2}:){5}[0-9a-f]{2}$', x[1], re.I): + log.error("Virtual network interface creation error - invalid MAC Address entered: %s", x[1]) + raise VmError("Cannot create a new virtual network interface - MAC address is not valid!"); + if self.domid is not None: try: dev_config_dict['devid'] = devid = \ From be01c537b27616e84d2fa8238c2b7ce60be5a6ef Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:13:56 +0100 Subject: [PATCH 04/76] xend: fix domain_migrate When the guest(pv-on-hvm guest that cannot suspend) reboot in LiveMigration, the disconnecting of src-side is not transmitted to dist-side. As a result, the error processing on the dist side is not executed. Signed-off-by: Tomonari Horikoshi --- tools/python/xen/xend/XendDomain.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index b624f786ad..6cde465559 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -1378,6 +1378,7 @@ class XendDomain: XendCheckpoint.save(sock.fileno(), dominfo, True, live, dst, node=node) finally: + sock.shutdown(socket.SHUT_RDWR) sock.close() def domain_save(self, domid, dst, checkpoint=False): From f32b5caf311e6fedc1a22048a04b3724939142d0 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:16:01 +0100 Subject: [PATCH 05/76] xend: Save the state of PPCIs after hot-plug events. Signed-off-by: Yosuke Iwamatsu --- tools/python/xen/xend/XendNode.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py index 61779fa77e..1a40735cba 100644 --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -363,6 +363,8 @@ class XendNode: ppci_uuid = saved_ppci_table.get(pci_dev.name, uuid.createString()) XendPPCI(ppci_uuid, ppci_record) + self.save_PPCIs() + def remove_PPCI(self, pci_name): # Update lspci info @@ -373,6 +375,8 @@ class XendNode: ppci_ref = XendPPCI.get_by_sbdf(domain, bus, slot, func) XendAPIStore.get(ppci_ref, "PPCI").destroy() + self.save_PPCIs() + def add_PSCSI(self): # TODO From 6fe255bdc2edb6a26326f6532908ffebbf69336a Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:17:51 +0100 Subject: [PATCH 06/76] pygrub: More accurate try/except catch. Signed-off-by: Michal Novotny --- tools/pygrub/src/pygrub | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index ba70832e62..561bc7efe9 100644 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -532,7 +532,7 @@ def run_grub(file, entry, fs, arg): try: img = g.cf.images[sel] - except: + except IndexError: log.debug("PyGrub: Default selection is not valid, using first boot configuration...") img = g.cf.images[0] From fd598342a0befbbe36a446934e8d291b751b1175 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:19:26 +0100 Subject: [PATCH 07/76] cpuidle: export max_cstate access via libxc Signed-off-by: Wei Gang --- tools/libxc/xc_pm.c | 33 +++++++++++++++++++++++++++++++++ tools/libxc/xenctrl.h | 3 +++ xen/drivers/acpi/pmstat.c | 13 +++++++++++++ xen/include/public/sysctl.h | 6 ++++++ 4 files changed, 55 insertions(+) diff --git a/tools/libxc/xc_pm.c b/tools/libxc/xc_pm.c index 13342a3121..652f1729ef 100644 --- a/tools/libxc/xc_pm.c +++ b/tools/libxc/xc_pm.c @@ -362,3 +362,36 @@ int xc_set_sched_opt_smt(int xc_handle, uint32_t value) return rc; } +int xc_get_cpuidle_max_cstate(int xc_handle, uint32_t *value) +{ + int rc; + DECLARE_SYSCTL; + + if ( xc_handle < 0 || !value ) + return -EINVAL; + + sysctl.cmd = XEN_SYSCTL_pm_op; + sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_get_max_cstate; + sysctl.u.pm_op.cpuid = 0; + sysctl.u.pm_op.get_max_cstate = 0; + rc = do_sysctl(xc_handle, &sysctl); + *value = sysctl.u.pm_op.get_max_cstate; + + return rc; +} + +int xc_set_cpuidle_max_cstate(int xc_handle, uint32_t value) +{ + DECLARE_SYSCTL; + + if ( xc_handle < 0 ) + return -EINVAL; + + sysctl.cmd = XEN_SYSCTL_pm_op; + sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_set_max_cstate; + sysctl.u.pm_op.cpuid = 0; + sysctl.u.pm_op.set_max_cstate = value; + + return do_sysctl(xc_handle, &sysctl); +} + diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 9ce228620a..7111fa97c5 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -1262,4 +1262,7 @@ int xc_get_cputopo(int xc_handle, struct xc_get_cputopo *info); int xc_set_sched_opt_smt(int xc_handle, uint32_t value); +int xc_get_cpuidle_max_cstate(int xc_handle, uint32_t *value); +int xc_set_cpuidle_max_cstate(int xc_handle, uint32_t value); + #endif /* XENCTRL_H */ diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c index 1ac35c8237..8125e88951 100644 --- a/xen/drivers/acpi/pmstat.c +++ b/xen/drivers/acpi/pmstat.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -527,6 +528,18 @@ int do_pm_op(struct xen_sysctl_pm_op *op) break; } + case XEN_SYSCTL_pm_op_get_max_cstate: + { + op->get_max_cstate = max_cstate; + break; + } + + case XEN_SYSCTL_pm_op_set_max_cstate: + { + max_cstate = op->set_max_cstate; + break; + } + default: printk("not defined sub-hypercall @ do_pm_op\n"); ret = -ENOSYS; diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h index 48d327c067..cb03262bd2 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -382,6 +382,10 @@ struct xen_sysctl_pm_op { /* set/reset scheduler power saving option */ #define XEN_SYSCTL_pm_op_set_sched_opt_smt 0x21 + /* cpuidle max_cstate access command */ + #define XEN_SYSCTL_pm_op_get_max_cstate 0x22 + #define XEN_SYSCTL_pm_op_set_max_cstate 0x23 + uint32_t cmd; uint32_t cpuid; union { @@ -391,6 +395,8 @@ struct xen_sysctl_pm_op { uint64_t get_avgfreq; struct xen_get_cputopo get_topo; uint32_t set_sched_opt_smt; + uint32_t get_max_cstate; + uint32_t set_max_cstate; }; }; From c8432f0b5929a6d77cc17cfbc754035c3d86ea1a Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:19:56 +0100 Subject: [PATCH 08/76] xenpm: add cmd set-max-cstate Signed-off-by: Wei Gang --- tools/misc/xenpm.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c index 39eef6517f..1d65393706 100644 --- a/tools/misc/xenpm.c +++ b/tools/misc/xenpm.c @@ -57,6 +57,7 @@ void show_help(void) " it is used in ondemand governor.\n" " get-cpu-topology get thread/core/socket topology info\n" " set-sched-smt enable|disable enable/disable scheduler smt power saving\n" + " set-max-cstate set the C-State limitation ( >= 0)\n" " start [seconds] start collect Cx/Px statistics,\n" " output after CTRL-C or SIGINT or several seconds.\n" ); @@ -122,6 +123,18 @@ static int get_cxstat_by_cpuid(int xc_fd, int cpuid, struct xc_cx_stat *cxstat) return 0; } +static int show_max_cstate(int xc_fd) +{ + int ret = 0; + uint32_t value; + + if ( (ret = xc_get_cpuidle_max_cstate(xc_fd, &value)) ) + return ret; + + printf("Max C-state: C%d\n\n", value); + return 0; +} + static int show_cxstat_by_cpuid(int xc_fd, int cpuid) { int ret = 0; @@ -148,6 +161,8 @@ void cxstat_func(int argc, char *argv[]) if ( cpuid >= max_cpu_nr ) cpuid = -1; + show_max_cstate(xc_fd); + if ( cpuid < 0 ) { /* show cxstates on all cpus */ @@ -864,7 +879,24 @@ void set_sched_smt_func(int argc, char *argv[]) rc = xc_set_sched_opt_smt(xc_fd, value); printf("%s sched_smt_power_savings %s\n", argv[0], - rc? "failed":"successeed" ); + rc? "failed":"succeeded" ); + + return; +} + +void set_max_cstate_func(int argc, char *argv[]) +{ + int value, rc; + + if ( argc != 1 || sscanf(argv[0], "%d", &value) != 1 || value < 0 ) + { + show_help(); + exit(-1); + } + + rc = xc_set_cpuidle_max_cstate(xc_fd, (uint32_t)value); + printf("set max_cstate to C%d %s\n", value, + rc? "failed":"succeeded" ); return; } @@ -886,6 +918,7 @@ struct { { "set-up-threshold", scaling_up_threshold_func }, { "get-cpu-topology", cpu_topology_func}, { "set-sched-smt", set_sched_smt_func}, + { "set-max-cstate", set_max_cstate_func}, }; int main(int argc, char *argv[]) From da2c44502457ff12405934742363102bbc281602 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:21:14 +0100 Subject: [PATCH 09/76] x86: virt_to_mfn() fixes. Signed-off-by: Xiaowei Yang --- xen/common/page_alloc.c | 3 ++- xen/include/asm-x86/x86_32/page.h | 19 ++++++++++++++++--- xen/include/asm-x86/x86_64/page.h | 8 +++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 830e44cdb4..ab3445b44b 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -302,7 +302,8 @@ static unsigned long init_node_heap(int node, unsigned long mfn, (mfn + needed) <= (virt_to_mfn(DIRECTMAP_VIRT_END - 1) + 1) ) { _heap[node] = mfn_to_virt(mfn); - avail[node] = mfn_to_virt(mfn + needed) - sizeof(**avail) * NR_ZONES; + avail[node] = mfn_to_virt(mfn + needed - 1) + + PAGE_SIZE - sizeof(**avail) * NR_ZONES; } #endif else if ( get_order_from_bytes(sizeof(**_heap)) == diff --git a/xen/include/asm-x86/x86_32/page.h b/xen/include/asm-x86/x86_32/page.h index aef51f51af..648d96de87 100644 --- a/xen/include/asm-x86/x86_32/page.h +++ b/xen/include/asm-x86/x86_32/page.h @@ -27,9 +27,6 @@ #define __PAGE_OFFSET (0xFF000000) #define __XEN_VIRT_START __PAGE_OFFSET -#define virt_to_maddr(va) ((unsigned long)(va)-DIRECTMAP_VIRT_START) -#define maddr_to_virt(ma) ((void *)((unsigned long)(ma)+DIRECTMAP_VIRT_START)) - #define VADDR_BITS 32 #define VADDR_MASK (~0UL) @@ -44,6 +41,22 @@ #include #include +static inline unsigned long __virt_to_maddr(unsigned long va) +{ + ASSERT(va >= DIRECTMAP_VIRT_START && va < DIRECTMAP_VIRT_END); + return va - DIRECTMAP_VIRT_START; +} +#define virt_to_maddr(va) \ + (__virt_to_maddr((unsigned long)(va))) + +static inline void *__maddr_to_virt(unsigned long ma) +{ + ASSERT(ma < DIRECTMAP_VIRT_END - DIRECTMAP_VIRT_START); + return (void *)(ma + DIRECTMAP_VIRT_START); +} +#define maddr_to_virt(ma) \ + (__maddr_to_virt((unsigned long)(ma))) + /* read access (should only be used for debug printk's) */ typedef u64 intpte_t; #define PRIpte "016llx" diff --git a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h index 8899fe777c..fcfb8eef57 100644 --- a/xen/include/asm-x86/x86_64/page.h +++ b/xen/include/asm-x86/x86_64/page.h @@ -46,8 +46,14 @@ static inline unsigned long __virt_to_maddr(unsigned long va) } #define virt_to_maddr(va) \ (__virt_to_maddr((unsigned long)(va))) + +static inline void *__maddr_to_virt(unsigned long ma) +{ + ASSERT(ma < DIRECTMAP_VIRT_END - DIRECTMAP_VIRT_START); + return (void *)(ma + DIRECTMAP_VIRT_START); +} #define maddr_to_virt(ma) \ - ((void *)((unsigned long)(ma)+DIRECTMAP_VIRT_START)) + (__maddr_to_virt((unsigned long)(ma))) /* read access (should only be used for debug printk's) */ typedef u64 intpte_t; From ceb97ddf1c262ba0b237779c544511918c5240dd Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:23:38 +0100 Subject: [PATCH 10/76] xend: Properly save/restore vnc/vfb configuration In 19284:0942BAA2A088 provision was made for running vnc and sdl simultaneously. However, arrangements for saving and restoring the new structure-configuration, and arrangements for allowing the new code to load old savefiles, were not made. This patch adds these facilities. Amongst other things, HVM VNC save/restore will now work properly again. Signed-off-by: Ian Jackson --- tools/python/xen/xend/XendConfig.py | 15 +++++++++++++++ tools/python/xen/xend/server/vfbif.py | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 7bb6255aff..3950cca715 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -1410,6 +1410,21 @@ class XendConfig(dict): if dev_uuid not in target['console_refs']: target['console_refs'].append(dev_uuid) + # Cope with old-format save files which say under vfb + # (type vfb) rather than (vfb 1) + try: + vfb_type = dev_info['type'] + except KeyError: + vfb_type = None + log.debug("iwj dev_type=%s vfb type %s" % + (dev_type, `vfb_type`)) + + if vfb_type == 'vnc' or vfb_type == 'sdl': + dev_info[vfb_type] = 1 + del dev_info['type'] + log.debug("iwj dev_type=%s vfb setting dev_info['%s']" % + (dev_type, vfb_type)) + elif dev_type == 'console': if 'console_refs' not in target: target['console_refs'] = [] diff --git a/tools/python/xen/xend/server/vfbif.py b/tools/python/xen/xend/server/vfbif.py index 6f049d3c13..d1e99efb1b 100644 --- a/tools/python/xen/xend/server/vfbif.py +++ b/tools/python/xen/xend/server/vfbif.py @@ -6,7 +6,7 @@ import xen.xend import os CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused', - 'videoram', 'display', 'xauthority', 'keymap', + 'videoram', 'display', 'xauthority', 'keymap', 'vnc', 'sdl', 'uuid', 'location', 'protocol', 'opengl'] class VfbifController(DevController): From 14f5ee16c8423ef8d71b6473ac91c754f8b0ff1a Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:24:13 +0100 Subject: [PATCH 11/76] xend: Supply pass-through vslot to qemu-dm Signed-off-by: Simon Horman --- tools/python/xen/xend/server/pciif.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/python/xen/xend/server/pciif.py b/tools/python/xen/xend/server/pciif.py index e6ba4bc695..1b183884e3 100644 --- a/tools/python/xen/xend/server/pciif.py +++ b/tools/python/xen/xend/server/pciif.py @@ -90,6 +90,7 @@ class PciController(DevController): back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%01x" % \ (domain, bus, slot, func) back['uuid-%i' % pcidevid] = pci_config.get('uuid', '') + back['vslot-%i' % pcidevid] = "%02x" % vslot pcidevid += 1 if vslots != "": From ea3ee2e615de6ecd55a5b7e26eaee383e9b5eec2 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:26:10 +0100 Subject: [PATCH 12/76] xend: Allow drbd disks. From: Ben Timby Signed-off-by: Keir Fraser --- tools/python/xen/util/blkif.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/util/blkif.py b/tools/python/xen/util/blkif.py index 29b23fb7dd..6091afe5ac 100644 --- a/tools/python/xen/util/blkif.py +++ b/tools/python/xen/util/blkif.py @@ -75,7 +75,7 @@ def _parse_uname(uname): fn = taptype = None if uname.find(":") != -1: (typ, fn) = uname.split(":", 1) - if typ == "phy" and not fn.startswith("/"): + if typ in ("phy", "drbd") and not fn.startswith("/"): fn = "/dev/%s" %(fn,) if typ == "tap": (taptype, fn) = fn.split(":", 1) From 23d864769a614ec5ae094b0deddb67fe674d2aa6 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:27:10 +0100 Subject: [PATCH 13/76] xend: Fix scsi_id for pvSCSI pvSCSI allocations fail if the version of udev in a host OS is relatively new. I have not been able to detect the failure because I have used udev of the version 095. The failure occurs by an incompatibility problem of scsi_id command included udev. This patch tackles the incompatibility problem. Signed-off-by: Masaki Kanno --- tools/python/xen/util/vscsi_util.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/util/vscsi_util.py b/tools/python/xen/util/vscsi_util.py index 3b8d0536a8..a61f10455a 100644 --- a/tools/python/xen/util/vscsi_util.py +++ b/tools/python/xen/util/vscsi_util.py @@ -36,6 +36,11 @@ SYSFS_SCSI_DEV_TYPEID_PATH = '/type' SYSFS_SCSI_DEV_REVISION_PATH = '/rev' SYSFS_SCSI_DEV_SCSILEVEL_PATH = '/scsi_level' +SCSI_ID_COMMANDS = [ + "/lib/udev/scsi_id -gu --sg-version 3 -d /dev/%s 2>/dev/null", + "/sbin/scsi_id -gu -s /class/scsi_generic/%s 2>/dev/null" +] + def _vscsi_get_devname_by(name, scsi_devices): """A device name is gotten by the HCTL. (e.g., '0:0:0:0' to '/dev/sda') @@ -79,9 +84,10 @@ def _vscsi_get_hctl_by(phyname, scsi_devices): def _vscsi_get_scsiid(sg): - scsi_id = os.popen('/sbin/scsi_id -gu -s /class/scsi_generic/' + sg).read().split() - if len(scsi_id): - return scsi_id[0] + for scsi_id_command in SCSI_ID_COMMANDS: + scsi_id = os.popen(scsi_id_command % sg).read().split() + if len(scsi_id): + return scsi_id[0] return None From 75f6b53ab0b00cd26540c75dcde4be184cae9794 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:28:08 +0100 Subject: [PATCH 14/76] xend: Fix 'xm pci_list_assignable_devices' The current implementation of 'xm pci-list-assignable-devices' command has a problem that it directly invokes hypercall using xen.lowlevel.xc. This is probably based on an assumption that the command is executed on the host itself, but in fact there are cases xm commands can be executed on a remote server through xmlrpc. So this patch makes the xm command just inquire of xend about the information of available devices. Signed-off-by: Yosuke Iwamatsu --- tools/python/xen/xend/XendNode.py | 37 ++++++++++++++ tools/python/xen/xend/server/XMLRPCServer.py | 3 +- tools/python/xen/xm/main.py | 51 ++++++++------------ 3 files changed, 58 insertions(+), 33 deletions(-) diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py index 1a40735cba..047054a961 100644 --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -806,6 +806,43 @@ class XendNode: return [[k, info[k]] for k in ITEM_ORDER] + + def pciinfo(self): + # Each element of dev_list is a PciDevice + dev_list = PciUtil.find_all_devices_owned_by_pciback() + + # Each element of devs_list is a list of PciDevice + devs_list = PciUtil.check_FLR_capability(dev_list) + + devs_list = PciUtil.check_mmio_bar(devs_list) + + # Check if the devices have been assigned to guests. + final_devs_list = [] + for dev_list in devs_list: + available = True + for d in dev_list: + pci_str = '0x%x,0x%x,0x%x,0x%x' %(d.domain, d.bus, d.slot, d.func) + # Xen doesn't care what the domid is, so we pass 0 here... + domid = 0 + bdf = self.xc.test_assign_device(domid, pci_str) + if bdf != 0: + available = False + break + if available: + final_devs_list = final_devs_list + [dev_list] + + pci_sxp_list = [] + for dev_list in final_devs_list: + for d in dev_list: + pci_sxp = ['dev', ['domain', '0x%04x' % d.domain], + ['bus', '0x%02x' % d.bus], + ['slot', '0x%02x' % d.slot], + ['func', '0x%x' % d.func]] + pci_sxp_list.append(pci_sxp) + + return pci_sxp_list + + def xenschedinfo(self): sched_id = self.xc.sched_id_get() if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF: diff --git a/tools/python/xen/xend/server/XMLRPCServer.py b/tools/python/xen/xend/server/XMLRPCServer.py index 96c0ac24aa..fb9bdfee34 100644 --- a/tools/python/xen/xend/server/XMLRPCServer.py +++ b/tools/python/xen/xend/server/XMLRPCServer.py @@ -198,7 +198,8 @@ class XMLRPCServer: self.server.register_function(fn, "xend.domain.%s" % name[7:]) # Functions in XendNode and XendDmesg - for type, lst, n in [(XendNode, ['info', 'send_debug_keys'], 'node'), + for type, lst, n in [(XendNode, ['info', 'pciinfo', 'send_debug_keys'], + 'node'), (XendDmesg, ['info', 'clear'], 'node.dmesg')]: inst = type.instance() for name in lst: diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 46cf8e4052..8c7ba968e8 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -58,13 +58,6 @@ from xen.util.acmpolicy import ACM_LABEL_UNLABELED_DISPLAY import XenAPI -import xen.lowlevel.xc -try: - xc = xen.lowlevel.xc.xc() -except Exception, ex: - print >>sys.stderr, ("Is xen kernel running?") - sys.exit(1) - import inspect from xen.xend import XendOptions xoptions = XendOptions.instance() @@ -2188,34 +2181,28 @@ def xm_pci_list(args): hdr = 1 print ( fmt_str % x ) + +def parse_pci_info(info): + def get_info(n, t, d): + return t(sxp.child_value(info, n, d)) + return { + 'domain' : get_info('domain', parse_hex, 0), + 'bus' : get_info('bus', parse_hex, -1), + 'slot' : get_info('slot', parse_hex, -1), + 'func' : get_info('func', parse_hex, -1) + } + def xm_pci_list_assignable_devices(args): - # Each element of dev_list is a PciDevice - dev_list = find_all_devices_owned_by_pciback() + xenapi_unsupported() + arg_check(args, "pci-list-assignable-devices", 0) - # Each element of devs_list is a list of PciDevice - devs_list = check_FLR_capability(dev_list) + devs = server.xend.node.pciinfo() + + fmt_str = "%(domain)04x:%(bus)02x:%(slot)02x:%(func)01x" + for x in devs: + pci = parse_pci_info(x) + print fmt_str % pci - devs_list = check_mmio_bar(devs_list) - - # Check if the devices have been assigned to guests. - final_devs_list = [] - for dev_list in devs_list: - available = True - for d in dev_list: - pci_str = '0x%x,0x%x,0x%x,0x%x' %(d.domain, d.bus, d.slot, d.func) - # Xen doesn't care what the domid is, so we pass 0 here... - domid = 0 - bdf = xc.test_assign_device(domid, pci_str) - if bdf != 0: - available = False - break - if available: - final_devs_list = final_devs_list + [dev_list] - - for dev_list in final_devs_list: - for d in dev_list: - print d.name, - print def vscsi_sort(devs): def sort_hctl(ds, l): From d81fe9d33ad54cbe132c9c2852be4bd10b17674f Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:28:49 +0100 Subject: [PATCH 15/76] xend: Accept udev events about SCSI and update physical SCSI information Signed-off-by: Masaki Kanno --- tools/hotplug/Linux/xend.rules | 2 +- tools/python/xen/util/vscsi_util.py | 78 +++++++++++++---------- tools/python/xen/xend/XendNode.py | 36 +++++++++-- tools/python/xen/xend/server/udevevent.py | 22 +++++-- 4 files changed, 92 insertions(+), 46 deletions(-) diff --git a/tools/hotplug/Linux/xend.rules b/tools/hotplug/Linux/xend.rules index d996555702..8cb82956e9 100644 --- a/tools/hotplug/Linux/xend.rules +++ b/tools/hotplug/Linux/xend.rules @@ -1,3 +1,3 @@ SUBSYSTEM=="pci", RUN+="socket:/org/xen/xend/udev_event" -#SUBSYSTEM=="scsi", RUN+="socket:/org/xen/xend/udev_event" +SUBSYSTEM=="scsi", RUN+="socket:/org/xen/xend/udev_event" #SUBSYSTEM=="net", KERNEL!="vif[0-9]*.[0-9]*|tap[0-9]*.[0-9]*", RUN+="socket:/org/xen/xend/udev_event" diff --git a/tools/python/xen/util/vscsi_util.py b/tools/python/xen/util/vscsi_util.py index a61f10455a..8b26117fca 100644 --- a/tools/python/xen/util/vscsi_util.py +++ b/tools/python/xen/util/vscsi_util.py @@ -231,40 +231,50 @@ def get_scsi_scsilevel(pHCTL): except: return None +def _make_scsi_record(scsi_info): + scsi_rec = { + 'physical_HCTL': scsi_info[0], + 'dev_name': None, + 'sg_name': scsi_info[2], + 'scsi_id': None + } + if scsi_info[1] is not None: + scsi_rec['dev_name'] = scsi_info[1] + if scsi_info[3] is not None: + scsi_rec['scsi_id'] = scsi_info[3] + + scsi_rec['vendor_name'] = \ + get_scsi_vendor(scsi_rec['physical_HCTL']) + scsi_rec['model'] = \ + get_scsi_model(scsi_rec['physical_HCTL']) + scsi_rec['type_id'] = \ + get_scsi_typeid(scsi_rec['physical_HCTL']) + scsi_rec['revision'] = \ + get_scsi_revision(scsi_rec['physical_HCTL']) + scsi_rec['scsi_level'] = \ + get_scsi_scsilevel(scsi_rec['physical_HCTL']) + + try: + lsscsi_info = os.popen('lsscsi %s 2>/dev/null' % scsi_rec['physical_HCTL']).read().split() + scsi_rec['type'] = lsscsi_info[1] + except: + scsi_rec['type'] = None + + return scsi_rec + +def get_scsi_device(pHCTL): + scsis_info = _vscsi_get_scsidevices_by_lsscsi(pHCTL) + if not scsis_info: + scsis_info = _vscsi_get_scsidevices_by_sysfs() + for scsi_info in scsis_info: + if scsi_info[0] == pHCTL: + return _make_scsi_record(scsi_info) + return None + def get_all_scsi_devices(): - - scsi_devs = [] - + scsi_records = [] for scsi_info in vscsi_get_scsidevices(): - scsi_dev = { - 'physical_HCTL': scsi_info[0], - 'dev_name': None, - 'sg_name': scsi_info[2], - 'scsi_id': None - } - if scsi_info[1] is not None: - scsi_dev['dev_name'] = scsi_info[1] - if scsi_info[3] is not None: - scsi_dev['scsi_id'] = scsi_info[3] - - scsi_dev['vendor_name'] = \ - get_scsi_vendor(scsi_dev['physical_HCTL']) - scsi_dev['model'] = \ - get_scsi_model(scsi_dev['physical_HCTL']) - scsi_dev['type_id'] = \ - get_scsi_typeid(scsi_dev['physical_HCTL']) - scsi_dev['revision'] = \ - get_scsi_revision(scsi_dev['physical_HCTL']) - scsi_dev['scsi_level'] = \ - get_scsi_scsilevel(scsi_dev['physical_HCTL']) - - try: - lsscsi_info = os.popen('lsscsi %s 2>/dev/null' % scsi_dev['physical_HCTL']).read().split() - scsi_dev['type'] = lsscsi_info[1] - except: - scsi_dev['type'] = None - - scsi_devs.append(scsi_dev) - - return scsi_devs + scsi_record = _make_scsi_record(scsi_info) + scsi_records.append(scsi_record) + return scsi_records diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py index 047054a961..d1c4055ba4 100644 --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -378,14 +378,38 @@ class XendNode: self.save_PPCIs() - def add_PSCSI(self): - # TODO - log.debug("add_network(): Not implemented.") + def add_PSCSI(self, add_HCTL): + saved_pscsis = self.state_store.load_state('pscsi') + saved_pscsi_table = {} + if saved_pscsis: + for saved_uuid, saved_record in saved_pscsis.items(): + try: + saved_pscsi_table[saved_record['scsi_id']] = saved_uuid + except KeyError: + pass + + # Initialise the PSCSI + pscsi_record = vscsi_util.get_scsi_device(add_HCTL) + if pscsi_record and pscsi_record['scsi_id']: + pscsi_uuid = saved_pscsi_table.get(pscsi_record['scsi_id'], None) + if pscsi_uuid is None: + pscsi_uuid = uuid.createString() + XendPSCSI(pscsi_uuid, pscsi_record) + self.save_PSCSIs() - def remove_PSCSI(self): - # TODO - log.debug("add_network(): Not implemented.") + def remove_PSCSI(self, rem_HCTL): + saved_pscsis = self.state_store.load_state('pscsi') + if not saved_pscsis: + return + + # Remove the PSCSI + for pscsi_record in saved_pscsis.values(): + if rem_HCTL == pscsi_record['physical_HCTL']: + pscsi_ref = XendPSCSI.get_by_HCTL(rem_HCTL) + XendAPIStore.get(pscsi_ref, "PSCSI").destroy() + self.save_PSCSIs() + return ## def network_destroy(self, net_uuid): diff --git a/tools/python/xen/xend/server/udevevent.py b/tools/python/xen/xend/server/udevevent.py index b7ce26f917..b2b9f093f3 100644 --- a/tools/python/xen/xend/server/udevevent.py +++ b/tools/python/xen/xend/server/udevevent.py @@ -40,13 +40,25 @@ class UdevEventProtocol(protocol.Protocol): log.info("Removing pci device %s", pci_name) XendNode.instance().remove_PPCI(pci_name) - elif (udev_event.get('SUBSYSTEMS', None) == 'scsi'): + elif (udev_event.get('SUBSYSTEM', None) == 'scsi'): + hctl = None + devpath = udev_event.get('DEVPATH', None) + if devpath: + hctl = devpath.split('/')[-1] + if len(hctl.split(':')) != 4: + hctl = None + if hctl is None: + # By any possibility, if an HCTL isn't gotten from + # the udev event, the udev event is ignored. + log.warn("Invalid udev event about scsi received") + return + if (udev_event['ACTION'] == 'add'): - log.info("Adding scsi device") - XendNode.instance().add_PSCSI() + log.info("Adding scsi device %s", hctl) + XendNode.instance().add_PSCSI(hctl) elif (udev_event['ACTION'] == 'remove'): - log.info("Removing scci device") - XendNode.instance().remove_PSCSI() + log.info("Removing scsi device %s", hctl) + XendNode.instance().remove_PSCSI(hctl) elif (udev_event.get('SUBSYSTEM', None) == 'net'): interface = udev_event.get('INTERFACE', None) From e32808cc9cdd1527fc46c0c895848ccc661d1945 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:29:53 +0100 Subject: [PATCH 16/76] xend: fix hotplug for integrated devices For integrated devices(with bus number 0), self.find_parent() returns None, causing a python exception here. Signed-off-by: Dexuan Cui --- tools/python/xen/util/pci.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/util/pci.py b/tools/python/xen/util/pci.py index bb7720bb4e..a5eb407f33 100644 --- a/tools/python/xen/util/pci.py +++ b/tools/python/xen/util/pci.py @@ -417,7 +417,10 @@ class PciDevice: def find_the_uppermost_pci_bridge(self): # Find the uppermost PCI/PCI-X bridge - (dom, b, d, f) = self.find_parent() + dev = self.find_parent() + if dev is None: + return None + (dom, b, d, f) = dev dev = dev_parent = PciDevice(dom, b, d, f) while dev_parent.dev_type != DEV_TYPE_PCIe_BRIDGE: parent = dev_parent.find_parent() @@ -463,6 +466,11 @@ class PciDevice: element, the caller itself can remove it explicitly. ''' dev = self.find_the_uppermost_pci_bridge() + + # The 'self' device is on bus0. + if dev is None: + return [self.name] + dev_list = dev.find_all_devices_behind_the_bridge(ignore_bridge) dev_list = re.findall(PCI_DEV_REG_EXPRESS_STR, '%s' % dev_list) return dev_list @@ -559,7 +567,8 @@ class PciDevice: return self.find_all_the_multi_functions() elif self.dev_type == DEV_TYPE_PCI and not self.pci_af_flr: coassigned_pci_list = self.find_coassigned_pci_devices(True) - del coassigned_pci_list[0] + if len(coassigned_pci_list) > 1: + del coassigned_pci_list[0] return coassigned_pci_list else: return [self.name] From c9e8655cb793f0b0649c65b02f5963d41b43d334 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:31:08 +0100 Subject: [PATCH 17/76] xenapi: Fix VDI:read_only, VDI:sharable and VBD:mode of XenAPI I started a VM by using xm create, then I checked values of VDI records and values of VBD records. When I gave the following disk modes to a disk parameter, I got the following values from the records. "r" "w" "w!" VDI:read_only True True True <-- Always True! VDI:sharable True True True <-- Always True! VBD:mode RO RW RO ^^ <-- It should be RW. This patch fixes the values of the records as follows. "r" "w" "w!" VDI:read_only True False False VDI:sharable False False True VBD:mode RO RW RW Signed-off-by: Masaki Kanno --- tools/python/xen/xm/xenapi_create.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/python/xen/xm/xenapi_create.py b/tools/python/xen/xm/xenapi_create.py index d3cf5e2335..b66afaf414 100644 --- a/tools/python/xen/xm/xenapi_create.py +++ b/tools/python/xen/xm/xenapi_create.py @@ -218,8 +218,8 @@ class xenapi_create: "SR": self.DEFAULT_STORAGE_REPOSITORY, "virtual_size": vdi.attributes["size"].value, "type": vdi.attributes["type"].value, - "sharable": bool(vdi.attributes["sharable"].value), - "read_only": bool(vdi.attributes["read_only"].value), + "sharable": vdi.attributes["sharable"].value == "True", + "read_only": vdi.attributes["read_only"].value == "True", "other_config": {"location": vdi.attributes["src"].value} } @@ -804,6 +804,7 @@ class sxp2xml: def extract_vbd(self, vbd_sxp, document): src = get_child_by_name(vbd_sxp, "uname") + mode = get_child_by_name(vbd_sxp, "mode") name = str(src.__hash__()) vbd = document.createElement("vbd") @@ -811,8 +812,7 @@ class sxp2xml: vbd.attributes["name"] = "vdb" + name vbd.attributes["vdi"] = "vdi" + name vbd.attributes["mode"] \ - = get_child_by_name(vbd_sxp, "mode") != "w" \ - and "RO" or "RW" + = re.search("^w!{0,1}$", mode) and "RW" or "RO" vbd.attributes["device"] \ = re.sub(":cdrom$", "", get_child_by_name(vbd_sxp, "dev")) vbd.attributes["bootable"] = "1" @@ -825,17 +825,18 @@ class sxp2xml: def extract_vdi(self, vbd_sxp, document): src = get_child_by_name(vbd_sxp, "uname") + mode = get_child_by_name(vbd_sxp, "mode") name = "vdi" + str(src.__hash__()) vdi = document.createElement("vdi") vdi.attributes["src"] = src vdi.attributes["read_only"] \ - = (get_child_by_name(vbd_sxp, "mode") != "w") \ - and "True" or "False" + = re.search("^w!{0,1}$", mode) and "False" or "True" vdi.attributes["size"] = '-1' vdi.attributes["type"] = "system" - vdi.attributes["sharable"] = "False" + vdi.attributes["sharable"] \ + = re.search("^w!$", mode) and "True" or "False" vdi.attributes["name"] = name vdi.appendChild(self.make_name_tag(name, document)) From 03affb40e789671f1738560b2e2f2b0044e12fa3 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:32:56 +0100 Subject: [PATCH 18/76] libxc: Fix xc_translate_foreign_address in non-paged mode Returns paddr rather than gfn when in non-paged mode. Add a shift to fix it. Signed-off-by: George Dunlap --- tools/libxc/xc_pagetab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/libxc/xc_pagetab.c b/tools/libxc/xc_pagetab.c index 00ee0f8ea4..1a4a3d01e5 100644 --- a/tools/libxc/xc_pagetab.c +++ b/tools/libxc/xc_pagetab.c @@ -32,7 +32,7 @@ unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom, &ctx, sizeof ctx) != 0) return 0; if (!(ctx.cr0 & CR0_PG)) - return virt; + return virt >> PAGE_SHIFT; pt_levels = (ctx.msr_efer&EFER_LMA) ? 4 : (ctx.cr4&CR4_PAE) ? 3 : 2; paddr = ctx.cr3 & ((pt_levels == 3) ? ~0x1full : ~0xfffull); } else { From 49986faf5d961b5b3730c8791bc9b8d6fd811903 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:33:56 +0100 Subject: [PATCH 19/76] xenctx: Always show code context, even when not in kernel mode Signed-off-by: George Dunlap --- tools/xentrace/xenctx.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c index d5ec038d9f..38edb3fb55 100644 --- a/tools/xentrace/xenctx.c +++ b/tools/xentrace/xenctx.c @@ -683,12 +683,30 @@ static void print_stack_word(guest_word_t word, int width) printf(FMT_64B_WORD, word); } +static void print_code(vcpu_guest_context_any_t *ctx, int vcpu) +{ + guest_word_t instr; + int i; + + printf("Code:\n"); + instr = instr_pointer(ctx) - 21; + for(i=0; i<32; i++) { + unsigned char *c = map_page(ctx, vcpu, instr+i); + if (instr+i == instr_pointer(ctx)) + printf("<%02x> ", *c); + else + printf("%02x ", *c); + } + printf("\n"); + + printf("\n"); +} + static void print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width) { guest_word_t stack = stack_pointer(ctx); guest_word_t stack_limit; guest_word_t frame; - guest_word_t instr; guest_word_t word; guest_word_t *p; int i; @@ -709,19 +727,6 @@ static void print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width) } printf("\n"); - printf("Code:\n"); - instr = instr_pointer(ctx) - 21; - for(i=0; i<32; i++) { - unsigned char *c = map_page(ctx, vcpu, instr+i); - if (instr+i == instr_pointer(ctx)) - printf("<%02x> ", *c); - else - printf("%02x ", *c); - } - printf("\n"); - - printf("\n"); - if(stack_trace) printf("Stack Trace:\n"); else @@ -848,6 +853,7 @@ static void dump_ctx(int vcpu) #endif print_ctx(&ctx); + print_code(&ctx, vcpu); #ifndef NO_TRANSLATION if (is_kernel_text(instr_pointer(&ctx))) print_stack(&ctx, vcpu, guest_word_size); From 1ecaba192cef7fbdfb28504275d9396af7e4da36 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:36:11 +0100 Subject: [PATCH 20/76] minios: _chk_fail and _chk canaries for minios and newlib Add __stack_chk_fail to mini-os and __sprintf_chk __fprintf_chk to newlib, to cope with ocaml runtimes compiled with -fstack-protector. From: "George S. Coker, II" Signed-off-by: Samuel Thibault --- extras/mini-os/lib/stack_chk_fail.c | 8 ++++++++ stubdom/Makefile | 1 + 2 files changed, 9 insertions(+) create mode 100644 extras/mini-os/lib/stack_chk_fail.c diff --git a/extras/mini-os/lib/stack_chk_fail.c b/extras/mini-os/lib/stack_chk_fail.c new file mode 100644 index 0000000000..ade0045f0a --- /dev/null +++ b/extras/mini-os/lib/stack_chk_fail.c @@ -0,0 +1,8 @@ +#include +#include + +void __stack_chk_fail(void) +{ + printk("stack smashing detected\n"); + do_exit(); +} diff --git a/stubdom/Makefile b/stubdom/Makefile index dcb614fc85..fabb6908de 100644 --- a/stubdom/Makefile +++ b/stubdom/Makefile @@ -91,6 +91,7 @@ newlib-$(NEWLIB_VERSION).tar.gz: newlib-$(NEWLIB_VERSION): newlib-$(NEWLIB_VERSION).tar.gz tar xzf $< patch -d $@ -p0 < newlib.patch + patch -d $@ -p0 < newlib-chk.patch touch $@ NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libc.a From 0a0346fc3f81744534ea79fce2401675e2278356 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:38:05 +0100 Subject: [PATCH 21/76] xenctx: Teach xenctx how to find the right addresses in real-mode. Signed-off-by: George Dunlap --- tools/xentrace/xenctx.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c index 38edb3fb55..127379e671 100644 --- a/tools/xentrace/xenctx.c +++ b/tools/xentrace/xenctx.c @@ -42,6 +42,7 @@ typedef unsigned long long guest_word_t; int guest_word_size = sizeof (unsigned long); /* Word-length of the context record we get from xen */ int ctxt_word_size = sizeof (unsigned long); +int guest_protected_mode = 1; #elif defined (__ia64__) /* On ia64, we can't translate virtual address to physical address. */ #define NO_TRANSLATION @@ -206,6 +207,7 @@ static void read_symbol_table(const char *symtab) } #if defined(__i386__) || defined(__x86_64__) +#define CR0_PE 0x1 char *flag_values[22][2] = {/* clear, set, bit# */ { NULL, "c" }, // 0 Carry @@ -371,20 +373,38 @@ static void print_ctx(vcpu_guest_context_any_t *ctx) print_ctx_64(&ctx->x64); } +#define NONPROT_MODE_SEGMENT_SHIFT 4 + static guest_word_t instr_pointer(vcpu_guest_context_any_t *ctx) { - if (ctxt_word_size == 4) - return ctx->x32.user_regs.eip; + guest_word_t r; + if (ctxt_word_size == 4) + { + r = ctx->x32.user_regs.eip; + + if ( !guest_protected_mode ) + r += ctx->x32.user_regs.cs << NONPROT_MODE_SEGMENT_SHIFT; + } else - return ctx->x64.user_regs.rip; + r = ctx->x64.user_regs.rip; + + return r; } static guest_word_t stack_pointer(vcpu_guest_context_any_t *ctx) { - if (ctxt_word_size == 4) - return ctx->x32.user_regs.esp; + guest_word_t r; + if (ctxt_word_size == 4) + { + r = ctx->x32.user_regs.esp; + + if ( !guest_protected_mode ) + r += ctx->x32.user_regs.ss << NONPROT_MODE_SEGMENT_SHIFT; + } else - return ctx->x64.user_regs.rsp; + r = ctx->x64.user_regs.rsp; + + return r; } static guest_word_t frame_pointer(vcpu_guest_context_any_t *ctx) @@ -688,8 +708,9 @@ static void print_code(vcpu_guest_context_any_t *ctx, int vcpu) guest_word_t instr; int i; - printf("Code:\n"); - instr = instr_pointer(ctx) - 21; + instr = instr_pointer(ctx); + printf("Code (instr addr %08llx)\n", instr); + instr -= 21; for(i=0; i<32; i++) { unsigned char *c = map_page(ctx, vcpu, instr+i); if (instr+i == instr_pointer(ctx)) @@ -835,6 +856,7 @@ static void dump_ctx(int vcpu) exit(-1); } guest_word_size = (cpuctx.msr_efer & 0x400) ? 8 : 4; + guest_protected_mode = (cpuctx.cr0 & CR0_PE); /* HVM guest context records are always host-sized */ if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) { perror("xc_version"); From 1d11695836e0a23724e61ef46a600424ad023860 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:39:32 +0100 Subject: [PATCH 22/76] xen: include MSI/MSI-X information in interrupt debug output With per-domain irq-to-vector mappings, dump_irqs() omitted some vectors. This patch cycles through the vectors rather than interrupts and prints the same debug information. The patch also prints out information about mapped but unbound interrupts. Signed-off-by: Rolf Neugebauer --- xen/arch/x86/irq.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 18baba02db..8c790cf7fe 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1069,7 +1069,7 @@ extern void dump_ioapic_irq_info(void); static void dump_irqs(unsigned char key) { - int i, irq, vector; + int i, glob_irq, irq, vector; irq_desc_t *desc; irq_guest_action_t *action; struct domain *d; @@ -1077,41 +1077,47 @@ static void dump_irqs(unsigned char key) printk("Guest interrupt information:\n"); - for ( irq = 0; irq < NR_IRQS; irq++ ) + for ( vector = 0; vector < NR_VECTORS; vector++ ) { - vector = irq_to_vector(irq); - if ( vector == 0 ) - continue; + + glob_irq = vector_to_irq(vector); desc = &irq_desc[vector]; + if ( desc == NULL || desc->handler == &no_irq_type ) + continue; spin_lock_irqsave(&desc->lock, flags); - if ( desc->status & IRQ_GUEST ) + if ( !(desc->status & IRQ_GUEST) ) + printk(" Vec%3d IRQ%3d: type=%-15s status=%08x " + "mapped, unbound\n", + vector, glob_irq, desc->handler->typename, desc->status); + else { action = (irq_guest_action_t *)desc->action; - printk(" IRQ%3d Vec%3d: type=%-15s status=%08x " + printk(" Vec%3d IRQ%3d: type=%-15s status=%08x " "in-flight=%d domain-list=", - irq, vector, desc->handler->typename, + vector, glob_irq, desc->handler->typename, desc->status, action->in_flight); for ( i = 0; i < action->nr_guests; i++ ) { d = action->guest[i]; - printk("%u(%c%c%c%c)", - d->domain_id, - (test_bit(d->pirq_to_evtchn[irq], + irq = domain_vector_to_irq(d, vector); + printk("%u:%3d(%c%c%c%c)", + d->domain_id, irq, + (test_bit(d->pirq_to_evtchn[glob_irq], &shared_info(d, evtchn_pending)) ? 'P' : '-'), - (test_bit(d->pirq_to_evtchn[irq] / + (test_bit(d->pirq_to_evtchn[glob_irq] / BITS_PER_EVTCHN_WORD(d), &vcpu_info(d->vcpu[0], evtchn_pending_sel)) ? 'S' : '-'), - (test_bit(d->pirq_to_evtchn[irq], + (test_bit(d->pirq_to_evtchn[glob_irq], &shared_info(d, evtchn_mask)) ? 'M' : '-'), - (test_bit(irq, d->pirq_mask) ? + (test_bit(glob_irq, d->pirq_mask) ? 'M' : '-')); if ( i != action->nr_guests ) printk(","); From 7fdd501f11f56e7a4a0b8b9feac5d182f9ee3937 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:40:28 +0100 Subject: [PATCH 23/76] xend: Allow user to specify vslots 0 - 1f for static pass-through The current parser only accepts vslots 0 - f (hex), that is, only slots that have one digit. This is an omission as two digit slots with a leading 0 or 1 are also valid, representing the full range of slots 0 - 1f. Thanks to Dexuan Cui for spotting this problem. Cc: Dexuan Cui Signed-off-by: Simon Horman --- tools/python/xen/xm/create.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 8ad0fe6dfd..f5b505270b 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -1057,7 +1057,7 @@ def preprocess_pci(vals): r"(?P[0-9a-fA-F]{1,2})[:,]" + \ r"(?P[0-9a-fA-F]{1,2})[.,]" + \ r"(?P[0-7])" + \ - r"(@(?P[0-9a-fA-F]))?" + \ + r"(@(?P[01]?[0-9a-fA-F]))?" + \ r"(,(?P.*))?$", \ pci_dev_str) if pci_match!=None: From ce5ab42341d8a281416f07fdd2aa795b667bb9ec Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:41:13 +0100 Subject: [PATCH 24/76] vtd: fix iommu vector leak When we do Dom0 S3 for many times, iommu_set_interrupt() would fail during S3 resume because it can't obtain vector. We should not request new vector for every Dom0 S3 resume. We should re-use the same vector. Signed-off-by: Dexuan Cui --- xen/drivers/passthrough/vtd/iommu.c | 17 +++++++++++------ xen/include/xen/iommu.h | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 6e4d4a1afa..e2b026ca7e 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -911,6 +911,8 @@ static int iommu_alloc(struct acpi_drhd_unit *drhd) return -ENOMEM; memset(iommu, 0, sizeof(struct iommu)); + iommu->vector = -1; /* No vector assigned yet. */ + iommu->intel = alloc_intel_iommu(); if ( iommu->intel == NULL ) { @@ -1666,15 +1668,18 @@ static int init_vtd_hw(void) return -EIO; } - vector = iommu_set_interrupt(iommu); - if ( vector < 0 ) + if ( iommu->vector < 0 ) { - gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: interrupt setup failed\n"); - return vector; + vector = iommu_set_interrupt(iommu); + if ( vector < 0 ) + { + gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: interrupt setup failed\n"); + return vector; + } + iommu->vector = vector; } - dma_msi_data_init(iommu, vector); + dma_msi_data_init(iommu, iommu->vector); dma_msi_addr_init(iommu, cpu_physical_id(first_cpu(cpu_online_map))); - iommu->vector = vector; clear_fault_bits(iommu); dmar_writel(iommu->reg, DMAR_FECTL_REG, 0); diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index 37fa3c7aa8..b47049267d 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -55,7 +55,7 @@ struct iommu { spinlock_t lock; /* protect context, domain ids */ spinlock_t register_lock; /* protect iommu register handling */ u64 root_maddr; /* root entry machine address */ - unsigned int vector; + int vector; struct intel_iommu *intel; }; From a17ed5cc2784e64e72a9b6384928fce4efc4a572 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:47:20 +0100 Subject: [PATCH 25/76] x86: Clean up atomic.h comments and asm specifiers. Signed-off-by: Keir Fraser --- xen/include/asm-x86/atomic.h | 46 ++++++++++++++---------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/xen/include/asm-x86/atomic.h b/xen/include/asm-x86/atomic.h index f2ecf955e3..17becc5a7e 100644 --- a/xen/include/asm-x86/atomic.h +++ b/xen/include/asm-x86/atomic.h @@ -23,8 +23,7 @@ typedef struct { int counter; } atomic_t; * atomic_read - read atomic variable * @v: pointer of type atomic_t * - * Atomically reads the value of @v. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. + * Atomically reads the value of @v. */ #define _atomic_read(v) ((v).counter) #define atomic_read(v) (*(volatile int *)&((v)->counter)) @@ -34,8 +33,7 @@ typedef struct { int counter; } atomic_t; * @v: pointer of type atomic_t * @i: required value * - * Atomically sets the value of @v to @i. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. + * Atomically sets the value of @v to @i. */ #define _atomic_set(v,i) (((v).counter) = (i)) #define atomic_set(v,i) (*(volatile int *)&((v)->counter) = (i)) @@ -45,12 +43,11 @@ typedef struct { int counter; } atomic_t; * @i: integer value to add * @v: pointer of type atomic_t * - * Atomically adds @i to @v. Note that the guaranteed useful range - * of an atomic_t is only 24 bits. + * Atomically adds @i to @v. */ static __inline__ void atomic_add(int i, atomic_t *v) { - __asm__ __volatile__( + asm volatile( LOCK "addl %1,%0" :"=m" (*(volatile int *)&v->counter) :"ir" (i), "m" (*(volatile int *)&v->counter)); @@ -61,12 +58,11 @@ static __inline__ void atomic_add(int i, atomic_t *v) * @i: integer value to subtract * @v: pointer of type atomic_t * - * Atomically subtracts @i from @v. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. + * Atomically subtracts @i from @v. */ static __inline__ void atomic_sub(int i, atomic_t *v) { - __asm__ __volatile__( + asm volatile( LOCK "subl %1,%0" :"=m" (*(volatile int *)&v->counter) :"ir" (i), "m" (*(volatile int *)&v->counter)); @@ -79,14 +75,13 @@ static __inline__ void atomic_sub(int i, atomic_t *v) * * Atomically subtracts @i from @v and returns * true if the result is zero, or false for all - * other cases. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. + * other cases. */ static __inline__ int atomic_sub_and_test(int i, atomic_t *v) { unsigned char c; - __asm__ __volatile__( + asm volatile( LOCK "subl %2,%0; sete %1" :"=m" (*(volatile int *)&v->counter), "=qm" (c) :"ir" (i), "m" (*(volatile int *)&v->counter) : "memory"); @@ -97,12 +92,11 @@ static __inline__ int atomic_sub_and_test(int i, atomic_t *v) * atomic_inc - increment atomic variable * @v: pointer of type atomic_t * - * Atomically increments @v by 1. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. + * Atomically increments @v by 1. */ static __inline__ void atomic_inc(atomic_t *v) { - __asm__ __volatile__( + asm volatile( LOCK "incl %0" :"=m" (*(volatile int *)&v->counter) :"m" (*(volatile int *)&v->counter)); @@ -112,12 +106,11 @@ static __inline__ void atomic_inc(atomic_t *v) * atomic_dec - decrement atomic variable * @v: pointer of type atomic_t * - * Atomically decrements @v by 1. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. + * Atomically decrements @v by 1. */ static __inline__ void atomic_dec(atomic_t *v) { - __asm__ __volatile__( + asm volatile( LOCK "decl %0" :"=m" (*(volatile int *)&v->counter) :"m" (*(volatile int *)&v->counter)); @@ -129,14 +122,13 @@ static __inline__ void atomic_dec(atomic_t *v) * * Atomically decrements @v by 1 and * returns true if the result is 0, or false for all other - * cases. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. + * cases. */ static __inline__ int atomic_dec_and_test(atomic_t *v) { unsigned char c; - __asm__ __volatile__( + asm volatile( LOCK "decl %0; sete %1" :"=m" (*(volatile int *)&v->counter), "=qm" (c) :"m" (*(volatile int *)&v->counter) : "memory"); @@ -149,14 +141,13 @@ static __inline__ int atomic_dec_and_test(atomic_t *v) * * Atomically increments @v by 1 * and returns true if the result is zero, or false for all - * other cases. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. + * other cases. */ static __inline__ int atomic_inc_and_test(atomic_t *v) { unsigned char c; - __asm__ __volatile__( + asm volatile( LOCK "incl %0; sete %1" :"=m" (*(volatile int *)&v->counter), "=qm" (c) :"m" (*(volatile int *)&v->counter) : "memory"); @@ -170,14 +161,13 @@ static __inline__ int atomic_inc_and_test(atomic_t *v) * * Atomically adds @i to @v and returns true * if the result is negative, or false when - * result is greater than or equal to zero. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. + * result is greater than or equal to zero. */ static __inline__ int atomic_add_negative(int i, atomic_t *v) { unsigned char c; - __asm__ __volatile__( + asm volatile( LOCK "addl %2,%0; sets %1" :"=m" (*(volatile int *)&v->counter), "=qm" (c) :"ir" (i), "m" (*(volatile int *)&v->counter) : "memory"); From 9e7c906ffa79ad03531816f4dc6e80f3036173a0 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:48:07 +0100 Subject: [PATCH 26/76] XenAPI: Implement {get,set}_auto_power_on Signed-off-by: Masaki Kanno --- tools/python/README.XendConfig | 1 + tools/python/xen/xend/XendAPI.py | 8 +++++++- tools/python/xen/xend/XendConfig.py | 2 ++ tools/python/xen/xend/XendDomainInfo.py | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tools/python/README.XendConfig b/tools/python/README.XendConfig index 9776f3307b..9cc0eadaa6 100644 --- a/tools/python/README.XendConfig +++ b/tools/python/README.XendConfig @@ -25,6 +25,7 @@ name_label name name_description user_version is_a_template +auto_power_on resident_on memory_static_min memory memory_static_max maxmem diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index b4a33c4be1..e61e655bcf 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -1352,6 +1352,9 @@ class XendAPI(object): def VM_get_is_a_template(self, session, ref): return self.VM_get('is_a_template', session, ref) + def VM_get_auto_power_on(self, session, vm_ref): + return self.VM_get('auto_power_on', session, vm_ref) + def VM_get_memory_dynamic_max(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_success(dom.get_memory_dynamic_max()) @@ -1441,6 +1444,9 @@ class XendAPI(object): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_todo() + def VM_set_auto_power_on(self, session, vm_ref, val): + return self.VM_set('auto_power_on', session, vm_ref, val) + def VM_set_memory_dynamic_max(self, session, vm_ref, mem): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) dom.set_memory_dynamic_max(int(mem)) @@ -1682,7 +1688,7 @@ class XendAPI(object): 'name_description': xeninfo.getName(), 'user_version': 1, 'is_a_template': xeninfo.info['is_a_template'], - 'auto_power_on': False, + 'auto_power_on': xeninfo.info['auto_power_on'], 'resident_on': XendNode.instance().uuid, 'memory_static_min': xeninfo.get_memory_static_min(), 'memory_static_max': xeninfo.get_memory_static_max(), diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 3950cca715..f7bc850f9e 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -187,6 +187,7 @@ XENAPI_CFG_TYPES = { 'name_description': str, 'user_version': str, 'is_a_template': bool0, + 'auto_power_on': bool0, 'resident_on': str, 'memory_static_min': int, # note these are stored in bytes, not KB! 'memory_static_max': int, @@ -361,6 +362,7 @@ class XendConfig(dict): 'actions_after_crash': 'restart', 'actions_after_suspend': '', 'is_a_template': False, + 'auto_power_on': False, 'is_control_domain': False, 'features': '', 'PV_bootloader': '', diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 91be00e729..1fa0b338ad 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -144,6 +144,7 @@ def recreate(info, priv): xeninfo = XendConfig.XendConfig(dominfo = info) xeninfo['is_control_domain'] = priv xeninfo['is_a_template'] = False + xeninfo['auto_power_on'] = False domid = xeninfo['domid'] uuid1 = uuid.fromString(xeninfo['uuid']) needs_reinitialising = False From f02c18fff786578ae73581e8d329d2d2e91e7142 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:49:56 +0100 Subject: [PATCH 27/76] xend: Return True from device_update when cfg_xenapi When device_update is called by using cfg_xenapi, this patch returns True. Signed-off-by: Masaki Kanno --- tools/python/xen/xend/XendConfig.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index f7bc850f9e..e195ab1060 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -1912,6 +1912,7 @@ class XendConfig(dict): for key, val in cfg_xenapi.items(): dev_info[key] = val self['devices'][dev_uuid] = (dev_type, dev_info) + return True return False From 964fae8ac2fa6732856179a2532b0914dba5e4bb Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:51:56 +0100 Subject: [PATCH 28/76] cpuidle: suspend/resume scheduler tick timer during cpu idle state entry/exit cpuidle can collaborate with scheduler to reduce unnecessary timer interrupt. For example, credit scheduler accounting timer doesn't need to be active at idle time, so it can be stopped at cpuidle entry and resumed at cpuidle exit. This patch implements this function by adding two ops in scheduler: tick_suspend/tick_resume, and implement them for credit scheduler Signed-off-by: Yu Ke Signed-off-by: Tian Kevin --- xen/arch/x86/acpi/cpu_idle.c | 14 +++++++++++ xen/common/sched_credit.c | 49 +++++++++++++++++++++++++----------- xen/common/schedule.c | 10 ++++++++ xen/include/xen/sched-if.h | 3 +++ xen/include/xen/sched.h | 2 ++ 5 files changed, 64 insertions(+), 14 deletions(-) diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c index f8302d1f54..40263873e8 100644 --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -195,6 +195,15 @@ static void acpi_processor_idle(void) int sleep_ticks = 0; u32 t1, t2 = 0; + sched_tick_suspend(); + /* + * sched_tick_suspend may raise TIMER_SOFTIRQ by __stop_timer, + * which will break the later assumption of no sofirq pending, + * so add do_softirq + */ + if ( softirq_pending(smp_processor_id()) ) + do_softirq(); + /* * Interrupts must be disabled during bus mastering calculations and * for C2/C3 transitions. @@ -204,6 +213,7 @@ static void acpi_processor_idle(void) if ( softirq_pending(smp_processor_id()) ) { local_irq_enable(); + sched_tick_resume(); return; } @@ -223,6 +233,7 @@ static void acpi_processor_idle(void) pm_idle_save(); else acpi_safe_halt(); + sched_tick_resume(); return; } @@ -329,6 +340,7 @@ static void acpi_processor_idle(void) default: local_irq_enable(); + sched_tick_resume(); return; } @@ -339,6 +351,8 @@ static void acpi_processor_idle(void) cx->time += sleep_ticks; } + sched_tick_resume(); + if ( cpuidle_current_governor->reflect ) cpuidle_current_governor->reflect(power); } diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c index d724293bc1..c554c8b8b9 100644 --- a/xen/common/sched_credit.c +++ b/xen/common/sched_credit.c @@ -154,6 +154,7 @@ struct csched_private { spinlock_t lock; struct list_head active_sdom; uint32_t ncpus; + struct timer master_ticker; unsigned int master; cpumask_t idlers; uint32_t weight; @@ -757,7 +758,7 @@ csched_runq_sort(unsigned int cpu) } static void -csched_acct(void) +csched_acct(void* dummy) { unsigned long flags; struct list_head *iter_vcpu, *next_vcpu; @@ -792,7 +793,7 @@ csched_acct(void) csched_priv.credit_balance = 0; spin_unlock_irqrestore(&csched_priv.lock, flags); CSCHED_STAT_CRANK(acct_no_work); - return; + goto out; } CSCHED_STAT_CRANK(acct_run); @@ -950,6 +951,10 @@ csched_acct(void) /* Inform each CPU that its runq needs to be sorted */ csched_priv.runq_sort++; + +out: + set_timer( &csched_priv.master_ticker, NOW() + + MILLISECS(CSCHED_MSECS_PER_TICK) * CSCHED_TICKS_PER_ACCT ); } static void @@ -966,18 +971,6 @@ csched_tick(void *_cpu) if ( !is_idle_vcpu(current) ) csched_vcpu_acct(cpu); - /* - * Host-wide accounting duty - * - * Note: Currently, this is always done by the master boot CPU. Eventually, - * we could distribute or at the very least cycle the duty. - */ - if ( (csched_priv.master == cpu) && - (spc->tick % CSCHED_TICKS_PER_ACCT) == 0 ) - { - csched_acct(); - } - /* * Check if runq needs to be sorted * @@ -1310,10 +1303,35 @@ static __init int csched_start_tickers(void) set_timer(&spc->ticker, NOW() + MILLISECS(CSCHED_MSECS_PER_TICK)); } + init_timer( &csched_priv.master_ticker, csched_acct, NULL, + csched_priv.master); + + set_timer( &csched_priv.master_ticker, NOW() + + MILLISECS(CSCHED_MSECS_PER_TICK) * CSCHED_TICKS_PER_ACCT ); + return 0; } __initcall(csched_start_tickers); +static void csched_tick_suspend(void) +{ + struct csched_pcpu *spc; + + spc = CSCHED_PCPU(smp_processor_id()); + + stop_timer(&spc->ticker); +} + +static void csched_tick_resume(void) +{ + struct csched_pcpu *spc; + uint64_t now = NOW(); + + spc = CSCHED_PCPU(smp_processor_id()); + + set_timer(&spc->ticker, now + MILLISECS(CSCHED_MSECS_PER_TICK) + - now % MILLISECS(CSCHED_MSECS_PER_TICK) ); +} struct scheduler sched_credit_def = { .name = "SMP Credit Scheduler", @@ -1337,4 +1355,7 @@ struct scheduler sched_credit_def = { .dump_cpu_state = csched_dump_pcpu, .dump_settings = csched_dump, .init = csched_init, + + .tick_suspend = csched_tick_suspend, + .tick_resume = csched_tick_resume, }; diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 5e91f6c85d..f1121938da 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -964,6 +964,16 @@ void dump_runq(unsigned char key) local_irq_restore(flags); } +void sched_tick_suspend(void) +{ + SCHED_OP(tick_suspend); +} + +void sched_tick_resume(void) +{ + SCHED_OP(tick_resume); +} + #ifdef CONFIG_COMPAT #include "compat/schedule.c" #endif diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h index f6ba9faa5c..5caf8245d2 100644 --- a/xen/include/xen/sched-if.h +++ b/xen/include/xen/sched-if.h @@ -77,6 +77,9 @@ struct scheduler { struct xen_domctl_scheduler_op *); void (*dump_settings) (void); void (*dump_cpu_state) (int); + + void (*tick_suspend) (void); + void (*tick_resume) (void); }; #endif /* __XEN_SCHED_IF_H__ */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index efaec7e9b7..206bf6de4e 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -428,6 +428,8 @@ int sched_init_domain(struct domain *d); void sched_destroy_domain(struct domain *d); long sched_adjust(struct domain *, struct xen_domctl_scheduler_op *); int sched_id(void); +void sched_tick_suspend(void); +void sched_tick_resume(void); void vcpu_wake(struct vcpu *d); void vcpu_sleep_nosync(struct vcpu *d); void vcpu_sleep_sync(struct vcpu *d); From bc0fe8ff74c3e462c9d637eb3e93645f0b97a3f8 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:54:12 +0100 Subject: [PATCH 29/76] vtd: fix multiple Dom0 S3 on hosts that support Queued Invalidation. On such hosts we can't do multiple Dom0 S3 when VT-d is enabled. The cause is: during the first S3 resume, init_vtd_hw() initializes the invalidation function pointers to the register-based ones and later enable_qinval() forgets to overwrite the flush function pointers to queued-based ones, so actually Queued Invalidaton is enabled, but we actually use the register-based invalidation function! Later during the second Dom0 S3, in iommu_suspend() -> iommu_flush_all(), we try to use the register-based invalidation functions to perform global flush while Queued Invalidation is enabled, and this can cause a host reset because VT-d spec says: when the queued invalidation is enabled, software must submit invalidation commands only through the IQ (and not through any invalidation command registers). The attached patch fixes the buggy enable_qinval(). And in iommu_resume(), we invoke iommu_flush_all() for safety. Signed-off-by: Dexuan Cui --- xen/drivers/passthrough/vtd/iommu.c | 20 +++++++++++++++++++- xen/drivers/passthrough/vtd/qinval.c | 5 +++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index e2b026ca7e..dc18b3fde5 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1953,16 +1953,34 @@ void iommu_resume(void) { struct acpi_drhd_unit *drhd; struct iommu *iommu; + struct iommu_flush *flush; u32 i; if ( !vtd_enabled ) return; + /* Re-initialize the register-based flush functions. + * In iommu_flush_all(), we invoke iommu_flush_{context,iotlb}_global(), + * but at this point, on hosts that support QI(Queued Invalidation), QI + * hasn't been re-enabed yet, so for now let's use the register-based + * invalidation method before invoking init_vtd_hw(). + */ + if ( iommu_qinval ) + { + for_each_drhd_unit ( drhd ) + { + iommu = drhd->iommu; + flush = iommu_get_flush(iommu); + flush->context = flush_context_reg; + flush->iotlb = flush_iotlb_reg; + } + } + /* Not sure whether the flush operation is required to meet iommu * specification. Note that BIOS also executes in S3 resume and iommu may * be touched again, so let us do the flush operation for safety. */ - flush_all_cache(); + iommu_flush_all(); if ( init_vtd_hw() != 0 && force_iommu ) panic("IOMMU setup failed, crash Xen for security purpose!\n"); diff --git a/xen/drivers/passthrough/vtd/qinval.c b/xen/drivers/passthrough/vtd/qinval.c index e82337045f..60c7e0ad70 100644 --- a/xen/drivers/passthrough/vtd/qinval.c +++ b/xen/drivers/passthrough/vtd/qinval.c @@ -432,10 +432,11 @@ int enable_qinval(struct iommu *iommu) "Cannot allocate memory for qi_ctrl->qinval_maddr\n"); return -ENOMEM; } - flush->context = flush_context_qi; - flush->iotlb = flush_iotlb_qi; } + flush->context = flush_context_qi; + flush->iotlb = flush_iotlb_qi; + /* Setup Invalidation Queue Address(IQA) register with the * address of the page we just allocated. QS field at * bits[2:0] to indicate size of queue is one 4KB page. From b406180c4829a7fa509e03552254bef18b0cc606 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:55:42 +0100 Subject: [PATCH 30/76] tools build: No need for LFS flags on NetBSD. Signed-off-by: Christoph Egger --- tools/Rules.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/Rules.mk b/tools/Rules.mk index fbd69ea215..53434d51fc 100644 --- a/tools/Rules.mk +++ b/tools/Rules.mk @@ -33,10 +33,12 @@ CFLAGS += -D__XEN_TOOLS__ CFLAGS += -MMD -MF .$(@F).d DEPS = .*.d +ifneq ($(XEN_OS),NetBSD) # Enable implicit LFS support *and* explicit LFS names. CFLAGS += $(shell getconf LFS_CFLAGS) CFLAGS += -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE LDFLAGS += $(shell getconf LFS_LDFLAGS) +endif # 32-bit x86 does not perform well with -ve segment accesses on Xen. CFLAGS-$(CONFIG_X86_32) += $(call cc-option,$(CC),-mno-tls-direct-seg-refs) From 39a239fc0439e21684b75494fd2506ef7ce74b26 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 12:06:57 +0100 Subject: [PATCH 31/76] minios: Extend struct blkfront_aiocb. Signed-off-by: Stefano Stabellini --- extras/mini-os/include/blkfront.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extras/mini-os/include/blkfront.h b/extras/mini-os/include/blkfront.h index 8cbc0905d3..724137eb45 100644 --- a/extras/mini-os/include/blkfront.h +++ b/extras/mini-os/include/blkfront.h @@ -8,6 +8,8 @@ struct blkfront_aiocb uint8_t *aio_buf; size_t aio_nbytes; off_t aio_offset; + size_t total_bytes; + uint8_t is_write; void *data; grant_ref_t gref[BLKIF_MAX_SEGMENTS_PER_REQUEST]; From 57f5ad16f884c8a1ce326dcf0272b4fb4abc8c8d Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:11:56 +0100 Subject: [PATCH 32/76] x86 mce: fix c/s 17968 for 32-on-64 32-on-64 aspects were not properly considered. Add respective checking, and adjust structure layouts for the cases where the checking pointed out issues. Also, - fix a potential memory corruption issue (do_mca() could write beyond log_cpus' end if the guest specified less than the number of online CPUs - there is no reason to make the (not even properly prefixed) definitions in xen/public/arch-x86/xen-mca.h globally visible by including the file from xen/public/arch-x86/xen.h. Signed-off-by: Jan Beulich --- xen/arch/x86/cpu/mcheck/mce.c | 123 ++++++++++++++++++++------ xen/arch/x86/cpu/mcheck/x86_mca.h | 2 +- xen/include/public/arch-x86/xen-mca.h | 53 +++++------ xen/include/public/arch-x86/xen.h | 4 - xen/include/xlat.lst | 16 ++++ xen/tools/get-fields.sh | 2 +- 6 files changed, 137 insertions(+), 63 deletions(-) diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c index 3685056cba..bc18e3048b 100644 --- a/xen/arch/x86/cpu/mcheck/mce.c +++ b/xen/arch/x86/cpu/mcheck/mce.c @@ -984,14 +984,76 @@ static void x86_mc_mceinject(void *data) #error BITS_PER_LONG definition absent #endif +#ifdef CONFIG_COMPAT +# include + +# define xen_mcinfo_msr mcinfo_msr +CHECK_mcinfo_msr; +# undef xen_mcinfo_msr +# undef CHECK_mcinfo_msr +# define CHECK_mcinfo_msr struct mcinfo_msr + +# define xen_mcinfo_common mcinfo_common +CHECK_mcinfo_common; +# undef xen_mcinfo_common +# undef CHECK_mcinfo_common +# define CHECK_mcinfo_common struct mcinfo_common + +CHECK_FIELD_(struct, mc_fetch, flags); +CHECK_FIELD_(struct, mc_fetch, fetch_id); +# define CHECK_compat_mc_fetch struct mc_fetch + +CHECK_FIELD_(struct, mc_physcpuinfo, ncpus); +# define CHECK_compat_mc_physcpuinfo struct mc_physcpuinfo + +CHECK_mc; +# undef CHECK_compat_mc_fetch +# undef CHECK_compat_mc_physcpuinfo + +# define xen_mc_info mc_info +CHECK_mc_info; +# undef xen_mc_info + +# define xen_mcinfo_global mcinfo_global +CHECK_mcinfo_global; +# undef xen_mcinfo_global + +# define xen_mcinfo_bank mcinfo_bank +CHECK_mcinfo_bank; +# undef xen_mcinfo_bank + +# define xen_mcinfo_extended mcinfo_extended +CHECK_mcinfo_extended; +# undef xen_mcinfo_extended + +# define xen_mcinfo_recovery mcinfo_recovery +# define xen_cpu_offline_action cpu_offline_action +# define xen_page_offline_action page_offline_action +CHECK_mcinfo_recovery; +# undef xen_cpu_offline_action +# undef xen_page_offline_action +# undef xen_mcinfo_recovery +#else +# define compat_mc_fetch xen_mc_fetch +# define compat_mc_physcpuinfo xen_mc_physcpuinfo +# define compat_handle_is_null guest_handle_is_null +# define copy_to_compat copy_to_guest +#endif + /* Machine Check Architecture Hypercall */ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc) { long ret = 0; struct xen_mc curop, *op = &curop; struct vcpu *v = current; - struct xen_mc_fetch *mc_fetch; - struct xen_mc_physcpuinfo *mc_physcpuinfo; + union { + struct xen_mc_fetch *nat; + struct compat_mc_fetch *cmp; + } mc_fetch; + union { + struct xen_mc_physcpuinfo *nat; + struct compat_mc_physcpuinfo *cmp; + } mc_physcpuinfo; uint32_t flags, cmdflags; int nlcpu; xen_mc_logical_cpu_t *log_cpus = NULL; @@ -1009,8 +1071,8 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc) switch (op->cmd) { case XEN_MC_fetch: - mc_fetch = &op->u.mc_fetch; - cmdflags = mc_fetch->flags; + mc_fetch.nat = &op->u.mc_fetch; + cmdflags = mc_fetch.nat->flags; /* This hypercall is for Dom0 only */ if (!IS_PRIV(v->domain) ) @@ -1032,30 +1094,35 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc) flags = XEN_MC_OK; if (cmdflags & XEN_MC_ACK) { - mctelem_cookie_t cookie = ID2COOKIE(mc_fetch->fetch_id); + mctelem_cookie_t cookie = ID2COOKIE(mc_fetch.nat->fetch_id); mctelem_ack(which, cookie); } else { - if (guest_handle_is_null(mc_fetch->data)) + if (!is_pv_32on64_vcpu(v) + ? guest_handle_is_null(mc_fetch.nat->data) + : compat_handle_is_null(mc_fetch.cmp->data)) return x86_mcerr("do_mca fetch: guest buffer " "invalid", -EINVAL); if ((mctc = mctelem_consume_oldest_begin(which))) { struct mc_info *mcip = mctelem_dataptr(mctc); - if (copy_to_guest(mc_fetch->data, mcip, 1)) { + if (!is_pv_32on64_vcpu(v) + ? copy_to_guest(mc_fetch.nat->data, mcip, 1) + : copy_to_compat(mc_fetch.cmp->data, + mcip, 1)) { ret = -EFAULT; flags |= XEN_MC_FETCHFAILED; - mc_fetch->fetch_id = 0; + mc_fetch.nat->fetch_id = 0; } else { - mc_fetch->fetch_id = COOKIE2ID(mctc); + mc_fetch.nat->fetch_id = COOKIE2ID(mctc); } mctelem_consume_oldest_end(mctc); } else { /* There is no data */ flags |= XEN_MC_NODATA; - mc_fetch->fetch_id = 0; + mc_fetch.nat->fetch_id = 0; } - mc_fetch->flags = flags; + mc_fetch.nat->flags = flags; if (copy_to_guest(u_xen_mc, op, 1) != 0) ret = -EFAULT; } @@ -1069,14 +1136,16 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc) if ( !IS_PRIV(v->domain) ) return x86_mcerr("do_mca cpuinfo", -EPERM); - mc_physcpuinfo = &op->u.mc_physcpuinfo; + mc_physcpuinfo.nat = &op->u.mc_physcpuinfo; nlcpu = num_online_cpus(); - if (!guest_handle_is_null(mc_physcpuinfo->info)) { - if (mc_physcpuinfo->ncpus <= 0) + if (!is_pv_32on64_vcpu(v) + ? !guest_handle_is_null(mc_physcpuinfo.nat->info) + : !compat_handle_is_null(mc_physcpuinfo.cmp->info)) { + if (mc_physcpuinfo.nat->ncpus <= 0) return x86_mcerr("do_mca cpuinfo: ncpus <= 0", -EINVAL); - nlcpu = min(nlcpu, (int)mc_physcpuinfo->ncpus); + nlcpu = min(nlcpu, (int)mc_physcpuinfo.nat->ncpus); log_cpus = xmalloc_array(xen_mc_logical_cpu_t, nlcpu); if (log_cpus == NULL) return x86_mcerr("do_mca cpuinfo", -ENOMEM); @@ -1086,22 +1155,20 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc) xfree(log_cpus); return x86_mcerr("do_mca cpuinfo", -EIO); } - } - - mc_physcpuinfo->ncpus = nlcpu; - - if (copy_to_guest(u_xen_mc, op, 1)) { - if (log_cpus != NULL) - xfree(log_cpus); - return x86_mcerr("do_mca cpuinfo", -EFAULT); - } - - if (!guest_handle_is_null(mc_physcpuinfo->info)) { - if (copy_to_guest(mc_physcpuinfo->info, - log_cpus, nlcpu)) + if (!is_pv_32on64_vcpu(v) + ? copy_to_guest(mc_physcpuinfo.nat->info, + log_cpus, nlcpu) + : copy_to_compat(mc_physcpuinfo.cmp->info, + log_cpus, nlcpu)) ret = -EFAULT; xfree(log_cpus); } + + mc_physcpuinfo.nat->ncpus = nlcpu; + + if (copy_to_guest(u_xen_mc, op, 1)) + return x86_mcerr("do_mca cpuinfo", -EFAULT); + break; case XEN_MC_msrinject: diff --git a/xen/arch/x86/cpu/mcheck/x86_mca.h b/xen/arch/x86/cpu/mcheck/x86_mca.h index ac98744932..6333ccd3d0 100644 --- a/xen/arch/x86/cpu/mcheck/x86_mca.h +++ b/xen/arch/x86/cpu/mcheck/x86_mca.h @@ -18,9 +18,9 @@ */ #ifndef X86_MCA_H - #define X86_MCA_H +#include /* The MCA/MCE MSRs should not be used anywhere else. * They are cpu family/model specific and are only for use diff --git a/xen/include/public/arch-x86/xen-mca.h b/xen/include/public/arch-x86/xen-mca.h index b02ebf0e07..ee92d48ef3 100644 --- a/xen/include/public/arch-x86/xen-mca.h +++ b/xen/include/public/arch-x86/xen-mca.h @@ -62,7 +62,7 @@ * choose a different version number range that is numerically less * than that used in xen-unstable. */ -#define XEN_MCA_INTERFACE_VERSION 0x01ecc002 +#define XEN_MCA_INTERFACE_VERSION 0x01ecc003 /* IN: Dom0 calls hypercall to retrieve nonurgent telemetry */ #define XEN_MC_NONURGENT 0x0001 @@ -125,13 +125,13 @@ struct mcinfo_global { /* running domain at the time in error (most likely the impacted one) */ uint16_t mc_domid; + uint16_t mc_vcpuid; /* virtual cpu scheduled for mc_domid */ uint32_t mc_socketid; /* physical socket of the physical core */ uint16_t mc_coreid; /* physical impacted core */ - uint32_t mc_apicid; uint16_t mc_core_threadid; /* core thread of physical core */ - uint16_t mc_vcpuid; /* virtual cpu scheduled for mc_domid */ - uint64_t mc_gstatus; /* global status */ + uint32_t mc_apicid; uint32_t mc_flags; + uint64_t mc_gstatus; /* global status */ }; /* contains bank local x86 mc information */ @@ -216,8 +216,9 @@ struct cpu_offline_action }; #define MAX_UNION_SIZE 16 -struct mc_recovery +struct mcinfo_recovery { + struct mcinfo_common common; uint16_t mc_bank; /* bank nr */ uint8_t action_flags; uint8_t action_types; @@ -228,12 +229,6 @@ struct mc_recovery } action_info; }; -struct mcinfo_recovery -{ - struct mcinfo_common common; - struct mc_recovery mc_action; -}; - #define MCINFO_HYPERCALLSIZE 1024 #define MCINFO_MAXSIZE 768 @@ -241,8 +236,8 @@ struct mcinfo_recovery struct mc_info { /* Number of mcinfo_* entries in mi_data */ uint32_t mi_nentries; - - uint8_t mi_data[MCINFO_MAXSIZE - sizeof(uint32_t)]; + uint32_t _pad0; + uint64_t mi_data[(MCINFO_MAXSIZE - 1) / 8]; }; typedef struct mc_info mc_info_t; DEFINE_XEN_GUEST_HANDLE(mc_info_t); @@ -258,7 +253,7 @@ DEFINE_XEN_GUEST_HANDLE(mc_info_t); #define MC_CAPS_VIA 5 /* cpuid level 0xc0000001 */ #define MC_CAPS_AMD_ECX 6 /* cpuid level 0x80000001 (%ecx) */ -typedef struct mcinfo_logical_cpu { +struct mcinfo_logical_cpu { uint32_t mc_cpunr; uint32_t mc_chipid; uint16_t mc_coreid; @@ -280,7 +275,8 @@ typedef struct mcinfo_logical_cpu { uint32_t mc_cache_alignment; int32_t mc_nmsrvals; struct mcinfo_msr mc_msrvalues[__MC_MSR_ARRAYSIZE]; -} xen_mc_logical_cpu_t; +}; +typedef struct mcinfo_logical_cpu xen_mc_logical_cpu_t; DEFINE_XEN_GUEST_HANDLE(xen_mc_logical_cpu_t); @@ -299,12 +295,12 @@ DEFINE_XEN_GUEST_HANDLE(xen_mc_logical_cpu_t); * struct mcinfo_common *x86_mcinfo_first(struct mc_info *mi); */ #define x86_mcinfo_first(_mi) \ - (struct mcinfo_common *)((_mi)->mi_data) + ((struct mcinfo_common *)(_mi)->mi_data) /* Prototype: * struct mcinfo_common *x86_mcinfo_next(struct mcinfo_common *mic); */ #define x86_mcinfo_next(_mic) \ - (struct mcinfo_common *)((uint8_t *)(_mic) + (_mic)->size) + ((struct mcinfo_common *)((uint8_t *)(_mic) + (_mic)->size)) /* Prototype: * void x86_mcinfo_lookup(void *ret, struct mc_info *mi, uint16_t type); @@ -350,6 +346,7 @@ struct xen_mc_fetch { XEN_MC_ACK if ack'ing an earlier fetch */ /* OUT: XEN_MC_OK, XEN_MC_FETCHFAILED, XEN_MC_NODATA, XEN_MC_NOMATCH */ + uint32_t _pad0; uint64_t fetch_id; /* OUT: id for ack, IN: id we are ack'ing */ /* OUT variables. */ @@ -382,7 +379,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_mc_notifydomain_t); struct xen_mc_physcpuinfo { /* IN/OUT */ uint32_t ncpus; - uint32_t pad0; + uint32_t _pad0; /* OUT */ XEN_GUEST_HANDLE(xen_mc_logical_cpu_t) info; }; @@ -391,10 +388,10 @@ struct xen_mc_physcpuinfo { #define MC_MSRINJ_MAXMSRS 8 struct xen_mc_msrinject { /* IN */ - unsigned int mcinj_cpunr; /* target processor id */ + uint32_t mcinj_cpunr; /* target processor id */ uint32_t mcinj_flags; /* see MC_MSRINJ_F_* below */ uint32_t mcinj_count; /* 0 .. count-1 in array are valid */ - uint32_t mcinj_pad0; + uint32_t _pad0; struct mcinfo_msr mcinj_msr[MC_MSRINJ_MAXMSRS]; }; @@ -406,18 +403,16 @@ struct xen_mc_mceinject { unsigned int mceinj_cpunr; /* target processor id */ }; -typedef union { - struct xen_mc_fetch mc_fetch; - struct xen_mc_notifydomain mc_notifydomain; - struct xen_mc_physcpuinfo mc_physcpuinfo; - struct xen_mc_msrinject mc_msrinject; - struct xen_mc_mceinject mc_mceinject; -} xen_mc_arg_t; - struct xen_mc { uint32_t cmd; uint32_t interface_version; /* XEN_MCA_INTERFACE_VERSION */ - xen_mc_arg_t u; + union { + struct xen_mc_fetch mc_fetch; + struct xen_mc_notifydomain mc_notifydomain; + struct xen_mc_physcpuinfo mc_physcpuinfo; + struct xen_mc_msrinject mc_msrinject; + struct xen_mc_mceinject mc_mceinject; + } u; }; typedef struct xen_mc xen_mc_t; DEFINE_XEN_GUEST_HANDLE(xen_mc_t); diff --git a/xen/include/public/arch-x86/xen.h b/xen/include/public/arch-x86/xen.h index 084348fbc2..5f7579aab1 100644 --- a/xen/include/public/arch-x86/xen.h +++ b/xen/include/public/arch-x86/xen.h @@ -76,10 +76,6 @@ typedef unsigned long xen_pfn_t; /* Maximum number of virtual CPUs in multi-processor guests. */ #define MAX_VIRT_CPUS 32 - -/* Machine check support */ -#include "xen-mca.h" - #ifndef __ASSEMBLY__ typedef unsigned long xen_ulong_t; diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 17f47e91ed..f2e4597648 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -10,6 +10,22 @@ ! cpu_user_regs arch-x86/xen-@arch@.h ! trap_info arch-x86/xen.h ! vcpu_guest_context arch-x86/xen.h +? cpu_offline_action arch-x86/xen-mca.h +? mc arch-x86/xen-mca.h +? mcinfo_bank arch-x86/xen-mca.h +? mcinfo_common arch-x86/xen-mca.h +? mcinfo_extended arch-x86/xen-mca.h +? mcinfo_global arch-x86/xen-mca.h +? mcinfo_logical_cpu arch-x86/xen-mca.h +? mcinfo_msr arch-x86/xen-mca.h +? mcinfo_recovery arch-x86/xen-mca.h +! mc_fetch arch-x86/xen-mca.h +? mc_info arch-x86/xen-mca.h +? mc_mceinject arch-x86/xen-mca.h +? mc_msrinject arch-x86/xen-mca.h +? mc_notifydomain arch-x86/xen-mca.h +! mc_physcpuinfo arch-x86/xen-mca.h +? page_offline_action arch-x86/xen-mca.h ? evtchn_alloc_unbound event_channel.h ? evtchn_bind_interdomain event_channel.h ? evtchn_bind_ipi event_channel.h diff --git a/xen/tools/get-fields.sh b/xen/tools/get-fields.sh index 49019a43be..2537fc49a1 100644 --- a/xen/tools/get-fields.sh +++ b/xen/tools/get-fields.sh @@ -328,7 +328,7 @@ check_field () struct|union) ;; [a-zA-Z_]*) - echo -n " CHECK_$n" + echo -n " CHECK_${n#xen_}" break ;; *) From 10fc4d65532216a9d9320b1dcf0d1e8e2f9b66b3 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:12:35 +0100 Subject: [PATCH 33/76] x86 mce: fix c/s 18938 Provide for up to 16/32 on (32/64-bit) extended MCE MSRs, and use actually existing extended MSRs on 64-bits that were inaccessible so far. Signed-off-by: Jan Beulich --- xen/arch/x86/cpu/mcheck/mce_intel.c | 53 ++++++++++++++++----------- xen/include/asm-x86/msr-index.h | 10 ++++- xen/include/public/arch-x86/xen-mca.h | 10 ++--- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c index 27f1f58f92..a481d90293 100644 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c @@ -117,6 +117,16 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) } #endif /* CONFIG_X86_MCE_THERMAL */ +static inline void intel_get_extended_msr(struct mcinfo_extended *ext, u32 msr) +{ + if ( ext->mc_msrs < ARRAY_SIZE(ext->mc_msr) + && msr < MSR_IA32_MCG_EAX + nr_intel_ext_msrs ) { + ext->mc_msr[ext->mc_msrs].reg = msr; + rdmsrl(msr, ext->mc_msr[ext->mc_msrs].value); + ++ext->mc_msrs; + } +} + static enum mca_extinfo intel_get_extended_msrs(struct mc_info *mci, uint16_t bank, uint64_t status) { @@ -129,30 +139,29 @@ intel_get_extended_msrs(struct mc_info *mci, uint16_t bank, uint64_t status) memset(&mc_ext, 0, sizeof(struct mcinfo_extended)); mc_ext.common.type = MC_TYPE_EXTENDED; mc_ext.common.size = sizeof(mc_ext); - mc_ext.mc_msrs = 10; - mc_ext.mc_msr[0].reg = MSR_IA32_MCG_EAX; - rdmsrl(MSR_IA32_MCG_EAX, mc_ext.mc_msr[0].value); - mc_ext.mc_msr[1].reg = MSR_IA32_MCG_EBX; - rdmsrl(MSR_IA32_MCG_EBX, mc_ext.mc_msr[1].value); - mc_ext.mc_msr[2].reg = MSR_IA32_MCG_ECX; - rdmsrl(MSR_IA32_MCG_ECX, mc_ext.mc_msr[2].value); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EAX); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EBX); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_ECX); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EDX); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_ESI); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EDI); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EBP); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_ESP); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EFLAGS); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EIP); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_MISC); - mc_ext.mc_msr[3].reg = MSR_IA32_MCG_EDX; - rdmsrl(MSR_IA32_MCG_EDX, mc_ext.mc_msr[3].value); - mc_ext.mc_msr[4].reg = MSR_IA32_MCG_ESI; - rdmsrl(MSR_IA32_MCG_ESI, mc_ext.mc_msr[4].value); - mc_ext.mc_msr[5].reg = MSR_IA32_MCG_EDI; - rdmsrl(MSR_IA32_MCG_EDI, mc_ext.mc_msr[5].value); - - mc_ext.mc_msr[6].reg = MSR_IA32_MCG_EBP; - rdmsrl(MSR_IA32_MCG_EBP, mc_ext.mc_msr[6].value); - mc_ext.mc_msr[7].reg = MSR_IA32_MCG_ESP; - rdmsrl(MSR_IA32_MCG_ESP, mc_ext.mc_msr[7].value); - mc_ext.mc_msr[8].reg = MSR_IA32_MCG_EFLAGS; - rdmsrl(MSR_IA32_MCG_EFLAGS, mc_ext.mc_msr[8].value); - mc_ext.mc_msr[9].reg = MSR_IA32_MCG_EIP; - rdmsrl(MSR_IA32_MCG_EIP, mc_ext.mc_msr[9].value); +#ifdef __x86_64__ + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R8); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R9); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R10); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R11); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R12); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R13); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R14); + intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R15); +#endif x86_mcinfo_add(mci, &mc_ext); diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h index f6b3fd1ed1..ab3b2a62fb 100644 --- a/xen/include/asm-x86/msr-index.h +++ b/xen/include/asm-x86/msr-index.h @@ -326,7 +326,15 @@ #define MSR_IA32_MCG_ESP 0x00000187 #define MSR_IA32_MCG_EFLAGS 0x00000188 #define MSR_IA32_MCG_EIP 0x00000189 -#define MSR_IA32_MCG_RESERVED 0x0000018a +#define MSR_IA32_MCG_MISC 0x0000018a +#define MSR_IA32_MCG_R8 0x00000190 +#define MSR_IA32_MCG_R9 0x00000191 +#define MSR_IA32_MCG_R10 0x00000192 +#define MSR_IA32_MCG_R11 0x00000193 +#define MSR_IA32_MCG_R12 0x00000194 +#define MSR_IA32_MCG_R13 0x00000195 +#define MSR_IA32_MCG_R14 0x00000196 +#define MSR_IA32_MCG_R15 0x00000197 /* Pentium IV performance counter MSRs */ #define MSR_P4_BPU_PERFCTR0 0x00000300 diff --git a/xen/include/public/arch-x86/xen-mca.h b/xen/include/public/arch-x86/xen-mca.h index ee92d48ef3..13fc5b1866 100644 --- a/xen/include/public/arch-x86/xen-mca.h +++ b/xen/include/public/arch-x86/xen-mca.h @@ -166,11 +166,11 @@ struct mcinfo_extended { uint32_t mc_msrs; /* Number of msr with valid values. */ /* - * Currently Intel extended MSR (32/64) including all gp registers - * and E(R)DI, E(R)BP, E(R)SP, E(R)FLAGS, E(R)IP, E(R)MISC, only 10 - * of them might be useful. So expend this array to 10. - */ - struct mcinfo_msr mc_msr[10]; + * Currently Intel extended MSR (32/64) include all gp registers + * and E(R)FLAGS, E(R)IP, E(R)MISC, up to 11/19 of them might be + * useful at present. So expand this array to 16/32 to leave room. + */ + struct mcinfo_msr mc_msr[sizeof(void *) * 4]; }; /* Recovery Action flags. Giving recovery result information to DOM0 */ From 8b816120b1895b95923bfc791f8ce874e1c58af2 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:14:10 +0100 Subject: [PATCH 34/76] x86: small adjustment to asm constraints for c/s 19400 Properly indicate the variable that the asm writes to, and allow compiler more freedom in selecting a suitable input operand for the ltr instruction. Signed-off-by: Jan Beulich --- xen/arch/x86/traps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index dfdc7bf044..360b46bf26 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -3048,8 +3048,8 @@ void load_TR(void) /* Switch to non-compat GDT (which has B bit clear) to execute LTR. */ asm volatile ( - "sgdt %1; lgdt %2; ltr %%ax; lgdt %1" - : : "a" (TSS_ENTRY << 3), "m" (old_gdt), "m" (tss_gdt) : "memory" ); + "sgdt %0; lgdt %2; ltr %w1; lgdt %0" + : "=m" (old_gdt) : "rm" (TSS_ENTRY << 3), "m" (tss_gdt) : "memory" ); } void __devinit percpu_traps_init(void) From f0367a76f0f690579c6b8b4b4c7f115c58b1f3f8 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:17:48 +0100 Subject: [PATCH 35/76] x86 mce: fix and clean up c/s 19423 - fix inverted return value check for intel_mce_{rd,wr}msr() - fix broken initialization of d->arch.vmca_msrs.mci_ctl - remove pointless (!d || is_idle_domain(d)) checks - eliminate hard-coded limit to 9 banks - avoid redundant gdprintk()s Signed-off-by: Jan Beulich --- xen/arch/x86/cpu/mcheck/mce_intel.c | 294 +++++++++++----------------- xen/arch/x86/domain.c | 12 +- xen/arch/x86/traps.c | 32 ++- xen/include/asm-x86/traps.h | 5 + 4 files changed, 140 insertions(+), 203 deletions(-) diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c index a481d90293..d8fa0ebb07 100644 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c @@ -742,7 +742,7 @@ void mce_intel_feature_init(struct cpuinfo_x86 *c) intel_init_cmci(c); } -uint64_t g_mcg_cap; +static uint64_t g_mcg_cap; static void mce_cap_init(struct cpuinfo_x86 *c) { u32 l, h; @@ -754,9 +754,12 @@ static void mce_cap_init(struct cpuinfo_x86 *c) if ((l & MCG_CMCI_P) && cpu_has_apic) cmci_support = 1; - nr_mce_banks = l & 0xff; + nr_mce_banks = l & MCG_CAP_COUNT; if (nr_mce_banks > MAX_NR_BANKS) + { printk(KERN_WARNING "MCE: exceed max mce banks\n"); + g_mcg_cap = (g_mcg_cap & ~MCG_CAP_COUNT) | MAX_NR_BANKS; + } if (l & MCG_EXT_P) { nr_intel_ext_msrs = (l >> MCG_EXT_CNT) & 0xff; @@ -828,11 +831,22 @@ int intel_mcheck_init(struct cpuinfo_x86 *c) } /* Guest vMCE# MSRs virtualization ops (rdmsr/wrmsr) */ -int intel_mce_wrmsr(u32 msr, u32 lo, u32 hi) +void intel_mce_init_msr(struct domain *d) +{ + d->arch.vmca_msrs.mcg_status = 0x0; + d->arch.vmca_msrs.mcg_cap = g_mcg_cap; + d->arch.vmca_msrs.mcg_ctl = (uint64_t)~0x0; + d->arch.vmca_msrs.nr_injection = 0; + memset(d->arch.vmca_msrs.mci_ctl, ~0, + sizeof(d->arch.vmca_msrs.mci_ctl)); + INIT_LIST_HEAD(&d->arch.vmca_msrs.impact_header); +} + +int intel_mce_wrmsr(u32 msr, u64 value) { struct domain *d = current->domain; struct bank_entry *entry = NULL; - uint64_t value = (u64)hi << 32 | lo; + unsigned int bank; int ret = 1; spin_lock(&mce_locks); @@ -840,86 +854,71 @@ int intel_mce_wrmsr(u32 msr, u32 lo, u32 hi) { case MSR_IA32_MCG_CTL: if (value != (u64)~0x0 && value != 0x0) { - gdprintk(XENLOG_WARNING, "MCE: value writen to MCG_CTL" + gdprintk(XENLOG_WARNING, "MCE: value written to MCG_CTL" "should be all 0s or 1s\n"); ret = -1; break; } - if (!d || is_idle_domain(d)) { - gdprintk(XENLOG_WARNING, "MCE: wrmsr not in DOM context, skip\n"); - break; - } d->arch.vmca_msrs.mcg_ctl = value; break; case MSR_IA32_MCG_STATUS: - if (!d || is_idle_domain(d)) { - gdprintk(XENLOG_WARNING, "MCE: wrmsr not in DOM context, skip\n"); - break; - } d->arch.vmca_msrs.mcg_status = value; gdprintk(XENLOG_DEBUG, "MCE: wrmsr MCG_CTL %"PRIx64"\n", value); break; - case MSR_IA32_MC0_CTL2: - case MSR_IA32_MC1_CTL2: - case MSR_IA32_MC2_CTL2: - case MSR_IA32_MC3_CTL2: - case MSR_IA32_MC4_CTL2: - case MSR_IA32_MC5_CTL2: - case MSR_IA32_MC6_CTL2: - case MSR_IA32_MC7_CTL2: - case MSR_IA32_MC8_CTL2: + case MSR_IA32_MCG_CAP: + gdprintk(XENLOG_WARNING, "MCE: MCG_CAP is read-only\n"); + ret = -1; + break; + case MSR_IA32_MC0_CTL2 ... MSR_IA32_MC0_CTL2 + MAX_NR_BANKS - 1: gdprintk(XENLOG_WARNING, "We have disabled CMCI capability, " "Guest should not write this MSR!\n"); break; - case MSR_IA32_MC0_CTL: - case MSR_IA32_MC1_CTL: - case MSR_IA32_MC2_CTL: - case MSR_IA32_MC3_CTL: - case MSR_IA32_MC4_CTL: - case MSR_IA32_MC5_CTL: - case MSR_IA32_MC6_CTL: - case MSR_IA32_MC7_CTL: - case MSR_IA32_MC8_CTL: - if (value != (u64)~0x0 && value != 0x0) { - gdprintk(XENLOG_WARNING, "MCE: value writen to MCi_CTL" - "should be all 0s or 1s\n"); + case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * MAX_NR_BANKS - 1: + bank = (msr - MSR_IA32_MC0_CTL) / 4; + if (bank >= (d->arch.vmca_msrs.mcg_cap & MCG_CAP_COUNT)) { + gdprintk(XENLOG_WARNING, "MCE: bank %u does not exist\n", bank); ret = -1; break; } - if (!d || is_idle_domain(d)) { - gdprintk(XENLOG_WARNING, "MCE: wrmsr not in DOM context, skip\n"); - break; - } - d->arch.vmca_msrs.mci_ctl[(msr - MSR_IA32_MC0_CTL)/4] = value; - break; - case MSR_IA32_MC0_STATUS: - case MSR_IA32_MC1_STATUS: - case MSR_IA32_MC2_STATUS: - case MSR_IA32_MC3_STATUS: - case MSR_IA32_MC4_STATUS: - case MSR_IA32_MC5_STATUS: - case MSR_IA32_MC6_STATUS: - case MSR_IA32_MC7_STATUS: - case MSR_IA32_MC8_STATUS: - if (!d || is_idle_domain(d)) { - /* Just skip */ - gdprintk(XENLOG_WARNING, "mce wrmsr: not in domain context!\n"); - break; - } - /* Give the first entry of the list, it corresponds to current - * vMCE# injection. When vMCE# is finished processing by the - * the guest, this node will be deleted. - * Only error bank is written. Non-error bank simply return. - */ - if ( !list_empty(&d->arch.vmca_msrs.impact_header) ) { - entry = list_entry(d->arch.vmca_msrs.impact_header.next, - struct bank_entry, list); - if ( entry->bank == (msr - MSR_IA32_MC0_STATUS)/4 ) { - entry->mci_status = value; + switch (msr & (MSR_IA32_MC0_CTL | 3)) + { + case MSR_IA32_MC0_CTL: + if (value != (u64)~0x0 && value != 0x0) { + gdprintk(XENLOG_WARNING, "MCE: value written to MC%u_CTL" + "should be all 0s or 1s (is %"PRIx64")\n", + bank, value); + ret = -1; + break; } - gdprintk(XENLOG_DEBUG, "MCE: wmrsr mci_status in vMCE# context\n"); + d->arch.vmca_msrs.mci_ctl[(msr - MSR_IA32_MC0_CTL)/4] = value; + break; + case MSR_IA32_MC0_STATUS: + /* Give the first entry of the list, it corresponds to current + * vMCE# injection. When vMCE# is finished processing by the + * the guest, this node will be deleted. + * Only error bank is written. Non-error banks simply return. + */ + if (!list_empty(&d->arch.vmca_msrs.impact_header)) { + entry = list_entry(d->arch.vmca_msrs.impact_header.next, + struct bank_entry, list); + if ( entry->bank == bank ) + entry->mci_status = value; + gdprintk(XENLOG_DEBUG, + "MCE: wr MC%u_STATUS %"PRIx64" in vMCE#\n", + bank, value); + } else + gdprintk(XENLOG_DEBUG, + "MCE: wr MC%u_STATUS %"PRIx64"\n", bank, value); + break; + case MSR_IA32_MC0_ADDR: + gdprintk(XENLOG_WARNING, "MCE: MC%u_ADDR is read-only\n", bank); + ret = -1; + break; + case MSR_IA32_MC0_MISC: + gdprintk(XENLOG_WARNING, "MCE: MC%u_MISC is read-only\n", bank); + ret = -1; + break; } - gdprintk(XENLOG_DEBUG, "MCE: wrmsr mci_status val:%"PRIx64"\n", value); break; default: ret = 0; @@ -933,6 +932,7 @@ int intel_mce_rdmsr(u32 msr, u32 *lo, u32 *hi) { struct domain *d = current->domain; int ret = 1; + unsigned int bank; struct bank_entry *entry = NULL; *lo = *hi = 0x0; @@ -940,142 +940,82 @@ int intel_mce_rdmsr(u32 msr, u32 *lo, u32 *hi) switch(msr) { case MSR_IA32_MCG_STATUS: - if (!d || is_idle_domain(d)) { - gdprintk(XENLOG_WARNING, "MCE: rdmsr not in domain context!\n"); - *lo = *hi = 0x0; - break; - } *lo = (u32)d->arch.vmca_msrs.mcg_status; *hi = (u32)(d->arch.vmca_msrs.mcg_status >> 32); gdprintk(XENLOG_DEBUG, "MCE: rd MCG_STATUS lo %x hi %x\n", *lo, *hi); break; case MSR_IA32_MCG_CAP: - if (!d || is_idle_domain(d)) { - gdprintk(XENLOG_WARNING, "MCE: rdmsr not in domain context!\n"); - *lo = *hi = 0x0; - break; - } *lo = (u32)d->arch.vmca_msrs.mcg_cap; *hi = (u32)(d->arch.vmca_msrs.mcg_cap >> 32); gdprintk(XENLOG_DEBUG, "MCE: rdmsr MCG_CAP lo %x hi %x\n", *lo, *hi); break; case MSR_IA32_MCG_CTL: - if (!d || is_idle_domain(d)) { - gdprintk(XENLOG_WARNING, "MCE: rdmsr not in domain context!\n"); - *lo = *hi = 0x0; - break; - } *lo = (u32)d->arch.vmca_msrs.mcg_ctl; *hi = (u32)(d->arch.vmca_msrs.mcg_ctl >> 32); gdprintk(XENLOG_DEBUG, "MCE: rdmsr MCG_CTL lo %x hi %x\n", *lo, *hi); break; - case MSR_IA32_MC0_CTL2: - case MSR_IA32_MC1_CTL2: - case MSR_IA32_MC2_CTL2: - case MSR_IA32_MC3_CTL2: - case MSR_IA32_MC4_CTL2: - case MSR_IA32_MC5_CTL2: - case MSR_IA32_MC6_CTL2: - case MSR_IA32_MC7_CTL2: - case MSR_IA32_MC8_CTL2: + case MSR_IA32_MC0_CTL2 ... MSR_IA32_MC0_CTL2 + MAX_NR_BANKS - 1: gdprintk(XENLOG_WARNING, "We have disabled CMCI capability, " "Guest should not read this MSR!\n"); break; - case MSR_IA32_MC0_CTL: - case MSR_IA32_MC1_CTL: - case MSR_IA32_MC2_CTL: - case MSR_IA32_MC3_CTL: - case MSR_IA32_MC4_CTL: - case MSR_IA32_MC5_CTL: - case MSR_IA32_MC6_CTL: - case MSR_IA32_MC7_CTL: - case MSR_IA32_MC8_CTL: - if (!d || is_idle_domain(d)) { - gdprintk(XENLOG_WARNING, "MCE: rdmsr not in domain context!\n"); - *lo = *hi = 0x0; + case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * MAX_NR_BANKS - 1: + bank = (msr - MSR_IA32_MC0_CTL) / 4; + if (bank >= (d->arch.vmca_msrs.mcg_cap & MCG_CAP_COUNT)) { + gdprintk(XENLOG_WARNING, "MCE: bank %u does not exist\n", bank); + ret = -1; break; } - *lo = (u32)d->arch.vmca_msrs.mci_ctl[(msr - MSR_IA32_MC0_CTL)/4]; - *hi = - (u32)(d->arch.vmca_msrs.mci_ctl[(msr - MSR_IA32_MC0_CTL)/4] - >> 32); - gdprintk(XENLOG_DEBUG, "MCE: rdmsr MCi_CTL lo %x hi %x\n", *lo, *hi); - break; - case MSR_IA32_MC0_STATUS: - case MSR_IA32_MC1_STATUS: - case MSR_IA32_MC2_STATUS: - case MSR_IA32_MC3_STATUS: - case MSR_IA32_MC4_STATUS: - case MSR_IA32_MC5_STATUS: - case MSR_IA32_MC6_STATUS: - case MSR_IA32_MC7_STATUS: - case MSR_IA32_MC8_STATUS: - /* Only error bank is read. Non-error bank simply return */ - *lo = *hi = 0x0; - gdprintk(XENLOG_DEBUG, "MCE: rdmsr mci_status\n"); - if (!d || is_idle_domain(d)) { - gdprintk(XENLOG_WARNING, "mce_rdmsr: not in domain context!\n"); + switch (msr & (MSR_IA32_MC0_CTL | 3)) + { + case MSR_IA32_MC0_CTL: + *lo = (u32)d->arch.vmca_msrs.mci_ctl[bank]; + *hi = (u32)(d->arch.vmca_msrs.mci_ctl[bank] >> 32); + gdprintk(XENLOG_DEBUG, "MCE: rd MC%u_CTL lo %x hi %x\n", + bank, *lo, *hi); break; - } - if (!list_empty(&d->arch.vmca_msrs.impact_header)) { - entry = list_entry(d->arch.vmca_msrs.impact_header.next, - struct bank_entry, list); - if ( entry->bank == (msr - MSR_IA32_MC0_STATUS)/4 ) { - *lo = entry->mci_status; - *hi = entry->mci_status >> 32; - gdprintk(XENLOG_DEBUG, "MCE: rdmsr MCi_STATUS in vmCE# context " - "lo %x hi %x\n", *lo, *hi); + case MSR_IA32_MC0_STATUS: + /* Only error bank is read. Non-error banks simply return. */ + if (!list_empty(&d->arch.vmca_msrs.impact_header)) { + entry = list_entry(d->arch.vmca_msrs.impact_header.next, + struct bank_entry, list); + if (entry->bank == bank) { + *lo = entry->mci_status; + *hi = entry->mci_status >> 32; + gdprintk(XENLOG_DEBUG, + "MCE: rd MC%u_STATUS in vmCE# context " + "lo %x hi %x\n", bank, *lo, *hi); + } else + entry = NULL; } - } - break; - case MSR_IA32_MC0_ADDR: - case MSR_IA32_MC1_ADDR: - case MSR_IA32_MC2_ADDR: - case MSR_IA32_MC3_ADDR: - case MSR_IA32_MC4_ADDR: - case MSR_IA32_MC5_ADDR: - case MSR_IA32_MC6_ADDR: - case MSR_IA32_MC7_ADDR: - case MSR_IA32_MC8_ADDR: - *lo = *hi = 0x0; - if (!d || is_idle_domain(d)) { - gdprintk(XENLOG_WARNING, "mce_rdmsr: not in domain context!\n"); + if (!entry) + gdprintk(XENLOG_DEBUG, "MCE: rd MC%u_STATUS\n", bank); break; - } - if (!list_empty(&d->arch.vmca_msrs.impact_header)) { - entry = list_entry(d->arch.vmca_msrs.impact_header.next, - struct bank_entry, list); - if ( entry->bank == (msr - MSR_IA32_MC0_ADDR)/4 ) { - *lo = entry->mci_addr; - *hi = entry->mci_addr >> 32; - gdprintk(XENLOG_DEBUG, "MCE: rdmsr MCi_ADDR in vMCE# context " - "lo %x hi %x\n", *lo, *hi); + case MSR_IA32_MC0_ADDR: + if (!list_empty(&d->arch.vmca_msrs.impact_header)) { + entry = list_entry(d->arch.vmca_msrs.impact_header.next, + struct bank_entry, list); + if (entry->bank == bank) { + *lo = entry->mci_addr; + *hi = entry->mci_addr >> 32; + gdprintk(XENLOG_DEBUG, + "MCE: rd MC%u_ADDR in vMCE# context lo %x hi %x\n", + bank, *lo, *hi); + } } - } - break; - case MSR_IA32_MC0_MISC: - case MSR_IA32_MC1_MISC: - case MSR_IA32_MC2_MISC: - case MSR_IA32_MC3_MISC: - case MSR_IA32_MC4_MISC: - case MSR_IA32_MC5_MISC: - case MSR_IA32_MC6_MISC: - case MSR_IA32_MC7_MISC: - case MSR_IA32_MC8_MISC: - *lo = *hi = 0x0; - if (!d || is_idle_domain(d)) { - gdprintk(XENLOG_WARNING, "MCE: rdmsr not in domain context!\n"); break; - } - if (!list_empty(&d->arch.vmca_msrs.impact_header)) { - entry = list_entry(d->arch.vmca_msrs.impact_header.next, - struct bank_entry, list); - if ( entry->bank == (msr - MSR_IA32_MC0_MISC)/4 ) { - *lo = entry->mci_misc; - *hi = entry->mci_misc >> 32; - gdprintk(XENLOG_DEBUG, "MCE: rdmsr MCi_MISC in vMCE# context " - " lo %x hi %x\n", *lo, *hi); + case MSR_IA32_MC0_MISC: + if (!list_empty(&d->arch.vmca_msrs.impact_header)) { + entry = list_entry(d->arch.vmca_msrs.impact_header.next, + struct bank_entry, list); + if (entry->bank == bank) { + *lo = entry->mci_misc; + *hi = entry->mci_misc >> 32; + gdprintk(XENLOG_DEBUG, + "MCE: rd MC%u_MISC in vMCE# context lo %x hi %x\n", + bank, *lo, *hi); + } } + break; } break; default: diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 8d7a166f65..7ceb0e4516 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -373,7 +374,6 @@ void vcpu_destroy(struct vcpu *v) hvm_vcpu_destroy(v); } -extern uint64_t g_mcg_cap; int arch_domain_create(struct domain *d, unsigned int domcr_flags) { #ifdef __x86_64__ @@ -458,14 +458,8 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags) goto fail; /* For Guest vMCE MSRs virtualization */ - d->arch.vmca_msrs.mcg_status = 0x0; - d->arch.vmca_msrs.mcg_cap = g_mcg_cap; - d->arch.vmca_msrs.mcg_ctl = (uint64_t)~0x0; - d->arch.vmca_msrs.nr_injection = 0; - memset(d->arch.vmca_msrs.mci_ctl, 0x1, - sizeof(d->arch.vmca_msrs.mci_ctl)); - INIT_LIST_HEAD(&d->arch.vmca_msrs.impact_header); - + if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) + intel_mce_init_msr(d); } if ( is_hvm_domain(d) ) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 360b46bf26..eb18792539 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1637,10 +1637,6 @@ static int is_cpufreq_controller(struct domain *d) (d->domain_id == 0)); } -/*Intel vMCE MSRs virtualization*/ -extern int intel_mce_wrmsr(u32 msr, u32 lo, u32 hi); -extern int intel_mce_rdmsr(u32 msr, u32 *lo, u32 *hi); - static int emulate_privileged_op(struct cpu_user_regs *regs) { struct vcpu *v = current; @@ -2210,10 +2206,10 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) break; if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) { - int rc = intel_mce_wrmsr(regs->ecx, eax, edx); - if ( rc == -1 ) + int rc = intel_mce_wrmsr(regs->ecx, res); + if ( rc < 0 ) goto fail; - if ( rc == 0 ) + if ( rc ) break; } @@ -2291,25 +2287,27 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) default: if ( rdmsr_hypervisor_regs(regs->ecx, &l, &h) ) { + rdmsr_writeback: regs->eax = l; regs->edx = h; break; } + + if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) + { + int rc = intel_mce_rdmsr(regs->ecx, &l, &h); + + if ( rc < 0 ) + goto fail; + if ( rc ) + goto rdmsr_writeback; + } + /* Everyone can read the MSR space. */ /* gdprintk(XENLOG_WARNING,"Domain attempted RDMSR %p.\n", _p(regs->ecx));*/ if ( rdmsr_safe(regs->ecx, regs->eax, regs->edx) ) goto fail; - - if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) - { - int rc = intel_mce_rdmsr(regs->ecx, &eax, &edx); - if ( rc == -1 ) - goto fail; - if ( rc == 0 ) - break; - } - break; } break; diff --git a/xen/include/asm-x86/traps.h b/xen/include/asm-x86/traps.h index 85a422363f..c2a0982c04 100644 --- a/xen/include/asm-x86/traps.h +++ b/xen/include/asm-x86/traps.h @@ -47,4 +47,9 @@ extern int guest_has_trap_callback(struct domain *d, uint16_t vcpuid, extern int send_guest_trap(struct domain *d, uint16_t vcpuid, unsigned int trap_nr); +/* Intel vMCE MSRs virtualization */ +extern void intel_mce_init_msr(struct domain *d); +extern int intel_mce_wrmsr(u32 msr, u64 value); +extern int intel_mce_rdmsr(u32 msr, u32 *lo, u32 *hi); + #endif /* ASM_TRAP_H */ From 55ec31da6c4c64a0d19d646e8b78e3cb56dea2c7 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:19:07 +0100 Subject: [PATCH 36/76] xend: Check for valid CPU_CAP value when creating new domain Signed-off-by: Michal Novotny Signed-off-by: Masaki Kanno --- tools/python/xen/xend/XendDomainInfo.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 1fa0b338ad..7497c7e435 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -2313,6 +2313,21 @@ class XendDomainInfo: # Set maximum number of vcpus in domain xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max'])) + # Check for cpu_{cap|weight} validity for credit scheduler + if XendNode.instance().xenschedinfo() == 'credit': + cap = self.getCap() + weight = self.getWeight() + + assert type(weight) == int + assert type(cap) == int + + if weight < 1 or weight > 65535: + raise VmError("Cpu weight out of range, valid values are within range from 1 to 65535") + + if cap < 0 or cap > dominfo.getVCpuCount() * 100: + raise VmError("Cpu cap out of range, valid range is from 0 to %s for specified number of vcpus" % + (dominfo.getVCpuCount() * 100)) + # Test whether the devices can be assigned with VT-d pci = self.info["platform"].get("pci") pci_str = '' From f94d6532fc05a80cf368b8470c90e4ea5b1070ff Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:20:04 +0100 Subject: [PATCH 37/76] xend: less noise in xend-debug.log on HVM shutdown Shutting down a hvm, xend-debug.log always shows: Unhandled exception in thread started by=20 Traceback (most recent call last): File "//usr/lib64/python/xen/xend/image.py", line 549, in _sentinel_watch self._dmfailed(message) File "//usr/lib64/python/xen/xend/image.py", line 491, in _dmfailed xc.domain_shutdown(self.vm.getDomid(), DOMAIN_CRASH) xen.lowlevel.xc.Error: (3, 'No such process') Signed-off-by: Kouya Shimura --- tools/python/xen/xend/image.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 04689c3eee..239165b55f 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -488,7 +488,10 @@ class ImageHandler: def _dmfailed(self, message): log.warning("domain %s: %s", self.vm.getName(), message) - xc.domain_shutdown(self.vm.getDomid(), DOMAIN_CRASH) + try: + xc.domain_shutdown(self.vm.getDomid(), DOMAIN_CRASH) + except: + pass def recreate(self): if self.device_model is None: From 3f64466b4bfbc47a9cb97416d7ed883606a329d2 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:21:36 +0100 Subject: [PATCH 38/76] ia64, pygrub: Allow command-line editing in Lilo boot loader On IA64 platform reset() function has one more parameter for Lilo bootloader used by IA64 than for GRUB bootloader used for other platforms. Signed-off-by: Michal Novotny --- tools/pygrub/src/pygrub | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index 561bc7efe9..e43dcc2d9a 100644 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -316,7 +316,11 @@ class Grub: curline = len(img.lines) - 1 if self.isdone: - origimg.reset(img.lines) + # Fix to allow pygrub command-line editing in Lilo bootloader (used by IA64) + if platform.machine() == 'ia64': + origimg.reset(img.lines, img.path) + else: + origimg.reset(img.lines) def edit_line(self, line): self.screen.erase() From ed25dad906fd3bec60fa79bc124afb3e854d67f0 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:22:12 +0100 Subject: [PATCH 39/76] Use unlikely() in BUG_ON()/WARN_ON() -fno-reorder-blocks was added in c/s 1712, when x86-64 just started to become enabled. The reason it got added is entirely unclear to me, and it prevents the intended effect of unlikely() constructs (in particular the ones added here) of moving out of line code which is expected to never get executed, as well as using forward branches (which are statically predicted taken by various processors' branch prediction units) preferably to reach infrequently executed code. Signed-off-by: Jan Beulich --- xen/arch/x86/Rules.mk | 2 +- xen/include/xen/lib.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk index e9e1d5b952..d97cea4777 100644 --- a/xen/arch/x86/Rules.mk +++ b/xen/arch/x86/Rules.mk @@ -42,7 +42,7 @@ x86_64 := n endif ifeq ($(TARGET_SUBARCH),x86_64) -CFLAGS += -mno-red-zone -fpic -fno-reorder-blocks +CFLAGS += -mno-red-zone -fpic CFLAGS += -fno-asynchronous-unwind-tables # -fvisibility=hidden reduces -fpic cost, if it's available ifneq ($(call cc-option,$(CC),-fvisibility=hidden,n),n) diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index 93fdabb9f1..f5c21f64f7 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -12,8 +12,8 @@ void __bug(char *file, int line) __attribute__((noreturn)); void __warn(char *file, int line); -#define BUG_ON(p) do { if (p) BUG(); } while (0) -#define WARN_ON(p) do { if (p) WARN(); } while (0) +#define BUG_ON(p) do { if (unlikely(p)) BUG(); } while (0) +#define WARN_ON(p) do { if (unlikely(p)) WARN(); } while (0) /* Force a compilation error if condition is true */ #define BUILD_BUG_ON(condition) ((void)sizeof(struct { int:-!!(condition); })) From 7f6385949637051d1529431d7acd59e1677318c8 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:23:11 +0100 Subject: [PATCH 40/76] x86: unify BUG() & Co, reduce overhead on x86-64 Since it's only the string pointer representations that differ between i386 and x86-64, abstract out those and make everything else shared. While touching this code, also use - proper instructions rather than a mixture of such and raw .byte/ .long/.quad data emissions, - PC-relative pointers on x86-64 to cut the amount of storage (and in particular cache space) needed for string references by half. Signed-off-by: Jan Beulich --- xen/arch/x86/traps.c | 14 +++++++++----- xen/include/asm-x86/bug.h | 24 ++++++++++++++++++++++++ xen/include/asm-x86/x86_32/bug.h | 29 +++-------------------------- xen/include/asm-x86/x86_64/bug.h | 31 ++++--------------------------- 4 files changed, 40 insertions(+), 58 deletions(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index eb18792539..c085655735 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -841,7 +841,7 @@ asmlinkage void do_invalid_op(struct cpu_user_regs *regs) { struct bug_frame bug; struct bug_frame_str bug_str; - char *filename, *predicate, *eip = (char *)regs->eip; + const char *filename, *predicate, *eip = (char *)regs->eip; unsigned long fixup; int id, lineno; @@ -873,11 +873,13 @@ asmlinkage void do_invalid_op(struct cpu_user_regs *regs) /* WARN, BUG or ASSERT: decode the filename pointer and line number. */ if ( !is_kernel(eip) || __copy_from_user(&bug_str, eip, sizeof(bug_str)) || - memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) ) + (bug_str.mov != 0xbc) ) goto die; + filename = bug_str(bug_str, eip); eip += sizeof(bug_str); - filename = is_kernel(bug_str.str) ? (char *)bug_str.str : ""; + if ( !is_kernel(filename) ) + filename = ""; lineno = bug.id >> 2; if ( id == BUGFRAME_warn ) @@ -900,11 +902,13 @@ asmlinkage void do_invalid_op(struct cpu_user_regs *regs) ASSERT(id == BUGFRAME_assert); if ( !is_kernel(eip) || __copy_from_user(&bug_str, eip, sizeof(bug_str)) || - memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) ) + (bug_str.mov != 0xbc) ) goto die; + predicate = bug_str(bug_str, eip); eip += sizeof(bug_str); - predicate = is_kernel(bug_str.str) ? (char *)bug_str.str : ""; + if ( !is_kernel(predicate) ) + predicate = ""; printk("Assertion '%s' failed at %.50s:%d\n", predicate, filename, lineno); DEBUGGER_trap_fatal(TRAP_invalid_op, regs); diff --git a/xen/include/asm-x86/bug.h b/xen/include/asm-x86/bug.h index 975576185c..df64549e44 100644 --- a/xen/include/asm-x86/bug.h +++ b/xen/include/asm-x86/bug.h @@ -18,4 +18,28 @@ struct bug_frame { #define BUGFRAME_bug 2 #define BUGFRAME_assert 3 +#define dump_execution_state() \ + asm volatile ( \ + "ud2 ; ret $0" \ + : : "i" (BUGFRAME_dump) ) + +#define WARN() \ + asm volatile ( \ + "ud2 ; ret %0" BUG_STR(1) \ + : : "i" (BUGFRAME_warn | (__LINE__<<2)), \ + "i" (__FILE__) ) + +#define BUG() \ + asm volatile ( \ + "ud2 ; ret %0" BUG_STR(1) \ + : : "i" (BUGFRAME_bug | (__LINE__<<2)), \ + "i" (__FILE__) ) + +#define assert_failed(p) \ + asm volatile ( \ + "ud2 ; ret %0" BUG_STR(1) BUG_STR(2) \ + : : "i" (BUGFRAME_assert | (__LINE__<<2)), \ + "i" (__FILE__), "i" (#p) ) + + #endif /* __X86_BUG_H__ */ diff --git a/xen/include/asm-x86/x86_32/bug.h b/xen/include/asm-x86/x86_32/bug.h index 20a9137063..dfb5955296 100644 --- a/xen/include/asm-x86/x86_32/bug.h +++ b/xen/include/asm-x86/x86_32/bug.h @@ -2,33 +2,10 @@ #define __X86_32_BUG_H__ struct bug_frame_str { - unsigned char mov[1]; + unsigned char mov; unsigned long str; } __attribute__((packed)); -#define BUG_MOV_STR "\xbc" - -#define dump_execution_state() \ - asm volatile ( \ - "ud2 ; ret $%c0" \ - : : "i" (BUGFRAME_dump) ) - -#define WARN() \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1" \ - : : "i" (BUGFRAME_warn | (__LINE__<<2)), \ - "i" (__FILE__) ) - -#define BUG() \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1" \ - : : "i" (BUGFRAME_bug | (__LINE__<<2)), \ - "i" (__FILE__) ) - -#define assert_failed(p) \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1" \ - " ; .byte 0xbc ; .long %c2" \ - : : "i" (BUGFRAME_assert | (__LINE__<<2)), \ - "i" (__FILE__), "i" (#p) ) +#define bug_str(b, eip) ((const char *)(b).str) +#define BUG_STR(n) "; movl %" #n ", %%esp" #endif /* __X86_32_BUG_H__ */ diff --git a/xen/include/asm-x86/x86_64/bug.h b/xen/include/asm-x86/x86_64/bug.h index 3fa5debfa7..ecae455b83 100644 --- a/xen/include/asm-x86/x86_64/bug.h +++ b/xen/include/asm-x86/x86_64/bug.h @@ -2,33 +2,10 @@ #define __X86_64_BUG_H__ struct bug_frame_str { - unsigned char mov[2]; - unsigned long str; + unsigned char mov; + signed int str_disp; } __attribute__((packed)); -#define BUG_MOV_STR "\x48\xbc" - -#define dump_execution_state() \ - asm volatile ( \ - "ud2 ; ret $%c0" \ - : : "i" (BUGFRAME_dump) ) - -#define WARN() \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1" \ - : : "i" (BUGFRAME_warn | (__LINE__<<2)), \ - "i" (__FILE__) ) - -#define BUG() \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1" \ - : : "i" (BUGFRAME_bug | (__LINE__<<2)), \ - "i" (__FILE__) ) - -#define assert_failed(p) \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1" \ - " ; .byte 0x48,0xbc ; .quad %c2" \ - : : "i" (BUGFRAME_assert | (__LINE__<<2)), \ - "i" (__FILE__), "i" (#p) ) +#define bug_str(b, rip) ((const char *)(rip) + (b).str_disp) +#define BUG_STR(n) "; movl %" #n " - ., %%esp" #endif /* __X86_64_BUG_H__ */ From 539cb7fec62a287be5e71badd4875f791ef80c0b Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:27:03 +0100 Subject: [PATCH 41/76] hvmloader acpi: Reserve ioport ranges for expanded PHP Now there are two control registers plus one register for each of the 32 PHP slots. A total of 34 registers. Accordingly the ioport space required has expanded by from 3 to 34 bytes. Signed-off-by: Simon Horman hvmloader acpi: Use If and Else instead of Switch Signed-off-by: Simon Horman --- tools/firmware/hvmloader/acpi/dsdt.asl | 227 ++++++++++--------- tools/firmware/hvmloader/acpi/dsdt.c | 290 ++++++++++++------------- 2 files changed, 272 insertions(+), 245 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/dsdt.asl b/tools/firmware/hvmloader/acpi/dsdt.asl index a21574e0bb..44a502208e 100644 --- a/tools/firmware/hvmloader/acpi/dsdt.asl +++ b/tools/firmware/hvmloader/acpi/dsdt.asl @@ -123,7 +123,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0) Name (_BBN, 0x00) /* - * Reserve the IO port ranges [0x10c0, 0x10c2] and [0xb044, 0xb047]. + * Reserve the IO port ranges [0x10c0, 0x10e1] and [0xb044, 0xb047]. * Or else, for a hotplugged-in device, the port IO BAR assigned * by guest OS may conflict with the ranges here. */ @@ -131,7 +131,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0) { Name(_HID, EISAID("PNP0C02")) Name(_CRS, ResourceTemplate() { - IO (Decode16, 0x10c0, 0x10c0, 0x00, 0x03) + IO (Decode16, 0x10c0, 0x10c0, 0x00, 0x22) IO (Decode16, 0xb044, 0xb044, 0x00, 0x04) }) } @@ -2067,104 +2067,133 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0) Store (SLT, DPT1) Store (EVT, DPT2) - Switch (SLT) + If ( LEqual(SLT, 0x00) ) { - Case (0x00) { - Notify (\_SB.PCI0.S00, EVT) - } - Case (0x01) { - Notify (\_SB.PCI0.S01, EVT) - } - Case (0x02) { - Notify (\_SB.PCI0.S02, EVT) - } - Case (0x03) { - Notify (\_SB.PCI0.S03, EVT) - } - Case (0x04) { - Notify (\_SB.PCI0.S04, EVT) - } - Case (0x05) { - Notify (\_SB.PCI0.S05, EVT) - } - Case (0x06) { - Notify (\_SB.PCI0.S06, EVT) - } - Case (0x07) { - Notify (\_SB.PCI0.S07, EVT) - } - Case (0x08) { - Notify (\_SB.PCI0.S08, EVT) - } - Case (0x09) { - Notify (\_SB.PCI0.S09, EVT) - } - Case (0x0a) { - Notify (\_SB.PCI0.S0A, EVT) - } - Case (0x0b) { - Notify (\_SB.PCI0.S0B, EVT) - } - Case (0x0c) { - Notify (\_SB.PCI0.S0C, EVT) - } - Case (0x0d) { - Notify (\_SB.PCI0.S0D, EVT) - } - Case (0x0e) { - Notify (\_SB.PCI0.S0E, EVT) - } - Case (0x0f) { - Notify (\_SB.PCI0.S0F, EVT) - } - Case (0x10) { - Notify (\_SB.PCI0.S10, EVT) - } - Case (0x11) { - Notify (\_SB.PCI0.S11, EVT) - } - Case (0x12) { - Notify (\_SB.PCI0.S12, EVT) - } - Case (0x13) { - Notify (\_SB.PCI0.S13, EVT) - } - Case (0x14) { - Notify (\_SB.PCI0.S14, EVT) - } - Case (0x15) { - Notify (\_SB.PCI0.S15, EVT) - } - Case (0x16) { - Notify (\_SB.PCI0.S16, EVT) - } - Case (0x17) { - Notify (\_SB.PCI0.S17, EVT) - } - Case (0x18) { - Notify (\_SB.PCI0.S18, EVT) - } - Case (0x19) { - Notify (\_SB.PCI0.S19, EVT) - } - Case (0x1a) { - Notify (\_SB.PCI0.S1A, EVT) - } - Case (0x1b) { - Notify (\_SB.PCI0.S1B, EVT) - } - Case (0x1c) { - Notify (\_SB.PCI0.S1C, EVT) - } - Case (0x1d) { - Notify (\_SB.PCI0.S1D, EVT) - } - Case (0x1e) { - Notify (\_SB.PCI0.S1E, EVT) - } - Case (0x1f) { - Notify (\_SB.PCI0.S1F, EVT) - } + Notify (\_SB.PCI0.S00, EVT) + } + ElseIf ( LEqual(SLT, 0x01) ) + { + Notify (\_SB.PCI0.S01, EVT) + } + ElseIf ( LEqual(SLT, 0x02) ) + { + Notify (\_SB.PCI0.S02, EVT) + } + ElseIf ( LEqual(SLT, 0x03) ) + { + Notify (\_SB.PCI0.S03, EVT) + } + ElseIf ( LEqual(SLT, 0x04) ) + { + Notify (\_SB.PCI0.S04, EVT) + } + ElseIf ( LEqual(SLT, 0x05) ) + { + Notify (\_SB.PCI0.S05, EVT) + } + ElseIf ( LEqual(SLT, 0x06) ) + { + Notify (\_SB.PCI0.S06, EVT) + } + ElseIf ( LEqual(SLT, 0x07) ) + { + Notify (\_SB.PCI0.S07, EVT) + } + ElseIf ( LEqual(SLT, 0x08) ) + { + Notify (\_SB.PCI0.S08, EVT) + } + ElseIf ( LEqual(SLT, 0x09) ) + { + Notify (\_SB.PCI0.S09, EVT) + } + ElseIf ( LEqual(SLT, 0x0a) ) + { + Notify (\_SB.PCI0.S0A, EVT) + } + ElseIf ( LEqual(SLT, 0x0b) ) + { + Notify (\_SB.PCI0.S0B, EVT) + } + ElseIf ( LEqual(SLT, 0x0c) ) + { + Notify (\_SB.PCI0.S0C, EVT) + } + ElseIf ( LEqual(SLT, 0x0d) ) + { + Notify (\_SB.PCI0.S0D, EVT) + } + ElseIf ( LEqual(SLT, 0x0e) ) + { + Notify (\_SB.PCI0.S0E, EVT) + } + ElseIf ( LEqual(SLT, 0x0f) ) + { + Notify (\_SB.PCI0.S0F, EVT) + } + ElseIf ( LEqual(SLT, 0x10) ) + { + Notify (\_SB.PCI0.S10, EVT) + } + ElseIf ( LEqual(SLT, 0x11) ) + { + Notify (\_SB.PCI0.S11, EVT) + } + ElseIf ( LEqual(SLT, 0x12) ) + { + Notify (\_SB.PCI0.S12, EVT) + } + ElseIf ( LEqual(SLT, 0x13) ) + { + Notify (\_SB.PCI0.S13, EVT) + } + ElseIf ( LEqual(SLT, 0x14) ) + { + Notify (\_SB.PCI0.S14, EVT) + } + ElseIf ( LEqual(SLT, 0x15) ) + { + Notify (\_SB.PCI0.S15, EVT) + } + ElseIf ( LEqual(SLT, 0x16) ) + { + Notify (\_SB.PCI0.S16, EVT) + } + ElseIf ( LEqual(SLT, 0x17) ) + { + Notify (\_SB.PCI0.S17, EVT) + } + ElseIf ( LEqual(SLT, 0x18) ) + { + Notify (\_SB.PCI0.S18, EVT) + } + ElseIf ( LEqual(SLT, 0x19) ) + { + Notify (\_SB.PCI0.S19, EVT) + } + ElseIf ( LEqual(SLT, 0x1a) ) + { + Notify (\_SB.PCI0.S1A, EVT) + } + ElseIf ( LEqual(SLT, 0x1b) ) + { + Notify (\_SB.PCI0.S1B, EVT) + } + ElseIf ( LEqual(SLT, 0x1c) ) + { + Notify (\_SB.PCI0.S1C, EVT) + } + ElseIf ( LEqual(SLT, 0x1d) ) + { + Notify (\_SB.PCI0.S1D, EVT) + } + ElseIf ( LEqual(SLT, 0x1e) ) + { + Notify (\_SB.PCI0.S1E, EVT) + } + ElseIf ( LEqual(SLT, 0x1f) ) + { + Notify (\_SB.PCI0.S1F, EVT) } } } diff --git a/tools/firmware/hvmloader/acpi/dsdt.c b/tools/firmware/hvmloader/acpi/dsdt.c index ca58b32ee3..8216f8b006 100644 --- a/tools/firmware/hvmloader/acpi/dsdt.c +++ b/tools/firmware/hvmloader/acpi/dsdt.c @@ -1,22 +1,22 @@ /* * * Intel ACPI Component Architecture - * ASL Optimizing Compiler version 20090220 [Mar 9 2009] - * Copyright (C) 2000 - 2009 Intel Corporation + * ASL Optimizing Compiler version 20081204 [Jan 23 2009] + * Copyright (C) 2000 - 2008 Intel Corporation * Supports ACPI Specification Revision 3.0a * - * Compilation of "dsdt.asl" - Tue Mar 17 10:44:21 2009 + * Compilation of "dsdt.asl" - Tue Mar 31 13:24:51 2009 * * C source code output * */ unsigned char AmlCode[] = { - 0x44,0x53,0x44,0x54,0x02,0x32,0x00,0x00, /* 00000000 "DSDT.2.." */ - 0x02,0xC6,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ + 0x44,0x53,0x44,0x54,0xF3,0x31,0x00,0x00, /* 00000000 "DSDT.1.." */ + 0x02,0x12,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ 0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00, /* 00000010 "HVM....." */ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ - 0x20,0x02,0x09,0x20,0x08,0x50,0x4D,0x42, /* 00000020 " .. .PMB" */ + 0x04,0x12,0x08,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "... .PMB" */ 0x53,0x0B,0x00,0x0C,0x08,0x50,0x4D,0x4C, /* 00000028 "S....PML" */ 0x4E,0x0A,0x08,0x08,0x49,0x4F,0x42,0x31, /* 00000030 "N...IOB1" */ 0x00,0x08,0x49,0x4F,0x4C,0x31,0x00,0x08, /* 00000038 "..IOL1.." */ @@ -81,7 +81,7 @@ unsigned char AmlCode[] = 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000210 "._HID.A." */ 0x0C,0x02,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000218 "..._CRS." */ 0x15,0x0A,0x12,0x47,0x01,0xC0,0x10,0xC0, /* 00000220 "...G...." */ - 0x10,0x00,0x03,0x47,0x01,0x44,0xB0,0x44, /* 00000228 "...G.D.D" */ + 0x10,0x00,0x22,0x47,0x01,0x44,0xB0,0x44, /* 00000228 ".."G.D.D" */ 0xB0,0x00,0x04,0x79,0x00,0x14,0x4E,0x0C, /* 00000230 "...y..N." */ 0x5F,0x43,0x52,0x53,0x00,0x08,0x50,0x52, /* 00000238 "_CRS..PR" */ 0x54,0x30,0x11,0x42,0x07,0x0A,0x6E,0x88, /* 00000240 "T0.B..n." */ @@ -1446,7 +1446,7 @@ unsigned char AmlCode[] = 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00002CB8 "DPT1p..\" */ 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002CC0 "._GPEDPT" */ 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002CC8 "2.\._GPE" */ - 0x50,0x48,0x31,0x46,0x10,0x4D,0x52,0x5F, /* 00002CD0 "PH1F.MR_" */ + 0x50,0x48,0x31,0x46,0x10,0x4E,0x51,0x5F, /* 00002CD0 "PH1F.NQ_" */ 0x47,0x50,0x45,0x5B,0x80,0x50,0x48,0x50, /* 00002CD8 "GPE[.PHP" */ 0x5F,0x01,0x0B,0xC0,0x10,0x0A,0x22,0x5B, /* 00002CE0 "_....."[" */ 0x81,0x41,0x0B,0x50,0x48,0x50,0x5F,0x01, /* 00002CE8 ".A.PHP_." */ @@ -1475,143 +1475,141 @@ unsigned char AmlCode[] = 0x01,0x0B,0x44,0xB0,0x0A,0x04,0x5B,0x81, /* 00002DA0 "..D...[." */ 0x10,0x44,0x47,0x31,0x5F,0x01,0x44,0x50, /* 00002DA8 ".DG1_.DP" */ 0x54,0x31,0x08,0x44,0x50,0x54,0x32,0x08, /* 00002DB0 "T1.DPT2." */ - 0x14,0x49,0x44,0x5F,0x4C,0x30,0x33,0x08, /* 00002DB8 ".ID_L03." */ - 0x08,0x5F,0x54,0x5F,0x30,0x00,0x08,0x53, /* 00002DC0 "._T_0..S" */ - 0x4C,0x54,0x5F,0x00,0x08,0x45,0x56,0x54, /* 00002DC8 "LT_..EVT" */ - 0x5F,0x00,0x70,0x50,0x53,0x54,0x41,0x61, /* 00002DD0 "_.pPSTAa" */ - 0x7B,0x61,0x0A,0x0F,0x45,0x56,0x54,0x5F, /* 00002DD8 "{a..EVT_" */ - 0x70,0x50,0x53,0x54,0x42,0x61,0x7B,0x61, /* 00002DE0 "pPSTBa{a" */ - 0x0A,0xFF,0x53,0x4C,0x54,0x5F,0x70,0x53, /* 00002DE8 "..SLT_pS" */ - 0x4C,0x54,0x5F,0x44,0x50,0x54,0x31,0x70, /* 00002DF0 "LT_DPT1p" */ - 0x45,0x56,0x54,0x5F,0x44,0x50,0x54,0x32, /* 00002DF8 "EVT_DPT2" */ - 0x70,0x53,0x4C,0x54,0x5F,0x5F,0x54,0x5F, /* 00002E00 "pSLT__T_" */ - 0x30,0xA0,0x1B,0x93,0x5F,0x54,0x5F,0x30, /* 00002E08 "0..._T_0" */ - 0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002E10 "..\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x30, /* 00002E18 "_PCI0S00" */ - 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4C,0x3D, /* 00002E20 "_EVT_.L=" */ - 0xA0,0x1B,0x93,0x5F,0x54,0x5F,0x30,0x01, /* 00002E28 "..._T_0." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002E30 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x31,0x5F, /* 00002E38 "PCI0S01_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x3B,0xA0, /* 00002E40 "EVT_.M;." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x02, /* 00002E48 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002E50 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x32,0x5F, /* 00002E58 "PCI0S02_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x39,0xA0, /* 00002E60 "EVT_.M9." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x03, /* 00002E68 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002E70 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x33,0x5F, /* 00002E78 "PCI0S03_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x37,0xA0, /* 00002E80 "EVT_.M7." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x04, /* 00002E88 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002E90 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x34,0x5F, /* 00002E98 "PCI0S04_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x35,0xA0, /* 00002EA0 "EVT_.M5." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x05, /* 00002EA8 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002EB0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x35,0x5F, /* 00002EB8 "PCI0S05_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x33,0xA0, /* 00002EC0 "EVT_.M3." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x06, /* 00002EC8 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002ED0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x36,0x5F, /* 00002ED8 "PCI0S06_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x31,0xA0, /* 00002EE0 "EVT_.M1." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x07, /* 00002EE8 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002EF0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x37,0x5F, /* 00002EF8 "PCI0S07_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2F,0xA0, /* 00002F00 "EVT_.M/." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x08, /* 00002F08 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002F10 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x38,0x5F, /* 00002F18 "PCI0S08_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2D,0xA0, /* 00002F20 "EVT_.M-." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x09, /* 00002F28 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002F30 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x39,0x5F, /* 00002F38 "PCI0S09_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2B,0xA0, /* 00002F40 "EVT_.M+." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0A, /* 00002F48 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002F50 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x41,0x5F, /* 00002F58 "PCI0S0A_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x29,0xA0, /* 00002F60 "EVT_.M)." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0B, /* 00002F68 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002F70 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x42,0x5F, /* 00002F78 "PCI0S0B_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x27,0xA0, /* 00002F80 "EVT_.M'." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0C, /* 00002F88 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002F90 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x43,0x5F, /* 00002F98 "PCI0S0C_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x25,0xA0, /* 00002FA0 "EVT_.M%." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0D, /* 00002FA8 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002FB0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x44,0x5F, /* 00002FB8 "PCI0S0D_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x23,0xA0, /* 00002FC0 "EVT_.M#." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0E, /* 00002FC8 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002FD0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x45,0x5F, /* 00002FD8 "PCI0S0E_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x21,0xA0, /* 00002FE0 "EVT_.M!." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0F, /* 00002FE8 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002FF0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x30,0x46,0x5F, /* 00002FF8 "PCI0S0F_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1F,0xA0, /* 00003000 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x10, /* 00003008 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003010 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x30,0x5F, /* 00003018 "PCI0S10_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1D,0xA0, /* 00003020 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x11, /* 00003028 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003030 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x31,0x5F, /* 00003038 "PCI0S11_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1B,0xA0, /* 00003040 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x12, /* 00003048 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003050 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x32,0x5F, /* 00003058 "PCI0S12_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x19,0xA0, /* 00003060 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x13, /* 00003068 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003070 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x33,0x5F, /* 00003078 "PCI0S13_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x17,0xA0, /* 00003080 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x14, /* 00003088 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003090 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x34,0x5F, /* 00003098 "PCI0S14_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x15,0xA0, /* 000030A0 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x15, /* 000030A8 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000030B0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x35,0x5F, /* 000030B8 "PCI0S15_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x13,0xA0, /* 000030C0 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x16, /* 000030C8 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000030D0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x36,0x5F, /* 000030D8 "PCI0S16_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x11,0xA0, /* 000030E0 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x17, /* 000030E8 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000030F0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x37,0x5F, /* 000030F8 "PCI0S17_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0F,0xA0, /* 00003100 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x18, /* 00003108 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003110 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x38,0x5F, /* 00003118 "PCI0S18_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0D,0xA0, /* 00003120 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x19, /* 00003128 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003130 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x39,0x5F, /* 00003138 "PCI0S19_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0B,0xA0, /* 00003140 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1A, /* 00003148 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003150 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x41,0x5F, /* 00003158 "PCI0S1A_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x09,0xA0, /* 00003160 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1B, /* 00003168 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003170 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x42,0x5F, /* 00003178 "PCI0S1B_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x07,0xA0, /* 00003180 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1C, /* 00003188 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003190 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x43,0x5F, /* 00003198 "PCI0S1C_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x05,0xA0, /* 000031A0 "EVT_.M.." */ - 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1D, /* 000031A8 ".._T_0.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000031B0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x44,0x5F, /* 000031B8 "PCI0S1D_" */ - 0x45,0x56,0x54,0x5F,0xA1,0x3D,0xA0,0x1C, /* 000031C0 "EVT_.=.." */ - 0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1E,0x86, /* 000031C8 "._T_0..." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 000031D0 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x31,0x45,0x5F,0x45, /* 000031D8 "CI0S1E_E" */ - 0x56,0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93, /* 000031E0 "VT_....." */ - 0x5F,0x54,0x5F,0x30,0x0A,0x1F,0x86,0x5C, /* 000031E8 "_T_0...\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 000031F0 "/._SB_PC" */ - 0x49,0x30,0x53,0x31,0x46,0x5F,0x45,0x56, /* 000031F8 "I0S1F_EV" */ - 0x54,0x5F, + 0x14,0x4A,0x43,0x5F,0x4C,0x30,0x33,0x08, /* 00002DB8 ".JC_L03." */ + 0x08,0x53,0x4C,0x54,0x5F,0x00,0x08,0x45, /* 00002DC0 ".SLT_..E" */ + 0x56,0x54,0x5F,0x00,0x70,0x50,0x53,0x54, /* 00002DC8 "VT_.pPST" */ + 0x41,0x61,0x7B,0x61,0x0A,0x0F,0x45,0x56, /* 00002DD0 "Aa{a..EV" */ + 0x54,0x5F,0x70,0x50,0x53,0x54,0x42,0x61, /* 00002DD8 "T_pPSTBa" */ + 0x7B,0x61,0x0A,0xFF,0x53,0x4C,0x54,0x5F, /* 00002DE0 "{a..SLT_" */ + 0x70,0x53,0x4C,0x54,0x5F,0x44,0x50,0x54, /* 00002DE8 "pSLT_DPT" */ + 0x31,0x70,0x45,0x56,0x54,0x5F,0x44,0x50, /* 00002DF0 "1pEVT_DP" */ + 0x54,0x32,0xA0,0x1B,0x93,0x53,0x4C,0x54, /* 00002DF8 "T2...SLT" */ + 0x5F,0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53, /* 00002E00 "_..\/._S" */ + 0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x30, /* 00002E08 "B_PCI0S0" */ + 0x30,0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4C, /* 00002E10 "0_EVT_.L" */ + 0x3D,0xA0,0x1B,0x93,0x53,0x4C,0x54,0x5F, /* 00002E18 "=...SLT_" */ + 0x01,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002E20 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x31, /* 00002E28 "_PCI0S01" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x3B, /* 00002E30 "_EVT_.M;" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002E38 "...SLT_." */ + 0x02,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002E40 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x32, /* 00002E48 "_PCI0S02" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x39, /* 00002E50 "_EVT_.M9" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002E58 "...SLT_." */ + 0x03,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002E60 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x33, /* 00002E68 "_PCI0S03" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x37, /* 00002E70 "_EVT_.M7" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002E78 "...SLT_." */ + 0x04,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002E80 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x34, /* 00002E88 "_PCI0S04" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x35, /* 00002E90 "_EVT_.M5" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002E98 "...SLT_." */ + 0x05,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002EA0 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x35, /* 00002EA8 "_PCI0S05" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x33, /* 00002EB0 "_EVT_.M3" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002EB8 "...SLT_." */ + 0x06,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002EC0 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x36, /* 00002EC8 "_PCI0S06" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x31, /* 00002ED0 "_EVT_.M1" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002ED8 "...SLT_." */ + 0x07,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002EE0 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x37, /* 00002EE8 "_PCI0S07" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2F, /* 00002EF0 "_EVT_.M/" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002EF8 "...SLT_." */ + 0x08,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002F00 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x38, /* 00002F08 "_PCI0S08" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2D, /* 00002F10 "_EVT_.M-" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002F18 "...SLT_." */ + 0x09,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002F20 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x39, /* 00002F28 "_PCI0S09" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2B, /* 00002F30 "_EVT_.M+" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002F38 "...SLT_." */ + 0x0A,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002F40 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x41, /* 00002F48 "_PCI0S0A" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x29, /* 00002F50 "_EVT_.M)" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002F58 "...SLT_." */ + 0x0B,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002F60 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x42, /* 00002F68 "_PCI0S0B" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x27, /* 00002F70 "_EVT_.M'" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002F78 "...SLT_." */ + 0x0C,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002F80 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x43, /* 00002F88 "_PCI0S0C" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x25, /* 00002F90 "_EVT_.M%" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002F98 "...SLT_." */ + 0x0D,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002FA0 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x44, /* 00002FA8 "_PCI0S0D" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x23, /* 00002FB0 "_EVT_.M#" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002FB8 "...SLT_." */ + 0x0E,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002FC0 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x45, /* 00002FC8 "_PCI0S0E" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x21, /* 00002FD0 "_EVT_.M!" */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002FD8 "...SLT_." */ + 0x0F,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002FE0 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x46, /* 00002FE8 "_PCI0S0F" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1F, /* 00002FF0 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00002FF8 "...SLT_." */ + 0x10,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00003000 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x30, /* 00003008 "_PCI0S10" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1D, /* 00003010 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00003018 "...SLT_." */ + 0x11,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00003020 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x31, /* 00003028 "_PCI0S11" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1B, /* 00003030 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00003038 "...SLT_." */ + 0x12,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00003040 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x32, /* 00003048 "_PCI0S12" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x19, /* 00003050 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00003058 "...SLT_." */ + 0x13,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00003060 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x33, /* 00003068 "_PCI0S13" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x17, /* 00003070 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00003078 "...SLT_." */ + 0x14,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00003080 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x34, /* 00003088 "_PCI0S14" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x15, /* 00003090 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00003098 "...SLT_." */ + 0x15,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 000030A0 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x35, /* 000030A8 "_PCI0S15" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x13, /* 000030B0 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 000030B8 "...SLT_." */ + 0x16,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 000030C0 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x36, /* 000030C8 "_PCI0S16" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x11, /* 000030D0 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 000030D8 "...SLT_." */ + 0x17,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 000030E0 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x37, /* 000030E8 "_PCI0S17" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0F, /* 000030F0 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 000030F8 "...SLT_." */ + 0x18,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00003100 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x38, /* 00003108 "_PCI0S18" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0D, /* 00003110 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00003118 "...SLT_." */ + 0x19,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00003120 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x39, /* 00003128 "_PCI0S19" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0B, /* 00003130 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00003138 "...SLT_." */ + 0x1A,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00003140 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x41, /* 00003148 "_PCI0S1A" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x09, /* 00003150 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00003158 "...SLT_." */ + 0x1B,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00003160 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x42, /* 00003168 "_PCI0S1B" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x07, /* 00003170 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00003178 "...SLT_." */ + 0x1C,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00003180 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x43, /* 00003188 "_PCI0S1C" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4D,0x05, /* 00003190 "_EVT_.M." */ + 0xA0,0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A, /* 00003198 "...SLT_." */ + 0x1D,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 000031A0 "..\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x44, /* 000031A8 "_PCI0S1D" */ + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x3D,0xA0, /* 000031B0 "_EVT_.=." */ + 0x1C,0x93,0x53,0x4C,0x54,0x5F,0x0A,0x1E, /* 000031B8 "..SLT_.." */ + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000031C0 ".\/._SB_" */ + 0x50,0x43,0x49,0x30,0x53,0x31,0x45,0x5F, /* 000031C8 "PCI0S1E_" */ + 0x45,0x56,0x54,0x5F,0xA1,0x1E,0xA0,0x1C, /* 000031D0 "EVT_...." */ + 0x93,0x53,0x4C,0x54,0x5F,0x0A,0x1F,0x86, /* 000031D8 ".SLT_..." */ + 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 000031E0 "\/._SB_P" */ + 0x43,0x49,0x30,0x53,0x31,0x46,0x5F,0x45, /* 000031E8 "CI0S1F_E" */ + 0x56,0x54,0x5F, }; int DsdtLen=sizeof(AmlCode); From e24c23a5110ee350c95ed7400f8270e4bb4d9f33 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:28:45 +0100 Subject: [PATCH 42/76] x86: Enable S3 for 32bit dom0 on 64bit Xen Three SYSENTER MSRs should be taken care of at save/restore BSP context, or else 32bit dom0 rejects working after S3 resume. Thanks for Jan's help to find this missing part. Signed-off-by: Guanqun Lu Signed-off-by: Kevin Tian --- xen/arch/x86/acpi/suspend.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xen/arch/x86/acpi/suspend.c b/xen/arch/x86/acpi/suspend.c index 0aac31da68..bcb3e83bde 100644 --- a/xen/arch/x86/acpi/suspend.c +++ b/xen/arch/x86/acpi/suspend.c @@ -16,6 +16,7 @@ #if defined(CONFIG_X86_64) static unsigned long saved_lstar, saved_cstar; +static unsigned long saved_sysenter_esp, saved_sysenter_eip; #endif void save_rest_processor_state(void) @@ -26,6 +27,11 @@ void save_rest_processor_state(void) #if defined(CONFIG_X86_64) rdmsrl(MSR_CSTAR, saved_cstar); rdmsrl(MSR_LSTAR, saved_lstar); + if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) + { + rdmsrl(MSR_IA32_SYSENTER_ESP, saved_sysenter_esp); + rdmsrl(MSR_IA32_SYSENTER_EIP, saved_sysenter_eip); + } #endif } @@ -41,6 +47,14 @@ void restore_rest_processor_state(void) wrmsrl(MSR_CSTAR, saved_cstar); wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS); wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U); + + if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) + { + /* Recover sysenter MSRs */ + wrmsrl(MSR_IA32_SYSENTER_ESP, saved_sysenter_esp); + wrmsrl(MSR_IA32_SYSENTER_EIP, saved_sysenter_eip); + wrmsr(MSR_IA32_SYSENTER_CS, __HYPERVISOR_CS, 0); + } #else /* !defined(CONFIG_X86_64) */ if ( supervisor_mode_kernel && cpu_has_sep ) wrmsr(MSR_IA32_SYSENTER_ESP, &init_tss[smp_processor_id()].esp1, 0); From 98da66a3bda9c9d31630c7d794db68413916a104 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:30:50 +0100 Subject: [PATCH 43/76] build: Get rid of some more hardcoded install paths Signed-off-by: Christoph Egger --- Config.mk | 6 ++++-- config/StdGNU.mk | 3 ++- tools/pygrub/Makefile | 2 +- tools/python/Makefile | 10 +++++----- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Config.mk b/Config.mk index abdb1abe4a..2cdc7660e3 100644 --- a/Config.mk +++ b/Config.mk @@ -19,8 +19,6 @@ HOSTCFLAGS += -fno-strict-aliasing DISTDIR ?= $(XEN_ROOT)/dist DESTDIR ?= / -DOCDIR ?= /usr/share/doc/xen -MANDIR ?= /usr/share/man # Allow phony attribute to be listed as dependency rather than fake target .PHONY: .phony @@ -28,6 +26,10 @@ MANDIR ?= /usr/share/man include $(XEN_ROOT)/config/$(XEN_OS).mk include $(XEN_ROOT)/config/$(XEN_TARGET_ARCH).mk +SHAREDIR ?= $(PREFIX)/share +DOCDIR ?= $(SHAREDIR)/doc/xen +MANDIR ?= $(SHAREDIR)/man + ifneq ($(EXTRA_PREFIX),) EXTRA_INCLUDES += $(EXTRA_PREFIX)/include EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBLEAFDIR) diff --git a/config/StdGNU.mk b/config/StdGNU.mk index d3d69bf944..812d389a28 100644 --- a/config/StdGNU.mk +++ b/config/StdGNU.mk @@ -31,7 +31,8 @@ LIBDIR = $(PREFIX)/$(LIBLEAFDIR) LIBDIR_x86_32 = $(PREFIX)/$(LIBLEAFDIR_x86_32) LIBDIR_x86_64 = $(PREFIX)/$(LIBLEAFDIR_x86_64) LIBEXEC = $(LIBDIR_x86_32)/xen/bin -MANDIR = $(PREFIX)/share/man +SHAREDIR = $(PREFIX)/share +MANDIR = $(SHAREDIR)/man MAN1DIR = $(MANDIR)/man1 MAN8DIR = $(MANDIR)/man8 SBINDIR = $(PREFIX)/sbin diff --git a/tools/pygrub/Makefile b/tools/pygrub/Makefile index 03c8ed9530..48e982c075 100644 --- a/tools/pygrub/Makefile +++ b/tools/pygrub/Makefile @@ -12,7 +12,7 @@ build: ifndef XEN_PYTHON_NATIVE_INSTALL install: LIBPATH=$(shell PYTHONPATH=../python/xen/util python -c "import auxbin; print auxbin.libpath()") install: all - CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" --prefix="" --install-lib="$(DESTDIR)$(LIBPATH)/python" + CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)$(PREFIX)" --prefix="" --install-lib="$(DESTDIR)$(LIBDIR)/python" $(INSTALL_DIR) $(DESTDIR)/var/run/xend/boot else install: all diff --git a/tools/python/Makefile b/tools/python/Makefile index 4ae0a2d777..249bf634e7 100644 --- a/tools/python/Makefile +++ b/tools/python/Makefile @@ -12,7 +12,7 @@ PODIR := xen/xm/messages POTFILE := $(PODIR)/xen-xm.pot I18NSRCFILES = $(shell find xen/xm/ -name '*.py') CATALOGS = $(patsubst %,xen/xm/messages/%.mo,$(LINGUAS)) -NLSDIR = /usr/share/locale +NLSDIR = $(SHAREDIR)/locale .PHONY: build buildpy buildpy: @@ -57,19 +57,19 @@ refresh-po: $(POTFILE) ifndef XEN_PYTHON_NATIVE_INSTALL install: LIBPATH=$(shell PYTHONPATH=xen/util python -c "import auxbin; print auxbin.libpath()") install: install-messages install-dtd - CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" --prefix="" --force --install-lib="$(DESTDIR)$(LIBPATH)/python" + CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)$(PREFIX)" --prefix="" --force --install-lib="$(DESTDIR)$(LIBDIR)/python" else install: install-messages install-dtd CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --force endif install-dtd: all - $(INSTALL_DIR) $(DESTDIR)/usr/share/xen - $(INSTALL_DATA) xen/xm/create.dtd $(DESTDIR)/usr/share/xen + $(INSTALL_DIR) $(DESTDIR)$(DOCDIR) + $(INSTALL_DATA) xen/xm/create.dtd $(DESTDIR)$(DOCDIR) install-messages: all set -e; if which $(MSGFMT) >/dev/null ; then \ - mkdir -p $(DESTDIR)$(NLSDIR); \ + $(INSTALL_DIR) $(DESTDIR)$(NLSDIR); \ for l in $(LINGUAS); do \ $(INSTALL_DIR) $(DESTDIR)$(NLSDIR)/$$l; \ $(INSTALL_DIR) $(DESTDIR)$(NLSDIR)/$$l/LC_MESSAGES; \ From 2fa8c71b9f71b6973cce13cd41a45aac4baf17de Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 13:57:11 +0100 Subject: [PATCH 44/76] xend: Fix domain creation. Signed-off-by: Keir Fraser --- tools/python/xen/xend/XendDomainInfo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 7497c7e435..8cc2084acf 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -2324,9 +2324,9 @@ class XendDomainInfo: if weight < 1 or weight > 65535: raise VmError("Cpu weight out of range, valid values are within range from 1 to 65535") - if cap < 0 or cap > dominfo.getVCpuCount() * 100: + if cap < 0 or cap > self.getVCpuCount() * 100: raise VmError("Cpu cap out of range, valid range is from 0 to %s for specified number of vcpus" % - (dominfo.getVCpuCount() * 100)) + (self.getVCpuCount() * 100)) # Test whether the devices can be assigned with VT-d pci = self.info["platform"].get("pci") From c2901a5cc44c85a9ceeebd47ff21946bb35ba930 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 14:04:50 +0100 Subject: [PATCH 45/76] hvmloader: ROMBIOS must POST in big real mode, since it supports PMM, and hence Option ROMs can expect noi segment limit checks. Signed-off-by: Keir Fraser --- tools/firmware/hvmloader/hvmloader.c | 4 ++-- tools/firmware/rombios/32bitgateway.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c index 39aa949e1b..7552122d4a 100644 --- a/tools/firmware/hvmloader/hvmloader.c +++ b/tools/firmware/hvmloader/hvmloader.c @@ -88,8 +88,8 @@ asm ( " .align 8 \n" "gdt: \n" " .quad 0x0000000000000000 \n" - " .quad 0x00009a000000ffff \n" /* Ring 0 code, base 0 limit 0xffff */ - " .quad 0x000092000000ffff \n" /* Ring 0 data, base 0 limit 0xffff */ + " .quad 0x008f9a000000ffff \n" /* Ring 0 16b code, base 0 limit 4G */ + " .quad 0x008f92000000ffff \n" /* Ring 0 16b data, base 0 limit 4G */ "gdt_end: \n" " \n" " .bss \n" diff --git a/tools/firmware/rombios/32bitgateway.c b/tools/firmware/rombios/32bitgateway.c index 8b3dffa591..d76f19400f 100644 --- a/tools/firmware/rombios/32bitgateway.c +++ b/tools/firmware/rombios/32bitgateway.c @@ -56,13 +56,13 @@ gdt_entry_pm_32bit_cs: .byte 0x00, 0x9b, 0xcf, 0x00 gdt_entry_pm_16bit_cs: .word 0xffff, 0x0000 - .byte REAL_MODE_CODE_OFFSET >> 16, 0x9b, 0x0, 0x0 + .byte REAL_MODE_CODE_OFFSET >> 16, 0x9b, 0x8f, 0x0 gdt_entry_pm_32bit_ds: .word 0xffff, 0x0000 .byte 0x0, 0x93, 0xcf, 0x0 gdt_entry_pm_16bit_ds: .word 0xffff, 0x0000 - .byte 0x0, 0x93, 0x0, 0x0 + .byte 0x0, 0x93, 0x8f, 0x0 gdt_entry_end: protmode_gdtdesc: From 5f0dffe668f2792978a8a07520d43df0dd5d7ce3 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 15:03:59 +0100 Subject: [PATCH 46/76] Simplify spinlock code and re-enable IRQs where possible when spinning. Based on a patch by Juergen Gross. Signed-off-by: Keir Fraser --- xen/common/spinlock.c | 21 +++- xen/include/asm-ia64/linux-xen/asm/spinlock.h | 105 ------------------ xen/include/asm-x86/spinlock.h | 13 --- 3 files changed, 18 insertions(+), 121 deletions(-) diff --git a/xen/common/spinlock.c b/xen/common/spinlock.c index 002f82eee4..ac2aaab814 100644 --- a/xen/common/spinlock.c +++ b/xen/common/spinlock.c @@ -2,6 +2,7 @@ #include #include #include +#include #ifndef NDEBUG @@ -43,7 +44,9 @@ void spin_debug_disable(void) void _spin_lock(spinlock_t *lock) { check_lock(&lock->debug); - _raw_spin_lock(&lock->raw); + while ( unlikely(!_raw_spin_trylock(&lock->raw)) ) + while ( likely(_raw_spin_is_locked(&lock->raw)) ) + cpu_relax(); } void _spin_lock_irq(spinlock_t *lock) @@ -51,7 +54,13 @@ void _spin_lock_irq(spinlock_t *lock) ASSERT(local_irq_is_enabled()); local_irq_disable(); check_lock(&lock->debug); - _raw_spin_lock(&lock->raw); + while ( unlikely(!_raw_spin_trylock(&lock->raw)) ) + { + local_irq_enable(); + while ( likely(_raw_spin_is_locked(&lock->raw)) ) + cpu_relax(); + local_irq_disable(); + } } unsigned long _spin_lock_irqsave(spinlock_t *lock) @@ -59,7 +68,13 @@ unsigned long _spin_lock_irqsave(spinlock_t *lock) unsigned long flags; local_irq_save(flags); check_lock(&lock->debug); - _raw_spin_lock(&lock->raw); + while ( unlikely(!_raw_spin_trylock(&lock->raw)) ) + { + local_irq_restore(flags); + while ( likely(_raw_spin_is_locked(&lock->raw)) ) + cpu_relax(); + local_irq_save(flags); + } return flags; } diff --git a/xen/include/asm-ia64/linux-xen/asm/spinlock.h b/xen/include/asm-ia64/linux-xen/asm/spinlock.h index 14bf3a3c1b..f49d008bce 100644 --- a/xen/include/asm-ia64/linux-xen/asm/spinlock.h +++ b/xen/include/asm-ia64/linux-xen/asm/spinlock.h @@ -21,111 +21,9 @@ typedef struct { volatile unsigned int lock; -#ifdef CONFIG_PREEMPT - unsigned int break_lock; -#endif -#ifdef DEBUG_SPINLOCK - void *locker; -#endif } raw_spinlock_t; -#ifdef XEN -#ifdef DEBUG_SPINLOCK -#define _RAW_SPIN_LOCK_UNLOCKED /*(raw_spinlock_t)*/ { 0, NULL } -#else #define _RAW_SPIN_LOCK_UNLOCKED /*(raw_spinlock_t)*/ { 0 } -#endif -#else -#define _RAW_SPIN_LOCK_UNLOCKED /*(raw_spinlock_t)*/ { 0 } -#endif - -#ifdef ASM_SUPPORTED -/* - * Try to get the lock. If we fail to get the lock, make a non-standard call to - * ia64_spinlock_contention(). We do not use a normal call because that would force all - * callers of spin_lock() to be non-leaf routines. Instead, ia64_spinlock_contention() is - * carefully coded to touch only those registers that spin_lock() marks "clobbered". - */ - -#define IA64_SPINLOCK_CLOBBERS "ar.ccv", "ar.pfs", "p14", "p15", "r27", "r28", "r29", "r30", "b6", "memory" - -static inline void -_raw_spin_lock_flags (raw_spinlock_t *lock, unsigned long flags) -{ - register volatile unsigned int *ptr asm ("r31") = &lock->lock; - -#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) -# ifdef CONFIG_ITANIUM - /* don't use brl on Itanium... */ - asm volatile ("{\n\t" - " mov ar.ccv = r0\n\t" - " mov r28 = ip\n\t" - " mov r30 = 1;;\n\t" - "}\n\t" - "cmpxchg4.acq r30 = [%1], r30, ar.ccv\n\t" - "movl r29 = ia64_spinlock_contention_pre3_4;;\n\t" - "cmp4.ne p14, p0 = r30, r0\n\t" - "mov b6 = r29;;\n\t" - "mov r27=%2\n\t" - "(p14) br.cond.spnt.many b6" - : "=r"(ptr) : "r"(ptr), "r" (flags) : IA64_SPINLOCK_CLOBBERS); -# else - asm volatile ("{\n\t" - " mov ar.ccv = r0\n\t" - " mov r28 = ip\n\t" - " mov r30 = 1;;\n\t" - "}\n\t" - "cmpxchg4.acq r30 = [%1], r30, ar.ccv;;\n\t" - "cmp4.ne p14, p0 = r30, r0\n\t" - "mov r27=%2\n\t" - "(p14) brl.cond.spnt.many ia64_spinlock_contention_pre3_4;;" - : "=r"(ptr) : "r"(ptr), "r" (flags) : IA64_SPINLOCK_CLOBBERS); -# endif /* CONFIG_MCKINLEY */ -#else -# ifdef CONFIG_ITANIUM - /* don't use brl on Itanium... */ - /* mis-declare, so we get the entry-point, not it's function descriptor: */ - asm volatile ("mov r30 = 1\n\t" - "mov r27=%2\n\t" - "mov ar.ccv = r0;;\n\t" - "cmpxchg4.acq r30 = [%0], r30, ar.ccv\n\t" - "movl r29 = ia64_spinlock_contention;;\n\t" - "cmp4.ne p14, p0 = r30, r0\n\t" - "mov b6 = r29;;\n\t" - "(p14) br.call.spnt.many b6 = b6" - : "=r"(ptr) : "r"(ptr), "r" (flags) : IA64_SPINLOCK_CLOBBERS); -# else - asm volatile ("mov r30 = 1\n\t" - "mov r27=%2\n\t" - "mov ar.ccv = r0;;\n\t" - "cmpxchg4.acq r30 = [%0], r30, ar.ccv;;\n\t" - "cmp4.ne p14, p0 = r30, r0\n\t" - "(p14) brl.call.spnt.many b6=ia64_spinlock_contention;;" - : "=r"(ptr) : "r"(ptr), "r" (flags) : IA64_SPINLOCK_CLOBBERS); -# endif /* CONFIG_MCKINLEY */ -#endif - -#ifdef DEBUG_SPINLOCK - asm volatile ("mov %0=ip" : "=r" (lock->locker)); -#endif -} -#define _raw_spin_lock(lock) _raw_spin_lock_flags(lock, 0) -#else /* !ASM_SUPPORTED */ -#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) -# define _raw_spin_lock(x) \ -do { \ - __u32 *ia64_spinlock_ptr = (__u32 *) (x); \ - __u64 ia64_spinlock_val; \ - ia64_spinlock_val = ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0); \ - if (unlikely(ia64_spinlock_val)) { \ - do { \ - while (*ia64_spinlock_ptr) \ - ia64_barrier(); \ - ia64_spinlock_val = ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0); \ - } while (ia64_spinlock_val); \ - } \ -} while (0) -#endif /* !ASM_SUPPORTED */ #define _raw_spin_is_locked(x) ((x)->lock != 0) #define _raw_spin_unlock(x) do { barrier(); (x)->lock = 0; } while (0) @@ -134,9 +32,6 @@ do { \ typedef struct { volatile unsigned int read_counter : 31; volatile unsigned int write_lock : 1; -#ifdef CONFIG_PREEMPT - unsigned int break_lock; -#endif } raw_rwlock_t; #define _RAW_RW_LOCK_UNLOCKED /*(raw_rwlock_t)*/ { 0, 0 } diff --git a/xen/include/asm-x86/spinlock.h b/xen/include/asm-x86/spinlock.h index 66c4d51435..f1a5feb03c 100644 --- a/xen/include/asm-x86/spinlock.h +++ b/xen/include/asm-x86/spinlock.h @@ -13,19 +13,6 @@ typedef struct { #define _raw_spin_is_locked(x) ((x)->lock <= 0) -static always_inline void _raw_spin_lock(raw_spinlock_t *lock) -{ - asm volatile ( - "1: lock; decw %0 \n" - " jns 3f \n" - "2: rep; nop \n" - " cmpw $0,%0 \n" - " jle 2b \n" - " jmp 1b \n" - "3:" - : "=m" (lock->lock) : : "memory" ); -} - static always_inline void _raw_spin_unlock(raw_spinlock_t *lock) { ASSERT(_raw_spin_is_locked(lock)); From 14d0d003b64cb62bef1702290e9b3bfa6c5cc513 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 18:37:58 +0100 Subject: [PATCH 47/76] stubdom: Add newlib-chk.patch From: "George S. Coker, II" Signed-off-by: Samuel Thibault --- stubdom/newlib-chk.patch | 159 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 stubdom/newlib-chk.patch diff --git a/stubdom/newlib-chk.patch b/stubdom/newlib-chk.patch new file mode 100644 index 0000000000..29c1de2d68 --- /dev/null +++ b/stubdom/newlib-chk.patch @@ -0,0 +1,159 @@ +diff -Naur newlib-1.16.0/newlib/libc/stdio/fprintf_chk.c newlib-1.16.0/newlib/libc/stdio/fprintf_chk.c +--- newlib-1.16.0/newlib/libc/stdio/fprintf_chk.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.16.0/newlib/libc/stdio/fprintf_chk.c 2009-02-26 19:02:53.000000000 -0500 +@@ -0,0 +1,21 @@ ++#include ++#include ++ ++/* ++ * Stub implementation of __fprintf_chk adapted from glibc 2.7. This ++ * doesn't actually implement any buffer overflow protection. It just makes ++ * the linker happy :) ++*/ ++int ++__fprintf_chk (FILE *fp, int flag, const char *format, ...) ++{ ++ va_list ap; ++ int done; ++ ++ va_start (ap, format); ++ done = vfprintf (fp, format, ap); ++ va_end (ap); ++ ++ return done; ++} ++ +diff -Naur newlib-1.16.0/newlib/libc/stdio/Makefile.am newlib-1.16.0/newlib/libc/stdio/Makefile.am +--- ./newlib-1.16.0/newlib/libc/stdio/Makefile.am 2007-08-02 16:23:06.000000000 -0400 ++++ ./newlib-1.16.0/newlib/libc/stdio/Makefile.am 2009-02-26 18:14:53.000000000 -0500 +@@ -20,6 +20,7 @@ + flags.c \ + fopen.c \ + fprintf.c \ ++ fprintf_chk.c \ + fputc.c \ + fputs.c \ + fread.c \ +@@ -65,6 +66,7 @@ + sniprintf.c \ + snprintf.c \ + sprintf.c \ ++ sprintf_chk.c \ + sscanf.c \ + stdio.c \ + tmpfile.c \ +diff -Naur newlib-1.16.0/newlib/libc/stdio/Makefile.in newlib-1.16.0/newlib/libc/stdio/Makefile.in +--- newlib-1.16.0/newlib/libc/stdio/Makefile.in 2007-12-19 17:36:38.000000000 -0500 ++++ newlib-1.16.0/newlib/libc/stdio/Makefile.in 2009-02-26 18:43:52.000000000 -0500 +@@ -63,7 +63,8 @@ + lib_a-fgets.$(OBJEXT) lib_a-fileno.$(OBJEXT) \ + lib_a-findfp.$(OBJEXT) lib_a-fiprintf.$(OBJEXT) \ + lib_a-flags.$(OBJEXT) lib_a-fopen.$(OBJEXT) \ +- lib_a-fprintf.$(OBJEXT) lib_a-fputc.$(OBJEXT) \ ++ lib_a-fprintf.$(OBJEXT) lib_a-fprintf_chk.$(OBJEXT) \ ++ lib_a-fputc.$(OBJEXT) \ + lib_a-fputs.$(OBJEXT) lib_a-fread.$(OBJEXT) \ + lib_a-freopen.$(OBJEXT) lib_a-fscanf.$(OBJEXT) \ + lib_a-fiscanf.$(OBJEXT) lib_a-fseek.$(OBJEXT) \ +@@ -86,6 +87,7 @@ + lib_a-setvbuf.$(OBJEXT) lib_a-siprintf.$(OBJEXT) \ + lib_a-siscanf.$(OBJEXT) lib_a-sniprintf.$(OBJEXT) \ + lib_a-snprintf.$(OBJEXT) lib_a-sprintf.$(OBJEXT) \ ++ lib_a-sprintf_chk.$(OBJEXT) \ + lib_a-sscanf.$(OBJEXT) lib_a-stdio.$(OBJEXT) \ + lib_a-tmpfile.$(OBJEXT) lib_a-tmpnam.$(OBJEXT) \ + lib_a-ungetc.$(OBJEXT) lib_a-vdiprintf.$(OBJEXT) \ +@@ -122,15 +124,15 @@ + LTLIBRARIES = $(noinst_LTLIBRARIES) + am__objects_4 = clearerr.lo fclose.lo fdopen.lo feof.lo ferror.lo \ + fflush.lo fgetc.lo fgetpos.lo fgets.lo fileno.lo findfp.lo \ +- fiprintf.lo flags.lo fopen.lo fprintf.lo fputc.lo fputs.lo \ +- fread.lo freopen.lo fscanf.lo fiscanf.lo fseek.lo fsetpos.lo \ ++ fiprintf.lo flags.lo fopen.lo fprintf.lo fprintf_chk.lo fputc.lo \ ++ fputs.lo fread.lo freopen.lo fscanf.lo fiscanf.lo fseek.lo fsetpos.lo \ + ftell.lo fvwrite.lo fwalk.lo fwrite.lo getc.lo getchar.lo \ + getc_u.lo getchar_u.lo getdelim.lo getline.lo gets.lo \ + iprintf.lo iscanf.lo makebuf.lo perror.lo printf.lo putc.lo \ + putchar.lo putc_u.lo putchar_u.lo puts.lo refill.lo remove.lo \ + rename.lo rewind.lo rget.lo scanf.lo sccl.lo setbuf.lo \ + setbuffer.lo setlinebuf.lo setvbuf.lo siprintf.lo siscanf.lo \ +- sniprintf.lo snprintf.lo sprintf.lo sscanf.lo stdio.lo \ ++ sniprintf.lo snprintf.lo sprintf.lo sprintf_chk.lo sscanf.lo stdio.lo \ + tmpfile.lo tmpnam.lo ungetc.lo vdiprintf.lo vdprintf.lo \ + viprintf.lo viscanf.lo vprintf.lo vscanf.lo vsiprintf.lo \ + vsiscanf.lo vsnprintf.lo vsniprintf.lo vsprintf.lo vsscanf.lo \ +@@ -344,6 +346,7 @@ + flags.c \ + fopen.c \ + fprintf.c \ ++ fprintf_chk.c \ + fputc.c \ + fputs.c \ + fread.c \ +@@ -389,6 +392,7 @@ + sniprintf.c \ + snprintf.c \ + sprintf.c \ ++ sprintf_chk.c \ + sscanf.c \ + stdio.c \ + tmpfile.c \ +@@ -508,6 +512,7 @@ + siprintf.def \ + siscanf.def \ + sprintf.def \ ++ sprintf_chk.def \ + sscanf.def \ + tmpfile.def \ + tmpnam.def \ +@@ -678,6 +683,12 @@ + lib_a-fprintf.obj: fprintf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fprintf.obj `if test -f 'fprintf.c'; then $(CYGPATH_W) 'fprintf.c'; else $(CYGPATH_W) '$(srcdir)/fprintf.c'; fi` + ++lib_a-fprintf_chk.o: fprintf_chk.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fprintf_chk.o `test -f 'fprintf_chk.c' || echo '$(srcdir)/'`fprintf_chk.c ++ ++lib_a-fprintf_chk.obj: fprintf_chk.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fprintf_chk.obj `if test -f 'fprintf_chk.c'; then $(CYGPATH_W) 'fprintf_chk.c'; else $(CYGPATH_W) '$(srcdir)/fprintf_chk.c'; fi` ++ + lib_a-fputc.o: fputc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fputc.o `test -f 'fputc.c' || echo '$(srcdir)/'`fputc.c + +@@ -948,6 +959,12 @@ + lib_a-sprintf.obj: sprintf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-sprintf.obj `if test -f 'sprintf.c'; then $(CYGPATH_W) 'sprintf.c'; else $(CYGPATH_W) '$(srcdir)/sprintf.c'; fi` + ++lib_a-sprintf_chk.o: sprintf_chk.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-sprintf_chk.o `test -f 'sprintf_chk.c' || echo '$(srcdir)/'`sprintf_chk.c ++ ++lib_a-sprintf_chk.obj: sprintf_chk.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-sprintf_chk.obj `if test -f 'sprintf_chk.c'; then $(CYGPATH_W) 'sprintf_chk.c'; else $(CYGPATH_W) '$(srcdir)/sprintf_chk.c'; fi` ++ + lib_a-sscanf.o: sscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-sscanf.o `test -f 'sscanf.c' || echo '$(srcdir)/'`sscanf.c + +diff -Naur ./newlib-1.16.0/newlib/libc/stdio/sprintf_chk.c ../newlib-1.16.0/newlib/libc/stdio/sprintf_chk.c +--- newlib-1.16.0/newlib/libc/stdio/sprintf_chk.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.16.0/newlib/libc/stdio/sprintf_chk.c 2009-02-26 19:02:26.000000000 -0500 +@@ -0,0 +1,21 @@ ++#include ++#include ++ ++/* ++ * Stub implementation of __sprintf_chk adapted from glibc 2.7. This ++ * doesn't actually implement any buffer overflow protection. It just makes ++ * the linker happy :) ++*/ ++int ++__sprintf_chk (char *s, int flags, size_t slen, const char *format, ...) ++{ ++ va_list arg; ++ int done; ++ ++ va_start (arg, format); ++ done = vsprintf (s, format, arg); ++ va_end (arg); ++ ++ return done; ++} ++ From fdf48b0b708ba566874ed8e3a6a8de15371c7cec Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 08:36:21 +0100 Subject: [PATCH 48/76] stubdom: Fix newlib-chk.patch so it applies Signed-off-by: Keir Fraser --- stubdom/newlib-chk.patch | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/stubdom/newlib-chk.patch b/stubdom/newlib-chk.patch index 29c1de2d68..848dbd50c1 100644 --- a/stubdom/newlib-chk.patch +++ b/stubdom/newlib-chk.patch @@ -1,6 +1,5 @@ -diff -Naur newlib-1.16.0/newlib/libc/stdio/fprintf_chk.c newlib-1.16.0/newlib/libc/stdio/fprintf_chk.c ---- newlib-1.16.0/newlib/libc/stdio/fprintf_chk.c 1969-12-31 19:00:00.000000000 -0500 -+++ newlib-1.16.0/newlib/libc/stdio/fprintf_chk.c 2009-02-26 19:02:53.000000000 -0500 +--- newlib/libc/stdio/fprintf_chk.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib/libc/stdio/fprintf_chk.c 2009-02-26 19:02:53.000000000 -0500 @@ -0,0 +1,21 @@ +#include +#include @@ -23,9 +22,8 @@ diff -Naur newlib-1.16.0/newlib/libc/stdio/fprintf_chk.c newlib-1.16.0/newlib/li + return done; +} + -diff -Naur newlib-1.16.0/newlib/libc/stdio/Makefile.am newlib-1.16.0/newlib/libc/stdio/Makefile.am ---- ./newlib-1.16.0/newlib/libc/stdio/Makefile.am 2007-08-02 16:23:06.000000000 -0400 -+++ ./newlib-1.16.0/newlib/libc/stdio/Makefile.am 2009-02-26 18:14:53.000000000 -0500 +--- newlib/libc/stdio/Makefile.am 2007-08-02 16:23:06.000000000 -0400 ++++ newlib/libc/stdio/Makefile.am 2009-02-26 18:14:53.000000000 -0500 @@ -20,6 +20,7 @@ flags.c \ fopen.c \ @@ -42,9 +40,8 @@ diff -Naur newlib-1.16.0/newlib/libc/stdio/Makefile.am newlib-1.16.0/newlib/libc sscanf.c \ stdio.c \ tmpfile.c \ -diff -Naur newlib-1.16.0/newlib/libc/stdio/Makefile.in newlib-1.16.0/newlib/libc/stdio/Makefile.in ---- newlib-1.16.0/newlib/libc/stdio/Makefile.in 2007-12-19 17:36:38.000000000 -0500 -+++ newlib-1.16.0/newlib/libc/stdio/Makefile.in 2009-02-26 18:43:52.000000000 -0500 +--- newlib/libc/stdio/Makefile.in 2007-12-19 17:36:38.000000000 -0500 ++++ newlib/libc/stdio/Makefile.in 2009-02-26 18:43:52.000000000 -0500 @@ -63,7 +63,8 @@ lib_a-fgets.$(OBJEXT) lib_a-fileno.$(OBJEXT) \ lib_a-findfp.$(OBJEXT) lib_a-fiprintf.$(OBJEXT) \ @@ -132,9 +129,8 @@ diff -Naur newlib-1.16.0/newlib/libc/stdio/Makefile.in newlib-1.16.0/newlib/libc lib_a-sscanf.o: sscanf.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-sscanf.o `test -f 'sscanf.c' || echo '$(srcdir)/'`sscanf.c -diff -Naur ./newlib-1.16.0/newlib/libc/stdio/sprintf_chk.c ../newlib-1.16.0/newlib/libc/stdio/sprintf_chk.c ---- newlib-1.16.0/newlib/libc/stdio/sprintf_chk.c 1969-12-31 19:00:00.000000000 -0500 -+++ newlib-1.16.0/newlib/libc/stdio/sprintf_chk.c 2009-02-26 19:02:26.000000000 -0500 +--- newlib/libc/stdio/sprintf_chk.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib/libc/stdio/sprintf_chk.c 2009-02-26 19:02:26.000000000 -0500 @@ -0,0 +1,21 @@ +#include +#include From 0a690b0314ed62823aa4e4ebd6aa0c863a767ce5 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 11:44:10 +0100 Subject: [PATCH 49/76] acm: Restrict the XML of the policy to only allow one SimpleTypeEnforcementType node. Signed-off-by: Stefan Berger --- tools/python/xen/util/acmpolicy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/util/acmpolicy.py b/tools/python/xen/util/acmpolicy.py index 64978a68dc..1a95c3a2d5 100644 --- a/tools/python/xen/util/acmpolicy.py +++ b/tools/python/xen/util/acmpolicy.py @@ -216,7 +216,7 @@ ACM_SCHEMA=""" - + From c6d5b4e310e8c725bd752470b5c85b00dc0685aa Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 11:44:49 +0100 Subject: [PATCH 50/76] xend: allow hvm domain to have multiple serial consoles This patch allows hvm domain to have multiple serial ports with serial =3D [ '...', '...']. The old style, serial=3D'option string', is also accepted for compatibility. Signed-off-by: Isaku Yamahata --- tools/python/xen/xend/image.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 239165b55f..14b46fd586 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -781,6 +781,14 @@ class HVMImageHandler(ImageHandler): if v: ret.append("-%s" % a) except (ValueError, TypeError): pass # if we can't convert it to a sane type, ignore it + elif a == 'serial': + if v: + if type(v) == str: + v = [v] + for s in v: + if s: + ret.append("-serial") + ret.append("%s" % s) else: if v: ret.append("-%s" % a) From c9a16ee02d3f278cb255b079d5d6701fc87d07f0 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 11:45:22 +0100 Subject: [PATCH 51/76] xend: Set close-on-exec flag for datagram sockets We need to close the socket on the child side when xend creates a child process such as qemu-dm. Signed-off-by: Yosuke Iwamatsu --- tools/python/xen/web/connection.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/python/xen/web/connection.py b/tools/python/xen/web/connection.py index e507323e91..3d335d2fbd 100644 --- a/tools/python/xen/web/connection.py +++ b/tools/python/xen/web/connection.py @@ -317,6 +317,8 @@ class SocketDgramListener: def main(self): try: + fcntl.fcntl(self.sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC) + while True: try: data = self.sock.recv(BUFFER_SIZE) From 37307651ac01a283059f5bd9c9bfacfc896c617a Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 11:46:31 +0100 Subject: [PATCH 52/76] xend: Balloon 4MB memory slop when creating a domain I've found some problems when running 2 guests with and then trying to install a new machine (no matter whether using virt-manager or virt-install). Signed-off-by: Michal Novotny --- tools/python/xen/xend/XendDomainInfo.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 8cc2084acf..815fed65e0 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -2253,8 +2253,9 @@ class XendDomainInfo: # There is an implicit memory overhead for any domain creation. This # overhead is greater for some types of domain than others. For # example, an x86 HVM domain will have a default shadow-pagetable - # allocation of 1MB. We free up 2MB here to be on the safe side. - balloon.free(2*1024, self) # 2MB should be plenty + # allocation of 1MB. We free up 4MB here to be on the safe side. + # 2MB memory allocation was not enough in some cases, so it's 4MB now + balloon.free(4*1024, self) # 4MB should be plenty ssidref = 0 if security.on() == xsconstants.XS_POLICY_USE: From 8e558b0e97993b560cc0a199dcbfa8aa6ce464d1 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 11:47:25 +0100 Subject: [PATCH 53/76] xend: fix rtc_timeoffset when localtime=1 The rtc_timeoffset parameter in VM config is ignored when localtime=1. Also it is not preserved across reboot. NOTE: This patch changes the meaning of the xenstore /vm//rtc/timeoffset from utc offset to local offset. (it's OK for the ioemu) Signed-off-by: Kouya Shimura --- tools/python/xen/xend/XendDomainInfo.py | 17 ++++------------- tools/python/xen/xend/image.py | 11 ++++++++--- tools/python/xen/xm/create.py | 2 +- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 815fed65e0..2d42927b10 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1605,9 +1605,6 @@ class XendDomainInfo: # convert two lists into a python dictionary vm_details = dict(zip(cfg_vm, vm_details)) - if vm_details['rtc/timeoffset'] == None: - vm_details['rtc/timeoffset'] = "0" - for arg, val in vm_details.items(): if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG: xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg] @@ -1629,10 +1626,10 @@ class XendDomainInfo: self.info.update_with_image_sxp(sxp.from_string(image_sxp)) changed = True - # Check if the rtc offset has changes - if vm_details.get("rtc/timeoffset", "0") != self.info["platform"].get("rtc_timeoffset", "0"): - self.info["platform"]["rtc_timeoffset"] = vm_details.get("rtc/timeoffset", 0) - changed = True + # Update the rtc_timeoffset to be preserved across reboot. + # NB. No need to update xenstore domain section. + val = int(vm_details.get("rtc/timeoffset", 0)) + self.info["platform"]["rtc_timeoffset"] = val if changed: # Update the domain section of the store, as this contains some @@ -2440,12 +2437,6 @@ class XendDomainInfo: self._configureBootloader() try: - if self.info['platform'].get('localtime', 0): - if time.localtime(time.time())[8]: - self.info['platform']['rtc_timeoffset'] = -time.altzone - else: - self.info['platform']['rtc_timeoffset'] = -time.timezone - self.image = image.create(self, self.info) # repin domain vcpus if a restricted cpus list is provided diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 14b46fd586..c058cecb9e 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -119,9 +119,14 @@ class ImageHandler: self.vncconsole = int(vmConfig['platform'].get('vncconsole', 0)) self.dmargs = self.parseDeviceModelArgs(vmConfig) self.pid = None - rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset') - if rtc_timeoffset is not None: - xc.domain_set_time_offset(self.vm.getDomid(), int(rtc_timeoffset)) + rtc_timeoffset = int(vmConfig['platform'].get('rtc_timeoffset', 0)) + if vmConfig['platform'].get('localtime', 0): + if time.localtime(time.time())[8]: + rtc_timeoffset -= time.altzone + else: + rtc_timeoffset -= time.timezone + if rtc_timeoffset != 0: + xc.domain_set_time_offset(self.vm.getDomid(), rtc_timeoffset) self.cpuid = None self.cpuid_check = None diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index f5b505270b..ec73cf0cdc 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -204,7 +204,7 @@ gopts.var('cpus', val='CPUS', use="CPUS to run the domain on.") gopts.var('rtc_timeoffset', val='RTC_TIMEOFFSET', - fn=set_value, default="0", + fn=set_int, default=0, use="Set RTC offset.") gopts.var('pae', val='PAE', From eed32b0cbd0245f6269a4aa4cdc75470ef35f3ae Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 11:47:59 +0100 Subject: [PATCH 54/76] xend: modify a warning log message Signed-off-by: Kouya Shimura --- tools/python/xen/xend/image.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index c058cecb9e..1f2eb4a9f5 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -534,8 +534,8 @@ class ImageHandler: try: self.sentinel_fifo.read(1) except OSError, e: pass self.sentinel_lock.acquire() - try: - if self.pid: + if self.pid: + try: (p,st) = os.waitpid(self.pid, os.WNOHANG) if p == self.pid: message = oshelp.waitstatus_description(st) @@ -547,15 +547,15 @@ class ImageHandler: except: message = "malfunctioning or died ?" message = "pid %d: %s" % (self.pid, message) - else: - message = "no longer running" - except Exception, e: - message = "waitpid failed: %s" % utils.exception_string(e) - message = "device model failure: %s" % message - try: message += "; see %s " % self.logfile - except: pass - self._dmfailed(message) - self.pid = None + except Exception, e: + message = "waitpid failed: %s" % utils.exception_string(e) + message = "device model failure: %s" % message + try: message += "; see %s " % self.logfile + except: pass + self._dmfailed(message) + self.pid = None + else: + log.info("%s device model terminated", self.vm.getName()) self.sentinel_lock.release() def destroyDeviceModel(self): From 3a8690df4ac44731476b9d9f0aa30470bce3d66c Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 11:53:15 +0100 Subject: [PATCH 55/76] x86 hpet: fix irq_vector[] update of c/s 19419 Signed-off-by: Jan Beulich Signed-off-by: Keir Fraser --- xen/arch/x86/hpet.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index 97d0979305..ea7c5be144 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -343,20 +343,16 @@ static int hpet_setup_msi_irq(unsigned int vector) static int hpet_assign_irq(struct hpet_event_channel *ch) { - unsigned int vector; + int vector; - vector = assign_irq_vector(AUTO_ASSIGN_IRQ); - if ( !vector ) - return -EINVAL; + if ( (vector = assign_irq_vector(AUTO_ASSIGN_IRQ)) < 0 ) + return vector; - irq_vector[vector] = vector; - vector_irq[vector] = vector; vector_channel[vector] = ch - &hpet_events[0]; if ( hpet_setup_msi_irq(vector) ) { - irq_vector[vector] = 0; - vector_irq[vector] = FREE_TO_ASSIGN_IRQ; + free_irq_vector(vector); vector_channel[vector] = -1; return -EINVAL; } From fed6ed29b093cc6c717fefb1aad192f45bbb4149 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 13:12:13 +0100 Subject: [PATCH 56/76] ia64: Fix the build after max_cstate changes. Signed-off-by: Keir Fraser --- xen/drivers/acpi/pmstat.c | 4 ++-- xen/include/asm-x86/config.h | 1 + xen/include/xen/acpi.h | 4 +--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c index 8125e88951..33954307d7 100644 --- a/xen/drivers/acpi/pmstat.c +++ b/xen/drivers/acpi/pmstat.c @@ -530,13 +530,13 @@ int do_pm_op(struct xen_sysctl_pm_op *op) case XEN_SYSCTL_pm_op_get_max_cstate: { - op->get_max_cstate = max_cstate; + op->get_max_cstate = acpi_get_cstate_limit(); break; } case XEN_SYSCTL_pm_op_set_max_cstate: { - max_cstate = op->set_max_cstate; + acpi_set_cstate_limit(op->set_max_cstate); break; } diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index 9d140ef891..3e05dbf0bb 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -35,6 +35,7 @@ #define CONFIG_ACPI_SLEEP 1 #define CONFIG_ACPI_NUMA 1 #define CONFIG_ACPI_SRAT 1 +#define CONFIG_ACPI_CSTATE 1 #define CONFIG_VGA 1 diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h index cbf795aeaf..43bdade6c4 100644 --- a/xen/include/xen/acpi.h +++ b/xen/include/xen/acpi.h @@ -402,9 +402,7 @@ static inline int acpi_blacklisted(void) #endif /*!CONFIG_ACPI_INTERPRETER*/ -#define ACPI_CSTATE_LIMIT_DEFINED /* for driver builds */ -#ifdef CONFIG_ACPI - +#ifdef CONFIG_ACPI_CSTATE /* * Set highest legal C-state * 0: C0 okay, but not C1 From db8811093e5b8bfacb90e3144fbf94c04ef3ace3 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 13:17:34 +0100 Subject: [PATCH 57/76] xend: Revert c/s 19436 -- fails with Python 2.3, and sock.close() should suffice to shutdown a connection. Signed-off-by: Keir Fraser --- tools/python/xen/xend/XendDomain.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 6cde465559..b624f786ad 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -1378,7 +1378,6 @@ class XendDomain: XendCheckpoint.save(sock.fileno(), dominfo, True, live, dst, node=node) finally: - sock.shutdown(socket.SHUT_RDWR) sock.close() def domain_save(self, domid, dst, checkpoint=False): From a21645e1dff35eaec69f2eb9c61adeafbb16c971 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 13:49:35 +0100 Subject: [PATCH 58/76] x86: paging_log_dirty_op() should take care with invalid log_dirty.top Signed-off-by: Keir Fraser --- xen/arch/x86/mm/paging.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c index 2b898dd73b..0df7376c24 100644 --- a/xen/arch/x86/mm/paging.c +++ b/xen/arch/x86/mm/paging.c @@ -385,13 +385,14 @@ int paging_log_dirty_op(struct domain *d, struct xen_domctl_shadow_op *sc) } pages = 0; - l4 = map_domain_page(mfn_x(d->arch.paging.log_dirty.top)); + l4 = (mfn_valid(d->arch.paging.log_dirty.top) ? + map_domain_page(mfn_x(d->arch.paging.log_dirty.top)) : NULL); for ( i4 = 0; (pages < sc->pages) && (i4 < LOGDIRTY_NODE_ENTRIES); i4++ ) { - l3 = mfn_valid(l4[i4]) ? map_domain_page(mfn_x(l4[i4])) : NULL; + l3 = (l4 && mfn_valid(l4[i4])) ? map_domain_page(mfn_x(l4[i4])) : NULL; for ( i3 = 0; (pages < sc->pages) && (i3 < LOGDIRTY_NODE_ENTRIES); i3++ ) From 885b76a5fbdedcebc15b52aaa9711c9da8fd8026 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 14:04:46 +0100 Subject: [PATCH 59/76] x86 hpet: two more fixes for c/s 19419 vector_channel[], as its name already says, is vector-, not irq-indexed. hpet_assign_irq() sits not only in the boot path, but also in the resume one. Short of knowing why this is, simply checking whether a vector was already assigned prevents leaking previously assigned ones. Signed-off-by: Jan Beulich --- xen/arch/x86/hpet.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index ea7c5be144..7671634ef2 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -45,7 +45,7 @@ static unsigned int num_hpets_used; /* msi hpet channels used for broadcast */ DEFINE_PER_CPU(struct hpet_event_channel *, cpu_bc_channel); -static int vector_channel[NR_IRQS] = {[0 ... NR_IRQS-1] = -1}; +static int vector_channel[NR_VECTORS] = {[0 ... NR_VECTORS-1] = -1}; #define vector_to_channel(vector) vector_channel[vector] @@ -345,6 +345,9 @@ static int hpet_assign_irq(struct hpet_event_channel *ch) { int vector; + if ( ch->vector ) + return 0; + if ( (vector = assign_irq_vector(AUTO_ASSIGN_IRQ)) < 0 ) return vector; From ea78378d2cb685b6fa3897a91435c36235b75446 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 15:39:20 +0100 Subject: [PATCH 60/76] Only set scheduler quantum timer for non-idle VCPUs This removes the last idle periodic timer in xen, and enhances the idle average C state residency from two-digits ms to three-digit ms. Signed-off-by: Yu Ke Signed-off-by: Tian Kevin --- xen/common/schedule.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xen/common/schedule.c b/xen/common/schedule.c index f1121938da..23807ea330 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -818,8 +818,9 @@ static void schedule(void) next = next_slice.task; sd->curr = next; - - set_timer(&sd->s_timer, now + r_time); + + if ( !is_idle_vcpu(next) ) + set_timer(&sd->s_timer, now + r_time); if ( unlikely(prev == next) ) { From d3a7711f0c72e302bdbc5a2a1f0fa2649a6b6858 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 1 Apr 2009 16:20:30 +0100 Subject: [PATCH 61/76] x86: hvm_*io_intercept() should only update p->count if X86EMUL_OKAY. Signed-off-by: Stefano Stabellini Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/intercept.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c index 107b87d2f7..1a1f24c7f6 100644 --- a/xen/arch/x86/hvm/intercept.c +++ b/xen/arch/x86/hvm/intercept.c @@ -100,8 +100,11 @@ static int hvm_mmio_access(struct vcpu *v, } } - if ( (p->count = i) != 0 ) + if ( i != 0 ) + { + p->count = i; rc = X86EMUL_OKAY; + } return rc; } @@ -165,8 +168,11 @@ static int process_portio_intercept(portio_action_t action, ioreq_t *p) } } - if ( (p->count = i) != 0 ) + if ( i != 0 ) + { + p->count = i; rc = X86EMUL_OKAY; + } return rc; } From 58740d22ab313771dc1a8829f69a17e620a2d3e4 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 2 Apr 2009 07:53:11 +0100 Subject: [PATCH 62/76] x86: A further fix to paging_log_dirty_op() -- do not unmap_domain_page(NULL) Signed-off-by: Keir Fraser --- xen/arch/x86/mm/paging.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c index 0df7376c24..e9313e14f1 100644 --- a/xen/arch/x86/mm/paging.c +++ b/xen/arch/x86/mm/paging.c @@ -430,7 +430,8 @@ int paging_log_dirty_op(struct domain *d, struct xen_domctl_shadow_op *sc) if ( l3 ) unmap_domain_page(l3); } - unmap_domain_page(l4); + if ( l4 ) + unmap_domain_page(l4); if ( pages < sc->pages ) sc->pages = pages; From 0c29f97df0f61098c96a411ad745bb24e0adc7ae Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 2 Apr 2009 11:48:10 +0100 Subject: [PATCH 63/76] network-bridge: Fix do_ifup in the case of ${bridge} != ${netdev} On RHEL5.2, ifup ${bridge} fails if ${bridge} != ${netdev}, because RHEL5.2's ifup ${bridge} runs the following sequence: 1. Search CONFIG that has the same mac address of ${bridge}.=20 ifcfg-${netdev} is found. 2. Run "ip link set dev ${netdev} up". # ${bridge} is expected. 3. Output "Failed to bring up ${netdev}." Because ${netdev} does not exist. Thus, do_ifup() should not use ifup if ${bridge} != ${netdev}. Signed-off-by: KUWAMURA Shin'ya --- tools/hotplug/Linux/network-bridge | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/hotplug/Linux/network-bridge b/tools/hotplug/Linux/network-bridge index 9d7be4e2e5..091b8beb3e 100644 --- a/tools/hotplug/Linux/network-bridge +++ b/tools/hotplug/Linux/network-bridge @@ -106,7 +106,7 @@ get_ip_info() { } do_ifup() { - if ! ifup $1 ; then + if [ $1 != "${netdev}" ] || ! ifup $1 ; then if [ -n "$addr_pfx" ] ; then # use the info from get_ip_info() ip addr flush $1 @@ -223,9 +223,9 @@ op_start () { preiftransfer ${netdev} transfer_addrs ${netdev} ${tdev} + # Remember the IP details for do_ifup. + get_ip_info ${netdev} if ! ifdown ${netdev}; then - # If ifdown fails, remember the IP details. - get_ip_info ${netdev} ip link set ${netdev} down ip addr flush ${netdev} fi From 48fe42ec0b1cd6fe1fb26c27fb307e8bc5240fe0 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 2 Apr 2009 11:48:32 +0100 Subject: [PATCH 64/76] xenctx, ia64: fix compilation error. Signed-off-by: Isaku Yamahata --- tools/xentrace/xenctx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c index 127379e671..c67171ca7e 100644 --- a/tools/xentrace/xenctx.c +++ b/tools/xentrace/xenctx.c @@ -875,8 +875,8 @@ static void dump_ctx(int vcpu) #endif print_ctx(&ctx); - print_code(&ctx, vcpu); #ifndef NO_TRANSLATION + print_code(&ctx, vcpu); if (is_kernel_text(instr_pointer(&ctx))) print_stack(&ctx, vcpu, guest_word_size); #endif From ab438874b6a8ae955b337c36e7b3204e29b8d407 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 2 Apr 2009 12:40:09 +0100 Subject: [PATCH 65/76] hvm: add ACPI power button for HVM This patch adds the ACPI fixed hardware power button for HVM. It enables a graceful shutdown of a guest OS by direction of Dom0. (if a proper action for the power button is set inside the guest) usage: xm trigger power Signed-off-by: Kouya Shimura --- tools/firmware/hvmloader/acpi/static_tables.c | 2 +- tools/python/xen/xend/XendConstants.py | 6 +++-- tools/python/xen/xm/main.py | 2 +- xen/arch/x86/domctl.c | 13 +++++++++++ xen/arch/x86/hvm/pmtimer.c | 22 ++++++++++++------- xen/include/public/domctl.h | 1 + 6 files changed, 34 insertions(+), 12 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/static_tables.c b/tools/firmware/hvmloader/acpi/static_tables.c index ab544e15fd..e040c56187 100644 --- a/tools/firmware/hvmloader/acpi/static_tables.c +++ b/tools/firmware/hvmloader/acpi/static_tables.c @@ -69,7 +69,7 @@ struct acpi_20_fadt Fadt = { .p_lvl3_lat = 0x0fff, /* >1000, means we do not support C3 state */ .iapc_boot_arch = ACPI_8042, .flags = (ACPI_PROC_C1 | ACPI_SLP_BUTTON | - ACPI_WBINVD | ACPI_PWR_BUTTON | + ACPI_WBINVD | ACPI_FIX_RTC | ACPI_TMR_VAL_EXT), .reset_reg = { diff --git a/tools/python/xen/xend/XendConstants.py b/tools/python/xen/xend/XendConstants.py index b1c2957a7a..6775795bdd 100644 --- a/tools/python/xen/xend/XendConstants.py +++ b/tools/python/xen/xend/XendConstants.py @@ -105,13 +105,15 @@ LAST_SHUTDOWN_REASON = 'xend/last_shutdown_reason' TRIGGER_NMI = 0 TRIGGER_RESET = 1 TRIGGER_INIT = 2 -TRIGGER_S3RESUME = 3 +TRIGGER_POWER = 3 +TRIGGER_S3RESUME = 4 TRIGGER_TYPE = { "nmi" : TRIGGER_NMI, "reset" : TRIGGER_RESET, "init" : TRIGGER_INIT, - "s3resume": TRIGGER_S3RESUME + "s3resume": TRIGGER_S3RESUME, + "power": TRIGGER_POWER } # diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 8c7ba968e8..b3cfecb448 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -151,7 +151,7 @@ SUBCOMMAND_HELP = { 'Get/set credit scheduler parameters.'), 'sysrq' : (' ', 'Send a sysrq to a domain.'), 'debug-keys' : ('', 'Send debug keys to Xen.'), - 'trigger' : (' []', + 'trigger' : (' []', 'Send a trigger to a domain.'), 'vcpu-list' : ('[Domain, ...]', 'List the VCPUs for all/some domains.'), diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 7f4d7dbbea..1d748f6f15 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -587,6 +587,19 @@ long arch_do_domctl( } break; + case XEN_DOMCTL_SENDTRIGGER_POWER: + { + extern void hvm_acpi_power_button(struct domain *d); + + ret = -EINVAL; + if ( is_hvm_domain(d) ) + { + ret = 0; + hvm_acpi_power_button(d); + } + } + break; + default: ret = -ENOSYS; } diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c index 15bb3c3ef6..276538f028 100644 --- a/xen/arch/x86/hvm/pmtimer.c +++ b/xen/arch/x86/hvm/pmtimer.c @@ -29,18 +29,15 @@ /* The interesting bits of the PM1a_STS register */ #define TMR_STS (1 << 0) -#define PWRBTN_STS (1 << 5) -#define GBL_STS (1 << 8) +#define GBL_STS (1 << 5) +#define PWRBTN_STS (1 << 8) /* The same in PM1a_EN */ #define TMR_EN (1 << 0) -#define PWRBTN_EN (1 << 5) -#define GBL_EN (1 << 8) +#define GBL_EN (1 << 5) +#define PWRBTN_EN (1 << 8) -/* Mask of bits in PM1a_STS that can generate an SCI. Although the ACPI - * spec lists other bits, the PIIX4, which we are emulating, only - * supports these three. For now, we only use TMR_STS; in future we - * will let qemu set the other bits */ +/* Mask of bits in PM1a_STS that can generate an SCI. */ #define SCI_MASK (TMR_STS|PWRBTN_STS|GBL_STS) /* SCI IRQ number (must match SCI_INT number in ACPI FADT in hvmloader) */ @@ -61,6 +58,15 @@ static void pmt_update_sci(PMTState *s) hvm_isa_irq_deassert(s->vcpu->domain, SCI_IRQ); } +void hvm_acpi_power_button(struct domain *d) +{ + PMTState *s = &d->arch.hvm_domain.pl_time.vpmt; + spin_lock(&s->lock); + s->pm.pm1a_sts |= PWRBTN_STS; + pmt_update_sci(s); + spin_unlock(&s->lock); +} + /* Set the correct value in the timer, accounting for time elapsed * since the last time we did that. */ static void pmt_update_time(PMTState *s) diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 8574302bae..f7b1fc5ec7 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -433,6 +433,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_real_mode_area_t); #define XEN_DOMCTL_SENDTRIGGER_NMI 0 #define XEN_DOMCTL_SENDTRIGGER_RESET 1 #define XEN_DOMCTL_SENDTRIGGER_INIT 2 +#define XEN_DOMCTL_SENDTRIGGER_POWER 3 struct xen_domctl_sendtrigger { uint32_t trigger; /* IN */ uint32_t vcpu; /* IN */ From 1847d666d158d57a56db243434179a2f28e1a0ee Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 2 Apr 2009 12:40:44 +0100 Subject: [PATCH 66/76] xm: allow space characters in a vscsi definition. Signed-off-by: Masaki Kanno --- tools/python/xen/xm/create.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index ec73cf0cdc..61655ea61c 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -1081,7 +1081,7 @@ def preprocess_vscsi(vals): if not vals.vscsi: return scsi = [] for scsi_str in vals.vscsi: - d = scsi_str.split(',') + d = [tmp.strip() for tmp in scsi_str.split(',')] n = len(d) if n == 2: tmp = d[1].split(':') From e295a5ce4b7bb2b8f774fbc576bab45ab6663bc9 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 2 Apr 2009 13:02:13 +0100 Subject: [PATCH 67/76] x86: imply 'noapic' from 'nolapic' While in the comments to an earlier submitted (and already applied) patch I claimed to have fixed the need to specify both "nolapic" and "noapic" when "nolapic" alone should already have the intended effect, this doesn't appear to be the case. Here are the missing bits. Signed-off-by: Jan Beulich --- xen/arch/x86/apic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index 2bbb003eaa..aab68048eb 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -1303,8 +1303,10 @@ int __init APIC_init_uniprocessor (void) if (enable_local_apic < 0) clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); - if (!smp_found_config && !cpu_has_apic) + if (!smp_found_config && !cpu_has_apic) { + skip_ioapic_setup = 1; return -1; + } /* * Complain if the BIOS pretends there is one. @@ -1313,6 +1315,7 @@ int __init APIC_init_uniprocessor (void) printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", boot_cpu_physical_apicid); clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); + skip_ioapic_setup = 1; return -1; } From c806877d1b3992a9a75e4aa7604911d048891410 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 2 Apr 2009 14:17:19 +0100 Subject: [PATCH 68/76] Move logic for avoiding limited idle quantum into credit scheduler. Signed-off-by: Keir Fraser --- xen/common/sched_credit.c | 3 ++- xen/common/schedule.c | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c index c554c8b8b9..67ff04647f 100644 --- a/xen/common/sched_credit.c +++ b/xen/common/sched_credit.c @@ -1146,7 +1146,8 @@ csched_schedule(s_time_t now) /* * Return task to run next... */ - ret.time = MILLISECS(CSCHED_MSECS_PER_TSLICE); + ret.time = (is_idle_vcpu(snext->vcpu) ? + -1 : MILLISECS(CSCHED_MSECS_PER_TSLICE)); ret.task = snext->vcpu; CSCHED_VCPU_CHECK(ret.task); diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 23807ea330..fb2464f11d 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -798,7 +798,6 @@ static void schedule(void) s_time_t now = NOW(); struct schedule_data *sd; struct task_slice next_slice; - s32 r_time; /* time for new dom to run */ ASSERT(!in_irq()); ASSERT(this_cpu(mc_state).flags == 0); @@ -814,13 +813,12 @@ static void schedule(void) /* get policy-specific decision on scheduling... */ next_slice = ops.do_schedule(now); - r_time = next_slice.time; next = next_slice.task; sd->curr = next; - if ( !is_idle_vcpu(next) ) - set_timer(&sd->s_timer, now + r_time); + if ( next_slice.time >= 0 ) /* -ve means no limit */ + set_timer(&sd->s_timer, now + next_slice.time); if ( unlikely(prev == next) ) { @@ -836,7 +834,7 @@ static void schedule(void) next->domain->domain_id, (next->runstate.state == RUNSTATE_runnable) ? (now - next->runstate.state_entry_time) : 0, - r_time); + next_slice.time); ASSERT(prev->runstate.state == RUNSTATE_running); vcpu_runstate_change( From 3e15c37e68862b9d8f3a9f0085fab2d596e19e49 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 6 Apr 2009 13:46:11 +0100 Subject: [PATCH 69/76] x86 mce: Small fix for polling/CMCI race conditions. When CMCI happens very quickly, polling/CMCI processing path might cross. For Intel CPUs which support CMCI, if the error bank has CMCI capability, we'll disable poll on this bank. Signed-off-by: Liping Ke Signed-off-by: Yunhong Jiang --- xen/arch/x86/cpu/mcheck/mce.c | 13 +++++++++++++ xen/arch/x86/cpu/mcheck/mce.h | 4 ++++ xen/arch/x86/cpu/mcheck/mce_intel.c | 4 ++-- xen/arch/x86/cpu/mcheck/non-fatal.c | 8 ++------ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c index bc18e3048b..a43f2f131a 100644 --- a/xen/arch/x86/cpu/mcheck/mce.c +++ b/xen/arch/x86/cpu/mcheck/mce.c @@ -577,6 +577,7 @@ void mcheck_init(struct cpuinfo_x86 *c) break; } + set_poll_bankmask(c); if (!inited) printk(XENLOG_INFO "CPU%i: No machine check initialization\n", smp_processor_id()); @@ -1230,7 +1231,19 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc) return ret; } +void set_poll_bankmask(struct cpuinfo_x86 *c) +{ + if (cmci_support && !mce_disabled) { + memcpy(&(__get_cpu_var(poll_bankmask)), + &(__get_cpu_var(no_cmci_banks)), sizeof(cpu_banks_t)); + } + else { + memcpy(&(get_cpu_var(poll_bankmask)), &mca_allbanks, sizeof(cpu_banks_t)); + if (mce_firstbank(c)) + clear_bit(0, get_cpu_var(poll_bankmask)); + } +} void mc_panic(char *s) { console_start_sync(); diff --git a/xen/arch/x86/cpu/mcheck/mce.h b/xen/arch/x86/cpu/mcheck/mce.h index 2bd6f023d6..6b79e673e2 100644 --- a/xen/arch/x86/cpu/mcheck/mce.h +++ b/xen/arch/x86/cpu/mcheck/mce.h @@ -88,6 +88,10 @@ struct mca_summary { }; extern cpu_banks_t mca_allbanks; +void set_poll_bankmask(struct cpuinfo_x86 *c); +DECLARE_PER_CPU(cpu_banks_t, poll_bankmask); +DECLARE_PER_CPU(cpu_banks_t, no_cmci_banks); +extern int cmci_support; extern mctelem_cookie_t mcheck_mca_logout(enum mca_source, cpu_banks_t, struct mca_summary *); diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c index d8fa0ebb07..67d0342d99 100644 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c @@ -12,9 +12,10 @@ #include "x86_mca.h" DEFINE_PER_CPU(cpu_banks_t, mce_banks_owned); +DEFINE_PER_CPU(cpu_banks_t, no_cmci_banks); +int cmci_support = 0; static int nr_intel_ext_msrs = 0; -static int cmci_support = 0; static int firstbank; #ifdef CONFIG_X86_MCE_THERMAL @@ -548,7 +549,6 @@ static void intel_machine_check(struct cpu_user_regs * regs, long error_code) } static DEFINE_SPINLOCK(cmci_discover_lock); -static DEFINE_PER_CPU(cpu_banks_t, no_cmci_banks); /* * Discover bank sharing using the algorithm recommended in the SDM. diff --git a/xen/arch/x86/cpu/mcheck/non-fatal.c b/xen/arch/x86/cpu/mcheck/non-fatal.c index 167b1cea2a..9d66a12b6b 100644 --- a/xen/arch/x86/cpu/mcheck/non-fatal.c +++ b/xen/arch/x86/cpu/mcheck/non-fatal.c @@ -22,7 +22,7 @@ #include "mce.h" -static cpu_banks_t bankmask; +DEFINE_PER_CPU(cpu_banks_t, poll_bankmask); static struct timer mce_timer; #define MCE_PERIOD MILLISECS(8000) @@ -39,7 +39,7 @@ static void mce_checkregs (void *info) struct mca_summary bs; static uint64_t dumpcount = 0; - mctc = mcheck_mca_logout(MCA_POLLER, bankmask, &bs); + mctc = mcheck_mca_logout(MCA_POLLER, __get_cpu_var(poll_bankmask), &bs); if (bs.errcnt && mctc != NULL) { adjust++; @@ -94,10 +94,6 @@ static int __init init_nonfatal_mce_checker(void) if (!mce_available(c)) return -ENODEV; - memcpy(&bankmask, &mca_allbanks, sizeof (cpu_banks_t)); - if (mce_firstbank(c) == 1) - clear_bit(0, bankmask); - /* * Check for non-fatal errors every MCE_RATE s */ From 9d8216601857f5666b52c64139cde296456a8205 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 6 Apr 2009 13:49:16 +0100 Subject: [PATCH 70/76] xenpm: Set scheduler vcpu_migration_delay by xenpm Signed-off-by: Yu Ke Signed-off-by: Yang Xiaowei --- tools/libxc/xc_pm.c | 30 +++++++++++++++++++++ tools/libxc/xenctrl.h | 2 ++ tools/misc/xenpm.c | 52 +++++++++++++++++++++++++++++++++++++ xen/common/sched_credit.c | 10 +++++++ xen/common/sysctl.c | 8 ++++++ xen/drivers/acpi/pmstat.c | 12 +++++++++ xen/include/public/sysctl.h | 6 +++++ xen/include/xen/sched.h | 3 +++ xen/include/xsm/xsm.h | 12 +++++++++ xen/xsm/dummy.c | 10 +++++++ 10 files changed, 145 insertions(+) diff --git a/tools/libxc/xc_pm.c b/tools/libxc/xc_pm.c index 652f1729ef..501041073e 100644 --- a/tools/libxc/xc_pm.c +++ b/tools/libxc/xc_pm.c @@ -362,6 +362,36 @@ int xc_set_sched_opt_smt(int xc_handle, uint32_t value) return rc; } +int xc_set_vcpu_migration_delay(int xc_handle, uint32_t value) +{ + int rc; + DECLARE_SYSCTL; + + sysctl.cmd = XEN_SYSCTL_pm_op; + sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_set_vcpu_migration_delay; + sysctl.u.pm_op.cpuid = 0; + sysctl.u.pm_op.set_vcpu_migration_delay = value; + rc = do_sysctl(xc_handle, &sysctl); + + return rc; +} + +int xc_get_vcpu_migration_delay(int xc_handle, uint32_t *value) +{ + int rc; + DECLARE_SYSCTL; + + sysctl.cmd = XEN_SYSCTL_pm_op; + sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_get_vcpu_migration_delay; + sysctl.u.pm_op.cpuid = 0; + rc = do_sysctl(xc_handle, &sysctl); + + if (!rc && value) + *value = sysctl.u.pm_op.get_vcpu_migration_delay; + + return rc; +} + int xc_get_cpuidle_max_cstate(int xc_handle, uint32_t *value) { int rc; diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 7111fa97c5..c9b1866b60 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -1261,6 +1261,8 @@ struct xc_get_cputopo { int xc_get_cputopo(int xc_handle, struct xc_get_cputopo *info); int xc_set_sched_opt_smt(int xc_handle, uint32_t value); +int xc_set_vcpu_migration_delay(int xc_handle, uint32_t value); +int xc_get_vcpu_migration_delay(int xc_handle, uint32_t *value); int xc_get_cpuidle_max_cstate(int xc_handle, uint32_t *value); int xc_set_cpuidle_max_cstate(int xc_handle, uint32_t value); diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c index 1d65393706..015d80a5b9 100644 --- a/tools/misc/xenpm.c +++ b/tools/misc/xenpm.c @@ -57,6 +57,8 @@ void show_help(void) " it is used in ondemand governor.\n" " get-cpu-topology get thread/core/socket topology info\n" " set-sched-smt enable|disable enable/disable scheduler smt power saving\n" + " set-vcpu-migration-delay set scheduler vcpu migration delay in us\n" + " get-vcpu-migration-delay get scheduler vcpu migration delay\n" " set-max-cstate set the C-State limitation ( >= 0)\n" " start [seconds] start collect Cx/Px statistics,\n" " output after CTRL-C or SIGINT or several seconds.\n" @@ -884,6 +886,54 @@ void set_sched_smt_func(int argc, char *argv[]) return; } +void set_vcpu_migration_delay_func(int argc, char *argv[]) +{ + int value; + int rc; + + if (argc != 1){ + show_help(); + exit(-1); + } + + value = atoi(argv[0]); + + if (value < 0) + { + printf("Please try non-negative vcpu migration delay\n"); + exit(-1); + } + + rc = xc_set_vcpu_migration_delay(xc_fd, value); + printf("%s to set vcpu migration delay to %d us\n", + rc? "Fail":"Succeed", value ); + + return; +} + +void get_vcpu_migration_delay_func(int argc, char *argv[]) +{ + uint32_t value; + int rc; + + if (argc != 0){ + show_help(); + exit(-1); + } + + rc = xc_get_vcpu_migration_delay(xc_fd, &value); + if (!rc) + { + printf("Schduler vcpu migration delay is %d us\n", value); + } + else + { + printf("Failed to get scheduler vcpu migration delay, errno=%d\n", errno); + } + + return; +} + void set_max_cstate_func(int argc, char *argv[]) { int value, rc; @@ -918,6 +968,8 @@ struct { { "set-up-threshold", scaling_up_threshold_func }, { "get-cpu-topology", cpu_topology_func}, { "set-sched-smt", set_sched_smt_func}, + { "get-vcpu-migration-delay", get_vcpu_migration_delay_func}, + { "set-vcpu-migration-delay", set_vcpu_migration_delay_func}, { "set-max-cstate", set_max_cstate_func}, }; diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c index 67ff04647f..d0d31d9fff 100644 --- a/xen/common/sched_credit.c +++ b/xen/common/sched_credit.c @@ -326,6 +326,16 @@ __csched_vcpu_check(struct vcpu *vc) static unsigned int vcpu_migration_delay; integer_param("vcpu_migration_delay", vcpu_migration_delay); +void set_vcpu_migration_delay(unsigned int delay) +{ + vcpu_migration_delay = delay; +} + +unsigned int get_vcpu_migration_delay(void) +{ + return vcpu_migration_delay; +} + static inline int __csched_vcpu_is_cache_hot(struct vcpu *v) { diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c index 70da626416..fe254bbbbd 100644 --- a/xen/common/sysctl.c +++ b/xen/common/sysctl.c @@ -206,6 +206,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) case XEN_SYSCTL_get_pmstat: { + ret = xsm_get_pmstat(); + if ( ret ) + break; + ret = do_get_pm_info(&op->u.get_pmstat); if ( ret ) break; @@ -220,6 +224,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) case XEN_SYSCTL_pm_op: { + ret = xsm_pm_op(); + if ( ret ) + break; + ret = do_pm_op(&op->u.pm_op); if ( ret && (ret != -EAGAIN) ) break; diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c index 33954307d7..ad3623d5f2 100644 --- a/xen/drivers/acpi/pmstat.c +++ b/xen/drivers/acpi/pmstat.c @@ -528,6 +528,18 @@ int do_pm_op(struct xen_sysctl_pm_op *op) break; } + case XEN_SYSCTL_pm_op_set_vcpu_migration_delay: + { + set_vcpu_migration_delay(op->set_vcpu_migration_delay); + break; + } + + case XEN_SYSCTL_pm_op_get_vcpu_migration_delay: + { + op->get_vcpu_migration_delay = get_vcpu_migration_delay(); + break; + } + case XEN_SYSCTL_pm_op_get_max_cstate: { op->get_max_cstate = acpi_get_cstate_limit(); diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h index cb03262bd2..f17cd45072 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -386,6 +386,10 @@ struct xen_sysctl_pm_op { #define XEN_SYSCTL_pm_op_get_max_cstate 0x22 #define XEN_SYSCTL_pm_op_set_max_cstate 0x23 + /* set scheduler migration cost value */ + #define XEN_SYSCTL_pm_op_set_vcpu_migration_delay 0x24 + #define XEN_SYSCTL_pm_op_get_vcpu_migration_delay 0x25 + uint32_t cmd; uint32_t cpuid; union { @@ -397,6 +401,8 @@ struct xen_sysctl_pm_op { uint32_t set_sched_opt_smt; uint32_t get_max_cstate; uint32_t set_max_cstate; + uint32_t get_vcpu_migration_delay; + uint32_t set_vcpu_migration_delay; }; }; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 206bf6de4e..46731a5e98 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -552,6 +552,9 @@ uint64_t get_cpu_idle_time(unsigned int cpu); #define is_hvm_vcpu(v) (is_hvm_domain(v->domain)) #define need_iommu(d) ((d)->need_iommu && !(d)->is_hvm) +void set_vcpu_migration_delay(unsigned int delay); +unsigned int get_vcpu_migration_delay(void); + extern int sched_smt_power_savings; extern enum cpufreq_controller { diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index e5e15d5342..6d45efd0e2 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -75,6 +75,8 @@ struct xsm_operations { int (*debug_keys) (void); int (*getcpuinfo) (void); int (*availheap) (void); + int (*get_pmstat) (void); + int (*pm_op) (void); int (*evtchn_unbound) (struct domain *d, struct evtchn *chn, domid_t id2); int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1, @@ -282,6 +284,16 @@ static inline int xsm_getcpuinfo (void) return xsm_call(getcpuinfo()); } +static inline int xsm_get_pmstat(void) +{ + return xsm_call(get_pmstat()); +} + +static inline int xsm_pm_op(void) +{ + return xsm_call(pm_op()); +} + static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn, domid_t id2) { diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 8809828b7f..b6ac73a147 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -134,6 +134,16 @@ static int dummy_getcpuinfo (void) return 0; } +static int dummy_get_pmstat (void) +{ + return 0; +} + +static int dummy_pm_op (void) +{ + return 0; +} + static int dummy_availheap (void) { return 0; From b812d1ddc4f23d3781fefff6fdcac9d247ab7ebb Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 6 Apr 2009 13:49:59 +0100 Subject: [PATCH 71/76] xend: Use AUTO_PHP_SLOT where it ought to be Signed-off-by: Simon Horman --- tools/python/xen/xend/XendDomainInfo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 2d42927b10..644831b87d 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -620,7 +620,7 @@ class XendDomainInfo: pci_devs = pci_conf['devs'] for x in pci_devs: if (int(x['vslt'], 16) == int(new_dev['vslt'], 16) and - int(x['vslt'], 16) != 0 ): + int(x['vslt'], 16) != AUTO_PHP_SLOT): raise VmError("vslot %s already have a device." % (new_dev['vslt'])) if (int(x['domain'], 16) == int(new_dev['domain'], 16) and @@ -1053,7 +1053,7 @@ class XendDomainInfo: if devnum >= pci_len: raise VmError("Device @ vslot 0x%x doesn't exist." % (vslot)) - if vslot == 0: + if vslot == AUTO_PHP_SLOT: raise VmError("Device @ vslot 0x%x do not support hotplug." % (vslot)) # Check the co-assignment. From fdd33002ee45be20b317cad3e165714d14009390 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 6 Apr 2009 13:52:56 +0100 Subject: [PATCH 72/76] tools: Add device-path command to convert SBDF into device path. 'SBDF' format is "[SEG#:]BUS#:DEV#.FUNC#" ex) 0000:0a:1f.3 Device path format is "HID[:UID]-DEV#.FUNC#[-DEV#.FUNC#[...]]" ex) PNP0A08:0-2.0-0.0 The command can be executed as follows. # device_path 0a:1f.3 PNP0A08:0-2.0-0.0 Signed-off-by: Yuji Shimada --- Makefile | 2 +- tools/misc/Makefile | 2 +- tools/misc/device-path | 78 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 tools/misc/device-path diff --git a/Makefile b/Makefile index 131ab3d1a3..6081f4c0cd 100644 --- a/Makefile +++ b/Makefile @@ -224,7 +224,7 @@ uninstall: rm -rf $(D)$(LIBDIR)/xen/ rm -rf $(D)/usr/lib/xen/ rm -rf $(D)/usr/local/sbin/setmask $(D)/usr/local/sbin/xen* - rm -rf $(D)/usr/sbin/xen* $(D)/usr/sbin/netfix $(D)/usr/sbin/xm + rm -rf $(D)/usr/sbin/xen* $(D)/usr/sbin/netfix $(D)/usr/sbin/xm $(D)/usr/sbin/device-path rm -rf $(D)/usr/share/doc/xen rm -rf $(D)/usr/share/xen rm -rf $(D)/usr/share/man/man1/xen* diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 12c599cd75..83423e1537 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -22,7 +22,7 @@ INSTALL_BIN-y := xencons INSTALL_BIN-$(CONFIG_X86) += xen-detect INSTALL_BIN := $(INSTALL_BIN-y) -INSTALL_SBIN-y := netfix xm xen-bugtool xen-python-path xend xenperf xsview xenpm +INSTALL_SBIN-y := netfix xm xen-bugtool xen-python-path xend xenperf xsview xenpm device-path INSTALL_SBIN := $(INSTALL_SBIN-y) DEFAULT_PYTHON_PATH := $(shell $(XEN_ROOT)/tools/python/get-path) diff --git a/tools/misc/device-path b/tools/misc/device-path new file mode 100644 index 0000000000..b192eb2222 --- /dev/null +++ b/tools/misc/device-path @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# -*- mode: python; -*- +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# 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 +#============================================================================ +# Copyright (c) 2009, NEC Corporation. +#============================================================================ +# This script converts SBDF into device path. +# 'SBDF' format is "[SEG#:]BUS#:DEV#.FUNC#" +# ex) 0000:0a:1f.3 +# Device path format is "HID[:UID]-DEV#.FUNC#[-DEV#.FUNC#[...]]" +# ex) PNP0A08:0-2.0-0.0 +#============================================================================ + +import sys +import os + +# add fallback path for non-native python path installs if needed +sys.path.append('/usr/lib/python') +sys.path.append('/usr/lib64/python') +from xen.util.pci import * + +SYSFS_ACPI_DEVS_PATH = '/firmware/acpi/namespace/ACPI/_SB' + +def find_hid_uid(dom, b, d, f): + sb_path = find_sysfs_mnt() + SYSFS_ACPI_DEVS_PATH + obj_list = os.listdir(sb_path) + for obj in obj_list: + obj_path = sb_path + '/' + obj.strip() + '/' + if os.path.exists(obj_path + 'seg') and \ + os.path.exists(obj_path + 'bbn'): + seg = open(obj_path + 'seg').read() + bbn = open(obj_path + 'bbn').read() + if int(seg) == dom and int(bbn) == b: + hid = open(obj_path + 'hid').read() + if os.path.exists(obj_path + 'uid') is False: + path_str = hid.strip() + else: + uid = open(obj_path + 'uid').read() + path_str = hid.strip() + ':' + uid.strip() + return path_str + return None + +def make_device_path(dom, b, d, f): + dev = PciDevice(dom, b, d, f) + parent = dev.find_parent() + if parent is None: + path_str = find_hid_uid(dom, b, d, f) + path_str = path_str + '-' + hex(d).replace('0x', '') + '.' + \ + hex(f).replace('0x', '') + return path_str + (pdom, pb, pd, pf) = parent + path_str = make_device_path(pdom, pb, pd, pf) + path_str = path_str + '-' + hex(d).replace('0x', '') + '.' + \ + hex(f).replace('0x', '') + return path_str + +# main +if len(sys.argv) <> 2: + print 'Usage: device-path SBDF\n' +else: + path = os.environ['PATH'] + os.environ['PATH'] = path + ':/sbin' + ':/user/sbin' + sbdf = sys.argv[1] + (dom, b, d, f) = parse_pci_name(sbdf) + path_str = make_device_path(dom, b, d, f) + print path_str From a5428a4b5f54fa660b37d8eec88a69700f6f8352 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 6 Apr 2009 13:56:35 +0100 Subject: [PATCH 73/76] x86_64: explicitly zero CR[1] in getvcpucontext for guests with no user PT Signed-off-by: Ian Campbell --- xen/arch/x86/domctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 1d748f6f15..955c5e6088 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -1161,9 +1161,9 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) c.nat->ctrlreg[3] = xen_pfn_to_cr3( pagetable_get_pfn(v->arch.guest_table)); #ifdef __x86_64__ - if ( !pagetable_is_null(v->arch.guest_table_user) ) - c.nat->ctrlreg[1] = xen_pfn_to_cr3( - pagetable_get_pfn(v->arch.guest_table_user)); + c.nat->ctrlreg[1] = + pagetable_is_null(v->arch.guest_table_user) ? 0 + : xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table_user)); #endif /* Merge shadow DR7 bits into real DR7. */ From 75a5f05d44f1a7e41259451afead83360c76714f Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 6 Apr 2009 14:26:29 +0100 Subject: [PATCH 74/76] x86: Make special TSC handling (assuming all TSCs tick at exact same rate) dependent on a command-line option 'consistent_tscs'. Also clean up rendezvous logic. Signed-off-by: Keir Fraser --- xen/arch/x86/time.c | 111 ++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 41 deletions(-) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 223b44bbf9..ffe90ed1b9 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -35,6 +35,13 @@ static char opt_clocksource[10]; string_param("clocksource", opt_clocksource); +/* + * opt_consistent_tscs: All TSCs tick at the exact same rate, allowing + * simplified system time handling. + */ +static int opt_consistent_tscs; +boolean_param("consistent_tscs", opt_consistent_tscs); + unsigned long cpu_khz; /* CPU clock frequency in kHz. */ DEFINE_SPINLOCK(rtc_lock); unsigned long pit0_ticks; @@ -959,7 +966,7 @@ static void local_time_calibration(void) /* The overall calibration scale multiplier. */ u32 calibration_mul_frac; - if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ) + if ( opt_consistent_tscs ) { /* Atomically read cpu_calibration struct and write cpu_time struct. */ local_irq_disable(); @@ -1087,64 +1094,53 @@ static void local_time_calibration(void) */ struct calibration_rendezvous { cpumask_t cpu_calibration_map; - atomic_t count_start; - atomic_t count_end; + atomic_t semaphore; s_time_t master_stime; u64 master_tsc_stamp; }; -#define NR_LOOPS 5 - -static void time_calibration_rendezvous(void *_r) +static void time_calibration_tsc_rendezvous(void *_r) { int i; struct cpu_calibration *c = &this_cpu(cpu_calibration); struct calibration_rendezvous *r = _r; unsigned int total_cpus = cpus_weight(r->cpu_calibration_map); - /* - * Loop is used here to get rid of the cache's side effect to enlarge - * the TSC difference among CPUs. - */ - for ( i = 0; i < NR_LOOPS; i++ ) + /* Loop to get rid of cache effects on TSC skew. */ + for ( i = 4; i >= 0; i-- ) { if ( smp_processor_id() == 0 ) { - while ( atomic_read(&r->count_start) != (total_cpus - 1) ) + while ( atomic_read(&r->semaphore) != (total_cpus - 1) ) mb(); - + if ( r->master_stime == 0 ) { r->master_stime = read_platform_stime(); - if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ) - rdtscll(r->master_tsc_stamp); + rdtscll(r->master_tsc_stamp); } - atomic_set(&r->count_end, 0); - wmb(); - atomic_inc(&r->count_start); - - if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && - i == NR_LOOPS - 1 ) - write_tsc((u32)r->master_tsc_stamp, (u32)(r->master_tsc_stamp >> 32)); - - while (atomic_read(&r->count_end) != total_cpus - 1) + atomic_inc(&r->semaphore); + + if ( i == 0 ) + write_tsc((u32)r->master_tsc_stamp, + (u32)(r->master_tsc_stamp >> 32)); + + while ( atomic_read(&r->semaphore) != (2*total_cpus - 1) ) mb(); - atomic_set(&r->count_start, 0); - wmb(); - atomic_inc(&r->count_end); + atomic_set(&r->semaphore, 0); } else { - atomic_inc(&r->count_start); - while ( atomic_read(&r->count_start) != total_cpus ) + atomic_inc(&r->semaphore); + while ( atomic_read(&r->semaphore) < total_cpus ) mb(); - - if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && - i == NR_LOOPS - 1 ) - write_tsc((u32)r->master_tsc_stamp, (u32)(r->master_tsc_stamp >> 32)); - - atomic_inc(&r->count_end); - while (atomic_read(&r->count_end) != total_cpus) + + if ( i == 0 ) + write_tsc((u32)r->master_tsc_stamp, + (u32)(r->master_tsc_stamp >> 32)); + + atomic_inc(&r->semaphore); + while ( atomic_read(&r->semaphore) > total_cpus ) mb(); } } @@ -1156,18 +1152,48 @@ static void time_calibration_rendezvous(void *_r) raise_softirq(TIME_CALIBRATE_SOFTIRQ); } +static void time_calibration_std_rendezvous(void *_r) +{ + struct cpu_calibration *c = &this_cpu(cpu_calibration); + struct calibration_rendezvous *r = _r; + unsigned int total_cpus = cpus_weight(r->cpu_calibration_map); + + if ( smp_processor_id() == 0 ) + { + while ( atomic_read(&r->semaphore) != (total_cpus - 1) ) + cpu_relax(); + r->master_stime = read_platform_stime(); + mb(); /* write r->master_stime /then/ signal */ + atomic_inc(&r->semaphore); + } + else + { + atomic_inc(&r->semaphore); + while ( atomic_read(&r->semaphore) != total_cpus ) + cpu_relax(); + mb(); /* receive signal /then/ read r->master_stime */ + } + + rdtscll(c->local_tsc_stamp); + c->stime_local_stamp = get_s_time(); + c->stime_master_stamp = r->master_stime; + + raise_softirq(TIME_CALIBRATE_SOFTIRQ); +} + static void time_calibration(void *unused) { struct calibration_rendezvous r = { .cpu_calibration_map = cpu_online_map, - .count_start = ATOMIC_INIT(0), - .count_end = ATOMIC_INIT(0), - .master_stime = 0 + .semaphore = ATOMIC_INIT(0) }; /* @wait=1 because we must wait for all cpus before freeing @r. */ on_selected_cpus(r.cpu_calibration_map, - time_calibration_rendezvous, &r, 0, 1); + opt_consistent_tscs + ? time_calibration_tsc_rendezvous + : time_calibration_std_rendezvous, + &r, 0, 1); } void init_percpu_time(void) @@ -1194,8 +1220,11 @@ void init_percpu_time(void) /* Late init function (after all CPUs are booted). */ int __init init_xen_time(void) { + if ( !boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ) + opt_consistent_tscs = 0; + /* If we have constant TSCs then scale factor can be shared. */ - if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ) + if ( opt_consistent_tscs ) { int cpu; for_each_cpu ( cpu ) From 1a4c39bf21ad4f53427f5db4f9fd554a22bd1ff3 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 6 Apr 2009 20:56:02 +0100 Subject: [PATCH 75/76] Revert c/s 19504 -- uses an obsolete sysfs interface. Signed-off-by: Keir Fraser --- Makefile | 2 +- tools/misc/Makefile | 2 +- tools/misc/device-path | 78 ------------------------------------------ 3 files changed, 2 insertions(+), 80 deletions(-) delete mode 100644 tools/misc/device-path diff --git a/Makefile b/Makefile index 6081f4c0cd..131ab3d1a3 100644 --- a/Makefile +++ b/Makefile @@ -224,7 +224,7 @@ uninstall: rm -rf $(D)$(LIBDIR)/xen/ rm -rf $(D)/usr/lib/xen/ rm -rf $(D)/usr/local/sbin/setmask $(D)/usr/local/sbin/xen* - rm -rf $(D)/usr/sbin/xen* $(D)/usr/sbin/netfix $(D)/usr/sbin/xm $(D)/usr/sbin/device-path + rm -rf $(D)/usr/sbin/xen* $(D)/usr/sbin/netfix $(D)/usr/sbin/xm rm -rf $(D)/usr/share/doc/xen rm -rf $(D)/usr/share/xen rm -rf $(D)/usr/share/man/man1/xen* diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 83423e1537..12c599cd75 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -22,7 +22,7 @@ INSTALL_BIN-y := xencons INSTALL_BIN-$(CONFIG_X86) += xen-detect INSTALL_BIN := $(INSTALL_BIN-y) -INSTALL_SBIN-y := netfix xm xen-bugtool xen-python-path xend xenperf xsview xenpm device-path +INSTALL_SBIN-y := netfix xm xen-bugtool xen-python-path xend xenperf xsview xenpm INSTALL_SBIN := $(INSTALL_SBIN-y) DEFAULT_PYTHON_PATH := $(shell $(XEN_ROOT)/tools/python/get-path) diff --git a/tools/misc/device-path b/tools/misc/device-path deleted file mode 100644 index b192eb2222..0000000000 --- a/tools/misc/device-path +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -# -*- mode: python; -*- -#============================================================================ -# This library is free software; you can redistribute it and/or -# modify it under the terms of version 2.1 of the GNU Lesser General Public -# License as published by the Free Software Foundation. -# -# 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 -#============================================================================ -# Copyright (c) 2009, NEC Corporation. -#============================================================================ -# This script converts SBDF into device path. -# 'SBDF' format is "[SEG#:]BUS#:DEV#.FUNC#" -# ex) 0000:0a:1f.3 -# Device path format is "HID[:UID]-DEV#.FUNC#[-DEV#.FUNC#[...]]" -# ex) PNP0A08:0-2.0-0.0 -#============================================================================ - -import sys -import os - -# add fallback path for non-native python path installs if needed -sys.path.append('/usr/lib/python') -sys.path.append('/usr/lib64/python') -from xen.util.pci import * - -SYSFS_ACPI_DEVS_PATH = '/firmware/acpi/namespace/ACPI/_SB' - -def find_hid_uid(dom, b, d, f): - sb_path = find_sysfs_mnt() + SYSFS_ACPI_DEVS_PATH - obj_list = os.listdir(sb_path) - for obj in obj_list: - obj_path = sb_path + '/' + obj.strip() + '/' - if os.path.exists(obj_path + 'seg') and \ - os.path.exists(obj_path + 'bbn'): - seg = open(obj_path + 'seg').read() - bbn = open(obj_path + 'bbn').read() - if int(seg) == dom and int(bbn) == b: - hid = open(obj_path + 'hid').read() - if os.path.exists(obj_path + 'uid') is False: - path_str = hid.strip() - else: - uid = open(obj_path + 'uid').read() - path_str = hid.strip() + ':' + uid.strip() - return path_str - return None - -def make_device_path(dom, b, d, f): - dev = PciDevice(dom, b, d, f) - parent = dev.find_parent() - if parent is None: - path_str = find_hid_uid(dom, b, d, f) - path_str = path_str + '-' + hex(d).replace('0x', '') + '.' + \ - hex(f).replace('0x', '') - return path_str - (pdom, pb, pd, pf) = parent - path_str = make_device_path(pdom, pb, pd, pf) - path_str = path_str + '-' + hex(d).replace('0x', '') + '.' + \ - hex(f).replace('0x', '') - return path_str - -# main -if len(sys.argv) <> 2: - print 'Usage: device-path SBDF\n' -else: - path = os.environ['PATH'] - os.environ['PATH'] = path + ':/sbin' + ':/user/sbin' - sbdf = sys.argv[1] - (dom, b, d, f) = parse_pci_name(sbdf) - path_str = make_device_path(dom, b, d, f) - print path_str From e6e6785c99bccdd61ecf6ffcfd4aa3423e3a1255 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 6 Apr 2009 21:12:33 +0100 Subject: [PATCH 76/76] tools/misc: Remove some obsolete scripts. Signed-off-by: Keir Fraser --- tools/misc/Makefile | 2 +- tools/misc/fakei386xen | 32 ----------------- tools/misc/netfix | 69 ------------------------------------- tools/misc/xen-clone.README | 23 ------------- 4 files changed, 1 insertion(+), 125 deletions(-) delete mode 100755 tools/misc/fakei386xen delete mode 100644 tools/misc/netfix delete mode 100644 tools/misc/xen-clone.README diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 12c599cd75..c309a3f106 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -22,7 +22,7 @@ INSTALL_BIN-y := xencons INSTALL_BIN-$(CONFIG_X86) += xen-detect INSTALL_BIN := $(INSTALL_BIN-y) -INSTALL_SBIN-y := netfix xm xen-bugtool xen-python-path xend xenperf xsview xenpm +INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm INSTALL_SBIN := $(INSTALL_SBIN-y) DEFAULT_PYTHON_PATH := $(shell $(XEN_ROOT)/tools/python/get-path) diff --git a/tools/misc/fakei386xen b/tools/misc/fakei386xen deleted file mode 100755 index e1462c2f58..0000000000 --- a/tools/misc/fakei386xen +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -cln () { -while [ $# -gt 0 ]; do - ( - test -f "$1" || { echo "$1: No such file or directory" 1>&2; exit 1; } - { cp $1 cln$$ && rm $1 && mv cln$$ $1; } || { rm -f cln$$; exit 1; } - ) - shift -done -} - - -for i in `find include/asm-xen arch/xen -type l | xargs ls -l | egrep '../(asm-)?i386/' | awk '{print $9}'` -do - echo $i - cln $i -done - -mv include/asm-i386 include/asm-Xi386 -mv include/asm-xen include/asm-i386 -ln -s asm-i386 include/asm-xen -rm include/asm -ln -s asm-i386 include/asm -mv arch/i386 arch/Xi386 -mv arch/xen arch/i386 -ln -s i386 arch/xen - -mv Makefile XMakefile -#sed -e 's/^EXTRAVERSION =.*/EXTRAVERSION = -xen/' Makefile -echo ARCH=i386 >Makefile ; cat XMakefile >>Makefile - diff --git a/tools/misc/netfix b/tools/misc/netfix deleted file mode 100644 index 669a95497a..0000000000 --- a/tools/misc/netfix +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python -# -*- mode: python; -*- -#============================================================================ -# Copyright (C) 2004 Mike Wray -#============================================================================ -# Move the IP address from eth0 onto the Xen bridge (xenbr0). -# Only works if the bridge control utils (brctl) have been installed. -#============================================================================ - -from getopt import getopt - -# add fallback path for non-native python path installs if needed -sys.path.append('/usr/lib/python') -sys.path.append('/usr/lib64/python') -from xen.util.Brctl import * - -short_options = 'hvqni:b:c' -long_options = ['help', 'verbose', 'quiet', - 'interface=', 'bridge=', 'create'] - -defaults['interface'] = 'eth0' -defaults['bridge'] = 'xenbr0' - -def usage(): - print """Usage: - %s [options] - - Reconfigure routing so that has the IP address from - . This lets IP carry on working when - is attached to for virtual networking. - Uses brctl to add to , - so this can be run before any domains have been created. - """ % sys.argv[0] - print """ - -i, --interface interface, default %(interface)s. - -b, --bridge bridge, default %(bridge)s. - -c, --create create the bridge. - -v, --verbose Print commands. - -q, --quiet Don't print commands. - -n, --dry-run Don't execute commands. - -h, --help Print this help. - """ % defaults - sys.exit(1) - - -def main(): - lopts = set_opts(Opts(defaults)) - lopts.dryrun = 0 - (options, args) = getopt(sys.argv[1:], short_options, long_options) - if args: usage() - for k, v in options: - if k in ['-h', '--help']: - usage() - elif k in ['-c', '--create']: - lopts.create = 1 - elif k in ['-i', '--interface']: - lopts.interface = v - elif k in ['-b', '--bridge']: - lopts.bridge = v - elif k in ['-q', '--quiet']: - lopts.verbose = 0 - elif k in ['-v', '--verbose']: - lopts.verbose = 1 - elif k in ['-n', '--dry-run']: - lopts.dryrun = 1 - reconfigure(lopts.interface, lopts.bridge) - -if __name__ == '__main__': - main() diff --git a/tools/misc/xen-clone.README b/tools/misc/xen-clone.README deleted file mode 100644 index dfa86d1d75..0000000000 --- a/tools/misc/xen-clone.README +++ /dev/null @@ -1,23 +0,0 @@ - -xen-clone - -usage: xen-clone - -This script can be used to 'bk clone' and build a xen and xenolinux image -from the master BK repository, either from a local copy, or from the -public repository bk://xen.bkbits.net/xeno.bk - -In many circumstances, it can be invoked without any arguments and -just `does the right thing'. - -The default dest_dir is 'xeno-clone', relative to the current directory. - -To build xenolinux, the script needs a pristine copy of the equivalent -linux tree. The script looks in a couple of places on the local filesystem, -then tries a download from from ftp://ftp.kernel.org/pub/linux/kernel/v2.4/ - -The script also tries a number of optional UCCL site-specific operations -that configure the test machine booting infrastructure to boot the -resultant image. - -