diff --git a/20158-revert.patch b/20158-revert.patch new file mode 100644 index 0000000..23121e2 --- /dev/null +++ b/20158-revert.patch @@ -0,0 +1,55 @@ +# HG changeset patch +# User jfehlig@localhost +# Date 1293498049 25200 +# Node ID 7584dc7bc3de64340f193a0cab188e85bd50d594 +# Parent f9ce5858f7eae84bec34aa10d3585c7e6f6ca6c9 +Revert 20158:f9ce5858f7ea xend: Support "bootloader" mode for "drbd:" devices + +block-drbd (provided by drbd project) handles all the details that +c/s 20158 introduces within xend. Subtleties of configuring storage +subsystems should not be handled by xend, but instead delegated to the block +script mechansim provided by the xen toool stack. + +Note: Patch submitted upstream but not (yet) accepted since xend is on + the way out. + +http://lists.xensource.com/archives/html/xen-devel/2010-12/msg01160.html + +Index: xen-4.0.1-testing/tools/python/xen/util/blkif.py +=================================================================== +--- xen-4.0.1-testing.orig/tools/python/xen/util/blkif.py ++++ xen-4.0.1-testing/tools/python/xen/util/blkif.py +@@ -79,13 +79,6 @@ def parse_uname(uname): + if typ == "phy" and not fn.startswith("/"): + fn = "/dev/%s" %(fn,) + +- if typ == "drbd": +- if not fn.startswith("drbd"): +- (drbdadmstdin, drbdadmstdout) = os.popen2("/sbin/drbdadm "+"sh-dev "+fn) +- fn = drbdadmstdout.readline().strip() +- else: +- fn = "/dev/%s" %(fn,) +- + if typ in ("tap", "tap2"): + (taptype, fn) = fn.split(":", 1) + if taptype in ("tapdisk", "ioemu"): +Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-4.0.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -3283,15 +3283,6 @@ class XendDomainInfo: + + (fn, types) = parse_uname(disk) + +- # If this is a drbd volume, check if we need to activate it +- if disk.find(":") != -1: +- (disktype, diskname) = disk.split(':', 1) +- if disktype == 'drbd': +- (drbdadmstdin, drbdadmstdout) = os.popen2(["/sbin/drbdadm", "state", diskname]) +- (state, junk) = drbdadmstdout.readline().split('/', 1) +- if state == 'Secondary': +- os.system('/sbin/drbdadm primary ' + diskname) +- + def _shouldMount(types): + if types[0] in ('file', 'phy'): + return False diff --git a/21344-4.0-testing-xenstore-fd-leak.patch b/21344-4.0-testing-xenstore-fd-leak.patch new file mode 100644 index 0000000..f13a11f --- /dev/null +++ b/21344-4.0-testing-xenstore-fd-leak.patch @@ -0,0 +1,25 @@ +# HG changeset patch +# User Keir Fraser +# Date 1284535198 -3600 +# Node ID 86b99b9ad6ef9492b66c98e2377105f3ea584cbf +# Parent 89605b79f56529d34d963d0d91c67c46294a7b7c +Fix fd leak in xenstore + +Missing from commit 'libxl: Backported stuff from unstable' +Without this change, xs_daemon_open/xs_daemon_close will leak +file descriptors. + +Signed-off-by: Olaf Hering + +diff -r 89605b79f565 -r 86b99b9ad6ef tools/xenstore/xs.c +--- a/tools/xenstore/xs.c Mon Sep 13 17:51:50 2010 +0100 ++++ b/tools/xenstore/xs.c Wed Sep 15 08:19:58 2010 +0100 +@@ -285,6 +285,8 @@ + mutex_unlock(&h->request_mutex); + mutex_unlock(&h->reply_mutex); + mutex_unlock(&h->watch_mutex); ++ ++ close_fds_free(h); + } + + static bool read_all(int fd, void *data, unsigned int len) diff --git a/21432-4.0-cpu-boot-failure.patch b/21432-4.0-cpu-boot-failure.patch new file mode 100644 index 0000000..e6c6764 --- /dev/null +++ b/21432-4.0-cpu-boot-failure.patch @@ -0,0 +1,35 @@ +# HG changeset patch +# User Keir Fraser +# Date 1294742461 0 +# Node ID 7a203c60d588a7a15a28a6fb16c69feafd157e0d +# Parent 64bb7d9904a64cc4561c6d541d857acf46e42180 +x86: don't crash when a CPU cannot be brought online during boot +References: bnc#656369, bnc#658704 + +x86_cpu_to_apicid[] gets set to BAD_APICID when bringup of a secondary +CPU fails, yet srat_detect_node() wants to use this as array index. + +Signed-off-by: Jan Beulich + +Index: xen-4.0.1-testing/xen/arch/x86/setup.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/setup.c ++++ xen-4.0.1-testing/xen/arch/x86/setup.c +@@ -1103,10 +1103,13 @@ void __init __start_xen(unsigned long mb + __cpu_up(i); + } + +- /* Set up cpu_to_node[]. */ +- srat_detect_node(i); +- /* Set up node_to_cpumask based on cpu_to_node[]. */ +- numa_add_cpu(i); ++ if ( cpu_online(i) ) ++ { ++ /* Set up cpu_to_node[]. */ ++ srat_detect_node(i); ++ /* Set up node_to_cpumask based on cpu_to_node[]. */ ++ numa_add_cpu(i); ++ } + } + + printk("Brought up %ld CPUs\n", (long)num_online_cpus()); diff --git a/21810-x2apic-acpi.patch b/21810-x2apic-acpi.patch new file mode 100644 index 0000000..9ac67a7 --- /dev/null +++ b/21810-x2apic-acpi.patch @@ -0,0 +1,465 @@ +# HG changeset patch +# User Keir Fraser +# Date 1279284738 -3600 +# Node ID fedab6367c9a0141d49853c77a23d6642ba70ff6 +# Parent 1f7c2418e58c7d1d5650ea211016b30114de48f2 +ACPI: add support for x2APIC ACPI extensions +References: bnc#656369, bnc#658704 + +All logical processors with APIC ID values of 255 and greater will +have their APIC reported through Processor X2APIC structure (type-9 +entry type) and all logical processors with APIC ID less than 255 will +have their APIC reported through legacy Processor Local APIC (type-0 +entry type) only. This is the same case even for NMI structure +reporting. + +The Processor X2APIC Affinity structure provides the association +between the X2APIC ID of a logical processor and the proximity domain +to which the logical processor belongs. + +This patch adds 2 new subtables to MADT and one new subtable to SRAT. + +This patch also changes x86_acpiid_to_apicid from u8 to u32 for x2APIC +ID, and changes mp_register_lapic to accept 32-bit id. But there are +still some 8-bit apic id hardcode and assumptions in Xen code, it +needs to be fixed in future. + +Signed-off-by: Weidong Han + +--- a/xen/arch/x86/acpi/boot.c ++++ b/xen/arch/x86/acpi/boot.c +@@ -81,7 +81,7 @@ u8 acpi_enable_value, acpi_disable_value + #warning ACPI uses CMPXCHG, i486 and later hardware + #endif + +-u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = ++u32 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = + {[0 ... MAX_MADT_ENTRIES - 1] = 0xff }; + EXPORT_SYMBOL(x86_acpiid_to_apicid); + +@@ -156,6 +156,35 @@ static int __init acpi_parse_madt(struct + } + + static int __init ++acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) ++{ ++ struct acpi_table_x2apic *processor = NULL; ++ ++ processor = (struct acpi_table_x2apic *)header; ++ ++ if (BAD_MADT_ENTRY(processor, end)) ++ return -EINVAL; ++ ++ acpi_table_print_madt_entry(header); ++ ++ /* Record local apic id only when enabled */ ++ if (processor->flags.enabled) ++ x86_acpiid_to_apicid[processor->acpi_uid] = processor->id; ++ ++ /* ++ * We need to register disabled CPU as well to permit ++ * counting disabled CPUs. This allows us to size ++ * cpus_possible_map more accurately, to permit ++ * to not preallocating memory for all NR_CPUS ++ * when we use CPU hotplug. ++ */ ++ mp_register_lapic(processor->id, /* X2APIC ID */ ++ processor->flags.enabled); /* Enabled? */ ++ ++ return 0; ++} ++ ++static int __init + acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) + { + struct acpi_table_lapic *processor = NULL; +@@ -201,6 +230,25 @@ acpi_parse_lapic_addr_ovr(struct acpi_su + } + + static int __init ++acpi_parse_x2apic_nmi(struct acpi_subtable_header *header, ++ const unsigned long end) ++{ ++ struct acpi_table_x2apic_nmi *x2apic_nmi = NULL; ++ ++ x2apic_nmi = (struct acpi_table_x2apic_nmi *)header; ++ ++ if (BAD_MADT_ENTRY(x2apic_nmi, end)) ++ return -EINVAL; ++ ++ acpi_table_print_madt_entry(header); ++ ++ if (x2apic_nmi->lint != 1) ++ printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); ++ ++ return 0; ++} ++ ++static int __init + acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) + { + struct acpi_table_lapic_nmi *lapic_nmi = NULL; +@@ -465,7 +513,7 @@ static int __init acpi_parse_fadt(struct + */ + static int __init acpi_parse_madt_lapic_entries(void) + { +- int count; ++ int count, x2count; + + if (!cpu_has_apic) + return -ENODEV; +@@ -488,11 +536,13 @@ static int __init acpi_parse_madt_lapic_ + + count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, + MAX_APICS); +- if (!count) { ++ x2count = acpi_table_parse_madt(ACPI_MADT_X2APIC, acpi_parse_x2apic, ++ MAX_APICS); ++ if (!count && !x2count) { + printk(KERN_ERR PREFIX "No LAPIC entries present\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return -ENODEV; +- } else if (count < 0) { ++ } else if (count < 0 || x2count < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return count; +@@ -500,7 +550,10 @@ static int __init acpi_parse_madt_lapic_ + + count = + acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); +- if (count < 0) { ++ x2count = ++ acpi_table_parse_madt(ACPI_MADT_X2APIC_NMI, ++ acpi_parse_x2apic_nmi, 0); ++ if (count < 0 || x2count < 0) { + printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return count; +--- a/xen/arch/x86/mpparse.c ++++ b/xen/arch/x86/mpparse.c +@@ -838,7 +838,7 @@ void __init mp_register_lapic_address ( + + + int __devinit mp_register_lapic ( +- u8 id, ++ u32 id, + u8 enabled) + { + struct mpc_config_processor processor; +--- a/xen/arch/x86/srat.c ++++ b/xen/arch/x86/srat.c +@@ -164,6 +164,36 @@ void __init acpi_numa_slit_init(struct a + } + #endif + ++/* Callback for Proximity Domain -> x2APIC mapping */ ++void __init ++acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) ++{ ++ int pxm, node; ++ int apic_id; ++ ++ if (srat_disabled()) ++ return; ++ if (pa->header.length < sizeof(struct acpi_srat_x2apic_cpu_affinity)) { ++ bad_srat(); ++ return; ++ } ++ if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0) ++ return; ++ pxm = pa->proximity_domain; ++ node = setup_node(pxm); ++ if (node < 0) { ++ printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm); ++ bad_srat(); ++ return; ++ } ++ ++ apic_id = pa->apic_id; ++ apicid_to_node[apic_id] = node; ++ acpi_numa = 1; ++ printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n", ++ pxm, apic_id, node); ++} ++ + /* Callback for Proximity Domain -> LAPIC mapping */ + void __init + acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) +--- a/xen/drivers/acpi/numa.c ++++ b/xen/drivers/acpi/numa.c +@@ -90,6 +90,21 @@ void __init acpi_table_print_srat_entry( + #endif /* ACPI_DEBUG_OUTPUT */ + break; + ++ case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: ++#ifdef ACPI_DEBUG_OUTPUT ++ { ++ struct acpi_srat_x2apic_cpu_affinity *p = ++ (struct acpi_srat_x2apic_cpu_affinity *)header; ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, ++ "SRAT Processor (x2apicid[0x%08x]) in" ++ " proximity domain %d %s\n", ++ p->apic_id, ++ p->proximity_domain, ++ (p->flags & ACPI_SRAT_CPU_ENABLED) ? ++ "enabled" : "disabled")); ++ } ++#endif /* ACPI_DEBUG_OUTPUT */ ++ break; + default: + printk(KERN_WARNING PREFIX + "Found unsupported SRAT entry (type = 0x%x)\n", +@@ -105,6 +120,33 @@ static int __init acpi_parse_slit(struct + return 0; + } + ++void __init __attribute__ ((weak)) ++acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) ++{ ++ printk(KERN_WARNING PREFIX ++ "Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id); ++ return; ++} ++ ++ ++static int __init ++acpi_parse_x2apic_affinity(struct acpi_subtable_header *header, ++ const unsigned long end) ++{ ++ struct acpi_srat_x2apic_cpu_affinity *processor_affinity; ++ ++ processor_affinity = (struct acpi_srat_x2apic_cpu_affinity *)header; ++ if (!processor_affinity) ++ return -EINVAL; ++ ++ acpi_table_print_srat_entry(header); ++ ++ /* let architecture-dependent part to do it */ ++ acpi_numa_x2apic_affinity_init(processor_affinity); ++ ++ return 0; ++} ++ + static int __init + acpi_parse_processor_affinity(struct acpi_subtable_header * header, + const unsigned long end) +@@ -164,6 +206,8 @@ int __init acpi_numa_init(void) + { + /* SRAT: Static Resource Affinity Table */ + if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { ++ acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY, ++ acpi_parse_x2apic_affinity, NR_CPUS); + acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY, + acpi_parse_processor_affinity, + NR_CPUS); +--- a/xen/drivers/acpi/tables.c ++++ b/xen/drivers/acpi/tables.c +@@ -63,6 +63,18 @@ void __init acpi_table_print_madt_entry( + } + break; + ++ case ACPI_MADT_TYPE_LOCAL_X2APIC: ++ { ++ struct acpi_madt_local_x2apic *p = ++ (struct acpi_madt_local_x2apic *)header; ++ printk(KERN_INFO PREFIX ++ "X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n", ++ p->local_apic_id, p->uid, ++ (p->lapic_flags & ACPI_MADT_ENABLED) ? ++ "enabled" : "disabled"); ++ } ++ break; ++ + case ACPI_MADT_TYPE_IO_APIC: + { + struct acpi_madt_io_apic *p = +@@ -117,6 +129,24 @@ void __init acpi_table_print_madt_entry( + } + break; + ++ case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: ++ { ++ u16 polarity, trigger; ++ struct acpi_madt_local_x2apic_nmi *p = ++ (struct acpi_madt_local_x2apic_nmi *)header; ++ ++ polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK; ++ trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2; ++ ++ printk(KERN_INFO PREFIX ++ "X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n", ++ p->uid, ++ mps_inti_flags_polarity[polarity], ++ mps_inti_flags_trigger[trigger], ++ p->lint); ++ } ++ break; ++ + case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: + { + struct acpi_madt_local_apic_override *p = +--- a/xen/include/acpi/actbl1.h ++++ b/xen/include/acpi/actbl1.h +@@ -404,7 +404,9 @@ enum acpi_madt_type { + ACPI_MADT_TYPE_IO_SAPIC = 6, + ACPI_MADT_TYPE_LOCAL_SAPIC = 7, + ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8, +- ACPI_MADT_TYPE_RESERVED = 9 /* 9 and greater are reserved */ ++ ACPI_MADT_TYPE_LOCAL_X2APIC = 9, ++ ACPI_MADT_TYPE_LOCAL_X2APIC_NMI = 10, ++ ACPI_MADT_TYPE_RESERVED = 11 /* 11 and greater are reserved */ + }; + + /* +@@ -505,6 +507,26 @@ struct acpi_madt_interrupt_source { + + #define ACPI_MADT_CPEI_OVERRIDE (1) + ++/* 9: Processor Local X2APIC (ACPI 4.0) */ ++ ++struct acpi_madt_local_x2apic { ++ struct acpi_subtable_header header; ++ u16 reserved; /* Reserved - must be zero */ ++ u32 local_apic_id; /* Processor X2_APIC ID */ ++ u32 lapic_flags; ++ u32 uid; /* Extended X2_APIC processor ID */ ++}; ++ ++/* 10: Local X2APIC NMI (ACPI 4.0) */ ++ ++struct acpi_madt_local_x2apic_nmi { ++ struct acpi_subtable_header header; ++ u16 inti_flags; ++ u32 uid; /* Processor X2_APIC ID */ ++ u8 lint; /* LINTn to which NMI is connected */ ++ u8 reserved[3]; ++}; ++ + /* + * Common flags fields for MADT subtables + */ +@@ -646,11 +668,14 @@ struct acpi_table_srat { + enum acpi_srat_type { + ACPI_SRAT_TYPE_CPU_AFFINITY = 0, + ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1, +- ACPI_SRAT_TYPE_RESERVED = 2 ++ ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2, ++ ACPI_SRAT_TYPE_RESERVED = 3 /* 3 and greater are reserved */ + }; + + /* SRAT sub-tables */ + ++/* 0: Processor Local APIC/SAPIC Affinity */ ++ + struct acpi_srat_cpu_affinity { + struct acpi_subtable_header header; + u8 proximity_domain_lo; +@@ -661,9 +686,7 @@ struct acpi_srat_cpu_affinity { + u32 reserved; /* Reserved, must be zero */ + }; + +-/* Flags */ +- +-#define ACPI_SRAT_CPU_ENABLED (1) /* 00: Use affinity structure */ ++/* 1: Memory Affinity */ + + struct acpi_srat_mem_affinity { + struct acpi_subtable_header header; +@@ -682,6 +705,22 @@ struct acpi_srat_mem_affinity { + #define ACPI_SRAT_MEM_HOT_PLUGGABLE (1<<1) /* 01: Memory region is hot pluggable */ + #define ACPI_SRAT_MEM_NON_VOLATILE (1<<2) /* 02: Memory region is non-volatile */ + ++/* 2: Processor Local X2_APIC Affinity (ACPI 4.0) */ ++ ++struct acpi_srat_x2apic_cpu_affinity { ++ struct acpi_subtable_header header; ++ u16 reserved; /* Reserved, must be zero */ ++ u32 proximity_domain; ++ u32 apic_id; ++ u32 flags; ++ u32 clock_domain; ++ u32 reserved2; ++}; ++ ++/* Flags for struct acpi_srat_cpu_affinity and struct acpi_srat_x2apic_cpu_affinity */ ++ ++#define ACPI_SRAT_CPU_ENABLED (1) /* 00: Use affinity structure */ ++ + /******************************************************************************* + * + * TCPA - Trusted Computing Platform Alliance table +--- a/xen/include/asm-x86/acpi.h ++++ b/xen/include/asm-x86/acpi.h +@@ -151,7 +151,7 @@ struct acpi_sleep_info { + #endif /* CONFIG_ACPI_SLEEP */ + + #define MAX_MADT_ENTRIES 256 +-extern u8 x86_acpiid_to_apicid[]; ++extern u32 x86_acpiid_to_apicid[]; + #define MAX_LOCAL_APIC 256 + + extern u32 pmtmr_ioport; +--- a/xen/include/asm-x86/mpspec.h ++++ b/xen/include/asm-x86/mpspec.h +@@ -24,7 +24,7 @@ extern int pic_mode; + extern int using_apic_timer; + + #ifdef CONFIG_ACPI +-extern int mp_register_lapic (u8 id, u8 enabled); ++extern int mp_register_lapic (u32 id, u8 enabled); + extern void mp_unregister_lapic(uint32_t apic_id, uint32_t cpu); + extern void mp_register_lapic_address (u64 address); + extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); +--- a/xen/include/xen/acpi.h ++++ b/xen/include/xen/acpi.h +@@ -57,6 +57,8 @@ enum acpi_madt_entry_id { + ACPI_MADT_IOSAPIC, + ACPI_MADT_LSAPIC, + ACPI_MADT_PLAT_INT_SRC, ++ ACPI_MADT_X2APIC, ++ ACPI_MADT_X2APIC_NMI, + ACPI_MADT_ENTRY_COUNT + }; + +@@ -76,6 +78,17 @@ struct acpi_table_lapic { + } flags; + } __attribute__ ((packed)); + ++struct acpi_table_x2apic { ++ struct acpi_subtable_header header; ++ u16 reserved; ++ u32 id; ++ struct { ++ u32 enabled:1; ++ u32 reserved:31; ++ } flags; ++ u32 acpi_uid; ++} __attribute__ ((packed)); ++ + struct acpi_table_ioapic { + struct acpi_subtable_header header; + u8 id; +@@ -105,6 +118,14 @@ struct acpi_table_lapic_nmi { + u8 lint; + } __attribute__ ((packed)); + ++struct acpi_table_x2apic_nmi { ++ struct acpi_subtable_header header; ++ acpi_interrupt_flags flags; ++ u32 acpi_uid; ++ u8 lint; ++ u8 reserved[3]; ++} __attribute__ ((packed)); ++ + struct acpi_table_lapic_addr_ovr { + struct acpi_subtable_header header; + u8 reserved[2]; +@@ -280,6 +301,7 @@ void acpi_table_print_srat_entry (struct + /* the following four functions are architecture-dependent */ + void acpi_numa_slit_init (struct acpi_table_slit *slit); + void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); ++void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa); + void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); + void acpi_numa_arch_fixup(void); + diff --git a/21989-x2apic-resume.patch b/21989-x2apic-resume.patch new file mode 100644 index 0000000..e356b1e --- /dev/null +++ b/21989-x2apic-resume.patch @@ -0,0 +1,168 @@ +# HG changeset patch +# User Keir Fraser +# Date 1281707886 -3600 +# Node ID 3cee41690fa26853acb0be65065c52f6029ca599 +# Parent 01d185dab39e9be399b203bec91870e04f576c23 +x2APIC: Improve x2APIC suspend/resume +References: bnc#656369, bnc#658704 + +x2apic depends on interrupt remapping, so it should disable interrupt +remapping behind x2apic disabling. And also this patch wraps +__enable_x2apic to get rid of duplicated code. + +Signed-off-by: Weidong Han + +Index: xen-4.0.1-testing/xen/arch/x86/apic.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/apic.c ++++ xen-4.0.1-testing/xen/arch/x86/apic.c +@@ -496,9 +496,20 @@ static void apic_pm_activate(void) + apic_pm_state.active = 1; + } + ++static void __enable_x2apic(void) ++{ ++ u32 lo, hi; ++ ++ rdmsr(MSR_IA32_APICBASE, lo, hi); ++ if ( !(lo & MSR_IA32_APICBASE_EXTD) ) ++ { ++ lo |= MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD; ++ wrmsr(MSR_IA32_APICBASE, lo, 0); ++ } ++} ++ + static void resume_x2apic(void) + { +- uint64_t msr_content; + struct IO_APIC_route_entry **ioapic_entries = NULL; + + ASSERT(x2apic_enabled); +@@ -520,14 +531,7 @@ static void resume_x2apic(void) + mask_IO_APIC_setup(ioapic_entries); + + iommu_enable_IR(); +- +- rdmsrl(MSR_IA32_APICBASE, msr_content); +- if ( !(msr_content & MSR_IA32_APICBASE_EXTD) ) +- { +- msr_content |= MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD; +- msr_content = (uint32_t)msr_content; +- wrmsrl(MSR_IA32_APICBASE, msr_content); +- } ++ __enable_x2apic(); + + restore_IO_APIC_setup(ioapic_entries); + unmask_8259A(); +@@ -743,9 +747,10 @@ int lapic_suspend(void) + apic_pm_state.apic_tmict = apic_read(APIC_TMICT); + apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); + apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); +- ++ + local_irq_save(flags); + disable_local_APIC(); ++ iommu_disable_IR(); + local_irq_restore(flags); + return 0; + } +@@ -1042,15 +1047,8 @@ static void enable_bsp_x2apic(void) + + if ( !x2apic_preenabled ) + { +- u32 lo, hi; +- +- rdmsr(MSR_IA32_APICBASE, lo, hi); +- if ( !(lo & MSR_IA32_APICBASE_EXTD) ) +- { +- lo |= MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD; +- wrmsr(MSR_IA32_APICBASE, lo, 0); +- printk("x2APIC mode enabled.\n"); +- } ++ __enable_x2apic(); ++ printk("x2APIC mode enabled.\n"); + } + + restore_out: +@@ -1064,19 +1062,12 @@ out: + + static void enable_ap_x2apic(void) + { +- u32 lo, hi; +- + ASSERT(smp_processor_id() != 0); + + /* APs only enable x2apic when BSP did so. */ + BUG_ON(!x2apic_enabled); + +- rdmsr(MSR_IA32_APICBASE, lo, hi); +- if ( !(lo & MSR_IA32_APICBASE_EXTD) ) +- { +- lo |= MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD; +- wrmsr(MSR_IA32_APICBASE, lo, 0); +- } ++ __enable_x2apic(); + } + + void enable_x2apic(void) +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/intremap.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/drivers/passthrough/vtd/intremap.c ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/intremap.c +@@ -873,6 +873,24 @@ int iommu_enable_IR(void) + } + + /* ++ * This function is used to disable Interrutp remapping when ++ * suspend local apic ++ */ ++void iommu_disable_IR(void) ++{ ++ struct acpi_drhd_unit *drhd; ++ ++ if ( !iommu_supports_eim() ) ++ return; ++ ++ for_each_drhd_unit ( drhd ) ++ disable_intremap(drhd->iommu); ++ ++ for_each_drhd_unit ( drhd ) ++ disable_qinval(drhd->iommu); ++} ++ ++/* + * Check if interrupt remapping is enabled or not + * return 1: enabled + * return 0: not enabled +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/iommu.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/drivers/passthrough/vtd/iommu.c ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/iommu.c +@@ -2126,10 +2126,11 @@ static void vtd_suspend(void) + + iommu_disable_translation(iommu); + +- if ( iommu_intremap ) +- disable_intremap(iommu); +- +- if ( iommu_qinval ) ++ /* If interrupt remapping is enabled, queued invalidation ++ * will be disabled following interupt remapping disabling ++ * in local apic suspend ++ */ ++ if ( !iommu_intremap && iommu_qinval ) + disable_qinval(iommu); + } + } +Index: xen-4.0.1-testing/xen/include/xen/iommu.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/include/xen/iommu.h ++++ xen-4.0.1-testing/xen/include/xen/iommu.h +@@ -59,6 +59,7 @@ struct iommu { + int iommu_setup(void); + int iommu_supports_eim(void); + int iommu_enable_IR(void); ++void iommu_disable_IR(void); + int intremap_enabled(void); + + int iommu_add_device(struct pci_dev *pdev); diff --git a/22223-vtd-workarounds.patch b/22223-vtd-workarounds.patch index 7f18d0f..841fe16 100644 --- a/22223-vtd-workarounds.patch +++ b/22223-vtd-workarounds.patch @@ -41,15 +41,19 @@ enhancement. Signed-off-by: Allen Kay ---- a/xen/drivers/passthrough/vtd/Makefile -+++ b/xen/drivers/passthrough/vtd/Makefile +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/Makefile +=================================================================== +--- xen-4.0.1-testing.orig/xen/drivers/passthrough/vtd/Makefile ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/Makefile @@ -6,3 +6,4 @@ obj-y += dmar.o obj-y += utils.o obj-y += qinval.o obj-y += intremap.o +obj-y += quirks.o ---- a/xen/drivers/passthrough/vtd/dmar.c -+++ b/xen/drivers/passthrough/vtd/dmar.c +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/dmar.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/drivers/passthrough/vtd/dmar.c ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/dmar.c @@ -46,6 +46,7 @@ LIST_HEAD(acpi_rmrr_units); LIST_HEAD(acpi_atsr_units); LIST_HEAD(acpi_rhsa_units); @@ -86,8 +90,10 @@ Signed-off-by: Allen Kay break; case ACPI_DEV_IOAPIC: ---- a/xen/drivers/passthrough/vtd/dmar.h -+++ b/xen/drivers/passthrough/vtd/dmar.h +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/dmar.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/drivers/passthrough/vtd/dmar.h ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/dmar.h @@ -114,5 +114,6 @@ void *map_to_nocache_virt(int nr_iommus, int vtd_hw_check(void); void disable_pmr(struct iommu *iommu); @@ -95,8 +101,10 @@ Signed-off-by: Allen Kay +int is_igd_drhd(struct acpi_drhd_unit *drhd); #endif /* _DMAR_H_ */ ---- a/xen/drivers/passthrough/vtd/extern.h -+++ b/xen/drivers/passthrough/vtd/extern.h +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/extern.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/drivers/passthrough/vtd/extern.h ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/extern.h @@ -26,6 +26,7 @@ extern int qinval_enabled; @@ -162,8 +170,10 @@ Signed-off-by: Allen Kay +void me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map); #endif // _VTD_EXTERN_H_ ---- a/xen/drivers/passthrough/vtd/iommu.c -+++ b/xen/drivers/passthrough/vtd/iommu.c +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/iommu.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/drivers/passthrough/vtd/iommu.c ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/iommu.c @@ -43,7 +43,6 @@ #endif @@ -382,7 +392,7 @@ Signed-off-by: Allen Kay irq_to_iommu = xmalloc_array(struct iommu*, nr_irqs); BUG_ON(!irq_to_iommu); -@@ -2163,7 +2206,7 @@ static void vtd_resume(void) +@@ -2164,7 +2207,7 @@ static void vtd_resume(void) (u32) iommu_state[i][DMAR_FEUADDR_REG]); spin_unlock_irqrestore(&iommu->register_lock, flags); @@ -391,8 +401,10 @@ Signed-off-by: Allen Kay } } ---- a/xen/drivers/passthrough/vtd/iommu.h -+++ b/xen/drivers/passthrough/vtd/iommu.h +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/iommu.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/drivers/passthrough/vtd/iommu.h ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/iommu.h @@ -501,6 +501,7 @@ struct intel_iommu { struct qi_ctrl qi_ctrl; struct ir_ctrl ir_ctrl; @@ -401,8 +413,10 @@ Signed-off-by: Allen Kay }; #endif +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/quirks.c +=================================================================== --- /dev/null -+++ b/xen/drivers/passthrough/vtd/quirks.c ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/quirks.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2010, Intel Corporation. @@ -666,8 +680,10 @@ Signed-off-by: Allen Kay + + } +} ---- a/xen/drivers/passthrough/vtd/vtd.h -+++ b/xen/drivers/passthrough/vtd/vtd.h +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/vtd.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/drivers/passthrough/vtd/vtd.h ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/vtd.h @@ -23,6 +23,9 @@ #include @@ -697,8 +713,10 @@ Signed-off-by: Allen Kay -void iommu_free(struct acpi_drhd_unit *drhd); - #endif // _VTD_H_ ---- a/xen/drivers/passthrough/vtd/x86/vtd.c -+++ b/xen/drivers/passthrough/vtd/x86/vtd.c +Index: xen-4.0.1-testing/xen/drivers/passthrough/vtd/x86/vtd.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/drivers/passthrough/vtd/x86/vtd.c ++++ xen-4.0.1-testing/xen/drivers/passthrough/vtd/x86/vtd.c @@ -27,6 +27,7 @@ #include "../iommu.h" #include "../dmar.h" @@ -707,8 +725,10 @@ Signed-off-by: Allen Kay /* * iommu_inclusive_mapping: when set, all memory below 4GB is included in dom0 ---- a/xen/include/asm-x86/fixmap.h -+++ b/xen/include/asm-x86/fixmap.h +Index: xen-4.0.1-testing/xen/include/asm-x86/fixmap.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/include/asm-x86/fixmap.h ++++ xen-4.0.1-testing/xen/include/asm-x86/fixmap.h @@ -52,6 +52,7 @@ enum fixed_addresses { FIX_MSIX_IO_RESERV_BASE, FIX_MSIX_IO_RESERV_END = FIX_MSIX_IO_RESERV_BASE + FIX_MSIX_MAX_PAGES -1, diff --git a/22388-x2apic-panic.patch b/22388-x2apic-panic.patch new file mode 100644 index 0000000..34ff1f5 --- /dev/null +++ b/22388-x2apic-panic.patch @@ -0,0 +1,48 @@ +# HG changeset patch +# User Keir Fraser +# Date 1289813498 0 +# Node ID 87f248de52304bc96a80dc093250fed0197f37e0 +# Parent 8af10bd7f2d0e9300f1bc68f7e2fb137fa839365 +x2apic: Remove a panic condition in enabling x2APIC + +Currently Xen triggers a panic if user disables VT-d by command line +while not disable x2APIC. This requires users to specify both +"iommu=0" and "x2apic=0" to disable VT-d if the platform supports +x2APIC. It's not user friendly. This patch removes the panic +condition. That's to say, don't require user to specify "x2apic=0" +when specify "iommu=0". As long as VT-d is not enabled (disabled in +BIOS or in command line), x2APIC won't be enabled naturally (x2APIC +depends on VT-d Interrupt remapping). + +Signed-off-by: Weidong Han + +--- a/xen/arch/x86/apic.c ++++ b/xen/arch/x86/apic.c +@@ -1000,22 +1000,11 @@ static void enable_bsp_x2apic(void) + } + else + { +- if ( !iommu_enabled || !iommu_intremap || !iommu_qinval ) +- panic("Cannot enable x2APIC due to iommu or interrupt " +- "remapping or queued invalidation is disabled " +- "by command line!\n"); +- else +- { +- if ( x2apic_preenabled ) +- panic("x2APIC: already enabled by BIOS, but " +- "iommu_supports_eim fails\n"); +- else +- { +- printk("Not enable x2APIC due to " +- "iommu_supports_eim fails!\n"); +- return; +- } +- } ++ if ( x2apic_preenabled ) ++ panic("x2APIC: already enabled by BIOS, but " ++ "iommu_supports_eim failed!\n"); ++ printk("Not enabling x2APIC: depends oniommu_supports_eim\n"); ++ return; + } + } + diff --git a/22448-x86_64-gdt-ldt-fault-filter.patch b/22448-x86_64-gdt-ldt-fault-filter.patch new file mode 100644 index 0000000..ad1f0e2 --- /dev/null +++ b/22448-x86_64-gdt-ldt-fault-filter.patch @@ -0,0 +1,57 @@ +# HG changeset patch +# User Keir Fraser +# Date 1291041272 0 +# Node ID 5cd9612db2bba51f63ff7897aca4c72cc4b8e8c2 +# Parent aba70e59a90dcb0cacc2c6834a6ce19d03d88601 +x86-64: don't crash Xen upon direct pv guest access to GDT/LDT mapping area + +handle_gdt_ldt_mapping_fault() is intended to deal with indirect +accesses (i.e. those caused by descriptor loads) to the GDT/LDT +mapping area only. While for 32-bit segment limits indeed prevent the +function being entered for direct accesses (i.e. a #GP fault will be +raised even before the address translation gets done, on 64-bit even +user mode accesses would lead to control reaching the BUG_ON() at the +beginning of that function. + +Fortunately the fix is simple: Since the guest kernel runs in ring 3, +any guest direct access will have the "user mode" bit set, whereas +descriptor loads always do the translations to access the actual +descriptors as kernel mode ones. + +Signed-off-by: Jan Beulich + +Further, relax the BUG_ON() in handle_gdt_ldt_mapping_fault() to a +check-and-bail. This avoids any problems in future, if we don't +execute x86_64 guest kernels in ring 3 (e.g., because we use a +lightweight HVM container). + +Signed-off-by: Keir Fraser + +--- a/xen/arch/x86/traps.c ++++ b/xen/arch/x86/traps.c +@@ -1051,8 +1051,14 @@ static int handle_gdt_ldt_mapping_fault( + unsigned int is_ldt_area = (offset >> (GDT_LDT_VCPU_VA_SHIFT-1)) & 1; + unsigned int vcpu_area = (offset >> GDT_LDT_VCPU_VA_SHIFT); + +- /* Should never fault in another vcpu's area. */ +- BUG_ON(vcpu_area != curr->vcpu_id); ++ /* ++ * If the fault is in another vcpu's area, it cannot be due to ++ * a GDT/LDT descriptor load. Thus we can reasonably exit immediately, and ++ * indeed we have to since map_ldt_shadow_page() works correctly only on ++ * accesses to a vcpu's own area. ++ */ ++ if ( vcpu_area != curr->vcpu_id ) ++ return 0; + + /* Byte offset within the gdt/ldt sub-area. */ + offset &= (1UL << (GDT_LDT_VCPU_VA_SHIFT-1)) - 1UL; +@@ -1223,7 +1229,7 @@ static int fixup_page_fault(unsigned lon + + if ( unlikely(IN_HYPERVISOR_RANGE(addr)) ) + { +- if ( !(regs->error_code & PFEC_reserved_bit) && ++ if ( !(regs->error_code & (PFEC_user_mode | PFEC_reserved_bit)) && + (addr >= GDT_LDT_VIRT_START) && (addr < GDT_LDT_VIRT_END) ) + return handle_gdt_ldt_mapping_fault( + addr - GDT_LDT_VIRT_START, regs); diff --git a/22451-hvm-cap-clobber.patch b/22451-hvm-cap-clobber.patch new file mode 100644 index 0000000..93335b7 --- /dev/null +++ b/22451-hvm-cap-clobber.patch @@ -0,0 +1,43 @@ +# HG changeset patch +# User Keir Fraser +# Date 1291116848 0 +# Node ID 8420b82c22c2cad54860ffdbe8bcec21c65c86be +# Parent d281061e6ec06bbbf8e2b0fadbeb9d1a04bc32e2 +x86 hvm: Do not overwrite boot-cpu capability data on VMX/SVM startup. + +Apparently required back in the earliest days of Xen, we now properly +initialise CPU capabilities early during bootstrap. Re-writing +capability data later now causes problems if specific features have +been deliberately masked out. + +Thanks to Weidong Han at Intel for finding such a bug where XSAVE +feature is masked out by default, but then erroneously written back +during VMX initialisation. This would cause memory corruption problems +during boot for XSAVE-capable systems. + +Signed-off-by: Keir Fraser + +--- a/xen/arch/x86/hvm/svm/svm.c ++++ b/xen/arch/x86/hvm/svm/svm.c +@@ -915,9 +915,6 @@ void start_svm(struct cpuinfo_x86 *c) + return; + } + +- /* Xen does not fill x86_capability words except 0. */ +- boot_cpu_data.x86_capability[5] = cpuid_ecx(0x80000001); +- + if ( !test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability) ) + return; + +--- a/xen/arch/x86/hvm/vmx/vmx.c ++++ b/xen/arch/x86/hvm/vmx/vmx.c +@@ -1433,9 +1433,6 @@ void start_vmx(void) + return; + } + +- /* Xen does not fill x86_capability words except 0. */ +- boot_cpu_data.x86_capability[4] = cpuid_ecx(1); +- + if ( !test_bit(X86_FEATURE_VMXE, &boot_cpu_data.x86_capability) ) + return; + diff --git a/22452-x86-irq-migrate-directed-eoi.patch b/22452-x86-irq-migrate-directed-eoi.patch new file mode 100644 index 0000000..23cc1a0 --- /dev/null +++ b/22452-x86-irq-migrate-directed-eoi.patch @@ -0,0 +1,62 @@ +# HG changeset patch +# User Keir Fraser +# Date 1291234227 0 +# Node ID 62bf12040b0f4d802dc7e1cd61294776c8a41a89 +# Parent 8420b82c22c2cad54860ffdbe8bcec21c65c86be +x86: fix IRQ migration when using directed EOI (broken with c/s 20465) + +In directed-EOI mode, there is no chance to do the migration in +mask_and_ack_level_ioapic_irq(), as the remote IRR bit can't possibly +be clear after issuing the EOI to the LAPIC. Consequently, there's no +point to even try. Instead, migration must be done in +end_level_ioapic_irq(), and it requires masking the interrupt source +prior to issuing the EOI to the IO-APIC. + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/io_apic.c ++++ b/xen/arch/x86/io_apic.c +@@ -1642,11 +1642,14 @@ static void mask_and_ack_level_ioapic_ir + + ack_APIC_irq(); + ++ if ( directed_eoi_enabled ) ++ return; ++ + if ((irq_desc[irq].status & IRQ_MOVE_PENDING) && + !io_apic_level_ack_pending(irq)) +- move_native_irq(irq); ++ move_masked_irq(irq); + +- if (!directed_eoi_enabled && !(v & (1 << (i & 0x1f)))) { ++ if ( !(v & (1 << (i & 0x1f))) ) { + atomic_inc(&irq_mis_count); + spin_lock(&ioapic_lock); + __edge_IO_APIC_irq(irq); +@@ -1662,12 +1665,22 @@ static void end_level_ioapic_irq (unsign + + if ( !ioapic_ack_new ) + { +- if ( irq_desc[irq].status & IRQ_DISABLED ) +- return; +- + if ( directed_eoi_enabled ) ++ { ++ if ( !(irq_desc[irq].status & (IRQ_DISABLED|IRQ_MOVE_PENDING)) ) ++ { ++ eoi_IO_APIC_irq(irq); ++ return; ++ } ++ ++ mask_IO_APIC_irq(irq); + eoi_IO_APIC_irq(irq); +- else ++ if ( (irq_desc[irq].status & IRQ_MOVE_PENDING) && ++ !io_apic_level_ack_pending(irq) ) ++ move_masked_irq(irq); ++ } ++ ++ if ( !(irq_desc[irq].status & IRQ_DISABLED) ) + unmask_IO_APIC_irq(irq); + + return; diff --git a/22466-x86-sis-apic-bug.patch b/22466-x86-sis-apic-bug.patch new file mode 100644 index 0000000..4d3e671 --- /dev/null +++ b/22466-x86-sis-apic-bug.patch @@ -0,0 +1,36 @@ +# HG changeset patch +# User Keir Fraser +# Date 1291746724 0 +# Node ID bfd13358b8bf3a6ca49702d773435a67f1ea5551 +# Parent d4b35162b3a11f7d9c28501192b7e231609e561d +x86: remove BUG_ON() from QUIRK_IOAPIC_*_REGSEL handler +References: bnc#657692 + +Since (non-pvops, 32-bit only up to 2.6.27) Linux would report "BAD" +unconditionally on all SiS chipset versions (it only looks for a PCI +device at 0000:00:00.0 with SiS as the vendor), we must not crash if +the report on a 64-bit hypervisor doesn't match the #define (which is +zero). + +While we could honor the quirk indication even on 64-bit, it doesn't +seem worthwhile, as there's no evidence that newer SiS chipsets +(supporting 64-bit CPUs) are actually affected. + +This should also address bug 1687 (mis-reported, however, afaict). + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/platform_hypercall.c ++++ b/xen/arch/x86/platform_hypercall.c +@@ -192,7 +192,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe + dprintk(XENLOG_INFO, "Domain 0 says that IO-APIC REGSEL is %s\n", + sis_apic_bug ? "bad" : "good"); + #else +- BUG_ON(sis_apic_bug != (quirk_id == QUIRK_IOAPIC_BAD_REGSEL)); ++ if ( sis_apic_bug != (quirk_id == QUIRK_IOAPIC_BAD_REGSEL) ) ++ dprintk(XENLOG_WARNING, ++ "Domain 0 thinks that IO-APIC REGSEL is %s\n", ++ sis_apic_bug ? "good" : "bad"); + #endif + break; + default: diff --git a/22470-vlapic-tick-loss.patch b/22470-vlapic-tick-loss.patch new file mode 100644 index 0000000..1149589 --- /dev/null +++ b/22470-vlapic-tick-loss.patch @@ -0,0 +1,28 @@ +# HG changeset patch +# User Keir Fraser +# Date 1291883699 0 +# Node ID 0c97247c64d61511acff37d1903cb304b387f397 +# Parent 84a72f957fe9e1a5af3dfb8f53334faa555e22f8 +x86:vlapic: Fix possible guest tick losing after save/restore + +Guest vcpu may totally lose all ticks if the vlapic->pt.irq was not +restored during save/restore process. Fix it. + +Signed-off-by: Wei Gang + +--- a/xen/arch/x86/hvm/vlapic.c ++++ b/xen/arch/x86/hvm/vlapic.c +@@ -863,12 +863,12 @@ static void lapic_rearm(struct vlapic *s + unsigned long tmict = vlapic_get_reg(s, APIC_TMICT); + uint64_t period; + ++ s->pt.irq = vlapic_get_reg(s, APIC_LVTT) & APIC_VECTOR_MASK; + if ( (tmict = vlapic_get_reg(s, APIC_TMICT)) == 0 ) + return; + + period = ((uint64_t)APIC_BUS_CYCLE_NS * + (uint32_t)tmict * s->hw.timer_divisor); +- s->pt.irq = vlapic_get_reg(s, APIC_LVTT) & APIC_VECTOR_MASK; + create_periodic_time(vlapic_vcpu(s), &s->pt, period, + vlapic_lvtt_period(s) ? period : 0, + s->pt.irq, vlapic_pt_cb, diff --git a/22475-x2apic-cleanup.patch b/22475-x2apic-cleanup.patch new file mode 100644 index 0000000..433e9f9 --- /dev/null +++ b/22475-x2apic-cleanup.patch @@ -0,0 +1,480 @@ +# HG changeset patch +# User Keir Fraser +# Date 1291922374 0 +# Node ID d9fc83a64a82624e24876250dd88b2cd9528d266 +# Parent 49d2aa5cee4ecc2411d8d638e4ee32c10e9b2761 +x86: x2apic: Large cleanup +References: bnc#656369, bnc#658704 + +Signed-off-by: Keir Fraser + +--- a/xen/arch/x86/apic.c ++++ b/xen/arch/x86/apic.c +@@ -67,12 +67,12 @@ static int enable_local_apic __initdata + */ + int apic_verbosity; + ++static int opt_x2apic = 1; ++boolean_param("x2apic", opt_x2apic); ++ + int x2apic_enabled __read_mostly = 0; + int directed_eoi_enabled __read_mostly = 0; + +-/* x2APIC is enabled in BIOS */ +-static int x2apic_preenabled; +- + /* + * The following vectors are part of the Linux architecture, there + * is no hardware IRQ pin equivalent for them, they are triggered +@@ -944,30 +944,24 @@ no_apic: + return -1; + } + +-void check_x2apic_preenabled(void) ++void x2apic_setup(void) + { ++ struct IO_APIC_route_entry **ioapic_entries = NULL; + u32 lo, hi; + +- if ( !x2apic_is_available() ) +- return; +- +- rdmsr(MSR_IA32_APICBASE, lo, hi); +- if ( lo & MSR_IA32_APICBASE_EXTD ) ++ if ( smp_processor_id() != 0 ) + { +- printk("x2APIC mode is already enabled by BIOS.\n"); +- x2apic_preenabled = 1; +- x2apic_enabled = 1; ++ if ( x2apic_enabled ) ++ __enable_x2apic(); ++ return; + } +-} + +-static void enable_bsp_x2apic(void) +-{ +- struct IO_APIC_route_entry **ioapic_entries = NULL; +- const struct genapic *x2apic_genapic = NULL; +- +- ASSERT(smp_processor_id() == 0); ++ if ( !cpu_has_x2apic ) ++ return; + +- if ( x2apic_preenabled ) ++ /* Check whether x2apic mode was already enabled by the BIOS. */ ++ rdmsr(MSR_IA32_APICBASE, lo, hi); ++ if ( lo & MSR_IA32_APICBASE_EXTD ) + { + /* + * Interrupt remapping should be also enabled by BIOS when +@@ -977,39 +971,33 @@ static void enable_bsp_x2apic(void) + if ( !intremap_enabled() ) + panic("Interrupt remapping is not enabled by BIOS while " + "x2APIC is already enabled by BIOS!\n"); ++ ++ printk("x2APIC mode is already enabled by BIOS.\n"); ++ x2apic_enabled = 1; + } + +- x2apic_genapic = apic_x2apic_probe(); +- if ( x2apic_genapic ) +- genapic = x2apic_genapic; +- else ++ if ( !opt_x2apic ) + { +- if ( x2apic_cmdline_disable() ) ++ if ( !x2apic_enabled ) + { +- if ( x2apic_preenabled ) +- { +- /* Ignore x2apic=0, and set default x2apic mode */ +- genapic = &apic_x2apic_cluster; +- printk("x2APIC: already enabled by BIOS, ignore x2apic=0.\n"); +- } +- else +- { +- printk("Not enable x2APIC due to x2apic=0 is set.\n"); +- return; +- } ++ printk("Not enabling x2APIC: disabled by cmdline.\n"); ++ return; + } +- else ++ printk("x2APIC: Already enabled by BIOS: Ignoring cmdline disable.\n"); ++ } ++ ++ if ( !iommu_supports_eim() ) ++ { ++ if ( !x2apic_enabled ) + { +- if ( x2apic_preenabled ) +- panic("x2APIC: already enabled by BIOS, but " +- "iommu_supports_eim failed!\n"); +- printk("Not enabling x2APIC: depends oniommu_supports_eim\n"); ++ printk("Not enabling x2APIC: depends on iommu_supports_eim.\n"); + return; + } ++ panic("x2APIC: already enabled by BIOS, but " ++ "iommu_supports_eim failed!\n"); + } + +- ioapic_entries = alloc_ioapic_entries(); +- if ( !ioapic_entries ) ++ if ( (ioapic_entries = alloc_ioapic_entries()) == NULL ) + { + printk("Allocate ioapic_entries failed\n"); + goto out; +@@ -1031,13 +1019,13 @@ static void enable_bsp_x2apic(void) + goto restore_out; + } + +- x2apic_enabled = 1; ++ genapic = apic_x2apic_probe(); + printk("Switched to APIC driver %s.\n", genapic->name); + +- if ( !x2apic_preenabled ) ++ if ( !x2apic_enabled ) + { ++ x2apic_enabled = 1; + __enable_x2apic(); +- printk("x2APIC mode enabled.\n"); + } + + restore_out: +@@ -1049,24 +1037,6 @@ out: + free_ioapic_entries(ioapic_entries); + } + +-static void enable_ap_x2apic(void) +-{ +- ASSERT(smp_processor_id() != 0); +- +- /* APs only enable x2apic when BSP did so. */ +- BUG_ON(!x2apic_enabled); +- +- __enable_x2apic(); +-} +- +-void enable_x2apic(void) +-{ +- if ( smp_processor_id() == 0 ) +- enable_bsp_x2apic(); +- else +- enable_ap_x2apic(); +-} +- + void __init init_apic_mappings(void) + { + unsigned long apic_phys; +--- a/xen/arch/x86/cpu/common.c ++++ b/xen/arch/x86/cpu/common.c +@@ -250,8 +250,8 @@ static void __init early_cpu_detect(void + + c->x86 = 4; + if (c->cpuid_level >= 0x00000001) { +- u32 junk, tfms, cap0, misc; +- cpuid(0x00000001, &tfms, &misc, &junk, &cap0); ++ u32 cap4, tfms, cap0, misc; ++ cpuid(0x00000001, &tfms, &misc, &cap4, &cap0); + c->x86 = (tfms >> 8) & 15; + c->x86_model = (tfms >> 4) & 15; + if (c->x86 == 0xf) +@@ -260,9 +260,12 @@ static void __init early_cpu_detect(void + c->x86_model += ((tfms >> 16) & 0xF) << 4; + c->x86_mask = tfms & 15; + cap0 &= ~cleared_caps[0]; ++ cap4 &= ~cleared_caps[4]; + if (cap0 & (1<<19)) + c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8; +- c->x86_capability[0] = cap0; /* Added for Xen bootstrap */ ++ /* Leaf 0x1 capabilities filled in early for Xen. */ ++ c->x86_capability[0] = cap0; ++ c->x86_capability[4] = cap4; + } + } + +--- a/xen/arch/x86/genapic/x2apic.c ++++ b/xen/arch/x86/genapic/x2apic.c +@@ -23,89 +23,44 @@ + #include + #include + +-static int x2apic = 1; +-boolean_param("x2apic", x2apic); +- +-static int x2apic_phys; /* By default we use logical cluster mode. */ ++static int x2apic_phys; /* By default we use logical cluster mode. */ + boolean_param("x2apic_phys", x2apic_phys); + +-int x2apic_cmdline_disable(void) +-{ +- return (x2apic == 0); +-} +- +-static int probe_x2apic_phys(void) ++static void init_apic_ldr_x2apic_phys(void) + { +- return x2apic && x2apic_phys && x2apic_is_available() && +- iommu_supports_eim(); + } + +-static int probe_x2apic_cluster(void) +-{ +- return x2apic && !x2apic_phys && x2apic_is_available() && +- iommu_supports_eim(); +-} +- +-const struct genapic apic_x2apic_phys = { +- APIC_INIT("x2apic_phys", probe_x2apic_phys), +- GENAPIC_X2APIC_PHYS +-}; +- +-const struct genapic apic_x2apic_cluster = { +- APIC_INIT("x2apic_cluster", probe_x2apic_cluster), +- GENAPIC_X2APIC_CLUSTER +-}; +- +-const struct genapic *apic_x2apic_probe(void) +-{ +- if ( !x2apic || !x2apic_is_available() ) +- return NULL; +- +- if ( !iommu_supports_eim() ) +- return NULL; +- +- if ( x2apic_phys ) +- return &apic_x2apic_phys; +- else +- return &apic_x2apic_cluster; +-} +- +-void init_apic_ldr_x2apic_phys(void) +-{ +- return; +-} +- +-void init_apic_ldr_x2apic_cluster(void) ++static void init_apic_ldr_x2apic_cluster(void) + { + int cpu = smp_processor_id(); + cpu_2_logical_apicid[cpu] = apic_read(APIC_LDR); + } +-void clustered_apic_check_x2apic(void) ++ ++static void clustered_apic_check_x2apic(void) + { +- return; + } + +-cpumask_t target_cpus_x2apic(void) ++static cpumask_t target_cpus_x2apic(void) + { + return cpu_online_map; + } + +-cpumask_t vector_allocation_domain_x2apic(int cpu) ++static cpumask_t vector_allocation_domain_x2apic(int cpu) + { + return cpumask_of_cpu(cpu); + } + +-unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask) ++static unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask) + { + return cpu_physical_id(first_cpu(cpumask)); + } + +-unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask) ++static unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask) + { + return cpu_2_logical_apicid[first_cpu(cpumask)]; + } + +-void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector) ++static void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector) + { + unsigned int cpu, cfg; + unsigned long flags; +@@ -132,7 +87,7 @@ void send_IPI_mask_x2apic_phys(const cpu + local_irq_restore(flags); + } + +-void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector) ++static void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector) + { + unsigned int cpu, cfg; + unsigned long flags; +@@ -148,3 +103,34 @@ void send_IPI_mask_x2apic_cluster(const + + local_irq_restore(flags); + } ++ ++static const struct genapic apic_x2apic_phys = { ++ APIC_INIT("x2apic_phys", NULL), ++ .int_delivery_mode = dest_Fixed, ++ .int_dest_mode = 0 /* physical delivery */, ++ .init_apic_ldr = init_apic_ldr_x2apic_phys, ++ .clustered_apic_check = clustered_apic_check_x2apic, ++ .target_cpus = target_cpus_x2apic, ++ .vector_allocation_domain = vector_allocation_domain_x2apic, ++ .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_phys, ++ .send_IPI_mask = send_IPI_mask_x2apic_phys, ++ .send_IPI_self = send_IPI_self_x2apic ++}; ++ ++static const struct genapic apic_x2apic_cluster = { ++ APIC_INIT("x2apic_cluster", NULL), ++ .int_delivery_mode = dest_LowestPrio, ++ .int_dest_mode = 1 /* logical delivery */, ++ .init_apic_ldr = init_apic_ldr_x2apic_cluster, ++ .clustered_apic_check = clustered_apic_check_x2apic, ++ .target_cpus = target_cpus_x2apic, ++ .vector_allocation_domain = vector_allocation_domain_x2apic, ++ .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_cluster, ++ .send_IPI_mask = send_IPI_mask_x2apic_cluster, ++ .send_IPI_self = send_IPI_self_x2apic ++}; ++ ++const struct genapic *apic_x2apic_probe(void) ++{ ++ return x2apic_phys ? &apic_x2apic_phys : &apic_x2apic_cluster; ++} +--- a/xen/arch/x86/setup.c ++++ b/xen/arch/x86/setup.c +@@ -1006,9 +1006,6 @@ void __init __start_xen(unsigned long mb + + tboot_probe(); + +- /* Check if x2APIC is already enabled in BIOS */ +- check_x2apic_preenabled(); +- + /* Unmap the first page of CPU0's stack. */ + memguard_guard_stack(cpu0_stack); + +@@ -1039,8 +1036,7 @@ void __init __start_xen(unsigned long mb + + init_apic_mappings(); + +- if ( x2apic_is_available() ) +- enable_x2apic(); ++ x2apic_setup(); + + percpu_free_unused_areas(); + +--- a/xen/arch/x86/smpboot.c ++++ b/xen/arch/x86/smpboot.c +@@ -325,8 +325,7 @@ void __devinit smp_callin(void) + */ + wait_for_init_deassert(&init_deasserted); + +- if ( x2apic_enabled ) +- enable_x2apic(); ++ x2apic_setup(); + + /* + * (This works even if the APIC is not enabled.) +--- a/xen/drivers/passthrough/vtd/intremap.c ++++ b/xen/drivers/passthrough/vtd/intremap.c +@@ -129,15 +129,10 @@ int iommu_supports_eim(void) + struct acpi_drhd_unit *drhd; + int apic; + +- if ( !iommu_enabled || !iommu_qinval || !iommu_intremap ) ++ if ( !iommu_enabled || !iommu_qinval || !iommu_intremap || ++ list_empty(&acpi_drhd_units) ) + return 0; + +- if ( list_empty(&acpi_drhd_units) ) +- { +- dprintk(XENLOG_WARNING VTDPREFIX, "VT-d is not supported\n"); +- return 0; +- } +- + /* We MUST have a DRHD unit for each IOAPIC. */ + for ( apic = 0; apic < nr_ioapics; apic++ ) + if ( !ioapic_to_drhd(IO_APIC_ID(apic)) ) +--- a/xen/include/asm-x86/apic.h ++++ b/xen/include/asm-x86/apic.h +@@ -25,21 +25,8 @@ extern int apic_verbosity; + extern int x2apic_enabled; + extern int directed_eoi_enabled; + +-extern void check_x2apic_preenabled(void); +-extern int x2apic_cmdline_disable(void); +-extern void enable_x2apic(void); +- +-static __inline int x2apic_is_available(void) +-{ +- unsigned int op = 1, eax, ecx; +- +- asm ( "cpuid" +- : "=a" (eax), "=c" (ecx) +- : "0" (op) +- : "bx", "dx" ); +- +- return (ecx & (1U << 21)); +-} ++void x2apic_setup(void); ++const struct genapic *apic_x2apic_probe(void); + + /* + * Define the default level of output to be very little +--- a/xen/include/asm-x86/genapic.h ++++ b/xen/include/asm-x86/genapic.h +@@ -49,8 +49,6 @@ struct genapic { + APICFUNC(acpi_madt_oem_check) + + extern const struct genapic *genapic; +-extern const struct genapic apic_x2apic_phys; +-extern const struct genapic apic_x2apic_cluster; + + void init_apic_ldr_flat(void); + void clustered_apic_check_flat(void); +@@ -70,39 +68,6 @@ cpumask_t vector_allocation_domain_flat( + .send_IPI_mask = send_IPI_mask_flat, \ + .send_IPI_self = send_IPI_self_flat + +-const struct genapic *apic_x2apic_probe(void); +-void init_apic_ldr_x2apic_phys(void); +-void init_apic_ldr_x2apic_cluster(void); +-void clustered_apic_check_x2apic(void); +-cpumask_t target_cpus_x2apic(void); +-unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask); +-unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask); +-void send_IPI_mask_x2apic_phys(const cpumask_t *mask, int vector); +-void send_IPI_mask_x2apic_cluster(const cpumask_t *mask, int vector); +-void send_IPI_self_x2apic(int vector); +-cpumask_t vector_allocation_domain_x2apic(int cpu); +-#define GENAPIC_X2APIC_PHYS \ +- .int_delivery_mode = dest_Fixed, \ +- .int_dest_mode = 0 /* physical delivery */, \ +- .init_apic_ldr = init_apic_ldr_x2apic_phys, \ +- .clustered_apic_check = clustered_apic_check_x2apic, \ +- .target_cpus = target_cpus_x2apic, \ +- .vector_allocation_domain = vector_allocation_domain_x2apic, \ +- .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_phys, \ +- .send_IPI_mask = send_IPI_mask_x2apic_phys, \ +- .send_IPI_self = send_IPI_self_x2apic +- +-#define GENAPIC_X2APIC_CLUSTER \ +- .int_delivery_mode = dest_LowestPrio, \ +- .int_dest_mode = 1 /* logical delivery */, \ +- .init_apic_ldr = init_apic_ldr_x2apic_cluster, \ +- .clustered_apic_check = clustered_apic_check_x2apic, \ +- .target_cpus = target_cpus_x2apic, \ +- .vector_allocation_domain = vector_allocation_domain_x2apic, \ +- .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_cluster, \ +- .send_IPI_mask = send_IPI_mask_x2apic_cluster, \ +- .send_IPI_self = send_IPI_self_x2apic +- + void init_apic_ldr_phys(void); + void clustered_apic_check_phys(void); + cpumask_t target_cpus_phys(void); +@@ -121,4 +86,6 @@ cpumask_t vector_allocation_domain_phys( + .send_IPI_mask = send_IPI_mask_phys, \ + .send_IPI_self = send_IPI_self_phys + ++void send_IPI_self_x2apic(int vector); ++ + #endif diff --git a/22484-vlapic-tmcct-periodic.patch b/22484-vlapic-tmcct-periodic.patch new file mode 100644 index 0000000..6bd805f --- /dev/null +++ b/22484-vlapic-tmcct-periodic.patch @@ -0,0 +1,34 @@ +# HG changeset patch +# User Keir Fraser +# Date 1291999745 0 +# Node ID 3b3fce9050b9b14f3a11123f6943998413ea7e7e +# Parent 901c118b363e978566775f9d118b4f2f15598212 +hvm vlapic: Fix tmcct read logic when in periodic mode. + +Signed-off-by: Keir Fraser + +--- a/xen/arch/x86/hvm/vlapic.c ++++ b/xen/arch/x86/hvm/vlapic.c +@@ -428,12 +428,19 @@ int vlapic_ipi( + static uint32_t vlapic_get_tmcct(struct vlapic *vlapic) + { + struct vcpu *v = current; +- uint32_t tmcct, tmict = vlapic_get_reg(vlapic, APIC_TMICT); ++ uint32_t tmcct = 0, tmict = vlapic_get_reg(vlapic, APIC_TMICT); + uint64_t counter_passed; + + counter_passed = ((hvm_get_guest_time(v) - vlapic->timer_last_update) +- / APIC_BUS_CYCLE_NS / vlapic->hw.timer_divisor); +- tmcct = tmict - counter_passed; ++ / (APIC_BUS_CYCLE_NS * vlapic->hw.timer_divisor)); ++ ++ if ( tmict != 0 ) ++ { ++ if ( vlapic_lvtt_period(vlapic) ) ++ counter_passed %= tmict; ++ if ( counter_passed < tmict ) ++ tmcct = tmict - counter_passed; ++ } + + HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, + "timer initial count %d, timer current count %d, " diff --git a/22504-iommu-dom0-holes.patch b/22504-iommu-dom0-holes.patch new file mode 100644 index 0000000..19225ed --- /dev/null +++ b/22504-iommu-dom0-holes.patch @@ -0,0 +1,91 @@ +# HG changeset patch +# User Keir Fraser +# Date 1292320377 0 +# Node ID fd4cbfbbd83e6091a343844eae1da1468f54b72b +# Parent ab785e37499c8cdadd1fd5e4ab1bfbbacebf358b +x86/iommu: don't map RAM holes above 4G +References: bnc#658163 + +Matching the comment in iommu_set_dom0_mapping(), map only actual RAM +from the address range starting at 4G. It's not clear though whether +that comment is actually correct (which is why I'm sending this as +RFC), but it is certain that on systems with sparse physical memory +map we're currently wasting a potentially significant amount of memory +for setting up IOMMU page tables that will never be used. + +The main question is what happens for MMIO ranges living above 4G. Of +course, the same issue would currently exist for any such ranges +sitting beyond the end of RAM. + +Signed-off-by: Jan Beulich + +--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c ++++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c +@@ -239,8 +239,16 @@ static void amd_iommu_dom0_init(struct d + if ( !iommu_passthrough && !need_iommu(d) ) + { + /* Set up 1:1 page table for dom0 */ +- for ( i = 0; i < max_page; i++ ) +- amd_iommu_map_page(d, i, i, IOMMUF_readable|IOMMUF_writable); ++ for ( i = 0; i < max_pdx; i++ ) ++ { ++ unsigned long pfn = pdx_to_pfn(i); ++ ++ /* ++ * XXX Should we really map all non-RAM (above 4G)? Minimally ++ * a pfn_valid() check would seem desirable here. ++ */ ++ amd_iommu_map_page(d, pfn, pfn, IOMMUF_readable|IOMMUF_writable); ++ } + } + + amd_iommu_setup_dom0_devices(d); +--- a/xen/drivers/passthrough/vtd/x86/vtd.c ++++ b/xen/drivers/passthrough/vtd/x86/vtd.c +@@ -128,14 +128,14 @@ void hvm_dpci_isairq_eoi(struct domain * + + void iommu_set_dom0_mapping(struct domain *d) + { +- u64 i, j, tmp, max_pfn; ++ unsigned long i, j, tmp, top; + extern int xen_in_range(unsigned long mfn); + + BUG_ON(d->domain_id != 0); + +- max_pfn = max_t(u64, max_page, 0x100000000ull >> PAGE_SHIFT); ++ top = max(max_pdx, pfn_to_pdx(0xffffffffUL >> PAGE_SHIFT) + 1); + +- for ( i = 0; i < max_pfn; i++ ) ++ for ( i = 0; i < top; i++ ) + { + /* + * Set up 1:1 mapping for dom0. Default to use only conventional RAM +@@ -143,18 +143,23 @@ void iommu_set_dom0_mapping(struct domai + * inclusive mapping maps in everything below 4GB except unusable + * ranges. + */ +- if ( !page_is_ram_type(i, RAM_TYPE_CONVENTIONAL) && +- (!iommu_inclusive_mapping || +- page_is_ram_type(i, RAM_TYPE_UNUSABLE)) ) ++ unsigned long pfn = pdx_to_pfn(i); ++ ++ if ( pfn > (0xffffffffUL >> PAGE_SHIFT) ? ++ (!mfn_valid(pfn) || ++ !page_is_ram_type(pfn, RAM_TYPE_CONVENTIONAL)) : ++ iommu_inclusive_mapping ? ++ page_is_ram_type(pfn, RAM_TYPE_UNUSABLE) : ++ !page_is_ram_type(pfn, RAM_TYPE_CONVENTIONAL) ) + continue; + + /* Exclude Xen bits */ +- if ( xen_in_range(i) ) ++ if ( xen_in_range(pfn) ) + continue; + + tmp = 1 << (PAGE_SHIFT - PAGE_SHIFT_4K); + for ( j = 0; j < tmp; j++ ) +- iommu_map_page(d, (i*tmp+j), (i*tmp+j), ++ iommu_map_page(d, pfn * tmp + j, pfn * tmp + j, + IOMMUF_readable|IOMMUF_writable); + + if (!(i & (0xfffff >> (PAGE_SHIFT - PAGE_SHIFT_4K)))) diff --git a/22506-x86-iommu-dom0-estimate.patch b/22506-x86-iommu-dom0-estimate.patch new file mode 100644 index 0000000..cddd7e6 --- /dev/null +++ b/22506-x86-iommu-dom0-estimate.patch @@ -0,0 +1,40 @@ +# HG changeset patch +# User Keir Fraser +# Date 1292320450 0 +# Node ID 618ba64260faf45e6ec391582099d7388f013e81 +# Parent 72326371ae8106b91da0ca6b0436dd2b6478b7a7 +x86/iommu: account for necessary allocations when calculating Dom0's initial allocation size +References: bnc#658163 + +As of c/s 21812:e382656e4dcc, IOMMU related allocations for Dom0 +happen only after it got all of its memory allocated, and hence the +reserve (mainly for setting up its swiotlb) may get exhausted without +accounting for the necessary allocations up front. + +While not precise, the estimate has been found to be within a couple +of pages for the systems it got tested on. + +For the calculation to be reasonably correct, this depends on the +patch titled "x86/iommu: don't map RAM holes above 4G" sent out +yesterday. + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/domain_build.c ++++ b/xen/arch/x86/domain_build.c +@@ -188,6 +188,15 @@ static unsigned long __init compute_dom0 + if ( is_pv_32on64_domain(d) ) + avail -= opt_dom0_max_vcpus - 1; + ++ /* Reserve memory for iommu_dom0_init() (rough estimate). */ ++ if ( iommu_enabled ) ++ { ++ unsigned int s; ++ ++ for ( s = 9; s < BITS_PER_LONG; s += 9 ) ++ avail -= max_pdx >> s; ++ } ++ + /* + * If domain 0 allocation isn't specified, reserve 1/16th of available + * memory for things like DMA buffers. This reservation is clamped to diff --git a/22526-ept-access-once.patch b/22526-ept-access-once.patch new file mode 100644 index 0000000..d4ff994 --- /dev/null +++ b/22526-ept-access-once.patch @@ -0,0 +1,123 @@ +# HG changeset patch +# User Keir Fraser +# Date 1292410025 0 +# Node ID 7a5ee380041707177ca9c78e800095d1f5f3d373 +# Parent 01f3b350902385627d1fa9e8cd1c231953e7610c +ept: Remove lock in ept_get_entry, replace with access-once semantics. + +This mirrors the RVI/shadow situation, where p2m read access is +lockless because it's done in the hardware (linear map of the p2m +table). + +This fixes the original bug (call it bug A) without introducing bug B +(a deadlock). + +Bug A was caused by a race when updating p2m entries: between testing +if it's valid, and testing if it's populate-on-demand, it may have +been changed from populate-on-demand to valid. + +My original patch simply introduced a lock into ept_get_entry, but +that caused bug B, caused by circular locking order: p2m_change_type +[grabs p2m lock] -> set_p2m_entry -> ept_set_entry -> +ept_set_middle_level -> p2m_alloc [grabs hap lock] write cr4 -> +hap_update_paging_modes [grabes hap lock] -> hap_update_cr3 -> +gfn_to_mfn -> ept_get_entry -> [grabs p2m lock] + +Signed-off-by: George Dunlap + +--- a/xen/arch/x86/mm/hap/p2m-ept.c ++++ b/xen/arch/x86/mm/hap/p2m-ept.c +@@ -137,7 +137,7 @@ static int ept_next_level(struct domain + ept_entry_t **table, unsigned long *gfn_remainder, + u32 shift) + { +- ept_entry_t *ept_entry; ++ ept_entry_t *ept_entry, e; + ept_entry_t *next; + u32 index; + +@@ -145,9 +145,11 @@ static int ept_next_level(struct domain + + ept_entry = (*table) + index; + +- if ( !is_epte_present(ept_entry) ) ++ e=*ept_entry; ++ ++ if ( !is_epte_present(&e) ) + { +- if ( ept_entry->avail1 == p2m_populate_on_demand ) ++ if ( e.avail1 == p2m_populate_on_demand ) + return GUEST_TABLE_POD_PAGE; + + if ( read_only ) +@@ -155,15 +157,17 @@ static int ept_next_level(struct domain + + if ( !ept_set_middle_entry(d, ept_entry) ) + return GUEST_TABLE_MAP_FAILED; ++ else ++ e=*ept_entry; + } + + /* The only time sp would be set here is if we had hit a superpage */ +- if ( is_epte_superpage(ept_entry) ) ++ if ( is_epte_superpage(&e) ) + return GUEST_TABLE_SUPER_PAGE; + else + { + *gfn_remainder &= (1UL << shift) - 1; +- next = map_domain_page(ept_entry->mfn); ++ next = map_domain_page(e.mfn); + unmap_domain_page(*table); + *table = next; + return GUEST_TABLE_NORMAL_PAGE; +@@ -235,35 +239,39 @@ ept_set_entry(struct domain *d, unsigned + if ( mfn_valid(mfn_x(mfn)) || direct_mmio || p2m_is_paged(p2mt) || + (p2mt == p2m_ram_paging_in_start) ) + { +- ept_entry->emt = epte_get_entry_emt(d, gfn, mfn, &ipat, ++ ept_entry_t new_entry; ++ ++ new_entry.emt = epte_get_entry_emt(d, gfn, mfn, &ipat, + direct_mmio); +- ept_entry->ipat = ipat; +- ept_entry->sp = order ? 1 : 0; ++ new_entry.ipat = ipat; ++ new_entry.sp = order ? 1 : 0; + + if ( ret == GUEST_TABLE_SUPER_PAGE ) + { +- if ( ept_entry->mfn == (mfn_x(mfn) - offset) ) ++ if ( new_entry.mfn == (mfn_x(mfn) - offset) ) + need_modify_vtd_table = 0; + else +- ept_entry->mfn = mfn_x(mfn) - offset; ++ new_entry.mfn = mfn_x(mfn) - offset; + +- if ( (ept_entry->avail1 == p2m_ram_logdirty) ++ if ( (new_entry.avail1 == p2m_ram_logdirty) + && (p2mt == p2m_ram_rw) ) + for ( i = 0; i < 512; i++ ) + paging_mark_dirty(d, mfn_x(mfn) - offset + i); + } + else + { +- if ( ept_entry->mfn == mfn_x(mfn) ) ++ if ( new_entry.mfn == mfn_x(mfn) ) + need_modify_vtd_table = 0; + else +- ept_entry->mfn = mfn_x(mfn); ++ new_entry.mfn = mfn_x(mfn); + } + +- ept_entry->avail1 = p2mt; +- ept_entry->avail2 = 0; ++ new_entry.avail1 = p2mt; ++ new_entry.avail2 = 0; ++ ++ ept_p2m_type_to_flags(&new_entry, p2mt); + +- ept_p2m_type_to_flags(ept_entry, p2mt); ++ ept_entry->epte = new_entry.epte; + } + else + ept_entry->epte = 0; diff --git a/22533-x86-32bit-apicid.patch b/22533-x86-32bit-apicid.patch new file mode 100644 index 0000000..9714c14 --- /dev/null +++ b/22533-x86-32bit-apicid.patch @@ -0,0 +1,165 @@ +# HG changeset patch +# User Keir Fraser +# Date 1292413934 0 +# Node ID 548c808be2a6f166657ce7cfb86df7a296a9526a +# Parent c0662cb08260d831ae8d211ba16fc7038cb889b6 +x86: mpparse and cstate need to use 32bit apic id +References: bnc#656369, bnc#658704 + +Instead of going with mpc_config_processor struct. +that field ony have 8 bits. + +We should not change that struct, because it is shared with mptable. + +Also need to increase MAX_APICS. + +Signed-off-by: Yinghai Lu + +Rather than using a fixed value of 512, make this scale with NR_CPUS +(which obviously still doesn't cover all theoretically possible +systems, but at least allows some build time control). + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/acpi/cpu_idle.c ++++ b/xen/arch/x86/acpi/cpu_idle.c +@@ -742,7 +742,7 @@ static void set_cx( + int get_cpu_id(u8 acpi_id) + { + int i; +- u8 apic_id; ++ u32 apic_id; + + apic_id = x86_acpiid_to_apicid[acpi_id]; + if ( apic_id == 0xff ) +--- a/xen/arch/x86/mpparse.c ++++ b/xen/arch/x86/mpparse.c +@@ -99,7 +99,8 @@ static int mpc_record; + static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; + + /* Return xen's logical cpu_id of the new added cpu or <0 if error */ +-static int __devinit MP_processor_info (struct mpc_config_processor *m) ++static int __devinit MP_processor_info_x(struct mpc_config_processor *m, ++ u32 apicidx) + { + int ver, apicid, cpu = 0; + physid_mask_t phys_cpu; +@@ -107,7 +108,7 @@ static int __devinit MP_processor_info ( + if (!(m->mpc_cpuflag & CPU_ENABLED)) + return -EINVAL; + +- apicid = mpc_apic_id(m, translation_table[mpc_record]); ++ apicid = mpc_apic_id(m, apicidx, translation_table[mpc_record]); + + if (m->mpc_featureflag&(1<<0)) + Dprintk(" Floating point unit present.\n"); +@@ -159,7 +160,7 @@ static int __devinit MP_processor_info ( + + if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { + Dprintk(" Bootup CPU\n"); +- boot_cpu_physical_apicid = m->mpc_apicid; ++ boot_cpu_physical_apicid = apicid; + } + + ver = m->mpc_apicver; +@@ -170,10 +171,10 @@ static int __devinit MP_processor_info ( + if (ver == 0x0) { + printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! " + "fixing up to 0x10. (tell your hw vendor)\n", +- m->mpc_apicid); ++ apicid); + ver = 0x10; + } +- apic_version[m->mpc_apicid] = ver; ++ apic_version[apicid] = ver; + + phys_cpu = apicid_to_cpu_present(apicid); + physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu); +@@ -216,6 +217,11 @@ static int __devinit MP_processor_info ( + return cpu; + } + ++static int __devinit MP_processor_info(struct mpc_config_processor *m) ++{ ++ return MP_processor_info_x(m, m->mpc_apicid); ++} ++ + static void __init MP_bus_info (struct mpc_config_bus *m) + { + char str[7]; +@@ -844,7 +850,7 @@ int __devinit mp_register_lapic ( + struct mpc_config_processor processor; + int boot_cpu = 0; + +- if (MAX_APICS - id <= 0) { ++ if (MAX_APICS <= id) { + printk(KERN_WARNING "Processor #%d invalid (max %d)\n", + id, MAX_APICS); + return -EINVAL; +@@ -864,7 +870,7 @@ int __devinit mp_register_lapic ( + processor.mpc_reserved[0] = 0; + processor.mpc_reserved[1] = 0; + +- return MP_processor_info(&processor); ++ return MP_processor_info_x(&processor, id); + } + + void mp_unregister_lapic(uint32_t apic_id, uint32_t cpu) +--- a/xen/common/sched_sedf.c ++++ b/xen/common/sched_sedf.c +@@ -124,7 +124,6 @@ struct sedf_cpu_info { + + #define PERIOD_BEGIN(inf) ((inf)->deadl_abs - (inf)->period) + +-#define MIN(x,y) (((x)<(y))?(x):(y)) + #define DIV_UP(x,y) (((x) + (y) - 1) / y) + + #define extra_runs(inf) ((inf->status) & 6) +--- a/xen/include/asm-x86/mach-generic/mach_apic.h ++++ b/xen/include/asm-x86/mach-generic/mach_apic.h +@@ -26,15 +26,15 @@ static inline void enable_apic_mode(void + + extern u32 bios_cpu_apicid[]; + +-static inline int mpc_apic_id(struct mpc_config_processor *m, ++static inline int mpc_apic_id(struct mpc_config_processor *m, u32 apicid, + struct mpc_config_translation *translation_record) + { + printk("Processor #%d %d:%d APIC version %d\n", +- m->mpc_apicid, ++ apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); +- return (m->mpc_apicid); ++ return apicid; + } + + static inline void setup_portio_remap(void) +--- a/xen/include/asm-x86/mpspec_def.h ++++ b/xen/include/asm-x86/mpspec_def.h +@@ -14,7 +14,7 @@ + #define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_') + + #define MAX_MPC_ENTRY 1024 +-#define MAX_APICS 256 ++#define MAX_APICS MAX(256, 4 * NR_CPUS) + + struct intel_mp_floating + { +--- a/xen/include/xen/kernel.h ++++ b/xen/include/xen/kernel.h +@@ -33,6 +33,13 @@ + #define max_t(type,x,y) \ + ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) + ++/* ++ * pre-processor, array size, and bit field width suitable variants; ++ * please don't use in "normal" expressions. ++ */ ++#define MIN(x,y) ((x) < (y) ? (x) : (y)) ++#define MAX(x,y) ((x) > (y) ? (x) : (y)) ++ + /** + * container_of - cast a member of a structure out to the containing structure + * diff --git a/22534-x86-max-local-apic.patch b/22534-x86-max-local-apic.patch new file mode 100644 index 0000000..3ae3fe4 --- /dev/null +++ b/22534-x86-max-local-apic.patch @@ -0,0 +1,153 @@ +# HG changeset patch +# User Keir Fraser +# Date 1292414148 0 +# Node ID d4b373ec948bed71b8683e09e41c6afc99f1edb6 +# Parent 548c808be2a6f166657ce7cfb86df7a296a9526a +x86: increase MAX_LOCAL_APIC +References: bnc#656369, bnc#658704 + +otherwise apicid_to_node[MAX_LOCAL_APIC] will be overrun if apicid > +255. After patch, the mapping get right. + +Signed-off-by: Yinghai Lu + +Make this and also MAX_MADT_ENTRIES loosely depend on NR_CPUS. Tie +MAX_APICS to MAX_LOCAL_APIC. Fix initializer of x86_acpiid_to_apicid[] +to match the array member type of u32, as well as all checks in +readers of this array and x86_cpu_to_apicid[]. + +While the adjustment to xen_vcpu_physid_to_x86_{acpi,apic}id() is not +backward compatible, I think it should still be done this way as the +former reserving of values beyond 0xff should never have been part of +the interface. If considered impossible, a second best solution would +appear to be to make the macros depend on __XEN_INTERFACE_VERSION__. + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/acpi/boot.c ++++ b/xen/arch/x86/acpi/boot.c +@@ -82,7 +82,7 @@ u8 acpi_enable_value, acpi_disable_value + #endif + + u32 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = +- {[0 ... MAX_MADT_ENTRIES - 1] = 0xff }; ++ {[0 ... MAX_MADT_ENTRIES - 1] = BAD_APICID }; + EXPORT_SYMBOL(x86_acpiid_to_apicid); + + /* -------------------------------------------------------------------------- +@@ -534,6 +534,7 @@ static int __init acpi_parse_madt_lapic_ + + mp_register_lapic_address(acpi_lapic_addr); + ++ BUILD_BUG_ON(MAX_APICS != MAX_LOCAL_APIC); + count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, + MAX_APICS); + x2count = acpi_table_parse_madt(ACPI_MADT_X2APIC, acpi_parse_x2apic, +@@ -998,12 +999,12 @@ unsigned int acpi_get_processor_id(unsig + { + unsigned int acpiid, apicid; + +- if ((apicid = x86_cpu_to_apicid[cpu]) == 0xff) +- return 0xff; ++ if ((apicid = x86_cpu_to_apicid[cpu]) == BAD_APICID) ++ return INVALID_ACPIID; + + for (acpiid = 0; acpiid < ARRAY_SIZE(x86_acpiid_to_apicid); acpiid++) + if (x86_acpiid_to_apicid[acpiid] == apicid) + return acpiid; + +- return 0xff; ++ return INVALID_ACPIID; + } +--- a/xen/arch/x86/acpi/cpu_idle.c ++++ b/xen/arch/x86/acpi/cpu_idle.c +@@ -745,7 +745,7 @@ int get_cpu_id(u8 acpi_id) + u32 apic_id; + + apic_id = x86_acpiid_to_apicid[acpi_id]; +- if ( apic_id == 0xff ) ++ if ( apic_id == BAD_APICID ) + return -1; + + for ( i = 0; i < NR_CPUS; i++ ) +--- a/xen/arch/x86/smpboot.c ++++ b/xen/arch/x86/smpboot.c +@@ -96,7 +96,7 @@ struct cpuinfo_x86 cpu_data[NR_CPUS]; + EXPORT_SYMBOL(cpu_data); + + u32 x86_cpu_to_apicid[NR_CPUS] __read_mostly = +- { [0 ... NR_CPUS-1] = -1U }; ++ { [0 ... NR_CPUS-1] = BAD_APICID }; + EXPORT_SYMBOL(x86_cpu_to_apicid); + + static void map_cpu_to_logical_apicid(void); +@@ -1479,7 +1479,7 @@ int cpu_add(uint32_t apic_id, uint32_t a + return -EINVAL; + + /* Detect if the cpu has been added before */ +- if ( x86_acpiid_to_apicid[acpi_id] != 0xff) ++ if ( x86_acpiid_to_apicid[acpi_id] != BAD_APICID ) + { + if (x86_acpiid_to_apicid[acpi_id] != apic_id) + return -EINVAL; +@@ -1513,7 +1513,7 @@ int cpu_add(uint32_t apic_id, uint32_t a + { + dprintk(XENLOG_WARNING, + "Setup node failed for pxm %x\n", pxm); +- x86_acpiid_to_apicid[acpi_id] = 0xff; ++ x86_acpiid_to_apicid[acpi_id] = BAD_APICID; + mp_unregister_lapic(apic_id, cpu); + spin_unlock(&cpu_add_remove_lock); + return node; +--- a/xen/include/asm-x86/acpi.h ++++ b/xen/include/asm-x86/acpi.h +@@ -150,9 +150,11 @@ struct acpi_sleep_info { + + #endif /* CONFIG_ACPI_SLEEP */ + +-#define MAX_MADT_ENTRIES 256 ++#define MAX_MADT_ENTRIES MAX(256, 2 * NR_CPUS) + extern u32 x86_acpiid_to_apicid[]; +-#define MAX_LOCAL_APIC 256 ++#define MAX_LOCAL_APIC MAX(256, 4 * NR_CPUS) ++ ++#define INVALID_ACPIID (-1U) + + extern u32 pmtmr_ioport; + +--- a/xen/include/asm-x86/numa.h ++++ b/xen/include/asm-x86/numa.h +@@ -39,7 +39,7 @@ extern int setup_node(int pxm); + extern void srat_detect_node(int cpu); + + extern void setup_node_bootmem(int nodeid, u64 start, u64 end); +-extern unsigned char apicid_to_node[256]; ++extern unsigned char apicid_to_node[]; + #ifdef CONFIG_NUMA + extern void __init init_cpu_to_node(void); + +--- a/xen/include/public/vcpu.h ++++ b/xen/include/public/vcpu.h +@@ -187,8 +187,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_register_vc + /* + * Get the physical ID information for a pinned vcpu's underlying physical + * processor. The physical ID informmation is architecture-specific. +- * On x86: id[31:0]=apic_id, id[63:32]=acpi_id, and all values 0xff and +- * greater are reserved. ++ * On x86: id[31:0]=apic_id, id[63:32]=acpi_id. + * This command returns -EINVAL if it is not a valid operation for this VCPU. + */ + #define VCPUOP_get_physid 12 /* arg == vcpu_get_physid_t */ +@@ -197,10 +196,8 @@ struct vcpu_get_physid { + }; + typedef struct vcpu_get_physid vcpu_get_physid_t; + DEFINE_XEN_GUEST_HANDLE(vcpu_get_physid_t); +-#define xen_vcpu_physid_to_x86_apicid(physid) \ +- ((((uint32_t)(physid)) >= 0xff) ? 0xff : ((uint8_t)(physid))) +-#define xen_vcpu_physid_to_x86_acpiid(physid) \ +- ((((uint32_t)((physid)>>32)) >= 0xff) ? 0xff : ((uint8_t)((physid)>>32))) ++#define xen_vcpu_physid_to_x86_apicid(physid) ((uint32_t)(physid)) ++#define xen_vcpu_physid_to_x86_acpiid(physid) ((uint32_t)((physid) >> 32)) + + /* + * Register a memory location to get a secondary copy of the vcpu time diff --git a/22535-x2apic-preenabled.patch b/22535-x2apic-preenabled.patch new file mode 100644 index 0000000..d84510f --- /dev/null +++ b/22535-x2apic-preenabled.patch @@ -0,0 +1,82 @@ +# HG changeset patch +# User Keir Fraser +# Date 1292414185 0 +# Node ID fcc91cb3efcb83823b7e9c74ee3c97c4a9c0b7d5 +# Parent d4b373ec948bed71b8683e09e41c6afc99f1edb6 +x86: x2apic pre-enabled but intr-remapping is not enabled +References: bnc#656369, bnc#658704 + +Make it aligned with Linux kernel. + +Signed-off-by: Yinghai Lu + +Removed unnecessary bits from the original patch, and removed +intremap_enabled() with its only caller gone. + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/apic.c ++++ b/xen/arch/x86/apic.c +@@ -963,15 +963,6 @@ void x2apic_setup(void) + rdmsr(MSR_IA32_APICBASE, lo, hi); + if ( lo & MSR_IA32_APICBASE_EXTD ) + { +- /* +- * Interrupt remapping should be also enabled by BIOS when +- * x2APIC is already enabled by BIOS, otherwise it's a BIOS +- * bug +- */ +- if ( !intremap_enabled() ) +- panic("Interrupt remapping is not enabled by BIOS while " +- "x2APIC is already enabled by BIOS!\n"); +- + printk("x2APIC mode is already enabled by BIOS.\n"); + x2apic_enabled = 1; + } +@@ -1014,6 +1005,10 @@ void x2apic_setup(void) + + if ( iommu_enable_IR() ) + { ++ if ( x2apic_enabled ) ++ panic("Interrupt remapping could not be enabled while " ++ "x2APIC is already enabled by BIOS!\n"); ++ + printk("Would not enable x2APIC due to interrupt remapping " + "cannot be enabled.\n"); + goto restore_out; +--- a/xen/drivers/passthrough/vtd/intremap.c ++++ b/xen/drivers/passthrough/vtd/intremap.c +@@ -884,23 +884,3 @@ void iommu_disable_IR(void) + for_each_drhd_unit ( drhd ) + disable_qinval(drhd->iommu); + } +- +-/* +- * Check if interrupt remapping is enabled or not +- * return 1: enabled +- * return 0: not enabled +- */ +-int intremap_enabled(void) +-{ +- struct acpi_drhd_unit *drhd; +- u32 sts; +- +- for_each_drhd_unit ( drhd ) +- { +- sts = dmar_readl(drhd->iommu->reg, DMAR_GSTS_REG); +- if ( !(sts & DMA_GSTS_IRES) ) +- return 0; +- } +- +- return 1; +-} +--- a/xen/include/xen/iommu.h ++++ b/xen/include/xen/iommu.h +@@ -62,7 +62,6 @@ int iommu_setup(void); + int iommu_supports_eim(void); + int iommu_enable_IR(void); + void iommu_disable_IR(void); +-int intremap_enabled(void); + + int iommu_add_device(struct pci_dev *pdev); + int iommu_remove_device(struct pci_dev *pdev); diff --git a/22538-keyhandler-relax.patch b/22538-keyhandler-relax.patch new file mode 100644 index 0000000..ddf1c44 --- /dev/null +++ b/22538-keyhandler-relax.patch @@ -0,0 +1,101 @@ +# HG changeset patch +# User Keir Fraser +# Date 1292414674 0 +# Node ID a3a29e67aa7e75a094e1b4237b10a68cf829b542 +# Parent 16673224c1cc2ca3bb9730f1d7c84fe4d96e5323 +Reduce side effects of handling '*' debug key +References: bnc#659284 + +NMI watchdog should be suppressed when dumping IRQ handlers. Softirqs +should be handled periodically while processing non-IRQ handlers. + +Signed-off-by: Jan Beulich + +# HG changeset patch +# User Keir Fraser +# Date 1293185578 0 +# Node ID dca1b7cf2e2c27cd160bd1d1d284e3f810d4936c +# Parent e8acb9753ff1a5cd3d6a45eda5f4c6f0059c281a +re-add calls accidentally deleted from run_all_nonirq_keyhandlers() + +c/s 22538:a3a29e67aa7e, having got applied in a form different from +the one submitted, resulted in the calls to +console_{start,end}_log_everything() getting removed without +replacement. Add them back since, other than run_all_keyhandlers(), +this doesn't run with log-everything already in effect. + +Signed-off-by: Jan Beulich + +--- a/xen/common/keyhandler.c ++++ b/xen/common/keyhandler.c +@@ -407,14 +407,17 @@ static void run_all_nonirq_keyhandlers(u + int k; + + console_start_log_everything(); ++ + for ( k = 0; k < ARRAY_SIZE(key_table); k++ ) + { ++ process_pending_softirqs_nested(); + h = key_table[k]; + if ( (h == NULL) || !h->diagnostic || h->irq_callback ) + continue; + printk("[%c: %s]\n", k, h->desc); + (*h->u.fn)(k); + } ++ + console_end_log_everything(); + } + +@@ -426,10 +429,11 @@ static void run_all_keyhandlers(unsigned + struct keyhandler *h; + int k; + ++ watchdog_disable(); ++ + printk("'%c' pressed -> firing all diagnostic keyhandlers\n", key); + + /* Fire all the IRQ-context diangostic keyhandlers now */ +- console_start_log_everything(); + for ( k = 0; k < ARRAY_SIZE(key_table); k++ ) + { + h = key_table[k]; +@@ -438,7 +442,8 @@ static void run_all_keyhandlers(unsigned + printk("[%c: %s]\n", k, h->desc); + (*h->u.irq_fn)(k, regs); + } +- console_end_log_everything(); ++ ++ watchdog_enable(); + + /* Trigger the others from a tasklet in non-IRQ context */ + tasklet_schedule(&run_all_keyhandlers_tasklet); +--- a/xen/common/softirq.c ++++ b/xen/common/softirq.c +@@ -54,6 +54,16 @@ void process_pending_softirqs(void) + __do_softirq(1ul< +# Date 1292415031 0 +# Node ID d8279118b4bbb3bb3689b9c20abb25d0c09e2b69 +# Parent 20c65aa19075b1a696adb56325827412596ac0d4 +x86/32on64: zero-extend hypercall index before use in memory access (debug mode only) + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/x86_64/compat/entry.S ++++ b/xen/arch/x86/x86_64/compat/entry.S +@@ -36,7 +36,8 @@ ENTRY(compat_hypercall) + pushq UREGS_rbx(%rsp); pushq %rcx; pushq %rdx; pushq %rsi; pushq %rdi + pushq UREGS_rbp+5*8(%rsp) + leaq compat_hypercall_args_table(%rip),%r10 +- movq $6,%rcx ++ movl %eax,%eax ++ movl $6,%ecx + subb (%r10,%rax,1),%cl + movq %rsp,%rdi + movl $0xDEADBEEF,%eax diff --git a/22549-vtd-map-page-leak.patch b/22549-vtd-map-page-leak.patch new file mode 100644 index 0000000..4257a28 --- /dev/null +++ b/22549-vtd-map-page-leak.patch @@ -0,0 +1,28 @@ +# HG changeset patch +# User Keir Fraser +# Date 1292513937 0 +# Node ID aa18b8ddaf05084aef3f8cff11d92248a8b6fac8 +# Parent f46f46bbb69a788037f866025c88743d55dde416 +vtd: Require unmap_vtd_domain_page() on a couple of early exit paths. + +From: Jan Beulich +Signed-off-by: Keir Fraser + +--- a/xen/drivers/passthrough/vtd/iommu.c ++++ b/xen/drivers/passthrough/vtd/iommu.c +@@ -1330,6 +1330,7 @@ int domain_context_mapping_one( + if ( context_set_domain_id(context, domain, iommu) ) + { + spin_unlock(&iommu->lock); ++ unmap_vtd_domain_page(context_entries); + return -EFAULT; + } + +@@ -1671,6 +1672,7 @@ static int intel_iommu_map_page( + if ( old.val == new.val ) + { + spin_unlock(&hd->mapping_lock); ++ unmap_vtd_domain_page(page); + return 0; + } + *pte = new; diff --git a/22574-ept-skip-validation.patch b/22574-ept-skip-validation.patch new file mode 100644 index 0000000..49be640 --- /dev/null +++ b/22574-ept-skip-validation.patch @@ -0,0 +1,29 @@ +# HG changeset patch +# User Keir Fraser +# Date 1292954974 0 +# Node ID b5418c045d029e8bf5eadfd4e1ef0b1822da7186 +# Parent ff1b80ccecd9ed049cc694ab117100e83eab179f +x86 hvm ept: Remove EPT guest linear address validation + +For EPT violation resulting from an attempt to load the guest PDPTEs +as part of the execution of the MOV CR instruction, the EPT_GLA_VALID +is not valid. This situation should not happen in most situation, +since we always populate guest memory. But this is not ture for PAE +guest under the PoD/Page sharing situation. In that situation, a page +pointed by CR3 may be un-populated, and we need handle it in such +situation. + +Signed-off-by: Jiang, Yunhong + +--- a/xen/arch/x86/hvm/vmx/vmx.c ++++ b/xen/arch/x86/hvm/vmx/vmx.c +@@ -2129,8 +2129,7 @@ static void ept_handle_violation(unsigne + __trace_var(TRC_HVM_NPF, 0, sizeof(_d), (unsigned char *)&_d); + } + +- if ( (qualification & EPT_GLA_VALID) && +- hvm_hap_nested_page_fault(gfn) ) ++ if ( hvm_hap_nested_page_fault(gfn) ) + return; + + /* Everything else is an error. */ diff --git a/22632-vtd-print-entries.patch b/22632-vtd-print-entries.patch new file mode 100644 index 0000000..54d5d54 --- /dev/null +++ b/22632-vtd-print-entries.patch @@ -0,0 +1,121 @@ +# HG changeset patch +# User Keir Fraser +# Date 1293185641 0 +# Node ID 7cc87dcf30a13bcf600077aa661694caeb0c290c +# Parent dca1b7cf2e2c27cd160bd1d1d284e3f810d4936c +VT-d: fix and improve print_vtd_entries() + +Fix leaking of mapped domain pages (root_entry and ctxt_entry when +falling out of the level traversing loop). Do this by re-arranging +things slightly so that a mapping is retained only as long as it +really is needed. + +Fix the failure to use map_domain_page() in the level traversing loop +of the function. + +Add a mssing return statement in one of the error paths. + +Also I wonder whether not being able to call print_vtd_entries() from +iommu_page_fault_do_one() in ix86 is still correct, now that +map_domain_page() is IRQ safe. + +Signed-off-by: Jan Beulich + +--- a/xen/drivers/passthrough/vtd/utils.c ++++ b/xen/drivers/passthrough/vtd/utils.c +@@ -99,7 +99,7 @@ void print_vtd_entries(struct iommu *iom + struct context_entry *ctxt_entry; + struct root_entry *root_entry; + struct dma_pte pte; +- u64 *l; ++ u64 *l, val; + u32 l_index, level; + + printk("print_vtd_entries: iommu = %p bdf = %x:%x.%x gmfn = %"PRIx64"\n", +@@ -112,6 +112,11 @@ void print_vtd_entries(struct iommu *iom + } + + root_entry = (struct root_entry *)map_vtd_domain_page(iommu->root_maddr); ++ if ( root_entry == NULL ) ++ { ++ printk(" root_entry == NULL\n"); ++ return; ++ } + + printk(" root_entry = %p\n", root_entry); + printk(" root_entry[%x] = %"PRIx64"\n", bus, root_entry[bus].val); +@@ -122,61 +127,57 @@ void print_vtd_entries(struct iommu *iom + return; + } + +- ctxt_entry = +- (struct context_entry *)map_vtd_domain_page(root_entry[bus].val); ++ val = root_entry[bus].val; ++ unmap_vtd_domain_page(root_entry); ++ ctxt_entry = map_vtd_domain_page(val); + if ( ctxt_entry == NULL ) + { +- unmap_vtd_domain_page(root_entry); + printk(" ctxt_entry == NULL\n"); + return; + } + + printk(" context = %p\n", ctxt_entry); ++ val = ctxt_entry[devfn].lo; + printk(" context[%x] = %"PRIx64"_%"PRIx64"\n", +- devfn, ctxt_entry[devfn].hi, ctxt_entry[devfn].lo); ++ devfn, ctxt_entry[devfn].hi, val); + if ( !context_present(ctxt_entry[devfn]) ) + { + unmap_vtd_domain_page(ctxt_entry); +- unmap_vtd_domain_page(root_entry); + printk(" ctxt_entry[%x] not present\n", devfn); + return; + } + + level = agaw_to_level(context_address_width(ctxt_entry[devfn])); ++ unmap_vtd_domain_page(ctxt_entry); + if ( level != VTD_PAGE_TABLE_LEVEL_3 && + level != VTD_PAGE_TABLE_LEVEL_4) + { +- unmap_vtd_domain_page(ctxt_entry); +- unmap_vtd_domain_page(root_entry); + printk("Unsupported VTD page table level (%d)!\n", level); ++ return; + } + +- l = maddr_to_virt(ctxt_entry[devfn].lo); + do + { +- l = (u64*)(((unsigned long)l >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K); ++ l = map_vtd_domain_page(val); + printk(" l%d = %p\n", level, l); + if ( l == NULL ) + { +- unmap_vtd_domain_page(ctxt_entry); +- unmap_vtd_domain_page(root_entry); + printk(" l%d == NULL\n", level); + break; + } + l_index = get_level_index(gmfn, level); + printk(" l%d_index = %x\n", level, l_index); +- printk(" l%d[%x] = %"PRIx64"\n", level, l_index, l[l_index]); + +- pte.val = l[l_index]; ++ pte.val = val = l[l_index]; ++ unmap_vtd_domain_page(l); ++ printk(" l%d[%x] = %"PRIx64"\n", level, l_index, val); ++ ++ pte.val = val; + if ( !dma_pte_present(pte) ) + { +- unmap_vtd_domain_page(ctxt_entry); +- unmap_vtd_domain_page(root_entry); + printk(" l%d[%x] not present\n", level, l_index); + break; + } +- +- l = maddr_to_virt(l[l_index]); + } while ( --level ); + } + diff --git a/22645-amd-flush-filter.patch b/22645-amd-flush-filter.patch new file mode 100644 index 0000000..72ddbb6 --- /dev/null +++ b/22645-amd-flush-filter.patch @@ -0,0 +1,58 @@ +# HG changeset patch +# User Keir Fraser +# Date 1294220923 0 +# Node ID 76d897a06b316bf2278220b006d578faf31ce3fb +# Parent fece73d4d30985ce40ef87dcd379ce6beb8aadf3 +x86 amd: Revert 6382:b74c15e4dd4f (AMD flush filter configuration) + +Flush filter is not reliably supported by any processor, we already +have code to unconditionally disable the filter, so we don't need the +command-line config option. Remove it. + +Signed-off-by: Keir Fraser + +--- a/xen/arch/x86/cpu/amd.c ++++ b/xen/arch/x86/cpu/amd.c +@@ -237,20 +237,6 @@ int cpu_has_amd_erratum(const struct cpu + return 0; + } + +-/* +- * amd_flush_filter={on,off}. Forcibly Enable or disable the TLB flush +- * filter on AMD 64-bit processors. +- */ +-static int flush_filter_force; +-static void flush_filter(char *s) +-{ +- if (!strcmp(s, "off")) +- flush_filter_force = -1; +- if (!strcmp(s, "on")) +- flush_filter_force = 1; +-} +-custom_param("amd_flush_filter", flush_filter); +- + #define num_physpages 0 + + /* +@@ -545,21 +531,6 @@ static void __devinit init_amd(struct cp + break; + } + +- if (c->x86 == 15) { +- rdmsr(MSR_K7_HWCR, l, h); +- printk(KERN_INFO "CPU%d: AMD Flush Filter %sabled", +- smp_processor_id(), (l & (1<<6)) ? "dis" : "en"); +- if ((flush_filter_force > 0) && (l & (1<<6))) { +- l &= ~(1<<6); +- printk(" -> Forcibly enabled"); +- } else if ((flush_filter_force < 0) && !(l & (1<<6))) { +- l |= 1<<6; +- printk(" -> Forcibly disabled"); +- } +- wrmsr(MSR_K7_HWCR, l, h); +- printk("\n"); +- } +- + display_cacheinfo(c); + + if (cpuid_eax(0x80000000) >= 0x80000008) { diff --git a/22693-fam10-mmio-conf-base-protect.patch b/22693-fam10-mmio-conf-base-protect.patch new file mode 100644 index 0000000..7ea63de --- /dev/null +++ b/22693-fam10-mmio-conf-base-protect.patch @@ -0,0 +1,71 @@ +# HG changeset patch +# User Keir Fraser +# Date 1294648952 0 +# Node ID 08bb0eefe87107c30a9bdc6d72f26b20c55ae687 +# Parent 66e8062894641e5622aa6adc54297d5700b1cea3 +x86-64: don't allow wrmsr to MSR_FAM10H_MMIO_CONF_BASE when Xen itself is using it + +Signed-off-by: Jan Beulich + +# HG changeset patch +# User Keir Fraser +# Date 1294741846 0 +# Node ID a2dcebb88bc4571d64b3f30c1fbb33cfe4f6e2c5 +# Parent 1ae74f060a39ae1305b3a434d0faa1a19853fdab +x86-64: refine access permission check for wrmsr to MSR_FAM10H_MMIO_CONF_BASE + +We really don't want the mmconf window to move/disappear whenever we +use is ourselves, not only when we enabled it. + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/traps.c ++++ b/xen/arch/x86/traps.c +@@ -1704,6 +1704,10 @@ static int is_cpufreq_controller(struct + (d->domain_id == 0)); + } + ++#ifdef CONFIG_X86_64 ++#include "x86_64/mmconfig.h" ++#endif ++ + static int emulate_privileged_op(struct cpu_user_regs *regs) + { + struct vcpu *v = current; +@@ -2263,7 +2267,13 @@ static int emulate_privileged_op(struct + goto fail; + if ( !IS_PRIV(v->domain) ) + break; +- if ( (rdmsr_safe(MSR_FAM10H_MMIO_CONF_BASE, l, h) != 0) || ++ if ( (rdmsr_safe(MSR_FAM10H_MMIO_CONF_BASE, l, h) != 0) ) ++ goto fail; ++ if ( ++#ifdef CONFIG_X86_64 ++ (pci_probe & PCI_PROBE_MASK) == PCI_PROBE_MMCONF ? ++ eax != l || edx != h : ++#endif + (((((u64)h << 32) | l) ^ val) & + ~( FAM10H_MMIO_CONF_ENABLE | + (FAM10H_MMIO_CONF_BUSRANGE_MASK << +--- a/xen/arch/x86/x86_64/mmconfig.h ++++ b/xen/arch/x86/x86_64/mmconfig.h +@@ -34,6 +34,8 @@ + + #define PCI_VENDOR_ID_NVIDIA 0x10de + ++extern unsigned int pci_probe; ++ + /* + * AMD Fam10h CPUs are buggy, and cannot access MMIO config space + * on their northbrige except through the * %eax register. As such, you MUST +--- a/xen/arch/x86/x86_64/mmconfig-shared.c ++++ b/xen/arch/x86/x86_64/mmconfig-shared.c +@@ -24,7 +24,7 @@ + #include "mmconfig.h" + + static int __initdata known_bridge; +-static unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_MMCONF; ++unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_MMCONF; + + static void __init parse_mmcfg(char *s) + { diff --git a/22694-x86_64-no-weak.patch b/22694-x86_64-no-weak.patch new file mode 100644 index 0000000..0306577 --- /dev/null +++ b/22694-x86_64-no-weak.patch @@ -0,0 +1,44 @@ +# HG changeset patch +# User Keir Fraser +# Date 1294649119 0 +# Node ID 9b5d121c8805b40a4338248c346303e1e18d0c4e +# Parent 08bb0eefe87107c30a9bdc6d72f26b20c55ae687 +x86_64: don't use weak symbols on x86-64 +References: bnc#656369, bnc#658704 + +Various gcc versions inline functions that are both weak and hidden, +without even giving a warning. + +Certainly the risk exists that we'll see the problem again when +another weak function gets introduced, but I don't see a way to +protect us from that. + +Signed-off-by: Jan Beulich + +Just remove the weak attribute altogether. It's the only one in +non-ia64-specific code. We can get teh same effect with ifdefs which +although a bit unsightly is better than using compiler/linker features +we cannot trust. + +Signed-off-by: Keir Fraser + +--- a/xen/drivers/acpi/numa.c ++++ b/xen/drivers/acpi/numa.c +@@ -120,14 +120,15 @@ static int __init acpi_parse_slit(struct + return 0; + } + +-void __init __attribute__ ((weak)) ++#ifndef CONFIG_X86 ++void __init + acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) + { + printk(KERN_WARNING PREFIX + "Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id); + return; + } +- ++#endif + + static int __init + acpi_parse_x2apic_affinity(struct acpi_subtable_header *header, diff --git a/22707-x2apic-preenabled-check.patch b/22707-x2apic-preenabled-check.patch new file mode 100644 index 0000000..d3ce783 --- /dev/null +++ b/22707-x2apic-preenabled-check.patch @@ -0,0 +1,101 @@ +# HG changeset patch +# User Keir Fraser +# Date 1294746050 0 +# Node ID 2ff199e2842b7e4f08ea99558afc32536a77280c +# Parent ca10302ac2859b43a41afe425d79ae0df29f2a9c +x86: restore x2apic pre-enabled check logic +References: bnc#656369, bnc#658704 + +c/s 22475 removed the early checking without replacement, neglecting +the fact that x2apic_enabled must be set early for APIC register +accesses done during second stage ACPI table parsing (rooted at +acpi_boot_init()) to work correctly. Without this, particularly +determination of the boot CPU won't work, resulting in an attempt to +bring up that CPU again as a secondary one (which fails). + +Restore the functionality, now calling it from generic_apic_probe(). + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/apic.c ++++ b/xen/arch/x86/apic.c +@@ -947,7 +947,6 @@ no_apic: + void x2apic_setup(void) + { + struct IO_APIC_route_entry **ioapic_entries = NULL; +- u32 lo, hi; + + if ( smp_processor_id() != 0 ) + { +@@ -959,14 +958,6 @@ void x2apic_setup(void) + if ( !cpu_has_x2apic ) + return; + +- /* Check whether x2apic mode was already enabled by the BIOS. */ +- rdmsr(MSR_IA32_APICBASE, lo, hi); +- if ( lo & MSR_IA32_APICBASE_EXTD ) +- { +- printk("x2APIC mode is already enabled by BIOS.\n"); +- x2apic_enabled = 1; +- } +- + if ( !opt_x2apic ) + { + if ( !x2apic_enabled ) +--- a/xen/arch/x86/genapic/probe.c ++++ b/xen/arch/x86/genapic/probe.c +@@ -59,8 +59,10 @@ custom_param("apic", genapic_apic_force) + + void __init generic_apic_probe(void) + { +- int i; +- int changed = cmdline_apic = (genapic != NULL); ++ int i, changed; ++ ++ check_x2apic_preenabled(); ++ cmdline_apic = changed = (genapic != NULL); + + for (i = 0; !changed && apic_probe[i]; i++) { + if (apic_probe[i]->probe()) { +--- a/xen/arch/x86/genapic/x2apic.c ++++ b/xen/arch/x86/genapic/x2apic.c +@@ -20,6 +20,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + +@@ -134,3 +136,20 @@ const struct genapic *apic_x2apic_probe( + { + return x2apic_phys ? &apic_x2apic_phys : &apic_x2apic_cluster; + } ++ ++void __init check_x2apic_preenabled(void) ++{ ++ u32 lo, hi; ++ ++ if ( !cpu_has_x2apic ) ++ return; ++ ++ /* Check whether x2apic mode was already enabled by the BIOS. */ ++ rdmsr(MSR_IA32_APICBASE, lo, hi); ++ if ( lo & MSR_IA32_APICBASE_EXTD ) ++ { ++ printk("x2APIC mode is already enabled by BIOS.\n"); ++ x2apic_enabled = 1; ++ genapic = apic_x2apic_probe(); ++ } ++} +--- a/xen/include/asm-x86/apic.h ++++ b/xen/include/asm-x86/apic.h +@@ -25,6 +25,7 @@ extern int apic_verbosity; + extern int x2apic_enabled; + extern int directed_eoi_enabled; + ++void check_x2apic_preenabled(void); + void x2apic_setup(void); + const struct genapic *apic_x2apic_probe(void); + diff --git a/22708-xenctx-misc.patch b/22708-xenctx-misc.patch new file mode 100644 index 0000000..18e60ca --- /dev/null +++ b/22708-xenctx-misc.patch @@ -0,0 +1,112 @@ +# HG changeset patch +# User Keir Fraser +# Date 1294746099 0 +# Node ID 7926538a633297d65a5d6324bf9bd0eb158a6aff +# Parent 2ff199e2842b7e4f08ea99558afc32536a77280c +xenctx: misc adjustments + +- fix off-by-one errors during symbol insertion and lookup +- don't store the symbol type, as it wasn't needed at all so far and + is only needed now at parsing time +- don't insert certain kinds of symbols + +Signed-off-by: Jan Beulich + +--- a/tools/xentrace/xenctx.c ++++ b/tools/xentrace/xenctx.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -58,7 +59,6 @@ int disp_tlb; + + struct symbol { + guest_word_t address; +- char type; + char *name; + struct symbol *next; + } *symbol_table = NULL; +@@ -112,12 +112,12 @@ static void insert_symbol(struct symbol + + /* The System.map is usually already sorted... */ + if (prev +- && prev->address < symbol->address ++ && prev->address <= symbol->address + && (!prev->next || prev->next->address > symbol->address)) { + s = prev; + } else { + /* ... otherwise do crappy/slow search for the correct place */ +- while(s && s->next && s->next->address < symbol->address) ++ while (s->next && s->next->address <= symbol->address) + s = s->next; + } + +@@ -130,13 +130,13 @@ static struct symbol *lookup_symbol(gues + { + struct symbol *s = symbol_table; + +- while(s && s->next && s->next->address < address) +- s = s->next; ++ if (!s) ++ return NULL; + +- if (s && s->address < address) +- return s; ++ while (s->next && s->next->address < address) ++ s = s->next; + +- return NULL; ++ return s->next && s->next->address <= address ? s->next : s; + } + + static void print_symbol(guest_word_t addr) +@@ -159,7 +159,7 @@ static void print_symbol(guest_word_t ad + + static void read_symbol_table(const char *symtab) + { +- char line[256]; ++ char type, line[256]; + char *p; + struct symbol *symbol; + FILE *f; +@@ -178,9 +178,13 @@ static void read_symbol_table(const char + + /* need more checks for syntax here... */ + symbol->address = strtoull(line, &p, 16); +- p++; +- symbol->type = *p++; +- p++; ++ if (!isspace(*p++)) ++ continue; ++ type = *p++; ++ if (!isalpha(type) && type != '?') ++ continue; ++ if (!isspace(*p++)) ++ continue; + + /* in the future we should handle the module name + * being appended here, this would allow us to use +@@ -190,7 +194,18 @@ static void read_symbol_table(const char + p[strlen(p)-1] = '\0'; + symbol->name = strdup(p); + +- insert_symbol(symbol); ++ switch (type) { ++ case 'A': /* global absolute */ ++ case 'a': /* local absolute */ ++ break; ++ case 'U': /* undefined */ ++ case 'v': /* undefined weak object */ ++ case 'w': /* undefined weak function */ ++ continue; ++ default: ++ insert_symbol(symbol); ++ break; ++ } + + if (strcmp(symbol->name, "_stext") == 0) + kernel_stext = symbol->address; diff --git a/32on64-extra-mem.patch b/32on64-extra-mem.patch index 6249b76..87bf052 100644 --- a/32on64-extra-mem.patch +++ b/32on64-extra-mem.patch @@ -2,7 +2,7 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -2920,7 +2920,7 @@ class XendDomainInfo: +@@ -2919,7 +2919,7 @@ class XendDomainInfo: self.guest_bitsize = self.image.getBitSize() # Make sure there's enough RAM available for the domain diff --git a/7426-xenfb-depth.patch b/7426-xenfb-depth.patch new file mode 100644 index 0000000..1d5ae4b --- /dev/null +++ b/7426-xenfb-depth.patch @@ -0,0 +1,50 @@ +Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xenfb.c +=================================================================== +--- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/hw/xenfb.c ++++ xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xenfb.c +@@ -622,6 +622,18 @@ static void xenfb_guest_copy(struct XenF + oops = 1; + } + break; ++ case 16: ++ if (bpp == 16) { ++ for (line = y; line < (y+h); line++) { ++ memcpy (data + (line * linesize) + (x * bpp / 8), xenfb->pixels + xenfb->offset ++ + (line * xenfb->row_stride) + (x * xenfb->depth / 8), w * xenfb->depth / 8); ++ } ++ } else if (bpp == 32) { ++ BLT(uint16_t, uint32_t, 5, 6, 5, 8, 8, 8); ++ } else { ++ oops = 1; ++ } ++ break; + case 24: + if (bpp == 16) { + BLT(uint32_t, uint16_t, 8, 8, 8, 5, 6, 5); +@@ -631,6 +643,18 @@ static void xenfb_guest_copy(struct XenF + oops = 1; + } + break; ++ case 32: ++ if (bpp == 16) { ++ BLT(uint32_t, uint16_t, 8, 8, 8, 5, 6, 5); ++ } else if (bpp == 32) { ++ for (line = y; line < (y+h); line++) { ++ memcpy (data + (line * linesize) + (x * bpp / 8), xenfb->pixels + xenfb->offset ++ + (line * xenfb->row_stride) + (x * xenfb->depth / 8), w * xenfb->depth / 8); ++ } ++ } else { ++ oops = 1; ++ } ++ break; + default: + oops = 1; + } +@@ -784,6 +808,7 @@ static void xenfb_update(void *opaque) + static void xenfb_invalidate(void *opaque) + { + struct XenFB *xenfb = opaque; ++ xenfb->do_resize = 1; + xenfb->up_fullscreen = 1; + } + diff --git a/7433-qemu-altgr.patch b/7433-qemu-altgr.patch new file mode 100644 index 0000000..e75f9c6 --- /dev/null +++ b/7433-qemu-altgr.patch @@ -0,0 +1,46 @@ +--- a/tools/ioemu-qemu-xen/keymaps.c Wed Jan 05 23:16:54 2011 +0000 ++++ b/tools/ioemu-qemu-xen/keymaps.c Wed Jan 05 23:48:36 2011 +0000 +@@ -53,6 +53,20 @@ typedef struct { + struct key_range *localstate_range; + struct key_range *altgr_range; + } kbd_layout_t; ++ ++static void del_key_range(struct key_range **krp, int code) { ++ struct key_range *kr; ++ struct key_range *kr_pr; ++ for (kr = *krp; kr; kr_pr = kr, kr = kr->next) { ++ if (code >= kr->start && code <= kr->end) { ++ if (kr == *krp) ++ *krp = kr->next; ++ else ++ kr_pr->next = kr->next; ++ qemu_free(kr); ++ } ++ } ++} + + static void add_to_key_range(struct key_range **krp, int code) { + struct key_range *kr; +@@ -137,6 +151,8 @@ static kbd_layout_t *parse_keyboard_layo + if (rest && strstr(rest, "altgr")) { + add_to_key_range(&k->altgr_range, keysym); + //fprintf(stderr, "altgr keysym %04x keycode %d\n", keysym, keycode); ++ } else { ++ del_key_range(&k->altgr_range, keysym); + } + + /* if(keycode&0x80) + +--- a/tools/ioemu-qemu-xen/vnc.c Wed Jan 05 23:16:54 2011 +0000 ++++ b/tools/ioemu-qemu-xen/vnc.c Wed Jan 05 23:48:36 2011 +0000 +@@ -1279,11 +1279,9 @@ static void press_key_altgr_down(VncStat + kbd_put_keycode(0xe0); + if (down){ + kbd_put_keycode(0xb8 & 0x7f); +- vs->modifiers_state[0xb8] = 1; + } + else { + kbd_put_keycode(0xb8 | 0x80); +- vs->modifiers_state[0xb8] = 0; + } + } diff --git a/7434-qemu-rlimit-as.patch b/7434-qemu-rlimit-as.patch new file mode 100644 index 0000000..cad3bdb --- /dev/null +++ b/7434-qemu-rlimit-as.patch @@ -0,0 +1,34 @@ +# HG changeset patch +# User Jan Beulich +# Date 1294771190 0 +# Node ID d224cef9d82c5c1ba9a6d73ca2628f288ce6f434 +# Parent a283996796c91dd29ecff444b78798e0ce902047 +bump RLIMIT_AS if restricted +References: bnc#641419 + +Mostly the same as is already being done for several other RLIMIT_* +values. + +Signed-off-by: Jan Beulich +Acked-by: Stefano Stabellini + +committer: Ian Jackson +git-commit-id: 2aa36d470e97f4baa219f78df82e2d3fe3d9f96d + + +--- a/tools/ioemu-qemu-xen/vl.c ++++ b/tools/ioemu-qemu-xen/vl.c +@@ -4845,6 +4845,13 @@ int main(int argc, char **argv, char **e + rl.rlim_cur = rl.rlim_max; + if (setrlimit(RLIMIT_DATA, &rl) != 0) + perror("setrlimit(RLIMIT_DATA)"); ++ if (getrlimit(RLIMIT_AS, &rl) == 0) { ++ rl.rlim_cur = rl.rlim_max; ++ if (setrlimit(RLIMIT_AS, &rl) != 0) ++ perror("setrlimit(RLIMIT_AS)"); ++ } else { ++ perror("getrlimit(RLIMIT_AS)"); ++ } + rl.rlim_cur = RLIM_INFINITY; + rl.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_RSS, &rl) != 0) diff --git a/altgr_2.patch b/altgr_2.patch index cca3a6d..108b652 100644 --- a/altgr_2.patch +++ b/altgr_2.patch @@ -29,22 +29,11 @@ keycodes up and down events and make sure the intentionally added altgr keycode Signed-off by Chunyan Liu (cyliu@novell.com) -diff -r a108300bd904 tools/ioemu-qemu-xen/vnc.c ---- a/tools/ioemu-qemu-xen/vnc.c Mon Sep 27 21:20:36 2010 +0800 -+++ b/tools/ioemu-qemu-xen/vnc.c Wed Sep 29 01:55:55 2010 +0800 -@@ -1279,11 +1279,9 @@ - kbd_put_keycode(0xe0); - if (down){ - kbd_put_keycode(0xb8 & 0x7f); -- vs->modifiers_state[0xb8] = 1; - } - else { - kbd_put_keycode(0xb8 | 0x80); -- vs->modifiers_state[0xb8] = 0; - } - } - -@@ -1310,6 +1308,9 @@ +Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/vnc.c +=================================================================== +--- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/vnc.c ++++ xen-4.0.1-testing/tools/ioemu-qemu-xen/vnc.c +@@ -1308,6 +1308,9 @@ static void do_key_event(VncState *vs, i shift_keys = vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]; altgr_keys = vs->modifiers_state[0xb8]; diff --git a/bdrv_open2_flags_2.patch b/bdrv_open2_flags_2.patch index ffb6e3a..e5fbb73 100644 --- a/bdrv_open2_flags_2.patch +++ b/bdrv_open2_flags_2.patch @@ -2,7 +2,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c =================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.c +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c -@@ -235,6 +235,7 @@ static int open_disk(struct td_state *s, +@@ -237,6 +237,7 @@ static int open_disk(struct td_state *s, BlockDriver* drv; char* devname; static int devnumber = 0; @@ -10,7 +10,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c int i; DPRINTF("Opening %s as blktap%d\n", path, devnumber); -@@ -257,7 +258,7 @@ static int open_disk(struct td_state *s, +@@ -259,7 +260,7 @@ static int open_disk(struct td_state *s, DPRINTF("%s driver specified\n", drv ? drv->format_name : "No"); /* Open the image */ diff --git a/blktap-pv-cdrom.patch b/blktap-pv-cdrom.patch index 670ce5e..6a0b6f1 100644 --- a/blktap-pv-cdrom.patch +++ b/blktap-pv-cdrom.patch @@ -741,7 +741,7 @@ Index: xen-4.0.1-testing/tools/blktap/lib/blktaplib.h =================================================================== --- xen-4.0.1-testing.orig/tools/blktap/lib/blktaplib.h +++ xen-4.0.1-testing/tools/blktap/lib/blktaplib.h -@@ -224,6 +224,7 @@ typedef struct msg_pid { +@@ -225,6 +225,7 @@ typedef struct msg_pid { #define DISK_TYPE_RAM 3 #define DISK_TYPE_QCOW 4 #define DISK_TYPE_QCOW2 5 @@ -795,7 +795,7 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/server/BlktapController.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/server/BlktapController.py +++ xen-4.0.1-testing/tools/python/xen/xend/server/BlktapController.py -@@ -20,6 +20,7 @@ blktap1_disk_types = [ +@@ -21,6 +21,7 @@ blktap1_disk_types = [ 'ram', 'qcow', 'qcow2', diff --git a/capslock_enable.patch b/capslock_enable.patch index dacca9a..3becaa5 100644 --- a/capslock_enable.patch +++ b/capslock_enable.patch @@ -2,7 +2,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/vnc.c =================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/vnc.c +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/vnc.c -@@ -1344,6 +1344,11 @@ static void do_key_event(VncState *vs, i +@@ -1342,6 +1342,11 @@ static void do_key_event(VncState *vs, i } break; case 0x3a: /* CapsLock */ diff --git a/change_home_server.patch b/change_home_server.patch index 4aa6dae..a51d8de 100644 --- a/change_home_server.patch +++ b/change_home_server.patch @@ -2,7 +2,7 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -3136,6 +3136,11 @@ class XendDomainInfo: +@@ -3135,6 +3135,11 @@ class XendDomainInfo: self._cleanup_phantom_devs(paths) self._cleanupVm() diff --git a/cpupools-core-fixup.patch b/cpupools-core-fixup.patch index 1401cf4..239bf00 100644 --- a/cpupools-core-fixup.patch +++ b/cpupools-core-fixup.patch @@ -62,7 +62,7 @@ Index: xen-4.0.1-testing/xen/common/softirq.c =================================================================== --- xen-4.0.1-testing.orig/xen/common/softirq.c +++ xen-4.0.1-testing/xen/common/softirq.c -@@ -104,12 +104,15 @@ static void tasklet_schedule_list(struct +@@ -114,12 +114,15 @@ static void tasklet_schedule_list(struct { BUG_ON(!list_empty(&t->list)); list_add_tail(&t->list, tlist); @@ -79,7 +79,7 @@ Index: xen-4.0.1-testing/xen/common/softirq.c } spin_unlock_irqrestore(&tasklet_lock, flags); -@@ -120,7 +123,7 @@ void tasklet_schedule(struct tasklet *t) +@@ -130,7 +133,7 @@ void tasklet_schedule(struct tasklet *t) tasklet_schedule_list(t, &tasklet_list, smp_processor_id()); } @@ -88,7 +88,7 @@ Index: xen-4.0.1-testing/xen/common/softirq.c { tasklet_schedule_list(t, &per_cpu(tasklet_list_pcpu, cpu), cpu); } -@@ -156,7 +159,15 @@ static void tasklet_action(void) +@@ -166,7 +169,15 @@ static void tasklet_action(void) if ( t->is_scheduled ) { BUG_ON(t->is_dead || !list_empty(&t->list)); @@ -122,7 +122,7 @@ Index: xen-4.0.1-testing/xen/include/xen/softirq.h =================================================================== --- xen-4.0.1-testing.orig/xen/include/xen/softirq.h +++ xen-4.0.1-testing/xen/include/xen/softirq.h -@@ -50,15 +50,17 @@ struct tasklet +@@ -52,15 +52,17 @@ struct tasklet bool_t is_scheduled; bool_t is_running; bool_t is_dead; diff --git a/cpupools-core.patch b/cpupools-core.patch index 916383e..265539d 100644 --- a/cpupools-core.patch +++ b/cpupools-core.patch @@ -1,7 +1,9 @@ From: Juergen Gross ---- a/xen/arch/x86/acpi/power.c -+++ b/xen/arch/x86/acpi/power.c +Index: xen-4.0.1-testing/xen/arch/x86/acpi/power.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/acpi/power.c ++++ xen-4.0.1-testing/xen/arch/x86/acpi/power.c @@ -234,7 +234,7 @@ static int enter_state(u32 state) return error; } @@ -20,8 +22,10 @@ From: Juergen Gross } static int acpi_get_wake_status(void) ---- a/xen/arch/x86/domain.c -+++ b/xen/arch/x86/domain.c +Index: xen-4.0.1-testing/xen/arch/x86/domain.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/domain.c ++++ xen-4.0.1-testing/xen/arch/x86/domain.c @@ -1522,42 +1522,52 @@ void sync_vcpu_execstate(struct vcpu *v) } @@ -135,8 +139,10 @@ From: Juergen Gross return 0; } ---- a/xen/arch/x86/domain_build.c -+++ b/xen/arch/x86/domain_build.c +Index: xen-4.0.1-testing/xen/arch/x86/domain_build.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/domain_build.c ++++ xen-4.0.1-testing/xen/arch/x86/domain_build.c @@ -9,6 +9,7 @@ #include #include @@ -154,7 +160,7 @@ From: Juergen Gross if ( opt_dom0_max_vcpus > MAX_VIRT_CPUS ) opt_dom0_max_vcpus = MAX_VIRT_CPUS; -@@ -287,7 +288,7 @@ int __init construct_dom0( +@@ -296,7 +297,7 @@ int __init construct_dom0( unsigned long _initrd_start, unsigned long initrd_len, char *cmdline) { @@ -163,7 +169,7 @@ From: Juergen Gross struct cpu_user_regs *regs; unsigned long pfn, mfn; unsigned long nr_pages; -@@ -786,8 +787,12 @@ int __init construct_dom0( +@@ -795,8 +796,12 @@ int __init construct_dom0( printk("Dom0 has maximum %u VCPUs\n", opt_dom0_max_vcpus); @@ -177,8 +183,10 @@ From: Juergen Gross /* Set up CR3 value for write_ptbase */ if ( paging_mode_enabled(d) ) ---- a/xen/arch/x86/microcode.c -+++ b/xen/arch/x86/microcode.c +Index: xen-4.0.1-testing/xen/arch/x86/microcode.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/microcode.c ++++ xen-4.0.1-testing/xen/arch/x86/microcode.c @@ -114,7 +114,7 @@ static int microcode_update_cpu(const vo return err; } @@ -206,8 +214,10 @@ From: Juergen Gross + return continue_hypercall_on_cpu(info->cpu, NULL, + do_microcode_update, info); } ---- a/xen/arch/x86/mm.c -+++ b/xen/arch/x86/mm.c +Index: xen-4.0.1-testing/xen/arch/x86/mm.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/mm.c ++++ xen-4.0.1-testing/xen/arch/x86/mm.c @@ -243,7 +243,7 @@ void __init arch_init_memory(void) * Any Xen-heap pages that we will allow to be mapped will have * their domain field set to dom_xen. @@ -234,8 +244,10 @@ From: Juergen Gross BUG_ON(dom_cow == NULL); /* First 1MB of RAM is historically marked as I/O. */ ---- a/xen/arch/x86/platform_hypercall.c -+++ b/xen/arch/x86/platform_hypercall.c +Index: xen-4.0.1-testing/xen/arch/x86/platform_hypercall.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/platform_hypercall.c ++++ xen-4.0.1-testing/xen/arch/x86/platform_hypercall.c @@ -48,12 +48,12 @@ static DEFINE_PER_CPU(uint64_t, freq); extern int set_px_pminfo(uint32_t cpu, struct xen_processor_performance *perf); extern long set_cx_pminfo(uint32_t cpu, struct xen_processor_power *power); @@ -251,7 +263,7 @@ From: Juergen Gross { int cpu = (unsigned long)data; return cpu_down(cpu); -@@ -314,7 +314,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe +@@ -317,7 +317,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe if ( op->u.change_freq.flags || !cpu_online(op->u.change_freq.cpu) ) break; per_cpu(freq, op->u.change_freq.cpu) = op->u.change_freq.freq; @@ -260,7 +272,7 @@ From: Juergen Gross cpu_frequency_change_helper, NULL); break; -@@ -470,7 +470,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe +@@ -473,7 +473,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe break; } ret = continue_hypercall_on_cpu( @@ -269,8 +281,10 @@ From: Juergen Gross break; } break; ---- a/xen/arch/x86/setup.c -+++ b/xen/arch/x86/setup.c +Index: xen-4.0.1-testing/xen/arch/x86/setup.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/setup.c ++++ xen-4.0.1-testing/xen/arch/x86/setup.c @@ -2,6 +2,7 @@ #include #include @@ -288,7 +302,7 @@ From: Juergen Gross if ( idle_domain == NULL ) BUG(); idle_domain->vcpu = idle_vcpu; -@@ -1122,8 +1123,13 @@ void __init __start_xen(unsigned long mb +@@ -1121,8 +1122,13 @@ void __init __start_xen(unsigned long mb if ( !tboot_protect_mem_regions() ) panic("Could not protect TXT memory regions\n"); @@ -303,8 +317,10 @@ From: Juergen Gross if ( (dom0 == NULL) || (alloc_dom0_vcpu0() == NULL) ) panic("Error creating domain 0\n"); ---- a/xen/arch/x86/smpboot.c -+++ b/xen/arch/x86/smpboot.c +Index: xen-4.0.1-testing/xen/arch/x86/smpboot.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/smpboot.c ++++ xen-4.0.1-testing/xen/arch/x86/smpboot.c @@ -39,6 +39,7 @@ #include #include @@ -313,7 +329,7 @@ From: Juergen Gross #include #include #include -@@ -1306,10 +1307,11 @@ int __cpu_disable(void) +@@ -1305,10 +1306,11 @@ int __cpu_disable(void) __sync_lazy_execstate(); /* It's now safe to remove this processor from the online map */ @@ -326,7 +342,7 @@ From: Juergen Gross return 0; } -@@ -1341,16 +1343,12 @@ static int take_cpu_down(void *unused) +@@ -1340,16 +1342,12 @@ static int take_cpu_down(void *unused) int cpu_down(unsigned int cpu) { int err = 0; @@ -344,7 +360,7 @@ From: Juergen Gross /* Can not offline BSP */ if (cpu == 0) { err = -EINVAL; -@@ -1364,6 +1362,11 @@ int cpu_down(unsigned int cpu) +@@ -1363,6 +1361,11 @@ int cpu_down(unsigned int cpu) printk("Prepare to bring CPU%d down...\n", cpu); @@ -356,7 +372,7 @@ From: Juergen Gross cpufreq_del_cpu(cpu); err = stop_machine_run(take_cpu_down, NULL, cpu); -@@ -1379,6 +1382,8 @@ int cpu_down(unsigned int cpu) +@@ -1378,6 +1381,8 @@ int cpu_down(unsigned int cpu) out: if (!err) send_guest_global_virq(dom0, VIRQ_PCPU_STATE); @@ -365,7 +381,7 @@ From: Juergen Gross spin_unlock(&cpu_add_remove_lock); return err; } -@@ -1568,6 +1573,7 @@ int __devinit __cpu_up(unsigned int cpu) +@@ -1567,6 +1572,7 @@ int __devinit __cpu_up(unsigned int cpu) process_pending_softirqs(); } @@ -373,8 +389,10 @@ From: Juergen Gross cpufreq_add_cpu(cpu); return 0; } ---- a/xen/arch/x86/sysctl.c -+++ b/xen/arch/x86/sysctl.c +Index: xen-4.0.1-testing/xen/arch/x86/sysctl.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/sysctl.c ++++ xen-4.0.1-testing/xen/arch/x86/sysctl.c @@ -29,7 +29,7 @@ #define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) @@ -393,8 +411,10 @@ From: Juergen Gross break; case XEN_SYSCTL_CPU_HOTPLUG_STATUS: ret = 0; ---- a/xen/common/Makefile -+++ b/xen/common/Makefile +Index: xen-4.0.1-testing/xen/common/Makefile +=================================================================== +--- xen-4.0.1-testing.orig/xen/common/Makefile ++++ xen-4.0.1-testing/xen/common/Makefile @@ -1,5 +1,6 @@ obj-y += bitmap.o obj-y += cpu.o @@ -402,8 +422,10 @@ From: Juergen Gross obj-y += domctl.o obj-y += domain.o obj-y += event_channel.o +Index: xen-4.0.1-testing/xen/common/cpupool.c +=================================================================== --- /dev/null -+++ b/xen/common/cpupool.c ++++ xen-4.0.1-testing/xen/common/cpupool.c @@ -0,0 +1,609 @@ +/****************************************************************************** + * cpupool.c @@ -1014,8 +1036,10 @@ From: Juergen Gross + * indent-tabs-mode: nil + * End: + */ ---- a/xen/common/domain.c -+++ b/xen/common/domain.c +Index: xen-4.0.1-testing/xen/common/domain.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/common/domain.c ++++ xen-4.0.1-testing/xen/common/domain.c @@ -209,7 +209,7 @@ static void __init parse_extra_guest_irq custom_param("extra_guest_irqs", parse_extra_guest_irqs); @@ -1044,8 +1068,10 @@ From: Juergen Gross sched_destroy_domain(d); /* Free page used by xen oprofile buffer. */ ---- a/xen/common/domctl.c -+++ b/xen/common/domctl.c +Index: xen-4.0.1-testing/xen/common/domctl.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/common/domctl.c ++++ xen-4.0.1-testing/xen/common/domctl.c @@ -11,6 +11,7 @@ #include #include @@ -1121,8 +1147,10 @@ From: Juergen Gross if ( alloc_vcpu(d, i, cpu) == NULL ) goto maxvcpu_out; ---- a/xen/common/kexec.c -+++ b/xen/common/kexec.c +Index: xen-4.0.1-testing/xen/common/kexec.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/common/kexec.c ++++ xen-4.0.1-testing/xen/common/kexec.c @@ -235,7 +235,7 @@ void kexec_crash(void) BUG(); } @@ -1141,8 +1169,10 @@ From: Juergen Gross break; case KEXEC_TYPE_CRASH: kexec_crash(); /* Does not return */ ---- a/xen/common/sched_credit.c -+++ b/xen/common/sched_credit.c +Index: xen-4.0.1-testing/xen/common/sched_credit.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/common/sched_credit.c ++++ xen-4.0.1-testing/xen/common/sched_credit.c @@ -70,11 +70,15 @@ /* * Useful macros @@ -2031,7 +2061,7 @@ From: Juergen Gross .destroy_vcpu = csched_vcpu_destroy, .sleep = csched_vcpu_sleep, -@@ -1411,6 +1540,13 @@ const struct scheduler sched_credit_def +@@ -1411,6 +1540,13 @@ const struct scheduler sched_credit_def .dump_cpu_state = csched_dump_pcpu, .dump_settings = csched_dump, .init = csched_init, @@ -2045,8 +2075,10 @@ From: Juergen Gross .tick_suspend = csched_tick_suspend, .tick_resume = csched_tick_resume, ---- a/xen/common/sched_sedf.c -+++ b/xen/common/sched_sedf.c +Index: xen-4.0.1-testing/xen/common/sched_sedf.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/common/sched_sedf.c ++++ xen-4.0.1-testing/xen/common/sched_sedf.c @@ -21,6 +21,9 @@ printk(_a ); \ } while ( 0 ) @@ -2057,7 +2089,7 @@ From: Juergen Gross #ifndef NDEBUG #define SEDF_STATS #define CHECK(_p) \ -@@ -132,7 +135,7 @@ struct sedf_cpu_info { +@@ -131,7 +134,7 @@ struct sedf_cpu_info { #define sedf_runnable(edom) (!(EDOM_INFO(edom)->status & SEDF_ASLEEP)) @@ -2066,7 +2098,7 @@ From: Juergen Gross static inline int extraq_on(struct vcpu *d, int i) { -@@ -329,30 +332,17 @@ static inline void __add_to_runqueue_sor +@@ -328,30 +331,17 @@ static inline void __add_to_runqueue_sor } @@ -2103,7 +2135,7 @@ From: Juergen Gross /* Every VCPU gets an equal share of extratime by default. */ inf->deadl_abs = 0; inf->latency = 0; -@@ -383,39 +373,88 @@ static int sedf_init_vcpu(struct vcpu *v +@@ -382,39 +372,88 @@ static int sedf_init_vcpu(struct vcpu *v } else { @@ -2205,7 +2237,7 @@ From: Juergen Gross return first_cpu(online_affinity); } -@@ -751,7 +790,7 @@ static struct task_slice sedf_do_extra_s +@@ -750,7 +789,7 @@ static struct task_slice sedf_do_extra_s -timeslice for the current period used up -domain on waitqueue has started it's period -and various others ;) in general: determine which domain to run next*/ @@ -2214,7 +2246,7 @@ From: Juergen Gross { int cpu = smp_processor_id(); struct list_head *runq = RUNQ(cpu); -@@ -786,6 +825,13 @@ static struct task_slice sedf_do_schedul +@@ -785,6 +824,13 @@ static struct task_slice sedf_do_schedul } check_waitq: update_queues(now, runq, waitq); @@ -2228,7 +2260,7 @@ From: Juergen Gross /*now simply pick the first domain from the runqueue, which has the earliest deadline, because the list is sorted*/ -@@ -848,7 +894,7 @@ static struct task_slice sedf_do_schedul +@@ -847,7 +893,7 @@ static struct task_slice sedf_do_schedul } @@ -2237,7 +2269,7 @@ From: Juergen Gross { PRINT(2,"sedf_sleep was called, domain-id %i.%i\n", d->domain->domain_id, d->vcpu_id); -@@ -1067,7 +1113,7 @@ static inline int should_switch(struct v +@@ -1066,7 +1112,7 @@ static inline int should_switch(struct v return 1; } @@ -2246,7 +2278,7 @@ From: Juergen Gross { s_time_t now = NOW(); struct sedf_vcpu_info* inf = EDOM_INFO(d); -@@ -1220,8 +1266,8 @@ static void sedf_dump_domain(struct vcpu +@@ -1219,8 +1265,8 @@ static void sedf_dump_domain(struct vcpu } @@ -2257,7 +2289,7 @@ From: Juergen Gross { struct list_head *list, *queue, *tmp; struct sedf_vcpu_info *d_inf; -@@ -1294,7 +1340,7 @@ static void sedf_dump_cpu_state(int i) +@@ -1293,7 +1339,7 @@ static void sedf_dump_cpu_state(int i) /* Adjusts periods and slices of the domains accordingly to their weights. */ @@ -2266,7 +2298,7 @@ From: Juergen Gross { struct vcpu *p; struct domain *d; -@@ -1315,6 +1361,8 @@ static int sedf_adjust_weights(struct xe +@@ -1314,6 +1360,8 @@ static int sedf_adjust_weights(struct xe rcu_read_lock(&domlist_read_lock); for_each_domain( d ) { @@ -2275,7 +2307,7 @@ From: Juergen Gross for_each_vcpu( d, p ) { if ( EDOM_INFO(p)->weight ) -@@ -1366,7 +1414,7 @@ static int sedf_adjust_weights(struct xe +@@ -1365,7 +1413,7 @@ static int sedf_adjust_weights(struct xe /* set or fetch domain scheduling parameters */ @@ -2284,7 +2316,7 @@ From: Juergen Gross { struct vcpu *v; int rc; -@@ -1376,9 +1424,6 @@ static int sedf_adjust(struct domain *p, +@@ -1375,9 +1423,6 @@ static int sedf_adjust(struct domain *p, p->domain_id, op->u.sedf.period, op->u.sedf.slice, op->u.sedf.latency, (op->u.sedf.extratime)?"yes":"no"); @@ -2294,7 +2326,7 @@ From: Juergen Gross if ( op->cmd == XEN_DOMCTL_SCHEDOP_putinfo ) { /* Check for sane parameters. */ -@@ -1428,7 +1473,7 @@ static int sedf_adjust(struct domain *p, +@@ -1427,7 +1472,7 @@ static int sedf_adjust(struct domain *p, } } @@ -2303,7 +2335,7 @@ From: Juergen Gross if ( rc ) return rc; -@@ -1456,7 +1501,7 @@ static int sedf_adjust(struct domain *p, +@@ -1455,7 +1500,7 @@ static int sedf_adjust(struct domain *p, return 0; } @@ -2312,7 +2344,7 @@ From: Juergen Gross .name = "Simple EDF Scheduler", .opt_name = "sedf", .sched_id = XEN_SCHEDULER_SEDF, -@@ -1464,9 +1509,15 @@ const struct scheduler sched_sedf_def = +@@ -1463,9 +1508,15 @@ const struct scheduler sched_sedf_def = .init_domain = sedf_init_domain, .destroy_domain = sedf_destroy_domain, @@ -2329,8 +2361,10 @@ From: Juergen Gross .do_schedule = sedf_do_schedule, .pick_cpu = sedf_pick_cpu, .dump_cpu_state = sedf_dump_cpu_state, ---- a/xen/common/schedule.c -+++ b/xen/common/schedule.c +Index: xen-4.0.1-testing/xen/common/schedule.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/common/schedule.c ++++ xen-4.0.1-testing/xen/common/schedule.c @@ -53,10 +53,11 @@ static void poll_timer_fn(void *data); /* This is global for now so that private implementations can reach it */ @@ -2849,9 +2883,11 @@ From: Juergen Gross } #ifdef CONFIG_COMPAT ---- a/xen/common/softirq.c -+++ b/xen/common/softirq.c -@@ -88,9 +88,11 @@ void raise_softirq(unsigned int nr) +Index: xen-4.0.1-testing/xen/common/softirq.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/common/softirq.c ++++ xen-4.0.1-testing/xen/common/softirq.c +@@ -98,9 +98,11 @@ void raise_softirq(unsigned int nr) } static LIST_HEAD(tasklet_list); @@ -2864,7 +2900,7 @@ From: Juergen Gross { unsigned long flags; -@@ -101,28 +103,44 @@ void tasklet_schedule(struct tasklet *t) +@@ -111,28 +113,44 @@ void tasklet_schedule(struct tasklet *t) if ( !t->is_scheduled && !t->is_running ) { BUG_ON(!list_empty(&t->list)); @@ -2913,7 +2949,7 @@ From: Juergen Gross list_del_init(&t->list); BUG_ON(t->is_dead || t->is_running || !t->is_scheduled); -@@ -138,14 +156,15 @@ static void tasklet_action(void) +@@ -148,14 +166,15 @@ static void tasklet_action(void) if ( t->is_scheduled ) { BUG_ON(t->is_dead || !list_empty(&t->list)); @@ -2931,7 +2967,7 @@ From: Juergen Gross raise_softirq(TASKLET_SOFTIRQ); spin_unlock_irq(&tasklet_lock); -@@ -186,6 +205,12 @@ void tasklet_init( +@@ -196,6 +215,12 @@ void tasklet_init( void __init softirq_init(void) { @@ -2944,8 +2980,10 @@ From: Juergen Gross open_softirq(TASKLET_SOFTIRQ, tasklet_action); } ---- a/xen/common/sysctl.c -+++ b/xen/common/sysctl.c +Index: xen-4.0.1-testing/xen/common/sysctl.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/common/sysctl.c ++++ xen-4.0.1-testing/xen/common/sysctl.c @@ -314,6 +314,14 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc } break; @@ -2961,8 +2999,10 @@ From: Juergen Gross default: ret = arch_do_sysctl(op, u_sysctl); break; ---- a/xen/include/asm-x86/domain.h -+++ b/xen/include/asm-x86/domain.h +Index: xen-4.0.1-testing/xen/include/asm-x86/domain.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/include/asm-x86/domain.h ++++ xen-4.0.1-testing/xen/include/asm-x86/domain.h @@ -458,7 +458,8 @@ struct arch_vcpu #define hvm_svm hvm_vcpu.u.svm @@ -2973,8 +3013,10 @@ From: Juergen Gross void vcpu_show_execution_state(struct vcpu *); void vcpu_show_registers(const struct vcpu *); ---- a/xen/include/public/domctl.h -+++ b/xen/include/public/domctl.h +Index: xen-4.0.1-testing/xen/include/public/domctl.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/include/public/domctl.h ++++ xen-4.0.1-testing/xen/include/public/domctl.h @@ -60,10 +60,10 @@ struct xen_domctl_createdomain { /* Should domain memory integrity be verifed by tboot during Sx? */ #define _XEN_DOMCTL_CDF_s3_integrity 2 @@ -3003,8 +3045,10 @@ From: Juergen Gross struct xen_domctl { uint32_t cmd; #define XEN_DOMCTL_createdomain 1 ---- a/xen/include/public/sysctl.h -+++ b/xen/include/public/sysctl.h +Index: xen-4.0.1-testing/xen/include/public/sysctl.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/include/public/sysctl.h ++++ xen-4.0.1-testing/xen/include/public/sysctl.h @@ -491,6 +491,28 @@ struct xen_sysctl_lockprof_op { typedef struct xen_sysctl_lockprof_op xen_sysctl_lockprof_op_t; DEFINE_XEN_GUEST_HANDLE(xen_sysctl_lockprof_op_t); @@ -3042,8 +3086,10 @@ From: Juergen Gross uint8_t pad[128]; } u; }; ---- a/xen/include/xen/sched-if.h -+++ b/xen/include/xen/sched-if.h +Index: xen-4.0.1-testing/xen/include/xen/sched-if.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/include/xen/sched-if.h ++++ xen-4.0.1-testing/xen/include/xen/sched-if.h @@ -10,16 +10,26 @@ #include @@ -3135,8 +3181,10 @@ From: Juergen Gross +struct scheduler *scheduler_get_by_id(unsigned int id); + #endif /* __XEN_SCHED_IF_H__ */ ---- a/xen/include/xen/sched.h -+++ b/xen/include/xen/sched.h +Index: xen-4.0.1-testing/xen/include/xen/sched.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/include/xen/sched.h ++++ xen-4.0.1-testing/xen/include/xen/sched.h @@ -9,6 +9,7 @@ #include #include @@ -3145,7 +3193,7 @@ From: Juergen Gross #include #include #include -@@ -132,8 +133,6 @@ struct vcpu +@@ -132,8 +133,6 @@ struct vcpu bool_t defer_shutdown; /* VCPU is paused following shutdown request (d->is_shutting_down)? */ bool_t paused_for_shutdown; @@ -3218,9 +3266,11 @@ From: Juergen Gross #endif /* __SCHED_H__ */ /* ---- a/xen/include/xen/softirq.h -+++ b/xen/include/xen/softirq.h -@@ -58,6 +58,7 @@ struct tasklet +Index: xen-4.0.1-testing/xen/include/xen/softirq.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/include/xen/softirq.h ++++ xen-4.0.1-testing/xen/include/xen/softirq.h +@@ -60,6 +60,7 @@ struct tasklet struct tasklet name = { LIST_HEAD_INIT(name.list), 0, 0, 0, func, data } void tasklet_schedule(struct tasklet *t); diff --git a/del_usb_xend_entry.patch b/del_usb_xend_entry.patch index 2ddfc2f..ee7b62d 100644 --- a/del_usb_xend_entry.patch +++ b/del_usb_xend_entry.patch @@ -2,7 +2,7 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -1313,8 +1313,15 @@ class XendDomainInfo: +@@ -1312,8 +1312,15 @@ class XendDomainInfo: frontpath = self.getDeviceController(deviceClass).frontendPath(dev) backpath = xstransact.Read(frontpath, "backend") thread.start_new_thread(self.getDeviceController(deviceClass).finishDeviceCleanup, (backpath, path)) diff --git a/domUloader.py b/domUloader.py index 3100660..60fb82b 100644 --- a/domUloader.py +++ b/domUloader.py @@ -50,6 +50,18 @@ kpartx_args = '-p -part' # Helper functions +def kpartx_has_opt(opt): + """ Return True if kpartx supports option opt, otherwise False""" + have_opt = True + kpartx_cmd = 'kpartx -' + opt + ' 2>&1' + p = os.popen(kpartx_cmd) + for line in p.readlines(): + if line.find('invalid option') >= 0: + have_opt = False + break + p.close() + return have_opt + def error(s): print >> sys.stderr, "domUloader error: %s" % s @@ -75,6 +87,9 @@ def getWholedisk(part): # """Determines whether dev is a wholedisk dev""" # return not domUname[-1:].isdigit() +# If available, add '-f' option (bnc#613584) +if kpartx_has_opt('f'): + kpartx_args += ' -f' class Wholedisk: "Class representing a whole disk that may have partitions" diff --git a/hv_apic.patch b/hv_apic.patch deleted file mode 100644 index a3f670a..0000000 --- a/hv_apic.patch +++ /dev/null @@ -1,149 +0,0 @@ -Cleanup some APIC handling code in the HyperV shim. - -Signed-off-by: K. Y. Srinivasan - -Index: xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_intercept.c -=================================================================== ---- xen-4.0.1-testing.orig/xen/arch/x86/hvm/hyperv/hv_intercept.c 2010-10-04 14:04:46.000000000 -0600 -+++ xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_intercept.c 2010-10-04 18:30:42.000000000 -0600 -@@ -252,71 +252,6 @@ hv_get_max_vcpus_supported(void) - - - static inline void --hv_read_icr(u64 *icr_content) --{ -- unsigned long icr_low, icr_high; -- -- icr_low = vlapic_mmio_handler.read_handler(current, -- (vlapic_base_address(vcpu_vlapic(current)) + APIC_ICR), 4, &icr_low); -- icr_high = vlapic_mmio_handler.read_handler(current, -- (vlapic_base_address(vcpu_vlapic(current)) + APIC_ICR2), 4, &icr_high); -- *icr_content = (((u64)icr_high<< 32) | icr_low); -- --} -- --static inline void --hv_read_tpr(u64 *tpr_content) --{ -- -- vlapic_mmio_handler.read_handler(current, -- (vlapic_base_address(vcpu_vlapic(current)) + APIC_TASKPRI), -- 4, (unsigned long *)&tpr_content); --} -- --static inline void --hv_write_eoi(u64 msr_content) --{ -- u32 eoi = (u32)msr_content; -- -- vlapic_mmio_handler.write_handler(current, -- (vlapic_base_address(vcpu_vlapic(current)) + APIC_EOI), 4, eoi); -- --} -- --static inline void --hv_write_icr(u64 msr_content) --{ -- u32 icr_low, icr_high; -- icr_low = (u32)msr_content; -- icr_high = (u32)(msr_content >> 32); -- -- if (icr_high != 0) -- { -- vlapic_mmio_handler.write_handler(current, -- (vlapic_base_address(vcpu_vlapic(current)) + APIC_ICR2), 4, -- icr_high); -- } -- if (icr_low != 0) -- { -- vlapic_mmio_handler.write_handler(current, -- (vlapic_base_address(vcpu_vlapic(current)) + APIC_ICR), 4, -- icr_low); -- } -- --} -- --static inline void --hv_write_tpr(u64 msr_content) --{ -- u32 tpr = (u32)msr_content; -- -- -- vlapic_mmio_handler.write_handler(current, -- (vlapic_base_address(vcpu_vlapic(current)) + APIC_TASKPRI), 4, tpr); -- --} -- --static inline void - hv_hypercall_page_initialize(void *hypercall_page) - { - char *p; -@@ -810,21 +745,14 @@ hyperv_do_rd_msr(uint32_t idx, struct cp - regs->edx = (u32)(0x0); - break; - case HV_MSR_ICR: -- if (!hv_privilege_check(curp, HV_ACCESS_APIC_MSRS)) { -- goto msr_read_error; -- } -- hv_read_icr(&msr_content); -+ regs->eax = vlapic_get_reg(vcpu_vlapic(current), APIC_ICR); -+ regs->edx = vlapic_get_reg(vcpu_vlapic(current), APIC_ICR2); - #ifdef HV_STATS - cur_vcpu->stats.num_icr_reads++; - #endif -- regs->eax = (u32)(msr_content & 0xFFFFFFFF); -- regs->edx = (u32)(msr_content >> 32); - break; - case HV_MSR_TPR: -- if (!hv_privilege_check(curp, HV_ACCESS_APIC_MSRS)) { -- goto msr_read_error; -- } -- hv_read_tpr(&msr_content); -+ msr_content = vlapic_get_reg(vcpu_vlapic(current), APIC_TASKPRI); - #ifdef HV_STATS - cur_vcpu->stats.num_tpr_reads++; - #endif -@@ -922,28 +850,30 @@ hyperv_do_wr_msr(uint32_t idx, struct cp - goto msr_write_error; - - case HV_MSR_EOI: -- if (!hv_privilege_check(curp, HV_ACCESS_APIC_MSRS)) { -- goto msr_write_error; -- } -- hv_write_eoi(msr_content); -+ vlapic_EOI_set(vcpu_vlapic(current)); - #ifdef HV_STATS - cur_vcpu->stats.num_eoi_writes++; - #endif - break; -- case HV_MSR_ICR: -- if (!hv_privilege_check(curp, HV_ACCESS_APIC_MSRS)) { -- goto msr_write_error; -- } -- hv_write_icr(msr_content); -+ case HV_MSR_ICR: { -+ u32 eax = (u32)msr_content; -+ u32 edx = (u32)(msr_content >> 32); -+ struct vlapic *vlapic = vcpu_vlapic(current); -+ eax &= ~(1 << 12); -+ edx &= 0xff000000; -+ vlapic_set_reg(vlapic, APIC_ICR2, edx); -+ if ( vlapic_ipi(vlapic, eax, edx) == X86EMUL_OKAY ) -+ vlapic_set_reg(vlapic, APIC_ICR, eax); -+ break; -+ } -+ - #ifdef HV_STATS - cur_vcpu->stats.num_icr_writes++; - #endif - break; - case HV_MSR_TPR: -- if (!hv_privilege_check(curp, HV_ACCESS_APIC_MSRS)) { -- goto msr_write_error; -- } -- hv_write_tpr(msr_content); -+ vlapic_set_reg(vcpu_vlapic(current), APIC_TASKPRI, -+ (uint8_t)msr_content); - #ifdef HV_STATS - cur_vcpu->stats.num_tpr_writes++; - #endif diff --git a/hv_tools.patch b/hv_extid_compatibility.patch similarity index 63% rename from hv_tools.patch rename to hv_extid_compatibility.patch index 23985e3..8d841f3 100644 --- a/hv_tools.patch +++ b/hv_extid_compatibility.patch @@ -1,37 +1,3 @@ -Index: xen-4.0.1-testing/tools/python/xen/lowlevel/xc/xc.c -=================================================================== ---- xen-4.0.1-testing.orig/tools/python/xen/lowlevel/xc/xc.c -+++ xen-4.0.1-testing/tools/python/xen/lowlevel/xc/xc.c -@@ -944,16 +944,16 @@ static PyObject *pyxc_hvm_build(XcObject - #endif - int i; - char *image; -- int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1; -+ int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1, extid = 0; - PyObject *vcpu_avail_handle = NULL; - uint8_t vcpu_avail[(HVM_MAX_VCPUS + 7)/8]; - - static char *kwd_list[] = { "domid", -- "memsize", "image", "target", "vcpus", -- "vcpu_avail", "acpi", "apic", NULL }; -- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiOii", kwd_list, -+ "memsize", "image", "target", "vcpus", -+ "vcpu_avail", "extid", "acpi", "apic", NULL }; -+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiOiii", kwd_list, - &dom, &memsize, &image, &target, &vcpus, -- &vcpu_avail_handle, &acpi, &apic) ) -+ &vcpu_avail_handle, &extid, &acpi, &apic) ) - return NULL; - - memset(vcpu_avail, 0, sizeof(vcpu_avail)); -@@ -1005,6 +1005,7 @@ static PyObject *pyxc_hvm_build(XcObject - va_hvm->checksum -= sum; - munmap(va_map, XC_PAGE_SIZE); - #endif -+ xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_EXTEND_HYPERVISOR, extid); - - return Py_BuildValue("{}"); - } Index: xen-4.0.1-testing/tools/python/xen/xend/XendConfig.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/XendConfig.py @@ -44,6 +10,15 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendConfig.py 'rtc_timeoffset': int, 'parallel': str, 'serial': str, +@@ -509,6 +510,8 @@ class XendConfig(dict): + if self.is_hvm(): + if 'timer_mode' not in self['platform']: + self['platform']['timer_mode'] = 1 ++ if 'extid' in self['platform'] and int(self['platform']['extid']) == 1: ++ self['platform']['viridian'] = 1 + if 'viridian' not in self['platform']: + self['platform']['viridian'] = 0 + if 'rtc_timeoffset' not in self['platform']: Index: xen-4.0.1-testing/tools/python/xen/xend/image.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/image.py @@ -92,7 +67,18 @@ Index: xen-4.0.1-testing/tools/python/xen/xm/create.py 'usb', 'usbdevice', 'vcpus', 'vnc', 'vncconsole', 'vncdisplay', 'vnclisten', - 'vncunused', 'viridian', 'vpt_align', -+ 'vncunused', 'viridian', 'extid', 'vpt_align', ++ 'vncunused', 'vpt_align', 'xauthority', 'xen_extended_power_mgmt', 'xen_platform_pci', 'memory_sharing' ] +@@ -1100,6 +1104,10 @@ def configure_hvm(config_image, vals): + config_image.append([a, vals.__dict__[a]]) + if vals.vncpasswd is not None: + config_image.append(['vncpasswd', vals.vncpasswd]) ++ if vals.extid and vals.extid == 1: ++ config_image.append(['viridian', vals.extid]) ++ elif vals.viridian: ++ config_image.append(['viridian', vals.viridian]) + + + def make_config(vals): diff --git a/hv_win7_eoi_bug.patch b/hv_win7_eoi_bug.patch deleted file mode 100644 index 6d7ff3a..0000000 --- a/hv_win7_eoi_bug.patch +++ /dev/null @@ -1,29 +0,0 @@ -Index: xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_intercept.c -=================================================================== ---- xen-4.0.1-testing.orig/xen/arch/x86/hvm/hyperv/hv_intercept.c -+++ xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_intercept.c -@@ -33,6 +33,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -988,8 +989,15 @@ hyperv_do_wr_msr(uint32_t idx, struct cp - break; - case HV_MSR_APIC_ASSIST_PAGE: - /* -- * For now ignore this. -+ * We don't support the APIC assist page; windows7 appears to -+ * use this; set it up so that os uses the APIC MSR to indicate EOI. - */ -+ if (msr_content & 0x1) { -+ uint32_t data = 0; -+ paddr_t assist_page = msr_content & ~1UL; -+ (void)hvm_copy_to_guest_phys(assist_page, &data, sizeof(data)); -+ } -+ - break; - - default: diff --git a/hv_xen_base.patch b/hv_xen_base.patch deleted file mode 100644 index 441075c..0000000 --- a/hv_xen_base.patch +++ /dev/null @@ -1,203 +0,0 @@ -Index: xen-4.0.1-testing/xen/include/asm-x86/hvm/domain.h -=================================================================== ---- xen-4.0.1-testing.orig/xen/include/asm-x86/hvm/domain.h -+++ xen-4.0.1-testing/xen/include/asm-x86/hvm/domain.h -@@ -96,6 +96,7 @@ struct hvm_domain { - struct vmx_domain vmx; - struct svm_domain svm; - }; -+ void *hyperv_handle; /* will be NULL on creation*/ - }; - - #endif /* __ASM_X86_HVM_DOMAIN_H__ */ -Index: xen-4.0.1-testing/xen/arch/x86/hvm/Makefile -=================================================================== ---- xen-4.0.1-testing.orig/xen/arch/x86/hvm/Makefile -+++ xen-4.0.1-testing/xen/arch/x86/hvm/Makefile -@@ -1,5 +1,6 @@ - subdir-y += svm - subdir-y += vmx -+subdir-$(x86_64) += hyperv - - obj-y += asid.o - obj-y += emulate.o -Index: xen-4.0.1-testing/xen/arch/x86/hvm/hvm.c -=================================================================== ---- xen-4.0.1-testing.orig/xen/arch/x86/hvm/hvm.c -+++ xen-4.0.1-testing/xen/arch/x86/hvm/hvm.c -@@ -48,6 +48,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -435,6 +436,7 @@ void hvm_domain_relinquish_resources(str - - void hvm_domain_destroy(struct domain *d) - { -+ hyperx_intercept_domain_destroy(d); - hvm_funcs.domain_destroy(d); - rtc_deinit(d); - stdvga_deinit(d); -@@ -756,8 +758,14 @@ int hvm_vcpu_initialise(struct vcpu *v) - v->arch.hvm_vcpu.xfeature_mask = XSTATE_FP_SSE; - } - -+ if ((rc = hyperx_intercept_vcpu_initialize(v)) != 0) -+ goto fail1; -+ - if ( (rc = vlapic_init(v)) != 0 ) -+ { -+ hyperx_intercept_vcpu_destroy(v); - goto fail1; -+ } - - if ( (rc = hvm_funcs.vcpu_initialise(v)) != 0 ) - goto fail2; -@@ -808,12 +816,14 @@ int hvm_vcpu_initialise(struct vcpu *v) - hvm_funcs.vcpu_destroy(v); - fail2: - vlapic_destroy(v); -+ hyperx_intercept_vcpu_destroy(v); - fail1: - return rc; - } - - void hvm_vcpu_destroy(struct vcpu *v) - { -+ hyperx_intercept_vcpu_destroy(v); - tasklet_kill(&v->arch.hvm_vcpu.assert_evtchn_irq_tasklet); - hvm_vcpu_cacheattr_destroy(v); - vlapic_destroy(v); -@@ -1873,7 +1883,7 @@ void hvm_cpuid(unsigned int input, unsig - return; - - if ( cpuid_hypervisor_leaves(input, count, eax, ebx, ecx, edx) ) -- return; -+ goto hvm_cpuid_done; - - domain_cpuid(v->domain, input, *ecx, eax, ebx, ecx, edx); - -@@ -1940,6 +1950,8 @@ void hvm_cpuid(unsigned int input, unsig - *edx &= ~bitmaskof(X86_FEATURE_RDTSCP); - break; - } -+hvm_cpuid_done: -+ hyperx_intercept_do_cpuid(input, eax, ebx, ecx, edx); - } - - void hvm_rdtsc_intercept(struct cpu_user_regs *regs) -@@ -2040,6 +2052,8 @@ int hvm_msr_read_intercept(struct cpu_us - break; - /* ret == 0, This is not an MCE MSR, see other MSRs */ - else if (!ret) -+ if (hyperx_intercept_do_msr_read(ecx, regs)) -+ return X86EMUL_OKAY; - return hvm_funcs.msr_read_intercept(regs); - } - -@@ -2138,6 +2152,8 @@ int hvm_msr_write_intercept(struct cpu_u - else if ( ret ) - break; - else if (!ret) -+ if (hyperx_intercept_do_msr_write(ecx, regs)) -+ return X86EMUL_OKAY; - return hvm_funcs.msr_write_intercept(regs); - } - -@@ -2344,6 +2360,10 @@ int hvm_do_hypercall(struct cpu_user_reg - case 0: - break; - } -+ if (hyperx_intercept_do_hypercall(regs)) -+ { -+ return HVM_HCALL_completed; -+ } - - if ( (eax & 0x80000000) && is_viridian_domain(curr->domain) ) - return viridian_hypercall(regs); -@@ -2878,6 +2898,18 @@ long do_hvm_op(unsigned long op, XEN_GUE - rc = -EINVAL; - - break; -+ case HVM_PARAM_EXTEND_HYPERVISOR: -+#ifdef __x86_64__ -+ if (a.value != 1) -+ rc = -EINVAL; -+ else if (hyperv_initialize(d)) -+ rc = -ENOMEM; -+ else -+ break; -+#else -+ rc = -EINVAL; -+#endif -+ goto param_fail; - } - - if ( rc == 0 ) -Index: xen-4.0.1-testing/xen/include/public/arch-x86/hvm/save.h -=================================================================== ---- xen-4.0.1-testing.orig/xen/include/public/arch-x86/hvm/save.h -+++ xen-4.0.1-testing/xen/include/public/arch-x86/hvm/save.h -@@ -431,9 +431,24 @@ struct hvm_viridian_context { - - DECLARE_HVM_SAVE_TYPE(VIRIDIAN, 15, struct hvm_viridian_context); - -+struct hvm_hyperv_dom { -+ uint64_t guestid_msr; -+ uint64_t hypercall_msr; -+ uint32_t long_mode; -+ uint32_t ext_id; -+}; -+DECLARE_HVM_SAVE_TYPE(HYPERV_DOM, 16, struct hvm_hyperv_dom); -+ -+struct hvm_hyperv_cpu { -+ uint64_t control_msr; -+ uint64_t version_msr; -+ uint64_t pad[27]; //KYS: sles10 sp2 compatibility -+}; -+DECLARE_HVM_SAVE_TYPE(HYPERV_CPU, 17, struct hvm_hyperv_cpu); -+ - /* - * Largest type-code in use - */ --#define HVM_SAVE_CODE_MAX 15 -+#define HVM_SAVE_CODE_MAX 17 - - #endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */ -Index: xen-4.0.1-testing/xen/arch/x86/hvm/vlapic.c -=================================================================== ---- xen-4.0.1-testing.orig/xen/arch/x86/hvm/vlapic.c -+++ xen-4.0.1-testing/xen/arch/x86/hvm/vlapic.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -291,6 +292,7 @@ static int vlapic_accept_sipi(struct vcp - hvm_vcpu_reset_state(v, trampoline_vector << 8, 0); - - vcpu_unpause(v); -+ hyperx_intercept_vcpu_up(v); - - return X86EMUL_OKAY; - } -Index: xen-4.0.1-testing/xen/include/public/hvm/params.h -=================================================================== ---- xen-4.0.1-testing.orig/xen/include/public/hvm/params.h -+++ xen-4.0.1-testing/xen/include/public/hvm/params.h -@@ -109,6 +109,8 @@ - /* Boolean: Enable aligning all periodic vpts to reduce interrupts */ - #define HVM_PARAM_VPT_ALIGN 16 - --#define HVM_NR_PARAMS 17 -+#define HVM_PARAM_EXTEND_HYPERVISOR 17 -+ -+#define HVM_NR_PARAMS 18 - - #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff --git a/hv_xen_extension.patch b/hv_xen_extension.patch deleted file mode 100644 index a355338..0000000 --- a/hv_xen_extension.patch +++ /dev/null @@ -1,1776 +0,0 @@ -Index: xen-4.0.1-testing/xen/include/asm-x86/hvm/hvm_extensions.h -=================================================================== ---- /dev/null -+++ xen-4.0.1-testing/xen/include/asm-x86/hvm/hvm_extensions.h -@@ -0,0 +1,183 @@ -+/**************************************************************************** -+ | -+ | Copyright (c) [2007, 2008] Novell, Inc. -+ | All Rights Reserved. -+ | -+ | This program is free software; you can redistribute it and/or -+ | modify it under the terms of version 2 of the GNU General Public License as -+ | published by the Free Software Foundation. -+ | -+ | This program 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 General Public License for more details. -+ | -+ | You should have received a copy of the GNU General Public License -+ | along with this program; if not, contact Novell, Inc. -+ | -+ | To contact Novell about this file by physical or electronic mail, -+ | you may find current contact information at www.novell.com -+ | -+ |*************************************************************************** -+*/ -+ -+/* -+ * hvm_extensions.h -+ * Implement Hyperv extensions. -+ * Engineering Contact: K. Y. Srinivasan -+ */ -+ -+#ifndef HVM_EXTENSION_H -+#define HVM_EXTENSION_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+int -+hyperv_dom_create(struct domain *d); -+void -+hyperv_dom_destroy(struct domain *d); -+int -+hyperv_vcpu_initialize(struct vcpu *v); -+void -+hyperv_vcpu_up(struct vcpu *v); -+void -+hyperv_vcpu_destroy(struct vcpu *v); -+int -+hyperv_do_cpu_id(uint32_t input, unsigned int *eax, unsigned int *ebx, -+ unsigned int *ecx, unsigned int *edx); -+int -+hyperv_do_rd_msr(uint32_t idx, struct cpu_user_regs *regs); -+int -+hyperv_do_wr_msr(uint32_t idx, struct cpu_user_regs *regs); -+int -+hyperv_do_hypercall(struct cpu_user_regs *pregs); -+int -+hyperv_initialize(struct domain *d); -+ -+ -+ -+ -+static inline int -+hyperx_intercept_domain_create(struct domain *d) -+{ -+#ifdef __x86_64__ -+ if (d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] == 1) { -+ return(hyperv_dom_create(d)); -+ } -+#endif -+ return (0); -+} -+ -+static inline void -+hyperx_intercept_domain_destroy(struct domain *d) -+{ -+#ifdef __x86_64__ -+ if (d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] == 1) -+ { -+ hyperv_dom_destroy(d); -+ } -+#endif -+} -+ -+static inline int -+hyperx_intercept_vcpu_initialize(struct vcpu *v) -+{ -+#ifdef __x86_64__ -+ struct domain *d = v->domain; -+ if (d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] == 1) -+ { -+ return(hyperv_vcpu_initialize(v)); -+ } -+#endif -+ return (0); -+} -+ -+ -+static inline void -+hyperx_intercept_vcpu_up(struct vcpu *v) -+{ -+#ifdef __x86_64__ -+ struct domain *d = current->domain; -+ if (d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] == 1) -+ { -+ hyperv_vcpu_up(v); -+ } -+#endif -+} -+ -+static inline void -+hyperx_intercept_vcpu_destroy(struct vcpu *v) -+{ -+#ifdef __x86_64__ -+ struct domain *d = v->domain; -+ if (d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] == 1) -+ { -+ hyperv_vcpu_destroy(v); -+ } -+#endif -+} -+ -+static inline int -+hyperx_intercept_do_cpuid(uint32_t idx, unsigned int *eax, unsigned int *ebx, -+ unsigned int *ecx, unsigned int *edx) -+{ -+#ifdef __x86_64__ -+ struct domain *d = current->domain; -+ if (d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] == 1) -+ { -+ return(hyperv_do_cpu_id(idx, eax, ebx, ecx, edx)); -+ } -+#endif -+ return (0); -+} -+ -+static inline int -+hyperx_intercept_do_msr_read(uint32_t idx, struct cpu_user_regs *regs) -+{ -+#ifdef __x86_64__ -+ struct domain *d = current->domain; -+ if (d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] == 1) -+ { -+ return(hyperv_do_rd_msr(idx, regs)); -+ } -+#endif -+ return (0); -+} -+ -+static inline int -+hyperx_intercept_do_msr_write(uint32_t idx, struct cpu_user_regs *regs) -+{ -+#ifdef __x86_64__ -+ struct domain *d = current->domain; -+ if (d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] == 1) -+ { -+ return(hyperv_do_wr_msr(idx, regs)); -+ } -+#endif -+ return (0); -+} -+ -+static inline int -+hyperx_intercept_do_hypercall(struct cpu_user_regs *regs) -+{ -+#ifdef __x86_64__ -+ struct domain *d = current->domain; -+ if (d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] == 1) -+ { -+ return(hyperv_do_hypercall(regs)); -+ } -+#endif -+ return (0); -+} -+ -+int hyperx_initialize(struct domain *d); -+ -+#endif -Index: xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/Makefile -=================================================================== ---- /dev/null -+++ xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/Makefile -@@ -0,0 +1,2 @@ -+obj-y += hv_intercept.o -+obj-y += hv_hypercall.o -Index: xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_errno.h -=================================================================== ---- /dev/null -+++ xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_errno.h -@@ -0,0 +1,62 @@ -+/**************************************************************************** -+ | -+ | Copyright (c) [2007, 2008] Novell, Inc. -+ | All Rights Reserved. -+ | -+ | This program is free software; you can redistribute it and/or -+ | modify it under the terms of version 2 of the GNU General Public License as -+ | published by the Free Software Foundation. -+ | -+ | This program 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 General Public License for more details. -+ | -+ | You should have received a copy of the GNU General Public License -+ | along with this program; if not, contact Novell, Inc. -+ | -+ | To contact Novell about this file by physical or electronic mail, -+ | you may find current contact information at www.novell.com -+ | -+ |*************************************************************************** -+*/ -+ -+/* -+ * hv_errno.h -+ * Error codes for the Novell Shim. -+ * -+ * Engineering Contact: K. Y. Srinivasan -+ */ -+ -+#ifndef HV_ERRNO_H -+#define HV_ERRNO_H -+ -+#define HV_STATUS_SUCCESS 0x0000 -+#define HV_STATUS_INVALID_HYPERCALL_CODE 0x0002 -+#define HV_STATUS_INVALID_HYPERCALL_INPUT 0x0003 -+#define HV_STATUS_INVALID_ALIGNMENT 0x0004 -+#define HV_STATUS_INVALID_PARAMETER 0x0005 -+#define HV_STATUS_ACCESS_DENIED 0x0006 -+#define HV_STATUS_INVALID_PARTITION_STATE 0x0007 -+#define HV_STATUS_OPERATION_DENIED 0x0008 -+#define HV_STATUS_UNKNOWN_PROPERTY 0x0009 -+#define HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE 0x000A -+#define HV_STATUS_INSUFFICIENT_MEMORY 0x000B -+#define HV_STATUS_PARTITION_TOO_DEEP 0x000C -+#define HV_STATUS_INVALID_PARTITION_ID 0x000D -+#define HV_STATUS_INVALID_VP_INDEX 0x000E -+#define HV_STATUS_UNABLE_TO_RESTORE_STATE 0x000F -+#define HV_STATUS_NOT_FOUND 0x0010 -+#define HV_STATUS_INVALID_PORT_ID 0x0011 -+#define HV_STATUS_INVALID_CONNECTION_ID 0x0012 -+#define HV_STATUS_INSUFFICIENT_BUFFERS 0x0013 -+#define HV_STATUS_NOT_ACKNOWLEDGED 0x0014 -+#define HV_STATUS_INVALID_VP_STATE 0x0015 -+#define HV_STATUS_ACKNOWLEDGED 0x0016 -+#define HV_STATUS_INVALID_SAVE_RESTORE_STATE 0x0017 -+#define HV_STATUS_NO_MEMORY_4PAGES 0x0100 -+#define HV_STATUS_NO_MEMORY_16PAGES 0x0101 -+#define HV_STATUS_NO_MEMORY_64PAGES 0x0102 -+#define HV_STATUS_NO_MEMORY_256PAGES 0x0103 -+#define HV_STATUS_NO_MEMORY_1024PAGES 0x0104 -+#endif -Index: xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_hypercall.c -=================================================================== ---- /dev/null -+++ xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_hypercall.c -@@ -0,0 +1,153 @@ -+/**************************************************************************** -+ | -+ | Copyright (c) [2007, 2008] Novell, Inc. -+ | All Rights Reserved. -+ | -+ | This program is free software; you can redistribute it and/or -+ | modify it under the terms of version 2 of the GNU General Public License as -+ | published by the Free Software Foundation. -+ | -+ | This program 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 General Public License for more details. -+ | -+ | You should have received a copy of the GNU General Public License -+ | along with this program; if not, contact Novell, Inc. -+ | -+ | To contact Novell about this file by physical or electronic mail, -+ | you may find current contact information at www.novell.com -+ | -+ |*************************************************************************** -+*/ -+ -+/* -+ * nshypercall.c. -+ * This file implements the hypercall component of the hyperv Shim. -+ * -+ * Engineering Contact: K. Y. Srinivasan -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "hv_shim.h" -+#include "hv_errno.h" -+#include "hv_hypercall.h" -+ -+ -+void -+hv_print_stats(hv_partition_t *curp, int i) -+{ -+ hv_vcpu_t *v; -+ v = &curp->vcpu_state[i]; -+ printk("Printing stats for vcpu ID: %d\n", i); -+ -+ printk("Number of context switches: %lu\n", v->stats.num_switches); -+ printk("Number of long spin waits: %lu\n", v->stats.num_long_spinwaits); -+ printk("Number of TPR reads: %lu\n", v->stats.num_tpr_reads); -+ printk("Number of ICR reads: %lu\n", v->stats.num_icr_reads); -+ printk("Number of Eoi writes: %lu\n", v->stats.num_eoi_writes); -+ printk("Number of Tpr writes: %lu\n", v->stats.num_tpr_writes); -+ printk("Number of Icr writes: %lu\n", v->stats.num_icr_writes); -+ -+} -+ -+static int -+hv_switch_va(hv_vcpu_t *vcpup, int fast, paddr_t input) -+{ -+ paddr_t new_cr3; -+ int ret_val = HV_STATUS_SUCCESS; -+ -+ /* -+ * XXXKYS: the spec sys the asID is passed via memory at offset 0 of -+ * the page whose GPA is in the input register. However, it appears -+ * the current build of longhorn (longhorn-2007-02-06-x86_64-fv-02) -+ * passes the asID in the input register instead. Need to check if -+ * future builds do this. -+ * The fast bit defines how the parameter is passed. -+ */ -+ if (fast) -+ { -+ hvm_set_cr3(input); -+ } -+ else -+ { -+ /* -+ * Slow path; copy the new value. -+ */ -+ if (!hvm_copy_from_guest_phys(&new_cr3, input, sizeof(paddr_t))) -+ hvm_set_cr3(new_cr3); -+ else -+ ret_val = HV_STATUS_INVALID_PARAMETER; -+ } -+ -+#ifdef HV_STATS -+ vcpup->stats.num_switches++; -+#endif -+ return (ret_val); -+} -+ -+void -+hv_handle_hypercall(u64 opcode, u64 input, u64 output, -+ u64 *ret_val) -+{ -+ unsigned short verb; -+ int fast; -+ unsigned short rep_count; -+ unsigned short start_index; -+ hv_partition_t *curp = hv_get_current_partition(); -+ hv_vcpu_t *vcpup = &curp->vcpu_state[hv_get_current_vcpu_index()]; -+ u64 partition_id; -+ -+ fast = (int)((opcode >>16) & 0x1); -+ verb = (short)(opcode & 0xffff); -+ rep_count = (short)((opcode >>32) & 0xfff); -+ start_index = (short)((opcode >> 48) & 0xfff); -+ switch (verb) -+ { -+ case HV_GET_PARTITION_ID: -+ if (!hv_privilege_check(curp, HV_ACCESS_PARTITION_ID)) -+ { -+ *ret_val = -+ hv_build_hcall_retval(HV_STATUS_ACCESS_DENIED, 0); -+ return; -+ } -+ partition_id = (u64)current->domain->domain_id; -+ if (hvm_copy_to_guest_phys(output, &partition_id, 8)) -+ { -+ /* -+ * Invalid output area. -+ */ -+ *ret_val = -+ hv_build_hcall_retval(HV_STATUS_INVALID_PARAMETER, 0); -+ return; -+ } -+ *ret_val = hv_build_hcall_retval(HV_STATUS_SUCCESS, 0); -+ return; -+ case HV_SWITCH_VA: -+ *ret_val = hv_build_hcall_retval(hv_switch_va(vcpup, fast, input), 0); -+ return; -+ -+ case HV_NOTIFY_LONG_SPIN_WAIT: -+#ifdef HV_STATS -+ vcpup->stats.num_long_spinwaits++; -+#endif -+ do_sched_op_compat(SCHEDOP_yield, 0); -+ *ret_val = hv_build_hcall_retval(HV_STATUS_SUCCESS, 0); -+ return; -+ -+ default: -+ printk("Unkown/Unsupported hypercall: verb is: %d\n", verb); -+ *ret_val = -+ hv_build_hcall_retval(HV_STATUS_INVALID_HYPERCALL_CODE, 0); -+ return; -+ } -+} -Index: xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_hypercall.h -=================================================================== ---- /dev/null -+++ xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_hypercall.h -@@ -0,0 +1,46 @@ -+/**************************************************************************** -+ | -+ | Copyright (c) [2007, 2008] Novell, Inc. -+ | All Rights Reserved. -+ | -+ | This program is free software; you can redistribute it and/or -+ | modify it under the terms of version 2 of the GNU General Public License as -+ | published by the Free Software Foundation. -+ | -+ | This program 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 General Public License for more details. -+ | -+ | You should have received a copy of the GNU General Public License -+ | along with this program; if not, contact Novell, Inc. -+ | -+ | To contact Novell about this file by physical or electronic mail, -+ | you may find current contact information at www.novell.com -+ | -+ |*************************************************************************** -+*/ -+ -+/* -+ * hv_hypercall.h -+ * -+ * Engineering Contact: K. Y. Srinivasan -+ */ -+ -+#ifndef HV_HYPERCALL_H -+#define HV_HYPERCALL_H -+ -+ -+/* -+ * Hypercall verbs. -+ */ -+ -+#define HV_GET_PARTITION_PROPERTY 0x0044 -+#define HV_SET_PARTITION_PROPERTY 0x0045 -+#define HV_GET_PARTITION_ID 0x0046 -+#define HV_SWITCH_VA 0x0001 -+#define HV_FLUSH_VA 0x0002 -+#define HV_FLUSH_VA_LIST 0x0003 -+#define HV_NOTIFY_LONG_SPIN_WAIT 0x0008 -+ -+#endif /* HV_HYPERCALL_H */ -Index: xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_intercept.c -=================================================================== ---- /dev/null -+++ xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_intercept.c -@@ -0,0 +1,1009 @@ -+/**************************************************************************** -+ | -+ | Copyright (c) [2007, 2008] Novell, Inc. -+ | All Rights Reserved. -+ | -+ | This program is free software; you can redistribute it and/or -+ | modify it under the terms of version 2 of the GNU General Public License as -+ | published by the Free Software Foundation. -+ | -+ | This program 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 General Public License for more details. -+ | -+ | You should have received a copy of the GNU General Public License -+ | along with this program; if not, contact Novell, Inc. -+ | -+ | To contact Novell about this file by physical or electronic mail, -+ | you may find current contact information at www.novell.com -+ | -+ |*************************************************************************** -+*/ -+ -+/* -+ * nsintercept.c. -+ * This file implements the intercepts to support the Hyperv Shim. -+ * -+ * Engineering Contact: K. Y. Srinivasan -+ */ -+ -+#include -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+/* -+ * Local includes; extension specific. -+ */ -+#include "hv_errno.h" -+#include "hv_shim.h" -+ -+ -+/* -+ * Implement the Hyperv Shim. -+ */ -+ -+extern struct hvm_mmio_handler vlapic_mmio_handler; -+ -+ -+static inline void -+hv_hypercall_page_initialize(void *hypercall_page); -+ -+static inline void * -+get_virt_from_gmfn(struct domain *d, unsigned long gmfn) -+{ -+ unsigned long mfn = gmfn_to_mfn(d, gmfn); -+ if (mfn == INVALID_MFN) -+ return (NULL); -+ return (map_domain_page(mfn)); -+} -+ -+static inline void -+inject_interrupt(struct vcpu *v, int vector, int type) -+{ -+ struct vlapic *vlapic = vcpu_vlapic(v); -+ -+ /* -+ * XXXKYS: Check the trigger mode. -+ */ -+ if (vlapic_set_irq(vlapic, vector, 1)) -+ vcpu_kick(v); -+} -+ -+ -+static inline void -+hv_write_guestid_msr(hv_partition_t *curp, hv_vcpu_t *cur_vcpu, u64 msr_content) -+{ -+ curp->guest_id_msr = msr_content; -+ if (curp->guest_id_msr == 0) -+ { -+ /* -+ * Guest has cleared the guest ID; -+ * clear the hypercall page. -+ */ -+ if (curp->hypercall_msr) -+ cur_vcpu->flags &= ~HV_VCPU_UP; -+ } -+} -+ -+ -+static inline void -+hv_write_hypercall_msr(hv_partition_t *curp, -+ hv_vcpu_t *cur_vcpu, -+ u64 msr_content) -+{ -+ unsigned long gmfn; -+ void *hypercall_page; -+ struct domain *d = cur_vcpu->xen_vcpu->domain; -+ -+ spin_lock(&curp->lock); -+ gmfn = (msr_content >> 12); -+ if (curp->guest_id_msr == 0) -+ { -+ /* Nothing to do if the guest is not registered*/ -+ spin_unlock(&curp->lock); -+ return; -+ } -+ /* -+ * Guest is registered; see if we can turn-on the -+ * hypercall page. -+ * XXXKYS: Can the guest write the GPA in one call and -+ * subsequently enable it? Check. For now assume that all the -+ * info is specified in one call. -+ */ -+ if (((u32)msr_content & (0x00000001)) == 0) -+ { -+ /* -+ * The client is not enabling the hypercall; just -+ * ignore everything. -+ */ -+ spin_unlock(&curp->lock); -+ return; -+ } -+ hypercall_page = get_virt_from_gmfn(d,gmfn); -+ if (hypercall_page == NULL) -+ { -+ /* -+ * The guest specified a bogus GPA; inject a GP fault -+ * into the guest. -+ */ -+ hvm_inject_exception(TRAP_gp_fault, 0, 0); -+ spin_unlock(&curp->lock); -+ return; -+ } -+ hv_hypercall_page_initialize(hypercall_page); -+ unmap_domain_page(hypercall_page); -+ if (hvm_funcs.guest_x86_mode(current) == 8) -+ curp->long_mode_guest = 1; -+ else -+ curp->long_mode_guest = 0; -+ curp->hypercall_msr = msr_content; -+ spin_unlock(&curp->lock); -+ cur_vcpu->flags |= HV_VCPU_UP; -+} -+ -+ -+int -+hyperv_initialize(struct domain *d) -+{ -+ int i; -+ printk("Hyperv extensions initialized\n"); -+ if (hyperv_dom_create(d)) -+ { -+ printk("Hyperv dom create failed\n"); -+ return (1); -+ } -+ for (i = 0; i < d->max_vcpus; i++) -+ { -+ if (d->vcpu[i] != NULL) -+ { -+ if (hyperv_vcpu_initialize(d->vcpu[i])) -+ { -+ int j; -+ for (j= (i-1); j >=0; j--) -+ { -+ hyperv_vcpu_destroy(d->vcpu[j]); -+ } -+ hyperv_dom_destroy(d); -+ return (1); -+ } -+ } -+ } -+ return (0); -+} -+ -+static inline u64 -+hv_get_time_since_boot(hv_partition_t *curp) -+{ -+ u64 curTime = get_s_time(); -+ return ((curTime - curp->domain_boot_time)/100) ; -+} -+ -+static inline int -+hv_call_from_bios(void) -+{ -+ if (hvm_paging_enabled(current)) -+ return (0); -+ else -+ return (1); -+} -+ -+ -+static inline int -+hv_os_registered(void) -+{ -+ hv_partition_t *curp = hv_get_current_partition(); -+ return (curp->guest_id_msr != 0?1:0); -+} -+ -+ -+ -+static inline void -+hv_set_partition_privileges(hv_partition_t *hvpp) -+{ -+ /* -+ * This is based on the hypervisor spec under section 5.2.3. -+ */ -+ hvpp->privileges = HV_SHIM_PRIVILEGES; -+} -+ -+static inline u32 -+hv_get_recommendations(void) -+{ -+ /* -+ *For now we recommend all the features. Need to validate. -+ */ -+ if ( paging_mode_hap(current->domain)) -+ /* -+ * If HAP is enabled; the guest should not use TLB flush -+ * related enlightenments. -+ */ -+ return (USE_CSWITCH_HCALL | USE_APIC_MSRS | USE_RESET_MSR | USE_RELAXED_TIMING); -+ else -+ /* -+ * For now disable TLB flush enlightenments. -+ */ -+ return (USE_CSWITCH_HCALL | USE_APIC_MSRS | USE_RESET_MSR | USE_RELAXED_TIMING); -+} -+ -+static inline u32 -+hv_get_max_vcpus_supported(void) -+{ -+ return HVM_MAX_VCPUS; -+} -+ -+ -+static inline void -+hv_read_icr(u64 *icr_content) -+{ -+ unsigned long icr_low, icr_high; -+ -+ icr_low = vlapic_mmio_handler.read_handler(current, -+ (vlapic_base_address(vcpu_vlapic(current)) + APIC_ICR), 4, &icr_low); -+ icr_high = vlapic_mmio_handler.read_handler(current, -+ (vlapic_base_address(vcpu_vlapic(current)) + APIC_ICR2), 4, &icr_high); -+ *icr_content = (((u64)icr_high<< 32) | icr_low); -+ -+} -+ -+static inline void -+hv_read_tpr(u64 *tpr_content) -+{ -+ -+ vlapic_mmio_handler.read_handler(current, -+ (vlapic_base_address(vcpu_vlapic(current)) + APIC_TASKPRI), -+ 4, (unsigned long *)&tpr_content); -+} -+ -+static inline void -+hv_write_eoi(u64 msr_content) -+{ -+ u32 eoi = (u32)msr_content; -+ -+ vlapic_mmio_handler.write_handler(current, -+ (vlapic_base_address(vcpu_vlapic(current)) + APIC_EOI), 4, eoi); -+ -+} -+ -+static inline void -+hv_write_icr(u64 msr_content) -+{ -+ u32 icr_low, icr_high; -+ icr_low = (u32)msr_content; -+ icr_high = (u32)(msr_content >> 32); -+ -+ if (icr_high != 0) -+ { -+ vlapic_mmio_handler.write_handler(current, -+ (vlapic_base_address(vcpu_vlapic(current)) + APIC_ICR2), 4, -+ icr_high); -+ } -+ if (icr_low != 0) -+ { -+ vlapic_mmio_handler.write_handler(current, -+ (vlapic_base_address(vcpu_vlapic(current)) + APIC_ICR), 4, -+ icr_low); -+ } -+ -+} -+ -+static inline void -+hv_write_tpr(u64 msr_content) -+{ -+ u32 tpr = (u32)msr_content; -+ -+ -+ vlapic_mmio_handler.write_handler(current, -+ (vlapic_base_address(vcpu_vlapic(current)) + APIC_TASKPRI), 4, tpr); -+ -+} -+ -+static inline void -+hv_hypercall_page_initialize(void *hypercall_page) -+{ -+ char *p; -+ -+ memset(hypercall_page, 0, PAGE_SIZE); -+ p = (char *)(hypercall_page) ; -+ /* -+ * We need to differentiate hypercalls that are to be processed by Xen -+ * from those that need to be processed by the hyperV shim. Xen hypercalls -+ * use eax to pass the opcode; set the high order bit in eax for hypercalls -+ * destined for the hyperV shim (thanks Steven) -+ */ -+ *(u8 *)(p + 0) = 0x0d; /* eax or imm32 */ -+ *(u8 *)(p + 1) = 0x00; -+ *(u8 *)(p + 2) = 0x00; -+ *(u8 *)(p + 3) = 0x00; -+ *(u8 *)(p + 4) = 0x80; /* eax |= HYPERV_HCALL */ -+ -+ *(u8 *)(p + 5) = 0x0f; /* vmcall */ -+ *(u8 *)(p + 6) = 0x01; -+ if (boot_cpu_data.x86_vendor == 0) -+ *(u8 *)(p + 7) = 0xc1; -+ else -+ *(u8 *)(p + 7) = 0xd9; -+ *(u8 *)(p + 8) = 0xc3; /* ret */ -+} -+ -+static inline int -+hv_access_time_refcnt(hv_partition_t *curp, u64 *msr_content) -+{ -+ if (!hv_privilege_check(curp, HV_ACCESS_TIME_REF_CNT)) -+ { -+ /* -+ * The partition does not have the privilege to -+ * read this; return error. -+ */ -+ return (0); -+ } -+ *msr_content = hv_get_time_since_boot(curp); -+ return (1); -+} -+ -+ -+void -+hyperv_vcpu_up(struct vcpu *v) -+{ -+ hv_partition_t *curp = hv_get_current_partition(); -+ hv_vcpu_t *vcpup; -+ vcpup = &curp->vcpu_state[v->vcpu_id]; -+ vcpup->flags |= HV_VCPU_UP; -+} -+ -+int -+hyperv_do_hypercall(struct cpu_user_regs *pregs) -+{ -+ hv_partition_t *curp = hv_get_current_partition(); -+ hv_vcpu_t *vcpup; -+ int long_mode_guest = curp->long_mode_guest; -+ -+ if (pregs->_eax & HYPERV_HCALL) -+ { -+ u64 opcode, input, output, ret_val; -+ vcpup = &curp->vcpu_state[hv_get_current_vcpu_index()]; -+ -+ pregs->_eax &= ~HYPERV_HCALL; -+ /* -+ * This is an extension hypercall; process it; but first make -+ * sure that the CPU is in the right state for invoking -+ * the hypercall - protected mode at CPL 0. -+ */ -+ if (hv_invalid_cpu_state()) -+ { -+ hvm_inject_exception(TRAP_gp_fault, 0, 0); -+ ret_val = hv_build_hcall_retval(HV_STATUS_INVALID_VP_STATE, 0); -+ hv_set_syscall_retval(pregs, long_mode_guest, ret_val); -+ return (1); -+ } -+ if (long_mode_guest) -+ { -+ opcode = pregs->ecx; -+ input = pregs->edx; -+ output = pregs->r8; -+ } else -+ { -+ opcode = -+ ((((u64)pregs->edx) << 32) | ((u64)pregs->eax)); -+ input = -+ ((((u64)pregs->ebx) << 32) | ((u64)pregs->ecx)); -+ output = -+ ((((u64)pregs->edi) << 32) | ((u64)pregs->esi)); -+ } -+ hv_handle_hypercall(opcode, input, output, &ret_val); -+ hv_set_syscall_retval(pregs, long_mode_guest, ret_val); -+ return (1); -+ } -+ /* -+ * This hypercall page is not the page for the Veridian extension. -+ */ -+ return (0); -+} -+ -+ -+int -+hyperv_dom_create(struct domain *d) -+{ -+ hv_partition_t *hvpp; -+ hvpp = xmalloc_bytes(sizeof(hv_partition_t)); -+ if (hvpp == NULL) -+ { -+ printk("Hyprv Dom Create: Memory allocation failed\n"); -+ return (1); -+ } -+ memset(hvpp, 0, sizeof(*hvpp)); -+ spin_lock_init(&hvpp->lock); -+ /* -+ * Set the partition wide privilege; We can start with no privileges -+ * and progressively turn on fancier hypervisor features. -+ */ -+ hv_set_partition_privileges(hvpp); -+ /* -+ * Stash away pointer to our state in the hvm domain structure. -+ */ -+ d->arch.hvm_domain.hyperv_handle = hvpp; -+ hvpp->domain_boot_time = get_s_time(); -+ return (0); -+} -+ -+void -+hyperv_dom_destroy(struct domain *d) -+{ -+ int i; -+ hv_partition_t *curp = d->arch.hvm_domain.hyperv_handle; -+ printk("Hyper-V Domain Being Destroyed\n"); -+ ASSERT(curp != NULL); -+#ifdef HV_STATS -+ printk("DUMP STATS\n"); -+ for (i = 0; i < d->max_vcpus; i++) -+ if (d->vcpu[i] != NULL) -+ hv_print_stats(curp, i); -+#endif -+ -+ xfree(d->arch.hvm_domain.hyperv_handle); -+ d->arch.hvm_domain.hyperv_handle = NULL; -+} -+ -+int -+hyperv_vcpu_initialize(struct vcpu *v) -+{ -+ hv_vcpu_t *vcpup; -+ hv_partition_t *curp = v->domain->arch.hvm_domain.hyperv_handle; -+ vcpup = &curp->vcpu_state[v->vcpu_id]; -+ atomic_inc(&curp->vcpus_active); -+ if (v->vcpu_id == 0) -+ vcpup->flags |= HV_VCPU_BOOT_CPU; -+ /* -+ * Initialize all the synthetic MSRs corresponding to this VCPU. -+ * Note that all state is set to 0 to begin -+ * with. -+ */ -+ vcpup->version_msr = 0x00000001; -+ vcpup->xen_vcpu = v; -+ -+ return (0); -+} -+ -+void -+hyperv_vcpu_destroy(struct vcpu *v) -+{ -+ hv_vcpu_t *vcpup; -+ hv_partition_t *curp = v->domain->arch.hvm_domain.hyperv_handle; -+ -+ vcpup = &curp->vcpu_state[v->vcpu_id]; -+ atomic_dec(&curp->vcpus_active); -+ vcpup->flags &= ~HV_VCPU_UP; -+} -+ -+static int -+hyperv_vcpu_save(struct domain *d, hvm_domain_context_t *h) -+{ -+ struct vcpu *v; -+ struct hvm_hyperv_cpu ctxt; -+ -+ hv_vcpu_t *vcpup; -+ hv_partition_t *curp = d->arch.hvm_domain.hyperv_handle; -+ -+ if (curp == NULL) -+ return 0; -+ -+ for_each_vcpu(d, v) -+ { -+ vcpup = &curp->vcpu_state[v->vcpu_id]; -+ -+ /* -+ * We don't need to save state for a -+ * vcpu that is down; the restore -+ * code will leave it down if there is nothing saved. -+ */ -+ if ( test_bit(_VPF_down, &v->pause_flags) ) -+ continue; -+ ctxt.control_msr = vcpup->control_msr; -+ ctxt.version_msr = vcpup->version_msr; -+ if (hvm_save_entry(HYPERV_CPU, v->vcpu_id, h, &ctxt) != 0 ) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static int -+hyperv_vcpu_restore(struct domain *d, hvm_domain_context_t *h) -+{ -+ int vcpuid; -+ struct hvm_hyperv_cpu ctxt; -+ -+ hv_vcpu_t *vcpup; -+ hv_partition_t *curp = d->arch.hvm_domain.hyperv_handle; -+ -+ if (curp == NULL) -+ return 0; -+ /* Which vcpu is this? */ -+ vcpuid = hvm_load_instance(h); -+ vcpup = &curp->vcpu_state[vcpuid]; -+ ASSERT(vcpup != NULL); -+ if ( hvm_load_entry(HYPERV_CPU, h, &ctxt) != 0 ) -+ return -EINVAL; -+ -+ vcpup->control_msr = ctxt.control_msr; -+ vcpup->version_msr = ctxt.version_msr; -+ -+ vcpup->flags |= HV_VCPU_UP; -+ return 0; -+} -+ -+static int -+hyperv_dom_save(struct domain *d, hvm_domain_context_t *h) -+{ -+ struct hvm_hyperv_dom ctxt; -+ hv_partition_t *curp = d->arch.hvm_domain.hyperv_handle; -+ -+ if (curp == NULL) { -+ return 0; -+ } -+ -+ ctxt.guestid_msr = curp->guest_id_msr; -+ ctxt.hypercall_msr = curp->hypercall_msr; -+ ctxt.long_mode = curp->long_mode_guest; -+ ctxt.ext_id = d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR]; -+ return (hvm_save_entry(HYPERV_DOM, 0, h, &ctxt)); -+} -+ -+static int -+hyperv_dom_restore(struct domain *d, hvm_domain_context_t *h) -+{ -+ struct hvm_hyperv_dom ctxt; -+ hv_partition_t *curp; -+ void *hypercall_page; -+ -+ if ( hvm_load_entry(HYPERV_DOM, h, &ctxt) != 0 ) -+ return -EINVAL; -+ d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] = 1; -+ if (hyperv_initialize(d)) -+ return -EINVAL; -+ curp = d->arch.hvm_domain.hyperv_handle; -+ -+ curp->guest_id_msr = ctxt.guestid_msr; -+ curp->hypercall_msr = ctxt.hypercall_msr; -+ /* -+ * We may have migrated from a sles10 host; re-initialize the -+ * hypercall page. -+ */ -+ hypercall_page = get_virt_from_gmfn(d, (curp->hypercall_msr >>12)); -+ if (hypercall_page == NULL) -+ return -EINVAL; -+ hv_hypercall_page_initialize(hypercall_page); -+ unmap_domain_page(hypercall_page); -+ curp->long_mode_guest = ctxt.long_mode; -+ return 0; -+} -+ -+HVM_REGISTER_SAVE_RESTORE(HYPERV_DOM, hyperv_dom_save, hyperv_dom_restore, -+ 1, HVMSR_PER_DOM); -+ -+ -+HVM_REGISTER_SAVE_RESTORE(HYPERV_CPU,hyperv_vcpu_save,hyperv_vcpu_restore, -+ 1, HVMSR_PER_VCPU); -+ -+ -+static int -+hv_preprocess_cpuid_leaves(unsigned int input, unsigned int *eax, -+ unsigned int *ebx, unsigned int *ecx, -+ unsigned int *edx ) -+{ -+ struct domain *d = current->domain; -+ int extid = d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR]; -+ unsigned int count = *ecx; -+ -+ if (extid == 1) { -+ /* -+ * Enlightened Windows guest; need to remap and handle -+ * leaves used by PV front-end drivers. -+ */ -+ if ((input >= 0x40000000) && (input <= 0x40000005)) -+ return (0); -+ /* -+ * PV drivers use cpuid to query the hypervisor for details. On -+ * Windows we will use the following leaves for this: -+ * -+ * 4096: VMM Sinature (corresponds to 0x40000000 on Linux) -+ * 4097: VMM Version (corresponds to 0x40000001 on Linux) -+ * 4098: Hypercall details (corresponds to 0x40000002 on Linux) -+ */ -+ if ((input >= 0x40001000) && (input <= 0x40001002)) -+ { -+ /* Get rid of the offset and let xen handle it */ -+ input -= 0x1000; -+ cpuid_hypervisor_leaves(input, count, eax, ebx, ecx, edx); -+ /* Setup hypercall MSR value - add the offset*/ -+ if (input == 0x40000002) -+ *ebx |= 0x1000; -+ return (1); -+ } -+ } -+ return (0); -+} -+ -+int -+hyperv_do_cpu_id(unsigned int input, unsigned int *eax, unsigned int *ebx, -+ unsigned int *ecx, unsigned int *edx) -+{ -+ uint32_t idx; -+ hv_partition_t *curp = hv_get_current_partition(); -+ -+ /* -+ * hvmloader uses cpuid to set up a hypercall page; we don't want to -+ * intercept calls coming from the bootstrap (bios) code in the HVM -+ * guest; we discriminate based on if paging is enabled or not. -+ */ -+ if (hv_call_from_bios()) -+ /* -+ * We don't intercept this. -+ */ -+ return (0); -+ -+ if (input == 0x00000001) -+ { -+ *ecx |= 0x80000000; -+ return (1); -+ } -+ -+ if (hv_preprocess_cpuid_leaves(input, eax, ebx, ecx, edx)) -+ return (1); -+ idx = (input - 0x40000000); -+ -+ switch (idx) -+ { -+ case 0: -+ /* -+ * 0x40000000: Hypervisor identification. -+ */ -+ *eax = 0x40000005; /* For now clamp this */ -+ *ebx = 0x65766f4e; /* "Nove" */ -+ *ecx = 0x68536c6c; /* "llSh" */ -+ *edx = 0x76486d69; /* "imHv" */ -+ break; -+ -+ case 1: -+ /* -+ * 0x40000001: Hypervisor identification. -+ */ -+ *eax = 0x31237648; /* "Hv#1*/ -+ *ebx = 0; /* Reserved */ -+ *ecx = 0; /* Reserved */ -+ *edx = 0; /* Reserved */ -+ break; -+ case 2: -+ /* -+ * 0x40000002: Guest Info -+ */ -+ if (hv_os_registered()) -+ { -+ u64 guest_id = curp->guest_id_msr; -+ u32 guest_major, guest_minor; -+ -+ guest_major = ((guest_id >> 32) & 0xff); -+ guest_minor = ((guest_id >> 24) & 0xff); -+ *eax = (guest_id & 0xffff); /* Build # 15:0 */ -+ *ebx = -+ (guest_major << 16) | (guest_minor); /*Major: 31:16; Minor: 15:0*/ -+ *ecx = ((guest_id >>16) & 0xff); /*Service Pack/Version: 23:16*/ -+ /* -+ * Service branch (31:24)|Service number (23:0) -+ * Not sure what these numbers are: XXXKYS. -+ */ -+ *edx = 0; /*Service branch (31:24)|Service number (23:0) */ -+ } else -+ { -+ *eax = 0; -+ *ebx = 0; -+ *ecx = 0; -+ *edx = 0; -+ } -+ break; -+ case 3: -+ /* -+ * 0x40000003: Feature identification. -+ */ -+ *eax = HV_SHIM_SUPPORTED_MSRS; -+ /* We only support AcessSelfPartitionId bit 1 */ -+ *ebx = (HV_SHIM_PRIVILEGES>>32); -+ *ecx = 0; /* Reserved */ -+ *edx = 0; /*No MWAIT (bit 0), No debugging (bit 1)*/ -+ break; -+ case 4: -+ /* -+ * 0x40000004: Imlementation recommendations. -+ */ -+ *eax = hv_get_recommendations(); -+ *ebx = 2047; -+ *ebx = 0; /* Reserved */ -+ *ecx = 0; /* Reserved */ -+ *edx = 0; /* Reserved */ -+ break; -+ case 5: -+ /* -+ * 0x40000005: Implementation limits. -+ * Currently we retrieve maximum number of vcpus and -+ * logical processors (hardware threads) supported. -+ */ -+ *eax = hv_get_max_vcpus_supported(); -+ *ebx = 0; /* Reserved */ -+ *ecx = 0; /* Reserved */ -+ *edx = 0; /* Reserved */ -+ break; -+ case 6: -+ /* -+ * Implementation hardware features; for now set them all to zero. -+ */ -+ *eax = 0; -+ *ebx = 0; /* Reserved */ -+ *ecx = 0; /* Reserved */ -+ *edx = 0; /* Reserved */ -+ break; -+ -+ default: -+ /* -+ * We don't handle this leaf. -+ */ -+ return (0); -+ -+ } -+ return (1); -+} -+ -+int -+hyperv_do_rd_msr(uint32_t idx, struct cpu_user_regs *regs) -+{ -+ hv_partition_t *curp = hv_get_current_partition(); -+ unsigned int vcp_index = hv_get_current_vcpu_index(); -+ u64 msr_content = 0; -+ hv_vcpu_t *cur_vcpu = &curp->vcpu_state[vcp_index]; -+ -+ /* -+ * hvmloader uses rdmsr; we don't want to -+ * intercept calls coming from the bootstrap (bios) code in the HVM -+ * guest; we descriminate based on the instruction pointer. -+ */ -+ if (hv_call_from_bios()) -+ /* -+ * We don't intercept this. -+ */ -+ return (0); -+ switch (idx) -+ { -+ case HV_MSR_GUEST_OS_ID: -+ spin_lock(&curp->lock); -+ regs->eax = (u32)(curp->guest_id_msr & 0xFFFFFFFF); -+ regs->edx = (u32)(curp->guest_id_msr >> 32); -+ spin_unlock(&curp->lock); -+ break; -+ case HV_MSR_HYPERCALL: -+ spin_lock(&curp->lock); -+ regs->eax = (u32)(curp->hypercall_msr & 0xFFFFFFFF); -+ regs->edx = (u32)(curp->hypercall_msr >> 32); -+ spin_unlock(&curp->lock); -+ if ((((u32)curp->hypercall_msr) & (0x00000001)) != 0) { -+ cur_vcpu->flags |= HV_VCPU_UP; -+ } -+ break; -+ case HV_MSR_VP_INDEX: -+ regs->eax = (u32)(vcp_index); -+ regs->edx = (u32)(0x0); -+ break; -+ case HV_MSR_ICR: -+ if (!hv_privilege_check(curp, HV_ACCESS_APIC_MSRS)) { -+ goto msr_read_error; -+ } -+ hv_read_icr(&msr_content); -+#ifdef HV_STATS -+ cur_vcpu->stats.num_icr_reads++; -+#endif -+ regs->eax = (u32)(msr_content & 0xFFFFFFFF); -+ regs->edx = (u32)(msr_content >> 32); -+ break; -+ case HV_MSR_TPR: -+ if (!hv_privilege_check(curp, HV_ACCESS_APIC_MSRS)) { -+ goto msr_read_error; -+ } -+ hv_read_tpr(&msr_content); -+#ifdef HV_STATS -+ cur_vcpu->stats.num_tpr_reads++; -+#endif -+ regs->eax = (u32)(msr_content & 0xFFFFFFFF); -+ regs->edx = (u32)(msr_content >> 32); -+ break; -+ /* -+ * The following synthetic MSRs are implemented in the Novell Shim. -+ */ -+ case HV_MSR_SCONTROL: -+ if (!hv_privilege_check(curp, HV_ACCESS_SYNC_MSRS)) { -+ goto msr_read_error; -+ } -+ regs->eax = (u32)(cur_vcpu->control_msr & 0xFFFFFFFF); -+ regs->edx = (u32)(cur_vcpu->control_msr >> 32); -+ break; -+ case HV_MSR_SVERSION: -+ if (!hv_privilege_check(curp, HV_ACCESS_SYNC_MSRS)) { -+ goto msr_read_error; -+ } -+ regs->eax = (u32)(cur_vcpu->version_msr & 0xFFFFFFFF); -+ regs->edx = (u32)(cur_vcpu->version_msr >> 32); -+ break; -+ case HV_MSR_TIME_REF_COUNT: -+ if (!hv_access_time_refcnt(curp, &msr_content)) { -+ goto msr_read_error; -+ } -+ regs->eax = (u32)(msr_content & 0xFFFFFFFF); -+ regs->edx = (u32)(msr_content >> 32); -+ break; -+ case HV_MSR_PVDRV_HCALL: -+ regs->eax = 0; -+ regs->edx = 0; -+ break; -+ case HV_MSR_SYSTEM_RESET: -+ regs->eax = 0; -+ regs->edx = 0; -+ break; -+ case HV_MSR_APIC_ASSIST_PAGE: -+ /* -+ * For now ignore this. -+ */ -+ regs->eax = 0; -+ regs->edx = 0; -+ break; -+ default: -+ /* -+ * We did not handle the MSR address specified; -+ * let the caller figure out -+ * What to do. -+ */ -+ return (0); -+ } -+ return (1); -+msr_read_error: -+ /* -+ * Have to inject #GP fault. -+ */ -+ hvm_inject_exception(TRAP_gp_fault, 0, 0); -+ return (1); -+} -+ -+int -+hyperv_do_wr_msr(uint32_t idx, struct cpu_user_regs *regs) -+{ -+ hv_partition_t *curp = hv_get_current_partition(); -+ unsigned int vcp_index = hv_get_current_vcpu_index(); -+ u64 msr_content = 0; -+ hv_vcpu_t *cur_vcpu = &curp->vcpu_state[vcp_index]; -+ struct domain *d = current->domain; -+ -+ /* -+ * hvmloader uses wrmsr; we don't want to -+ * intercept calls coming from the bootstrap (bios) code in the HVM -+ * guest; we descriminate based on the instruction pointer. -+ */ -+ if (hv_call_from_bios()) -+ /* -+ * We don't intercept this. -+ */ -+ return (0); -+ msr_content = -+ (u32)regs->eax | ((u64)regs->edx << 32); -+ -+ switch (idx) -+ { -+ case HV_MSR_GUEST_OS_ID: -+ hv_write_guestid_msr(curp, cur_vcpu, msr_content); -+ break; -+ case HV_MSR_HYPERCALL: -+ hv_write_hypercall_msr(curp, cur_vcpu, msr_content); -+ break; -+ -+ case HV_MSR_VP_INDEX: -+ goto msr_write_error; -+ -+ case HV_MSR_EOI: -+ if (!hv_privilege_check(curp, HV_ACCESS_APIC_MSRS)) { -+ goto msr_write_error; -+ } -+ hv_write_eoi(msr_content); -+#ifdef HV_STATS -+ cur_vcpu->stats.num_eoi_writes++; -+#endif -+ break; -+ case HV_MSR_ICR: -+ if (!hv_privilege_check(curp, HV_ACCESS_APIC_MSRS)) { -+ goto msr_write_error; -+ } -+ hv_write_icr(msr_content); -+#ifdef HV_STATS -+ cur_vcpu->stats.num_icr_writes++; -+#endif -+ break; -+ case HV_MSR_TPR: -+ if (!hv_privilege_check(curp, HV_ACCESS_APIC_MSRS)) { -+ goto msr_write_error; -+ } -+ hv_write_tpr(msr_content); -+#ifdef HV_STATS -+ cur_vcpu->stats.num_tpr_writes++; -+#endif -+ break; -+ -+ /* -+ * The following MSRs are synthetic MSRs supported in the Novell Shim. -+ */ -+ case HV_MSR_SCONTROL: -+ if (!hv_privilege_check(curp, HV_ACCESS_SYNC_MSRS)) { -+ goto msr_write_error; -+ } -+ cur_vcpu->control_msr = msr_content; -+ break; -+ case HV_MSR_SVERSION: -+ if (!hv_privilege_check(curp, HV_ACCESS_SYNC_MSRS)) { -+ goto msr_write_error; -+ } -+ /* -+ * This is a read-only MSR; generate #GP -+ */ -+ hvm_inject_exception(TRAP_gp_fault, 0, 0); -+ break; -+ case HV_MSR_TIME_REF_COUNT: -+ /* -+ * This is a read-only msr. -+ */ -+ goto msr_write_error; -+ break; -+ case HV_MSR_PVDRV_HCALL: -+ /* -+ * Establish the hypercall page for PV drivers. -+ */ -+ wrmsr_hypervisor_regs(0x40000000, msr_content); -+ break; -+ case HV_MSR_SYSTEM_RESET: -+ /* -+ * Shutdown the domain/partition. -+ */ -+ if (msr_content & 0x1) { -+ domain_shutdown(d, SHUTDOWN_reboot); -+ } -+ break; -+ case HV_MSR_APIC_ASSIST_PAGE: -+ /* -+ * For now ignore this. -+ */ -+ break; -+ -+ default: -+ /* -+ * We did not handle the MSR address; -+ * let the caller deal with this. -+ */ -+ return (0); -+ } -+ return (1); -+msr_write_error: -+ /* -+ * Have to inject #GP fault. -+ */ -+ hvm_inject_exception(TRAP_gp_fault, 0, 0); -+ return (1); -+} -Index: xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_shim.h -=================================================================== ---- /dev/null -+++ xen-4.0.1-testing/xen/arch/x86/hvm/hyperv/hv_shim.h -@@ -0,0 +1,286 @@ -+/**************************************************************************** -+ | -+ | Copyright (c) [2007, 2008] Novell, Inc. -+ | All Rights Reserved. -+ | -+ | This program is free software; you can redistribute it and/or -+ | modify it under the terms of version 2 of the GNU General Public License as -+ | published by the Free Software Foundation. -+ | -+ | This program 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 General Public License for more details. -+ | -+ | You should have received a copy of the GNU General Public License -+ | along with this program; if not, contact Novell, Inc. -+ | -+ | To contact Novell about this file by physical or electronic mail, -+ | you may find current contact information at www.novell.com -+ | -+ |*************************************************************************** -+*/ -+ -+/* -+ * Hyperv Shim Implementation. -+ * -+ * Engineering Contact: K. Y. Srinivasan -+ */ -+ -+#ifndef HV_SHIM_H -+#define HV_SHIM_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "hv_hypercall.h" -+ -+/* -+ * Synthetic MSR addresses -+ */ -+#define HV_MSR_GUEST_OS_ID 0x40000000 -+#define HV_MSR_HYPERCALL 0x40000001 -+#define HV_MSR_VP_INDEX 0x40000002 -+#define HV_MSR_SYSTEM_RESET 0x40000003 -+#define HV_MSR_TIME_REF_COUNT 0x40000020 -+#define HV_MSR_EOI 0x40000070 -+#define HV_MSR_ICR 0x40000071 -+#define HV_MSR_TPR 0x40000072 -+#define HV_MSR_APIC_ASSIST_PAGE 0x40000073 -+ -+#define HV_MSR_SCONTROL 0x40000080 -+#define HV_MSR_SVERSION 0x40000081 -+#define HV_MSR_SIEFP 0x40000082 -+#define HV_MSR_SIMP 0x40000083 -+#define HV_MSR_SEOM 0x40000084 -+#define HV_MSR_SINT0 0x40000090 -+#define HV_MSR_SINT1 0x40000091 -+#define HV_MSR_SINT2 0x40000092 -+#define HV_MSR_SINT3 0x40000093 -+#define HV_MSR_SINT4 0x40000094 -+#define HV_MSR_SINT5 0x40000095 -+#define HV_MSR_SINT6 0x40000096 -+#define HV_MSR_SINT7 0x40000097 -+#define HV_MSR_SINT8 0x40000098 -+#define HV_MSR_SINT9 0x40000099 -+#define HV_MSR_SINT10 0x4000009A -+#define HV_MSR_SINT11 0x4000009B -+#define HV_MSR_SINT12 0x4000009C -+#define HV_MSR_SINT13 0x4000009D -+#define HV_MSR_SINT14 0x4000009E -+#define HV_MSR_SINT15 0x4000009F -+ -+#define HV_MSR_TIMER0_CONFIG 0x400000B0 -+#define HV_MSR_TIMER0_COUNT 0x400000B1 -+#define HV_MSR_TIMER1_CONFIG 0x400000B2 -+#define HV_MSR_TIMER1_COUNT 0x400000B3 -+#define HV_MSR_TIMER2_CONFIG 0x400000B4 -+#define HV_MSR_TIMER2_COUNT 0x400000B5 -+#define HV_MSR_TIMER3_CONFIG 0x400000B6 -+#define HV_MSR_TIMER3_COUNT 0x400000B7 -+ -+/* -+ * Domain privilege flags -+ */ -+ -+#define _ACCESS_VP_RUNTIME 0 -+#define ACCESS_VP_RUNTIME (1L<<_ACCESS_VP_RUNTIME) -+#define _ACCESS_TIME_REF_COUNT 1 -+#define ACCESS_TIME_REF_COUNT (1L<<_ACCESS_TIME_REF_COUNT) -+#define _ACCESS_SYNIC_MSRS 2 -+#define ACCESS_SYNIC_MSRS (1L<<_ACCESS_TIME_REF_COUNT) -+#define _ACCESS_SYNTHETIC_TIMERS 3 -+#define ACCESS_SYNTHETIC_TIMERS (1L<<_ACCESS_SYNTHETIC_TIMERS) -+#define _ACCESS_APIC_MSRS 4 -+#define ACCESS_APIC_MSRS (1L<<_ACCESS_APIC_MSRS) -+#define _ACCESS_HYPERCALL_MSRS 5 -+#define ACCESS_HYPERCALL_MSRS (1L<<_ACCESS_HYPERCALL_MSRS) -+#define _ACCESS_VP_INDEX 6 -+#define ACCESS_VP_INDEX (1L<<_ACCESS_VP_INDEX) -+#define _ACCESS_SELF_PARTITION_ID 33 -+#define ACCESS_SELF_PARTITION_ID (1L<<_ACCESS_SELF_PARTITION_ID) -+ -+#define HV_SHIM_PRIVILEGES \ -+ (ACCESS_TIME_REF_COUNT | ACCESS_APIC_MSRS | ACCESS_HYPERCALL_MSRS | \ -+ ACCESS_VP_INDEX |ACCESS_SELF_PARTITION_ID) -+ -+/* -+ * Guest recommendations -+ */ -+#define _USE_CSWITCH_HCALL 0 -+#define USE_CSWITCH_HCALL (1U<<_USE_CSWITCH_HCALL) -+#define _USE_TLBFLUSH_HCALL 1 -+#define USE_TLBFLUSH_HCALL (1U<<_USE_TLBFLUSH_HCALL) -+#define _USE_REMOTE_TLBFLUSH_HCALL 2 -+#define USE_REMOTE_TLBFLUSH_HCALL (1U<<_USE_REMOTE_TLBFLUSH_HCALL) -+#define _USE_APIC_MSRS 3 -+#define USE_APIC_MSRS (1U<<_USE_APIC_MSRS) -+#define _USE_RESET_MSR 4 -+#define USE_RESET_MSR (1U<<_USE_RESET_MSR) -+#define _USE_RELAXED_TIMING 5 -+#define USE_RELAXED_TIMING (1U<<_USE_RELAXED_TIMING) -+ -+/* -+ * Supported Synthetic MSRs. 0.83 HyperV spec, section 3.4 -+ * Supported features. -+ */ -+#define _MSR_VP_RUNTIME 0 -+#define MSR_VP_RUNTIME (1U<<_MSR_VP_RUNTIME) -+#define _MSR_TIME_REF_CNT 1 -+#define MSR_TIME_REF_CNT (1U<<_MSR_TIME_REF_CNT) -+#define _MSR_SYN_IC 2 -+#define MSR_SYN_IC (1U<<_MSR_SYN_IC) -+#define _MSR_SYN_TIMER 3 -+#define MSR_SYN_TIMER (1U<<_MSR_SYN_TIMER) -+#define _APIC_MSRS 4 -+#define APIC_MSRS (1U<<_APIC_MSRS) -+#define _HYPERCALL_MSRS 5 -+#define HYPERCALL_MSRS (1U<<_HYPERCALL_MSRS) -+#define _MSR_VP_INDEX 6 -+#define MSR_VP_INDEX (1U<<_MSR_VP_INDEX) -+#define _RESET_MSR 7 -+#define RESET_MSR (1U<<_RESET_MSR) -+ -+#define HV_SHIM_SUPPORTED_MSRS \ -+ (MSR_TIME_REF_CNT|APIC_MSRS|HYPERCALL_MSRS|MSR_VP_INDEX|RESET_MSR) -+ -+/* -+ * MSR for supporting PV drivers on longhorn. -+ */ -+#define HV_MSR_PVDRV_HCALL 0x40001000 -+ -+/* -+ * Tag for HyperV hcalls. -+ */ -+#define HYPERV_HCALL 0x80000000 -+ -+/* -+ * Hyperv Shim VCPU flags. -+ */ -+#define HV_VCPU_BOOT_CPU 0x00000001 -+#define HV_VCPU_UP 0x00000002 -+ -+ -+/* -+ * Stats structure. -+ */ -+ -+typedef struct { -+ u64 num_switches; -+ u64 num_long_spinwaits; -+ u64 num_tpr_reads; -+ u64 num_icr_reads; -+ u64 num_eoi_writes; -+ u64 num_tpr_writes; -+ u64 num_icr_writes; -+} hv_vcpu_stats_t; -+ -+typedef struct hv_vcpu { -+ /* -+ * Per-vcpu state to support the hyperv shim; -+ */ -+ unsigned long flags; -+ /* -+ * Synthetic msrs. -+ */ -+ u64 control_msr; -+ u64 version_msr; -+ struct vcpu *xen_vcpu; /*corresponding xen vcpu*/ -+ hv_vcpu_stats_t stats; -+} hv_vcpu_t; -+ -+ -+#define HV_STATS //KYS: Temporary -+ -+typedef struct hv_partition { -+ /* -+ * State maintained on a per guest basis to implement -+ * the Hyperv shim. -+ */ -+ s_time_t domain_boot_time; -+ spinlock_t lock; -+ atomic_t vcpus_active; -+ u64 guest_id_msr; -+ u64 hypercall_msr; -+ u64 privileges; -+ int long_mode_guest; -+ /* -+ * Each VCPU here corresponds to the vcpu in the underlying hypervisor; -+ * they share the same ID. -+ */ -+ hv_vcpu_t vcpu_state[HVM_MAX_VCPUS]; -+} hv_partition_t; -+ -+ -+/* -+ * Privilege flags. -+ */ -+ -+#define HV_ACCESS_VP_RUNTIME (1ULL << 0) -+#define HV_ACCESS_TIME_REF_CNT (1ULL << 1) -+#define HV_ACCESS_SYNC_MSRS (1ULL << 2) -+#define HV_ACCESS_SYNC_TIMERS (1ULL << 3) -+#define HV_ACCESS_APIC_MSRS (1ULL << 4) -+#define HV_ACCESS_PARTITION_ID (1ULL << 33) -+ -+#define hv_get_current_partition() \ -+((current)->domain->arch.hvm_domain.hyperv_handle) -+ -+#define hv_get_current_vcpu_index() (current)->vcpu_id -+ -+ -+static inline int -+hv_invalid_cpu_state(void) -+{ -+ int state; -+ state = hvm_funcs.guest_x86_mode(current); -+ if ((state == 4) || (state == 8)) -+ { -+ return (0); -+ } -+ return (1); -+} -+ -+static inline u64 -+hv_build_hcall_retval(int code, int reps) -+{ -+ u64 ret_val=0; -+ ret_val |= (code & 0xff); -+ ret_val |= (((long long)(reps & 0xfff)) << 32); -+ return (ret_val); -+} -+ -+static inline void hv_set_syscall_retval(struct cpu_user_regs *pregs, -+ int long_mode, u64 ret_val) -+{ -+ if (long_mode) -+ { -+ pregs->eax = ret_val; -+ } -+ else -+ { -+ pregs->edx = (u32)(ret_val >> 32); -+ pregs->eax = (u32)(ret_val); -+ } -+} -+ -+static inline int -+hv_privilege_check(hv_partition_t *curp, u64 flags) -+{ -+ return ((curp->privileges & flags)? 1: 0); -+} -+ -+void -+hv_handle_hypercall(u64 opcode, u64 input, u64 output, -+ u64 *ret_val); -+ -+ -+void hv_print_stats(hv_partition_t *curp, int i); -+ -+#endif /*HV_SHIM_H */ diff --git a/ioemu-bdrv-open-CACHE_WB.patch b/ioemu-bdrv-open-CACHE_WB.patch index 2d4916d..eb48cff 100644 --- a/ioemu-bdrv-open-CACHE_WB.patch +++ b/ioemu-bdrv-open-CACHE_WB.patch @@ -2,7 +2,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c =================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.c +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c -@@ -257,8 +257,11 @@ static int open_disk(struct td_state *s, +@@ -259,8 +259,11 @@ static int open_disk(struct td_state *s, drv = blktap_drivers[i].drv; DPRINTF("%s driver specified\n", drv ? drv->format_name : "No"); diff --git a/ioemu-blktap-barriers.patch b/ioemu-blktap-barriers.patch index 41d018c..43d7dc5 100644 --- a/ioemu-blktap-barriers.patch +++ b/ioemu-blktap-barriers.patch @@ -2,7 +2,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c =================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.c +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c -@@ -358,6 +358,15 @@ static void qemu_send_responses(void* op +@@ -360,6 +360,15 @@ static void qemu_send_responses(void* op } /** @@ -18,7 +18,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c * Callback function for the IO message pipe. Reads requests from the ring * and processes them (call qemu read/write functions). * -@@ -376,6 +385,7 @@ static void handle_blktap_iomsg(void* pr +@@ -378,6 +387,7 @@ static void handle_blktap_iomsg(void* pr blkif_t *blkif = s->blkif; tapdev_info_t *info = s->ring_info; int page_size = getpagesize(); @@ -26,7 +26,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c struct aiocb_info *aiocb_info; -@@ -408,7 +418,7 @@ static void handle_blktap_iomsg(void* pr +@@ -410,7 +420,7 @@ static void handle_blktap_iomsg(void* pr /* Don't allow writes on readonly devices */ if ((s->flags & TD_RDONLY) && @@ -35,7 +35,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c blkif->pending_list[idx].status = BLKIF_RSP_ERROR; goto send_response; } -@@ -429,7 +439,7 @@ static void handle_blktap_iomsg(void* pr +@@ -431,7 +441,7 @@ static void handle_blktap_iomsg(void* pr DPRINTF("Sector request failed:\n"); DPRINTF("%s request, idx [%d,%d] size [%llu], " "sector [%llu,%llu]\n", @@ -44,7 +44,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c "WRITE" : "READ"), idx,i, (long long unsigned) -@@ -442,8 +452,14 @@ static void handle_blktap_iomsg(void* pr +@@ -444,8 +454,14 @@ static void handle_blktap_iomsg(void* pr blkif->pending_list[idx].secs_pending += nsects; @@ -60,7 +60,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c case BLKIF_OP_WRITE: aiocb_info = malloc(sizeof(*aiocb_info)); -@@ -463,6 +479,10 @@ static void handle_blktap_iomsg(void* pr +@@ -465,6 +481,10 @@ static void handle_blktap_iomsg(void* pr DPRINTF("ERROR: bdrv_write() == NULL\n"); goto send_response; } diff --git a/ioemu-blktap-image-format.patch b/ioemu-blktap-image-format.patch index 18a499a..275a00f 100644 --- a/ioemu-blktap-image-format.patch +++ b/ioemu-blktap-image-format.patch @@ -19,7 +19,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c =================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.c +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c -@@ -228,9 +228,10 @@ static int map_new_dev(struct td_state * +@@ -230,9 +230,10 @@ static int map_new_dev(struct td_state * return -1; } @@ -31,7 +31,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c char* devname; static int devnumber = 0; int i; -@@ -240,7 +241,22 @@ static int open_disk(struct td_state *s, +@@ -242,7 +243,22 @@ static int open_disk(struct td_state *s, bs = bdrv_new(devname); free(devname); @@ -55,7 +55,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c fprintf(stderr, "Could not open image file %s\n", path); return -ENOMEM; } -@@ -519,7 +535,7 @@ static void handle_blktap_ctrlmsg(void* +@@ -521,7 +537,7 @@ static void handle_blktap_ctrlmsg(void* s = state_init(); /*Open file*/ @@ -68,7 +68,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.h =================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.h +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.h -@@ -52,4 +52,18 @@ typedef struct fd_list_entry { +@@ -53,4 +53,18 @@ typedef struct fd_list_entry { int init_blktap(void); diff --git a/ioemu-blktap-zero-size.patch b/ioemu-blktap-zero-size.patch index faa558b..2ec271e 100644 --- a/ioemu-blktap-zero-size.patch +++ b/ioemu-blktap-zero-size.patch @@ -16,7 +16,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c =================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.c +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c -@@ -266,6 +266,12 @@ static int open_disk(struct td_state *s, +@@ -268,6 +268,12 @@ static int open_disk(struct td_state *s, s->size = bs->total_sectors; s->sector_size = 512; diff --git a/ioemu-disable-emulated-ide-if-pv.patch b/ioemu-disable-emulated-ide-if-pv.patch new file mode 100644 index 0000000..323e38c --- /dev/null +++ b/ioemu-disable-emulated-ide-if-pv.patch @@ -0,0 +1,78 @@ +Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/qemu-xen.h +=================================================================== +--- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/qemu-xen.h ++++ xen-4.0.1-testing/tools/ioemu-qemu-xen/qemu-xen.h +@@ -1,6 +1,8 @@ + #ifndef QEMU_XEN_H + #define QEMU_XEN_H + ++#include "hw/boards.h" ++ + /* vl.c */ + extern int restore; + extern int vga_ram_size; +@@ -73,7 +75,7 @@ void handle_buffered_pio(void); + #endif + + /* xenstore.c */ +-void xenstore_parse_domain_config(int domid); ++void xenstore_parse_domain_config(int domid, QEMUMachine *machine); + int xenstore_parse_disable_pf_config(void); + int xenstore_fd(void); + void xenstore_process_event(void *opaque); +Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/vl.c +=================================================================== +--- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/vl.c ++++ xen-4.0.1-testing/tools/ioemu-qemu-xen/vl.c +@@ -5827,10 +5827,10 @@ int main(int argc, char **argv, char **e + if ((msg = xenbus_read(XBT_NIL, "domid", &domid_s))) + fprintf(stderr,"Can not read our own domid: %s\n", msg); + else +- xenstore_parse_domain_config(atoi(domid_s)); ++ xenstore_parse_domain_config(atoi(domid_s), machine); + } + #else +- xenstore_parse_domain_config(domid); ++ xenstore_parse_domain_config(domid, machine); + #endif /* CONFIG_STUBDOM */ + + /* we always create the cdrom drive, even if no disk is there */ +Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/xenstore.c +=================================================================== +--- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/xenstore.c ++++ xen-4.0.1-testing/tools/ioemu-qemu-xen/xenstore.c +@@ -397,7 +397,7 @@ static const char *xenstore_get_guest_uu + #define PT_PCI_POWER_MANAGEMENT_DEFAULT 0 + int direct_pci_msitranslate; + int direct_pci_power_mgmt; +-void xenstore_parse_domain_config(int hvm_domid) ++void xenstore_parse_domain_config(int hvm_domid, QEMUMachine *machine) + { + char **e_danger = NULL; + char *buf = NULL; +@@ -712,15 +712,19 @@ void xenstore_parse_domain_config(int hv + + #endif + +- drives_table[nb_drives].bdrv = bs; +- drives_table[nb_drives].used = 1; ++ if (machine == &xenfv_machine) { ++ drives_table[nb_drives].bdrv = bs; ++ drives_table[nb_drives].used = 1; + #ifdef CONFIG_STUBDOM +- media_filename[nb_drives] = strdup(danger_buf); ++ media_filename[nb_drives] = strdup(danger_buf); + #else +- media_filename[nb_drives] = strdup(bs->filename); ++ media_filename[nb_drives] = strdup(bs->filename); + #endif +- nb_drives++; +- ++ nb_drives++; ++ } else { ++ qemu_aio_flush(); ++ bdrv_close(bs); ++ } + } + + #ifdef CONFIG_STUBDOM diff --git a/ioemu-vnc-resize.patch b/ioemu-vnc-resize.patch index 5842337..f6782f5 100644 --- a/ioemu-vnc-resize.patch +++ b/ioemu-vnc-resize.patch @@ -2,7 +2,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/vnc.c =================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/vnc.c +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/vnc.c -@@ -1736,6 +1736,25 @@ static int protocol_client_msg(VncState +@@ -1734,6 +1734,25 @@ static int protocol_client_msg(VncState } set_encodings(vs, (int32_t *)(data + 4), limit); diff --git a/multi-xvdp.patch b/multi-xvdp.patch index dc38507..1927871 100644 --- a/multi-xvdp.patch +++ b/multi-xvdp.patch @@ -34,7 +34,7 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py xc = xen.lowlevel.xc.xc() xoptions = XendOptions.instance() -@@ -3314,20 +3314,27 @@ class XendDomainInfo: +@@ -3304,20 +3304,27 @@ class XendDomainInfo: # This is a file, not a device. pygrub can cope with a # file if it's raw, but if it's QCOW or other such formats # used through blktap, then we need to mount it first. @@ -76,7 +76,7 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py try: blcfg = bootloader(blexec, fn, self, False, -@@ -3335,11 +3342,11 @@ class XendDomainInfo: +@@ -3325,11 +3332,11 @@ class XendDomainInfo: finally: if mounted: log.info("Unmounting %s from %s." % diff --git a/qemu-fix-7433.patch b/qemu-fix-7433.patch new file mode 100644 index 0000000..321ba1a --- /dev/null +++ b/qemu-fix-7433.patch @@ -0,0 +1,22 @@ +--- a/tools/ioemu-qemu-xen/keymaps.c ++++ b/tools/ioemu-qemu-xen/keymaps.c +@@ -56,15 +56,12 @@ typedef struct { + + static void del_key_range(struct key_range **krp, int code) { + struct key_range *kr; +- struct key_range *kr_pr; +- for (kr = *krp; kr; kr_pr = kr, kr = kr->next) { ++ while ((kr = *krp) != NULL) { + if (code >= kr->start && code <= kr->end) { +- if (kr == *krp) +- *krp = kr->next; +- else +- kr_pr->next = kr->next; ++ *krp = kr->next; + qemu_free(kr); +- } ++ } else ++ krp = &kr->next; + } + } + diff --git a/snapshot-without-pv-fix.patch b/snapshot-without-pv-fix.patch index 8a640ae..11a7da8 100644 --- a/snapshot-without-pv-fix.patch +++ b/snapshot-without-pv-fix.patch @@ -8,16 +8,6 @@ ready, so the watch will tell qemu to add the disk entry to drives_table[], otherwise the disk in qemu will just stay opened,not showing up in drives_table[]. - -Signed-off-by: Li Dongyang ---- - tools/blktap/drivers/blktapctrl.c | 81 +++++++++++++++++++++++++++++++++- - tools/blktap/lib/blkif.c | 23 ++++++++++ - tools/blktap/lib/blktaplib.h | 5 ++ - tools/blktap/lib/xenbus.c | 69 +++++++++++++++++++++++++++++ - tools/ioemu-qemu-xen/hw/xen_blktap.c | 49 +++++++++++++++----- - 5 files changed, 213 insertions(+), 14 deletions(-) - Index: xen-4.0.1-testing/tools/blktap/drivers/blktapctrl.c =================================================================== --- xen-4.0.1-testing.orig/tools/blktap/drivers/blktapctrl.c @@ -198,7 +188,7 @@ Index: xen-4.0.1-testing/tools/blktap/lib/blktaplib.h void __init_blkif(void); typedef struct busy_state { -@@ -209,6 +212,8 @@ typedef struct msg_pid { +@@ -210,6 +213,8 @@ typedef struct msg_pid { #define CTLMSG_CLOSE_RSP 8 #define CTLMSG_PID 9 #define CTLMSG_PID_RSP 10 @@ -298,7 +288,16 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c =================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.c +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c -@@ -81,8 +81,18 @@ static void unmap_disk(struct td_state * +@@ -35,6 +35,8 @@ + #ifndef QEMU_TOOL + #include "qemu-common.h" + #include "sysemu.h" ++#include "irq.h" ++#include "hw.h" + #endif + + #include "xen_blktap.h" +@@ -81,8 +83,18 @@ static void unmap_disk(struct td_state * { tapdev_info_t *info = s->ring_info; fd_list_entry_t *entry; @@ -317,7 +316,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c if (info != NULL && info->mem > 0) munmap(info->mem, getpagesize() * BLKTAP_MMAP_REGION_SIZE); -@@ -242,18 +252,6 @@ static int open_disk(struct td_state *s, +@@ -242,18 +254,6 @@ static int open_disk(struct td_state *s, s->info = ((s->flags & TD_RDONLY) ? VDISK_READONLY : 0); @@ -336,7 +335,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c return 0; } -@@ -494,7 +492,7 @@ static void handle_blktap_ctrlmsg(void* +@@ -494,7 +494,7 @@ static void handle_blktap_ctrlmsg(void* msg_hdr_t *msg; msg_newdev_t *msg_dev; msg_pid_t *msg_pid; @@ -345,14 +344,15 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c struct td_state *s = NULL; fd_list_entry_t *entry; -@@ -584,6 +582,31 @@ static void handle_blktap_ctrlmsg(void* +@@ -584,6 +584,33 @@ static void handle_blktap_ctrlmsg(void* len = write(write_fd, buf, msglen); break; + case CTLMSG_ADDDEV: + s = get_state(msg->cookie); -+ if (s) { ++ if (s && !s->added) { +#ifndef QEMU_TOOL ++ ide_unplug_harddisks(); + for (i = 0; i < MAX_DRIVES + 1; i++) { + if (drives_table[i].bdrv == NULL) { + drives_table[i].bdrv = s->bs; @@ -361,6 +361,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c + drives_table[i].unit = 0; + drives_table[i].used = 1; + nb_drives++; ++ s->added = 1; + break; + } + } @@ -377,3 +378,17 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c default: break; } +Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.h +=================================================================== +--- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.h ++++ xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.h +@@ -40,7 +40,8 @@ struct td_state { + void *fd_entry; + uint64_t sector_size; + uint64_t size; +- unsigned int info; ++ unsigned int info; ++ int added; + }; + + typedef struct fd_list_entry { diff --git a/snapshot-xend.patch b/snapshot-xend.patch index f08848f..99d2d18 100644 --- a/snapshot-xend.patch +++ b/snapshot-xend.patch @@ -47,12 +47,13 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/server/blkif.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/server/blkif.py +++ xen-4.0.1-testing/tools/python/xen/xend/server/blkif.py -@@ -88,6 +88,9 @@ class BlkifController(DevController): +@@ -88,6 +88,10 @@ class BlkifController(DevController): if bootable != None: back['bootable'] = str(bootable) + if 'snapshotname' in self.vm.info: + back['snapshot'] = self.vm.info['snapshotname'] ++ self.vm.info.pop('snapshotname') + if security.on() == xsconstants.XS_POLICY_USE: self.do_access_control(config, uname) @@ -354,7 +355,25 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomain.py xc = xen.lowlevel.xc.xc() xoptions = XendOptions.instance() -@@ -1576,6 +1577,187 @@ class XendDomain: +@@ -319,11 +320,16 @@ class XendDomain: + fd, fn = tempfile.mkstemp() + f = os.fdopen(fd, 'w+b') + try: ++ snapshotname = '' ++ if dominfo.info.has_key('snapshotname'): ++ snapshotname = dominfo.info.pop('snapshotname') ++ + prettyprint(dominfo.sxpr(legacy_only = False), f, + width = 78) + finally: + f.close() +- ++ if snapshotname: ++ dominfo.info['snapshotname'] = snapshotname + try: + shutil.move(fn, self._managed_config_path(dom_uuid)) + except: +@@ -1576,6 +1582,187 @@ class XendDomain: else: log.debug("error: Domain is not running!") @@ -667,3 +686,42 @@ Index: xen-4.0.1-testing/tools/python/xen/xm/main.py "shutdown": xm_shutdown, "start": xm_start, "sysrq": xm_sysrq, +Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-4.0.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -507,7 +507,6 @@ class XendDomainInfo: + self._setSchedParams() + self._storeVmDetails() + self._createChannels() +- self._createDevices() + self._storeDomDetails() + self._endRestore() + except: +@@ -2383,7 +2382,7 @@ class XendDomainInfo: + return self.getDeviceController(deviceClass).reconfigureDevice( + devid, devconfig) + +- def _createDevices(self): ++ def _createDevices(self, resume = False): + """Create the devices for a vm. + + @raise: VmError for invalid devices +@@ -2432,7 +2431,7 @@ class XendDomainInfo: + + + if self.image: +- self.image.createDeviceModel() ++ self.image.createDeviceModel(resume) + + #if have pass-through devs, need the virtual pci slots info from qemu + self.pci_device_configure_boot() +@@ -3048,7 +3047,7 @@ class XendDomainInfo: + self._introduceDomain() + self.image = image.create(self, self.info) + if self.image: +- self.image.createDeviceModel(True) ++ self._createDevices(True) + self._storeDomDetails() + self._registerWatches() + self.refreshShutdown() diff --git a/suspend_evtchn_lock.patch b/suspend_evtchn_lock.patch new file mode 100644 index 0000000..9ed5749 --- /dev/null +++ b/suspend_evtchn_lock.patch @@ -0,0 +1,87 @@ +Improve suspend eventchn lock, use flock instead of exclusive lock +file to avoid that sometimes the lock file is not removed cleanly +and affacts later getting lock. +http://lists.xensource.com/archives/html/xen-devel/2010-11/msg01559.html + +Signed-off-by cyliu@novell.com + +Index: xen-4.0.1-testing/tools/libxc/xc_suspend.c +=================================================================== +--- xen-4.0.1-testing.orig/tools/libxc/xc_suspend.c ++++ xen-4.0.1-testing/tools/libxc/xc_suspend.c +@@ -6,25 +6,25 @@ + + #include "xc_private.h" + #include "xenguest.h" ++#include ++#include + + #define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn_lock.d" + static int lock_suspend_event(void) + { + int fd, rc; + mode_t mask; +- char buf[128]; + + mask = umask(022); +- fd = open(SUSPEND_LOCK_FILE, O_CREAT | O_EXCL | O_RDWR, 0666); ++ fd = open(SUSPEND_LOCK_FILE, O_CREAT | O_RDWR, 0666); + if (fd < 0) + { + ERROR("Can't create lock file for suspend event channel\n"); + return -EINVAL; + } + umask(mask); +- snprintf(buf, sizeof(buf), "%10ld", (long)getpid()); ++ rc = flock(fd, LOCK_EX | LOCK_NB); + +- rc = write_exact(fd, buf, strlen(buf)); + close(fd); + + return rc; +@@ -32,30 +32,21 @@ static int lock_suspend_event(void) + + static int unlock_suspend_event(void) + { +- int fd, pid, n; +- char buf[128]; ++ int fd, rc; + + fd = open(SUSPEND_LOCK_FILE, O_RDWR); + + if (fd < 0) + return -EINVAL; + +- n = read(fd, buf, 127); ++ rc = flock(fd, LOCK_UN | LOCK_NB); + + close(fd); + +- if (n > 0) +- { +- sscanf(buf, "%d", &pid); +- /* We are the owner, so we can simply delete the file */ +- if (pid == getpid()) +- { +- unlink(SUSPEND_LOCK_FILE); +- return 0; +- } +- } ++ if(!rc) ++ unlink(SUSPEND_LOCK_FILE); + +- return -EPERM; ++ return rc; + } + + int xc_await_suspend(int xce, int suspend_evtchn) +@@ -110,8 +101,7 @@ int xc_suspend_evtchn_init(int xc, int x + return suspend_evtchn; + + cleanup: +- if (suspend_evtchn != -1) +- xc_suspend_evtchn_release(xce, suspend_evtchn); ++ xc_suspend_evtchn_release(xce, suspend_evtchn); + + return -1; + } diff --git a/tapdisk-ioemu-shutdown-fix.patch b/tapdisk-ioemu-shutdown-fix.patch index f5de870..e30c3e9 100644 --- a/tapdisk-ioemu-shutdown-fix.patch +++ b/tapdisk-ioemu-shutdown-fix.patch @@ -20,7 +20,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c =================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/hw/xen_blktap.c +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c -@@ -65,6 +65,7 @@ int read_fd; +@@ -67,6 +67,7 @@ int read_fd; int write_fd; static pid_t process; @@ -28,7 +28,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c fd_list_entry_t *fd_start = NULL; static void handle_blktap_iomsg(void* private); -@@ -539,6 +540,7 @@ static void handle_blktap_ctrlmsg(void* +@@ -541,6 +542,7 @@ static void handle_blktap_ctrlmsg(void* /* Allocate the disk structs */ s = state_init(); @@ -36,7 +36,7 @@ Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/hw/xen_blktap.c /*Open file*/ if (s == NULL || open_disk(s, path, msg->drivertype, msg->readonly)) { -@@ -589,7 +591,8 @@ static void handle_blktap_ctrlmsg(void* +@@ -591,7 +593,8 @@ static void handle_blktap_ctrlmsg(void* case CTLMSG_CLOSE: s = get_state(msg->cookie); if (s) unmap_disk(s); diff --git a/x86-cpufreq-report.patch b/x86-cpufreq-report.patch index b036e77..429a552 100644 --- a/x86-cpufreq-report.patch +++ b/x86-cpufreq-report.patch @@ -1,5 +1,7 @@ ---- a/xen/arch/x86/platform_hypercall.c -+++ b/xen/arch/x86/platform_hypercall.c +Index: xen-4.0.1-testing/xen/arch/x86/platform_hypercall.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/platform_hypercall.c ++++ xen-4.0.1-testing/xen/arch/x86/platform_hypercall.c @@ -21,7 +21,7 @@ #include #include @@ -17,7 +19,7 @@ struct xen_platform_op curop, *op = &curop; if ( !IS_PRIV(current->domain) ) -@@ -486,6 +487,24 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe +@@ -489,6 +490,24 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe op->u.mem_add.epfn, op->u.mem_add.pxm); break; @@ -42,8 +44,10 @@ default: ret = -ENOSYS; break; ---- a/xen/include/public/platform.h -+++ b/xen/include/public/platform.h +Index: xen-4.0.1-testing/xen/include/public/platform.h +=================================================================== +--- xen-4.0.1-testing.orig/xen/include/public/platform.h ++++ xen-4.0.1-testing/xen/include/public/platform.h @@ -355,6 +355,14 @@ struct xenpf_mem_hotadd uint32_t flags; }; diff --git a/x86-ioapic-ack-default.patch b/x86-ioapic-ack-default.patch index 39f3be6..bcc40a2 100644 --- a/x86-ioapic-ack-default.patch +++ b/x86-ioapic-ack-default.patch @@ -1,7 +1,9 @@ Change default IO-APIC ack mode for single IO-APIC systems to old-style. ---- a/xen/arch/x86/io_apic.c -+++ b/xen/arch/x86/io_apic.c +Index: xen-4.0.1-testing/xen/arch/x86/io_apic.c +=================================================================== +--- xen-4.0.1-testing.orig/xen/arch/x86/io_apic.c ++++ xen-4.0.1-testing/xen/arch/x86/io_apic.c @@ -1559,7 +1559,7 @@ static unsigned int startup_level_ioapic return 0; /* don't check for pending */ } @@ -11,7 +13,7 @@ Change default IO-APIC ack mode for single IO-APIC systems to old-style. static void setup_ioapic_ack(char *s) { if ( !strcmp(s, "old") ) -@@ -2062,6 +2062,8 @@ void __init setup_IO_APIC(void) +@@ -2075,6 +2075,8 @@ void __init setup_IO_APIC(void) else io_apic_irqs = ~PIC_IRQS; diff --git a/x86-show-page-walk-early.patch b/x86-show-page-walk-early.patch index 196b236..4b946bd 100644 --- a/x86-show-page-walk-early.patch +++ b/x86-show-page-walk-early.patch @@ -15,7 +15,7 @@ Index: xen-4.0.1-testing/xen/arch/x86/traps.c =================================================================== --- xen-4.0.1-testing.orig/xen/arch/x86/traps.c +++ xen-4.0.1-testing/xen/arch/x86/traps.c -@@ -1336,6 +1336,7 @@ asmlinkage void do_early_page_fault(stru +@@ -1342,6 +1342,7 @@ asmlinkage void do_early_page_fault(stru unsigned long *stk = (unsigned long *)regs; printk("Early fatal page fault at %04x:%p (cr2=%p, ec=%04x)\n", regs->cs, _p(regs->eip), _p(cr2), regs->error_code); diff --git a/x86_64-gdt-ldt-fault-filter.patch b/x86_64-gdt-ldt-fault-filter.patch deleted file mode 100644 index 4da0f12..0000000 --- a/x86_64-gdt-ldt-fault-filter.patch +++ /dev/null @@ -1,13 +0,0 @@ -References: bnc#656245 - ---- a/xen/arch/x86/traps.c -+++ b/xen/arch/x86/traps.c -@@ -1223,7 +1223,7 @@ static int fixup_page_fault(unsigned lon - - if ( unlikely(IN_HYPERVISOR_RANGE(addr)) ) - { -- if ( !(regs->error_code & PFEC_reserved_bit) && -+ if ( !(regs->error_code & (PFEC_user_mode | PFEC_reserved_bit)) && - (addr >= GDT_LDT_VIRT_START) && (addr < GDT_LDT_VIRT_END) ) - return handle_gdt_ldt_mapping_fault( - addr - GDT_LDT_VIRT_START, regs); diff --git a/xen-minimum-restart-time.patch b/xen-minimum-restart-time.patch new file mode 100644 index 0000000..ade76c1 --- /dev/null +++ b/xen-minimum-restart-time.patch @@ -0,0 +1,15 @@ +References: bnc#661298 + +Index: xen-4.0.1-testing/tools/python/xen/xend/XendConstants.py +=================================================================== +--- xen-4.0.1-testing.orig/tools/python/xen/xend/XendConstants.py ++++ xen-4.0.1-testing/tools/python/xen/xend/XendConstants.py +@@ -92,7 +92,7 @@ DOM_STATES_OLD = [ + SHUTDOWN_TIMEOUT = (60.0 * 5) + + """Minimum time between domain restarts in seconds.""" +-MINIMUM_RESTART_TIME = 60 ++MINIMUM_RESTART_TIME = 10 + + RESTART_IN_PROGRESS = 'xend/restart_in_progress' + DUMPCORE_IN_PROGRESS = 'xend/dumpcore_in_progress' diff --git a/xen.changes b/xen.changes index ec9df56..bbe8ea1 100644 --- a/xen.changes +++ b/xen.changes @@ -1,3 +1,146 @@ +------------------------------------------------------------------- +Fri Jan 14 08:29:15 MST 2011 - carnold@novell.com + +- bnc#658704 - SLES11 SP1 Xen boot panic in x2apic mode + 22707-x2apic-preenabled-check.patch +- bnc#641419 - L3: Xen: qemu-dm reports "xc_map_foreign_batch: mmap failed: + Cannot allocate memory" + 7434-qemu-rlimit-as.patch +- Additional or upstream patches from Jan + 22693-fam10-mmio-conf-base-protect.patch + 22694-x86_64-no-weak.patch + 22708-xenctx-misc.patch + 21432-4.0-cpu-boot-failure.patch + 22645-amd-flush-filter.patch + qemu-fix-7433.patch + +------------------------------------------------------------------- +Wed Jan 12 21:28:18 MST 2011 - carnold@novell.com + +- Maintain compatibility with the extid flag even though it is + deprecated for both legacy and sxp config files. + hv_extid_compatibility.patch + +------------------------------------------------------------------- +Wed Jan 12 16:08:10 CST 2011 - cyliu@novell.com + +- bnc#649209-improve suspend eventchn lock + suspend_evtchn_lock.patch + +------------------------------------------------------------------- +Tue Jan 11 11:48:10 MST 2011 - carnold@novell.com + +- Removed the hyper-v shim patches in favor of using the upstream + version. + +------------------------------------------------------------------- +Mon Jan 10 21:15:43 MST 2011 - carnold@novell.com + +- bnc#641419 - L3: Xen: qemu-dm reports "xc_map_foreign_batch: mmap + failed: Cannot allocate memory" + qemu-rlimit-as.patch + +------------------------------------------------------------------- +Mon Jan 10 15:23:18 CST 2011 - cyliu@novell.com + +- Upstream c/s 7433 to replace qemu_altgr_more.patch + 7433-qemu-altgr.patch + +------------------------------------------------------------------- +Fri Jan 7 16:13:24 MST 2011 - jfehlig@novell.com + +- bnc#661931 - Fix fd leak in xenstore library + 21344-4.0-testing-xenstore-fd-leak.patch + +------------------------------------------------------------------- +Tue Jan 4 18:06:31 MST 2011 - carnold@novell.com + +- bnc#656369 - g5plus: sles11sp1 xen crash with 8 socket x2apic + preenabled + 21989-x2apic-resume.patch + 22475-x2apic-cleanup.patch + 22535-x2apic-preenabled.patch +- bnc#658163 - maintenance release - Nehalem system cannot boot + into xen with maintenance release installed + 22504-iommu-dom0-holes.patch + 22506-x86-iommu-dom0-estimate.patch +- bnc#658704 - SLES11 SP1 Xen boot panic in x2apic mode + 21810-x2apic-acpi.patch +- Upstream patches from Jan + 22470-vlapic-tick-loss.patch + 22484-vlapic-tmcct-periodic.patch + 22526-ept-access-once.patch + 22533-x86-32bit-apicid.patch + 22534-x86-max-local-apic.patch + 22538-keyhandler-relax.patch + 22540-32on64-hypercall-debug.patch + 22549-vtd-map-page-leak.patch + 22574-ept-skip-validation.patch + 22632-vtd-print-entries.patch + +------------------------------------------------------------------- +Tue Jan 4 16:53:54 MST 2011 - carnold@novell.com + +- bnc#661298 - maintenance release candidate - Windows VMs reboot + too fast, triggering failsafe + xen-minimum-restart-time.patch + +------------------------------------------------------------------- +Tue Jan 4 10:23:18 CST 2011 - cyliu@novell.com + +- bnc#659070 - Fail to input '|' in en-us keyboard + qemu_altgr_more.patch + +------------------------------------------------------------------- +Tue Dec 28 11:23:18 MST 2010 - jfehlig@novell.com + +- bnc#659466 - XEN drbd block device type not working on SLES 11 SP1 + 20158-revert.patch + +------------------------------------------------------------------- +Mon Dec 27 14:43:13 CST 2010 - lidongyang@novell.com + +- bnc#654543 - PV guest won't unplug the IDE disk created by + qemu-dm + a dirty hack, only add the device to drives_table[] if we are FV + domU, that will be unplugged anyway if a PV driver is loaded + later. + ioemu-disable-emulated-ide-if-pv.patch + +------------------------------------------------------------------- +Wed Dec 22 11:56:38 CST 2010 - cyliu@novell.com + +- Upstream patch to replace xenfb_32bpp.patch + 7426-xenfb-depth.patch + +------------------------------------------------------------------- +Tue Dec 21 11:31:52 CST 2010 - lidongyang@novell.com + +- bnc#651822 make sure we only apply the snapshot once, and the + changes made after snapshot-apply hit the disk. + snapshot-xend.patch + snapshot-without-pv-fix.patch + +------------------------------------------------------------------- +Fri Dec 17 14:34:18 CET 2010 - ohering@suse.de + +- fate#310510 - fix xenpaging + xenpaging.HVMCOPY_gfn_paged_out.patch + - remove incorrect and unneeded cleanup from do_memory_op + subfunctions + add mainline tag to merged patches + +------------------------------------------------------------------- +Thu Dec 16 17:33:52 MST 2010 - jfehlig@novell.com + +- bnc#613584 - If available, use kpartx '-f' option in domUloader + +------------------------------------------------------------------- +Thu Dec 16 10:21:13 MST 2010 - jfehlig@novell.com + +- bnc#659872 - xend: Do no release domain lock on checkpoint + operation. + ------------------------------------------------------------------- Tue Dec 7 15:38:58 CET 2010 - ohering@suse.de diff --git a/xen.spec b/xen.spec index 1743b58..b9fc0d9 100644 --- a/xen.spec +++ b/xen.spec @@ -1,5 +1,5 @@ # -# spec file for package xen (Version 4.0.1_02) +# spec file for package xen (Version 4.0.1_04) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -26,35 +26,35 @@ ExclusiveArch: %ix86 x86_64 %define xen_build_dir xen-4.0.1-testing %define with_kmp 1 %define with_stubdom 1 -BuildRequires: LibVNCServer-devel -BuildRequires: SDL-devel -BuildRequires: automake -BuildRequires: bin86 -BuildRequires: curl-devel -BuildRequires: dev86 -BuildRequires: graphviz -BuildRequires: latex2html -BuildRequires: libjpeg-devel -BuildRequires: libxml2-devel -BuildRequires: ncurses-devel -BuildRequires: openssl -BuildRequires: openssl-devel -BuildRequires: pciutils-devel -BuildRequires: python-devel -BuildRequires: texinfo -BuildRequires: transfig +BuildRequires: LibVNCServer-devel +BuildRequires: SDL-devel +BuildRequires: automake +BuildRequires: bin86 +BuildRequires: curl-devel +BuildRequires: dev86 +BuildRequires: graphviz +BuildRequires: latex2html +BuildRequires: libjpeg-devel +BuildRequires: libxml2-devel +BuildRequires: ncurses-devel +BuildRequires: openssl +BuildRequires: openssl-devel +BuildRequires: pciutils-devel +BuildRequires: python-devel +BuildRequires: texinfo +BuildRequires: transfig %if %suse_version <= 1110 -BuildRequires: pmtools +BuildRequires: pmtools %else -BuildRequires: acpica +BuildRequires: acpica %endif %if %suse_version >= 1030 -BuildRequires: texlive -BuildRequires: texlive-latex +BuildRequires: texlive +BuildRequires: texlive-latex %else -BuildRequires: te_ams -BuildRequires: te_latex -BuildRequires: tetex +BuildRequires: te_ams +BuildRequires: te_latex +BuildRequires: tetex %endif %ifarch x86_64 BuildRequires: glibc-32bit glibc-devel-32bit @@ -70,7 +70,7 @@ BuildRequires: glibc-devel %if %{?with_kmp}0 BuildRequires: kernel-source kernel-syms module-init-tools xorg-x11 %endif -Version: 4.0.1_02 +Version: 4.0.1_04 Release: 1 License: GPLv2+ Group: System/Kernel @@ -115,51 +115,84 @@ Patch1: 21235-crashkernel-advanced.patch Patch2: 21271-x86-cache-flush-global.patch Patch3: 21301-svm-lmsl.patch Patch4: 21304-keyhandler-alternative.patch -Patch5: 21406-x86-microcode-quiet.patch -Patch6: 21421-vts-ats-enabling.patch -Patch7: 21526-x86-nehalem-cpuid-mask.patch -Patch8: 21542-amd-erratum-411.patch -Patch9: 21615-dont-save-xen-heap-pages.patch -Patch10: 21627-cpuidle-wrap.patch -Patch11: 21653-xend-mac-addr.patch -Patch12: 21678-xend-mac-fix.patch -Patch13: 21683-vtd-kill-timer-conditional.patch -Patch14: 21723-get-domu-state.patch -Patch15: 21847-pscsi.patch -Patch16: 21866-xenapi.patch -Patch17: 21894-intel-unmask-cpuid.patch -Patch18: 22019-x86-cpuidle-online-check.patch -Patch19: 22045-python27-compat.patch -Patch20: 22051-x86-forced-EOI.patch -Patch21: 22067-x86-irq-domain.patch -Patch22: 22068-vtd-irte-RH-bit.patch -Patch23: 22071-ept-get-entry-lock.patch -Patch24: 22084-x86-xsave-off.patch -Patch25: 7410-qemu-alt-gr.patch -Patch26: 22135-heap-lock.patch -Patch27: 22148-serial-irq-dest.patch -Patch28: 22157-x86-debug-key-i.patch -Patch29: 22159-notify-evtchn-dying.patch -Patch30: 22160-Intel-C6-EOI.patch -Patch31: 22174-x86-pmtimer-accuracy.patch -Patch32: 22175-x86-irq-enter-exit.patch -Patch33: 22177-i386-irq-safe-map_domain_page.patch -Patch34: 22194-tmem-check-pv-mfn.patch -Patch35: 22213-x86-xsave-cpuid-check.patch -Patch36: 22214-x86-msr-misc-enable.patch -Patch37: 22222-x86-timer-extint.patch -Patch38: 22223-vtd-workarounds.patch -Patch39: 22231-x86-pv-ucode-msr-intel.patch -Patch40: 22232-x86-64-lahf-lm-bios-workaround.patch -Patch41: 22235-lxml-validator.patch -Patch42: 22280-kexec.patch -Patch43: 22337-vtd-scan-single-func.patch -Patch44: 22348-vtd-check-secbus-devfn.patch -Patch45: 22369-xend-pci-passthru-fix.patch -Patch46: 22389-amd-iommu-decls.patch -Patch47: 22416-acpi-check-mwait.patch -Patch48: 22417-vpmu-nehalem.patch -Patch49: 22431-p2m-remove-bug-check.patch +Patch5: 21344-4.0-testing-xenstore-fd-leak.patch +Patch6: 21406-x86-microcode-quiet.patch +Patch7: 21421-vts-ats-enabling.patch +Patch8: 21526-x86-nehalem-cpuid-mask.patch +Patch9: 21432-4.0-cpu-boot-failure.patch +Patch10: 21542-amd-erratum-411.patch +Patch11: 21615-dont-save-xen-heap-pages.patch +Patch12: 21627-cpuidle-wrap.patch +Patch13: 21653-xend-mac-addr.patch +Patch14: 21678-xend-mac-fix.patch +Patch15: 21683-vtd-kill-timer-conditional.patch +Patch16: 21723-get-domu-state.patch +Patch17: 21847-pscsi.patch +Patch18: 21866-xenapi.patch +Patch19: 21894-intel-unmask-cpuid.patch +Patch20: 22019-x86-cpuidle-online-check.patch +Patch21: 22045-python27-compat.patch +Patch22: 22051-x86-forced-EOI.patch +Patch23: 22067-x86-irq-domain.patch +Patch24: 22068-vtd-irte-RH-bit.patch +Patch25: 22071-ept-get-entry-lock.patch +Patch26: 22084-x86-xsave-off.patch +Patch27: 22135-heap-lock.patch +Patch28: 22148-serial-irq-dest.patch +Patch29: 22157-x86-debug-key-i.patch +Patch30: 22159-notify-evtchn-dying.patch +Patch31: 22160-Intel-C6-EOI.patch +Patch32: 22174-x86-pmtimer-accuracy.patch +Patch33: 22175-x86-irq-enter-exit.patch +Patch34: 22177-i386-irq-safe-map_domain_page.patch +Patch35: 22194-tmem-check-pv-mfn.patch +Patch36: 21810-x2apic-acpi.patch +Patch37: 21989-x2apic-resume.patch +Patch38: 22213-x86-xsave-cpuid-check.patch +Patch39: 22214-x86-msr-misc-enable.patch +Patch40: 22222-x86-timer-extint.patch +Patch41: 22223-vtd-workarounds.patch +Patch42: 22231-x86-pv-ucode-msr-intel.patch +Patch43: 22232-x86-64-lahf-lm-bios-workaround.patch +Patch44: 22235-lxml-validator.patch +Patch45: 22280-kexec.patch +Patch46: 22337-vtd-scan-single-func.patch +Patch47: 22348-vtd-check-secbus-devfn.patch +Patch48: 22369-xend-pci-passthru-fix.patch +Patch49: 22388-x2apic-panic.patch +Patch50: 22389-amd-iommu-decls.patch +Patch51: 22416-acpi-check-mwait.patch +Patch52: 22417-vpmu-nehalem.patch +Patch53: 22431-p2m-remove-bug-check.patch +Patch54: 22448-x86_64-gdt-ldt-fault-filter.patch +Patch55: 22451-hvm-cap-clobber.patch +Patch56: 22452-x86-irq-migrate-directed-eoi.patch +Patch57: 22466-x86-sis-apic-bug.patch +Patch58: 22470-vlapic-tick-loss.patch +Patch59: 22475-x2apic-cleanup.patch +Patch60: 22484-vlapic-tmcct-periodic.patch +Patch61: 22504-iommu-dom0-holes.patch +Patch62: 22506-x86-iommu-dom0-estimate.patch +Patch63: 22526-ept-access-once.patch +Patch64: 22533-x86-32bit-apicid.patch +Patch65: 22534-x86-max-local-apic.patch +Patch66: 22535-x2apic-preenabled.patch +Patch67: 22538-keyhandler-relax.patch +Patch68: 22540-32on64-hypercall-debug.patch +Patch69: 22549-vtd-map-page-leak.patch +Patch70: 22574-ept-skip-validation.patch +Patch71: 22632-vtd-print-entries.patch +Patch72: 22645-amd-flush-filter.patch +Patch73: 22693-fam10-mmio-conf-base-protect.patch +Patch74: 22694-x86_64-no-weak.patch +Patch75: 22707-x2apic-preenabled-check.patch +Patch76: 22708-xenctx-misc.patch +# Upstream qemu patches +Patch200: 7410-qemu-alt-gr.patch +Patch201: 7426-xenfb-depth.patch +Patch202: 7433-qemu-altgr.patch +Patch203: qemu-fix-7433.patch +Patch204: 7434-qemu-rlimit-as.patch # Our patches Patch300: xen-config.diff Patch301: xend-config.diff @@ -221,6 +254,8 @@ Patch372: popen2-argument-fix.patch Patch373: usb-list.patch Patch374: xend-devid-or-name.patch Patch375: 22326-cpu-pools-numa-placement.patch +Patch376: 20158-revert.patch +Patch377: suspend_evtchn_lock.patch # Patches for snapshot support Patch400: snapshot-ioemu-save.patch Patch401: snapshot-ioemu-restore.patch @@ -251,69 +286,63 @@ Patch433: multi-xvdp.patch Patch434: check_device_status.patch Patch435: change_home_server.patch Patch436: altgr_2.patch -Patch437: xenfb_32bpp.patch Patch438: stdvga-cache.patch Patch439: minios-fixups.patch Patch440: bdrv_default_rwflag.patch Patch441: blktap2.patch +Patch442: xen-minimum-restart-time.patch # Jim's domain lock patch Patch450: xend-domain-lock.patch # Hypervisor and PV driver Patches Patch500: 32on64-extra-mem.patch -Patch501: x86_64-gdt-ldt-fault-filter.patch -Patch502: x86-ioapic-ack-default.patch -Patch503: x86-cpufreq-report.patch -Patch504: dump-exec-state.patch -Patch505: dom-print.patch -Patch506: pvdrv-import-shared-info.patch -Patch507: x86-show-page-walk-early.patch -Patch508: x86-extra-trap-info.patch -Patch509: pvdrv_emulation_control.patch -Patch510: blktap-pv-cdrom.patch -Patch511: pv-driver-build.patch -Patch512: supported_module.diff -Patch513: magic_ioport_compat.patch +Patch501: x86-ioapic-ack-default.patch +Patch502: x86-cpufreq-report.patch +Patch503: dump-exec-state.patch +Patch504: dom-print.patch +Patch505: pvdrv-import-shared-info.patch +Patch506: x86-show-page-walk-early.patch +Patch507: x86-extra-trap-info.patch +Patch508: pvdrv_emulation_control.patch +Patch509: blktap-pv-cdrom.patch +Patch510: pv-driver-build.patch +Patch511: supported_module.diff +Patch512: magic_ioport_compat.patch Patch650: disable_emulated_device.diff Patch651: ioemu-disable-scsi.patch -# novell_shim patches -Patch700: hv_tools.patch -Patch701: hv_xen_base.patch -Patch702: hv_xen_extension.patch -Patch703: hv_win7_eoi_bug.patch -Patch704: hv_apic.patch +Patch652: ioemu-disable-emulated-ide-if-pv.patch +Patch700: hv_extid_compatibility.patch # Build patch Patch999: tmp_build.patch # FATE 310510 -Patch902: hotplug-block-losetup-a.patch -Patch10001: xenpaging.tools_xenpaging_cleanup.patch -Patch10002: xenpaging.pageout_policy.patch -Patch10003: xenpaging.xs_daemon_close.patch -Patch10004: xenpaging.get_paged_frame.patch -Patch10005: xenpaging.makefile.patch -Patch10010: xenpaging.policy_linear.patch -Patch10011: xenpaging.pagefile.patch -Patch10012: xenpaging.xenpaging_init.patch -Patch10013: xenpaging.mem_paging_tool_qemu_flush_cache.patch -Patch10014: xenpaging.machine_to_phys_mapping.patch -Patch10015: xenpaging.populate_only_if_paged.patch -Patch10017: xenpaging.autostart.patch -Patch10018: xenpaging.signal_handling.patch -Patch10019: xenpaging.MRU_SIZE.patch -Patch10020: xenpaging.guest_remove_page.patch -Patch10021: xenpaging.mem_event_check_ring-free_requests.patch -Patch10022: xenpaging.blacklist.patch -Patch10023: xenpaging.autostart_delay.patch -Patch10024: xenpaging.page_already_populated.patch -Patch10025: xenpaging.notify_policy_only_once.patch -Patch10026: xenpaging.num_pages_equal_max_pages.patch -Patch10027: xenpaging.p2m_mem_paging_populate_if_p2m_ram_paged.patch -Patch10028: xenpaging.HVMCOPY_gfn_paged_out.patch -Patch10029: xenpaging.optimize_p2m_mem_paging_populate.patch -Patch10030: xenpaging.paging_prep_enomem.patch -Patch10031: xenpaging.print-arguments.patch -Patch10040: xenpaging.doc.patch +Patch902: hotplug-block-losetup-a.patch +Patch10001: xenpaging.tools_xenpaging_cleanup.patch +Patch10002: xenpaging.pageout_policy.patch +Patch10003: xenpaging.get_paged_frame.patch +Patch10004: xenpaging.makefile.patch +Patch10010: xenpaging.policy_linear.patch +Patch10011: xenpaging.pagefile.patch +Patch10012: xenpaging.xenpaging_init.patch +Patch10013: xenpaging.mem_paging_tool_qemu_flush_cache.patch +Patch10014: xenpaging.machine_to_phys_mapping.patch +Patch10015: xenpaging.populate_only_if_paged.patch +Patch10017: xenpaging.autostart.patch +Patch10018: xenpaging.signal_handling.patch +Patch10019: xenpaging.MRU_SIZE.patch +Patch10020: xenpaging.guest_remove_page.patch +Patch10021: xenpaging.mem_event_check_ring-free_requests.patch +Patch10022: xenpaging.blacklist.patch +Patch10023: xenpaging.autostart_delay.patch +Patch10024: xenpaging.page_already_populated.patch +Patch10025: xenpaging.notify_policy_only_once.patch +Patch10026: xenpaging.num_pages_equal_max_pages.patch +Patch10027: xenpaging.p2m_mem_paging_populate_if_p2m_ram_paged.patch +Patch10028: xenpaging.HVMCOPY_gfn_paged_out.patch +Patch10029: xenpaging.optimize_p2m_mem_paging_populate.patch +Patch10030: xenpaging.paging_prep_enomem.patch +Patch10031: xenpaging.print-arguments.patch +Patch10040: xenpaging.doc.patch # xenalyze -Patch20000: xenalyze.64bit.patch +Patch20000: xenalyze.64bit.patch Url: http://www.cl.cam.ac.uk/Research/SRG/netos/xen/ BuildRoot: %{_tmppath}/%{name}-%{version}-build #%define pysite %(python -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib()") @@ -697,6 +726,38 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch47 -p1 %patch48 -p1 %patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 +%patch72 -p1 +%patch73 -p1 +%patch74 -p1 +%patch75 -p1 +%patch76 -p1 +%patch200 -p1 +%patch201 -p1 +%patch202 -p1 +%patch203 -p1 +%patch204 -p1 %patch300 -p1 %patch301 -p1 %patch302 -p1 @@ -756,6 +817,8 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch373 -p1 %patch374 -p1 %patch375 -p1 +%patch376 -p1 +#%patch377 -p1 %patch400 -p1 %patch401 -p1 %patch402 -p1 @@ -783,11 +846,11 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch434 -p1 %patch435 -p1 %patch436 -p1 -%patch437 -p1 %patch438 -p1 %patch439 -p1 %patch440 -p1 %patch441 -p1 +%patch442 -p1 %patch450 -p1 %patch500 -p1 %patch501 -p1 @@ -802,21 +865,16 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch510 -p1 %patch511 -p1 %patch512 -p1 -%patch513 -p1 %patch650 -p1 %patch651 -p1 +%patch652 -p1 %patch700 -p1 -%patch701 -p1 -%patch702 -p1 -%patch703 -p1 -%patch704 -p1 %patch999 -p1 %patch902 -p1 %patch10001 -p1 %patch10002 -p1 %patch10003 -p1 %patch10004 -p1 -%patch10005 -p1 %patch10010 -p1 %patch10011 -p1 %patch10012 -p1 @@ -842,6 +900,7 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools # %patch20000 -p1 + %build XEN_EXTRAVERSION=%version-%release XEN_EXTRAVERSION=${XEN_EXTRAVERSION#%{xvers}} diff --git a/xend-domain-lock.patch b/xend-domain-lock.patch index e87a14a..083e59a 100644 --- a/xend-domain-lock.patch +++ b/xend-domain-lock.patch @@ -94,7 +94,7 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py XendTask.log_progress(0, 30, self._constructDomain) XendTask.log_progress(31, 60, self._initDomain) -@@ -2990,6 +2992,11 @@ class XendDomainInfo: +@@ -2989,6 +2991,11 @@ class XendDomainInfo: self._stateSet(DOM_STATE_HALTED) self.domid = None # Do not push into _stateSet()! @@ -106,7 +106,7 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py finally: self.refresh_shutdown_lock.release() -@@ -4508,6 +4515,74 @@ class XendDomainInfo: +@@ -4498,6 +4505,74 @@ class XendDomainInfo: def has_device(self, dev_class, dev_uuid): return (dev_uuid in self.info['%s_refs' % dev_class.lower()]) @@ -232,15 +232,16 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendCheckpoint.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/XendCheckpoint.py +++ xen-4.0.1-testing/tools/python/xen/xend/XendCheckpoint.py -@@ -133,6 +133,7 @@ def save(fd, dominfo, network, live, dst +@@ -133,6 +133,8 @@ def save(fd, dominfo, network, live, dst dominfo.shutdown('suspend') dominfo.waitForSuspend() if line in ('suspend', 'suspended'): -+ dominfo.release_running_lock(domain_name) ++ if checkpoint == False: ++ dominfo.release_running_lock(domain_name) dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2, domain_name) log.info("Domain %d suspended.", dominfo.getDomid()) -@@ -410,6 +411,7 @@ def restore(xd, fd, dominfo = None, paus +@@ -410,6 +412,7 @@ def restore(xd, fd, dominfo = None, paus if not paused: dominfo.unpause() diff --git a/xenfb_32bpp.patch b/xenfb_32bpp.patch deleted file mode 100644 index d4c1a79..0000000 --- a/xenfb_32bpp.patch +++ /dev/null @@ -1,41 +0,0 @@ -Fix problem that press CTRL+ALT+2 and then CTRL+ALT+1 back to VM graphic console, screen cannot be restored. -xenfb_guest_copy only handles xenfb->depth=8 and 24 cases, because it assumes in xenfb->depth=16 or 32 cases, -buffer is shared, like in xenfb_update ==> qemu_create_displaysurface_from() does. But as the mentioned bug, -it didn't enter the xenfb_update do_resize hunk, buffer is not shared. -To solve that problem, either make it enter the xenfb_update do_resize hunk, or change xenfb_guest_copy(), let -it handle all cases. This patch is to let xenfb_guest_copy handle xenfb->depth=32 case. - -diff -r e4f337bb97f7 tools/ioemu-qemu-xen/hw/xenfb.c ---- a/tools/ioemu-qemu-xen/hw/xenfb.c Wed Oct 20 19:39:28 2010 +0800 -+++ b/tools/ioemu-qemu-xen/hw/xenfb.c Wed Oct 20 21:42:37 2010 +0800 -@@ -612,6 +612,12 @@ - uint8_t *data = ds_get_data(xenfb->c.ds); - - if (!is_buffer_shared(xenfb->c.ds->surface)) { -+ if (xenfb->depth == bpp) { -+ for (line = y; line < (y+h); line++) { -+ memcpy (data + (line * linesize) + (x * bpp / 8), xenfb->pixels + xenfb->offset + (line * xenfb->row_stride) + (x * xenfb->depth / 8), w * xenfb->depth / 8); -+ } -+ } -+ else{ - switch (xenfb->depth) { - case 8: - if (bpp == 16) { -@@ -631,9 +637,17 @@ - oops = 1; - } - break; -+ case 32: -+ if (bpp == 16) { -+ BLT(uint32_t, uint16_t, 8, 8, 8, 5, 6, 5); -+ } else { -+ oops = 1; -+ } -+ break; - default: - oops = 1; - } -+ } - } - if (oops) /* should not happen */ - xen_be_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n", diff --git a/xenpaging.HVMCOPY_gfn_paged_out.patch b/xenpaging.HVMCOPY_gfn_paged_out.patch index 97f1cab..31fad91 100644 --- a/xenpaging.HVMCOPY_gfn_paged_out.patch +++ b/xenpaging.HVMCOPY_gfn_paged_out.patch @@ -13,12 +13,14 @@ Signed-off-by: Olaf Hering --- xen/arch/x86/hvm/hvm.c | 4 ++++ - xen/common/memory.c | 44 +++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 43 insertions(+), 5 deletions(-) + xen/common/memory.c | 39 ++++++++++++++++++++++++++++++++++----- + 2 files changed, 38 insertions(+), 5 deletions(-) +Index: xen-4.0.1-testing/xen/arch/x86/hvm/hvm.c +=================================================================== --- xen-4.0.1-testing.orig/xen/arch/x86/hvm/hvm.c +++ xen-4.0.1-testing/xen/arch/x86/hvm/hvm.c -@@ -1853,6 +1853,8 @@ unsigned long copy_to_user_hvm(void *to, +@@ -1843,6 +1843,8 @@ unsigned long copy_to_user_hvm(void *to, rc = hvm_copy_to_guest_virt_nofault((unsigned long)to, (void *)from, len, 0); @@ -27,7 +29,7 @@ Signed-off-by: Olaf Hering return rc ? len : 0; /* fake a copy_to_user() return code */ } -@@ -1869,6 +1871,8 @@ unsigned long copy_from_user_hvm(void *t +@@ -1859,6 +1861,8 @@ unsigned long copy_from_user_hvm(void *t #endif rc = hvm_copy_from_guest_virt_nofault(to, (unsigned long)from, len, 0); @@ -36,6 +38,8 @@ Signed-off-by: Olaf Hering return rc ? len : 0; /* fake a copy_from_user() return code */ } +Index: xen-4.0.1-testing/xen/common/memory.c +=================================================================== --- xen-4.0.1-testing.orig/xen/common/memory.c +++ xen-4.0.1-testing/xen/common/memory.c @@ -47,6 +47,7 @@ static void increase_reservation(struct @@ -46,7 +50,7 @@ Signed-off-by: Olaf Hering xen_pfn_t mfn; struct domain *d = a->domain; -@@ -80,8 +81,14 @@ static void increase_reservation(struct +@@ -80,8 +81,13 @@ static void increase_reservation(struct if ( !guest_handle_is_null(a->extent_list) ) { mfn = page_to_mfn(page); @@ -54,7 +58,6 @@ Signed-off-by: Olaf Hering + ctg_ret = __copy_to_guest_offset(a->extent_list, i, &mfn, 1); + if ( unlikely(ctg_ret) ) + { -+ free_domheap_pages(page, a->extent_order); + if ( (long)ctg_ret == -EAGAIN ) + a->preempted = 1; goto out; @@ -62,7 +65,7 @@ Signed-off-by: Olaf Hering } } -@@ -93,6 +100,7 @@ static void populate_physmap(struct memo +@@ -93,6 +99,7 @@ static void populate_physmap(struct memo { struct page_info *page; unsigned long i, j; @@ -70,7 +73,7 @@ Signed-off-by: Olaf Hering xen_pfn_t gpfn, mfn; struct domain *d = a->domain; -@@ -111,8 +119,13 @@ static void populate_physmap(struct memo +@@ -111,8 +118,13 @@ static void populate_physmap(struct memo goto out; } @@ -85,7 +88,7 @@ Signed-off-by: Olaf Hering if ( a->memflags & MEMF_populate_on_demand ) { -@@ -142,8 +155,17 @@ static void populate_physmap(struct memo +@@ -142,8 +154,13 @@ static void populate_physmap(struct memo set_gpfn_from_mfn(mfn + j, gpfn + j); /* Inform the domain of the new page's machine address. */ @@ -93,10 +96,6 @@ Signed-off-by: Olaf Hering + cftg_ret = __copy_to_guest_offset(a->extent_list, i, &mfn, 1); + if ( unlikely(cftg_ret) ) + { -+ for ( j = 0; j < (1 << a->extent_order); j++ ) -+ set_gpfn_from_mfn(mfn + j, INVALID_M2P_ENTRY); -+ guest_physmap_remove_page(d, gpfn, mfn, a->extent_order); -+ free_domheap_pages(page, a->extent_order); + if ( (long)cftg_ret == -EAGAIN ) + a->preempted = 1; goto out; @@ -104,7 +103,7 @@ Signed-off-by: Olaf Hering } } } -@@ -212,6 +234,7 @@ int guest_remove_page(struct domain *d, +@@ -212,6 +229,7 @@ int guest_remove_page(struct domain *d, static void decrease_reservation(struct memop_args *a) { unsigned long i, j; @@ -112,7 +111,7 @@ Signed-off-by: Olaf Hering xen_pfn_t gmfn; if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done, -@@ -226,8 +249,13 @@ static void decrease_reservation(struct +@@ -226,8 +244,13 @@ static void decrease_reservation(struct goto out; } @@ -127,7 +126,7 @@ Signed-off-by: Olaf Hering if ( tb_init_done ) { -@@ -511,6 +539,7 @@ long do_memory_op(unsigned long cmd, XEN +@@ -511,6 +534,7 @@ long do_memory_op(unsigned long cmd, XEN int rc, op; unsigned int address_bits; unsigned long start_extent; @@ -135,7 +134,7 @@ Signed-off-by: Olaf Hering struct xen_memory_reservation reservation; struct memop_args args; domid_t domid; -@@ -524,8 +553,13 @@ long do_memory_op(unsigned long cmd, XEN +@@ -524,8 +548,13 @@ long do_memory_op(unsigned long cmd, XEN case XENMEM_populate_physmap: start_extent = cmd >> MEMOP_EXTENT_SHIFT; diff --git a/xenpaging.MRU_SIZE.patch b/xenpaging.MRU_SIZE.patch index f1c24d5..7a353c0 100644 --- a/xenpaging.MRU_SIZE.patch +++ b/xenpaging.MRU_SIZE.patch @@ -4,6 +4,8 @@ Increase recently used pages from 4MB to 64MB. Keeping more pages in memory allows the guest to make more progress if the paging file spans the entire guest memory. +(xen-unstable changeset: 22447:aba70e59a90d) + Signed-off-by: Olaf Hering --- diff --git a/xenpaging.autostart.patch b/xenpaging.autostart.patch index 662dfd7..31a74d3 100644 --- a/xenpaging.autostart.patch +++ b/xenpaging.autostart.patch @@ -81,20 +81,20 @@ Index: xen-4.0.1-testing/tools/python/xen/xend/XendConfig.py + self['platform']['xenpaging'] = None if 'timer_mode' not in self['platform']: self['platform']['timer_mode'] = 1 - if 'viridian' not in self['platform']: + if 'extid' in self['platform'] and int(self['platform']['extid']) == 1: Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -2442,6 +2442,7 @@ class XendDomainInfo: +@@ -2441,6 +2441,7 @@ class XendDomainInfo: if self.image: - self.image.createDeviceModel() + self.image.createDeviceModel(resume) + self.image.createXenPaging() #if have pass-through devs, need the virtual pci slots info from qemu self.pci_device_configure_boot() -@@ -2454,6 +2455,11 @@ class XendDomainInfo: +@@ -2453,6 +2454,11 @@ class XendDomainInfo: self.image.destroyDeviceModel() except Exception, e: log.exception("Device model destroy failed %s" % str(e)) diff --git a/xenpaging.guest_remove_page.patch b/xenpaging.guest_remove_page.patch index 16e2486..e833cc4 100644 --- a/xenpaging.guest_remove_page.patch +++ b/xenpaging.guest_remove_page.patch @@ -15,6 +15,8 @@ v2: xen/include/public/mem_event.h | 1 5 files changed, 73 insertions(+), 20 deletions(-) +Index: xen-4.0.1-testing/tools/xenpaging/xenpaging.c +=================================================================== --- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c +++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c @@ -600,12 +600,19 @@ int main(int argc, char *argv[]) @@ -42,6 +44,8 @@ v2: } /* Prepare the response */ +Index: xen-4.0.1-testing/xen/arch/x86/mm/p2m.c +=================================================================== --- xen-4.0.1-testing.orig/xen/arch/x86/mm/p2m.c +++ xen-4.0.1-testing/xen/arch/x86/mm/p2m.c @@ -2000,12 +2000,15 @@ p2m_remove_page(struct domain *d, unsign @@ -65,7 +69,7 @@ v2: } set_p2m_entry(d, gfn, _mfn(INVALID_MFN), page_order, p2m_invalid); } -@@ -2532,6 +2535,35 @@ int p2m_mem_paging_evict(struct domain * +@@ -2529,6 +2532,35 @@ int p2m_mem_paging_evict(struct domain * return 0; } @@ -101,7 +105,7 @@ v2: void p2m_mem_paging_populate(struct domain *d, unsigned long gfn) { struct vcpu *v = current; -@@ -2596,17 +2628,20 @@ void p2m_mem_paging_resume(struct domain +@@ -2593,17 +2625,20 @@ void p2m_mem_paging_resume(struct domain /* Pull the response off the ring */ mem_event_get_response(d, &rsp); @@ -132,6 +136,8 @@ v2: } /* Unpause domain */ +Index: xen-4.0.1-testing/xen/common/memory.c +=================================================================== --- xen-4.0.1-testing.orig/xen/common/memory.c +++ xen-4.0.1-testing/xen/common/memory.c @@ -162,6 +162,12 @@ int guest_remove_page(struct domain *d, @@ -147,6 +153,8 @@ v2: #else mfn = gmfn_to_mfn(d, gmfn); #endif +Index: xen-4.0.1-testing/xen/include/asm-x86/p2m.h +=================================================================== --- xen-4.0.1-testing.orig/xen/include/asm-x86/p2m.h +++ xen-4.0.1-testing/xen/include/asm-x86/p2m.h @@ -441,6 +441,8 @@ int set_shared_p2m_entry(struct domain * @@ -167,6 +175,8 @@ v2: static inline void p2m_mem_paging_populate(struct domain *d, unsigned long gfn) { } #endif +Index: xen-4.0.1-testing/xen/include/public/mem_event.h +=================================================================== --- xen-4.0.1-testing.orig/xen/include/public/mem_event.h +++ xen-4.0.1-testing/xen/include/public/mem_event.h @@ -37,6 +37,7 @@ diff --git a/xenpaging.machine_to_phys_mapping.patch b/xenpaging.machine_to_phys_mapping.patch index 1eba3c4..6c4ba6a 100644 --- a/xenpaging.machine_to_phys_mapping.patch +++ b/xenpaging.machine_to_phys_mapping.patch @@ -37,9 +37,11 @@ v2: xen/common/page_alloc.c | 9 +++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) +Index: xen-4.0.1-testing/xen/arch/x86/mm/p2m.c +=================================================================== --- xen-4.0.1-testing.orig/xen/arch/x86/mm/p2m.c +++ xen-4.0.1-testing/xen/arch/x86/mm/p2m.c -@@ -2598,9 +2598,16 @@ void p2m_mem_paging_resume(struct domain +@@ -2595,9 +2595,16 @@ void p2m_mem_paging_resume(struct domain /* Fix p2m entry */ mfn = gfn_to_mfn(d, rsp.gfn, &p2mt); @@ -59,6 +61,8 @@ v2: /* Unpause domain */ if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED ) +Index: xen-4.0.1-testing/xen/common/page_alloc.c +=================================================================== --- xen-4.0.1-testing.orig/xen/common/page_alloc.c +++ xen-4.0.1-testing/xen/common/page_alloc.c @@ -1178,9 +1178,18 @@ void free_domheap_pages(struct page_info diff --git a/xenpaging.mem_event_check_ring-free_requests.patch b/xenpaging.mem_event_check_ring-free_requests.patch index 8757d12..5c8d29d 100644 --- a/xenpaging.mem_event_check_ring-free_requests.patch +++ b/xenpaging.mem_event_check_ring-free_requests.patch @@ -3,6 +3,8 @@ Subject: xenpaging: print info when free request slots drop below 2 Add debugging aid to free request slots in the ring buffer. It should not happen that the ring gets full, print info anyway if it happens. +(xen-unstable changeset: 22439:3bbb3969236c) + Signed-off-by: Olaf Hering --- diff --git a/xenpaging.mem_paging_tool_qemu_flush_cache.patch b/xenpaging.mem_paging_tool_qemu_flush_cache.patch index 03a2fa4..c5e988d 100644 --- a/xenpaging.mem_paging_tool_qemu_flush_cache.patch +++ b/xenpaging.mem_paging_tool_qemu_flush_cache.patch @@ -15,9 +15,11 @@ Signed-off-by: Olaf Hering tools/ioemu-qemu-xen/xenstore.c | 3 +++ 1 file changed, 3 insertions(+) +Index: xen-4.0.1-testing/tools/ioemu-qemu-xen/xenstore.c +=================================================================== --- xen-4.0.1-testing.orig/tools/ioemu-qemu-xen/xenstore.c +++ xen-4.0.1-testing/tools/ioemu-qemu-xen/xenstore.c -@@ -1021,6 +1021,9 @@ static void xenstore_process_dm_command_ +@@ -1025,6 +1025,9 @@ static void xenstore_process_dm_command_ do_pci_add(par); free(par); #endif diff --git a/xenpaging.notify_policy_only_once.patch b/xenpaging.notify_policy_only_once.patch index 6467978..b1bc107 100644 --- a/xenpaging.notify_policy_only_once.patch +++ b/xenpaging.notify_policy_only_once.patch @@ -8,6 +8,8 @@ other already resumed pages too early. In the worst case, a page that was just resumed can be evicted right away, causing a deadlock in the guest. +(xen-unstable changeset: 22441:7d2c013727d7) + Signed-off-by: Olaf Hering --- @@ -16,7 +18,7 @@ Signed-off-by: Olaf Hering --- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c +++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c -@@ -377,7 +377,7 @@ int xenpaging_evict_page(xenpaging_t *pa +@@ -380,7 +380,7 @@ int xenpaging_evict_page(xenpaging_t *pa return ret; } @@ -25,7 +27,7 @@ Signed-off-by: Olaf Hering { int ret; -@@ -387,7 +387,8 @@ static int xenpaging_resume_page(xenpagi +@@ -390,7 +390,8 @@ static int xenpaging_resume_page(xenpagi goto out; /* Notify policy of page being paged in */ @@ -35,7 +37,7 @@ Signed-off-by: Olaf Hering /* Tell Xen page is ready */ ret = xc_mem_paging_resume(paging->xc_handle, paging->mem_event.domain_id, -@@ -619,7 +620,7 @@ int main(int argc, char *argv[]) +@@ -621,7 +622,7 @@ int main(int argc, char *argv[]) rsp.vcpu_id = req.vcpu_id; rsp.flags = req.flags; @@ -44,7 +46,7 @@ Signed-off-by: Olaf Hering if ( rc != 0 ) { ERROR("Error resuming page"); -@@ -648,7 +649,7 @@ int main(int argc, char *argv[]) +@@ -650,7 +651,7 @@ int main(int argc, char *argv[]) rsp.vcpu_id = req.vcpu_id; rsp.flags = req.flags; diff --git a/xenpaging.num_pages_equal_max_pages.patch b/xenpaging.num_pages_equal_max_pages.patch index e7c8f8f..f2e271f 100644 --- a/xenpaging.num_pages_equal_max_pages.patch +++ b/xenpaging.num_pages_equal_max_pages.patch @@ -4,6 +4,8 @@ Simplify paging size argument. If a negative number is specified, it means the entire guest memory should be paged out. This is useful for debugging. Also limit num_pages to the guests max_pages. +(xen-unstable changeset: 22442:1793318b35e6) + Signed-off-by: Olaf Hering --- @@ -12,7 +14,7 @@ Signed-off-by: Olaf Hering --- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c +++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c -@@ -512,8 +512,6 @@ int main(int argc, char *argv[]) +@@ -514,8 +514,6 @@ int main(int argc, char *argv[]) domain_id = atoi(argv[1]); num_pages = atoi(argv[2]); @@ -21,7 +23,7 @@ Signed-off-by: Olaf Hering /* Seed random-number generator */ srand(time(NULL)); -@@ -534,6 +532,13 @@ int main(int argc, char *argv[]) +@@ -536,6 +534,13 @@ int main(int argc, char *argv[]) return 2; } diff --git a/xenpaging.optimize_p2m_mem_paging_populate.patch b/xenpaging.optimize_p2m_mem_paging_populate.patch index 21d1cee..15add9e 100644 --- a/xenpaging.optimize_p2m_mem_paging_populate.patch +++ b/xenpaging.optimize_p2m_mem_paging_populate.patch @@ -7,6 +7,8 @@ does not need to be paused, p2m_mem_paging_resume will do nothing with the request. And also xenpaging will drop the request if the vcpu does not need a wakeup. +(xen-unstable changeset: 22444:7fe9cad00e15) + Signed-off-by: Olaf Hering --- @@ -15,7 +17,7 @@ Signed-off-by: Olaf Hering --- xen-4.0.1-testing.orig/xen/arch/x86/mm/p2m.c +++ xen-4.0.1-testing/xen/arch/x86/mm/p2m.c -@@ -2571,12 +2571,12 @@ void p2m_mem_paging_populate(struct doma +@@ -2567,12 +2567,12 @@ void p2m_mem_paging_populate(struct doma mem_event_request_t req; p2m_type_t p2mt; @@ -30,7 +32,7 @@ Signed-off-by: Olaf Hering /* Fix p2m mapping */ /* XXX: It seems inefficient to have this here, as it's only needed * in one case (ept guest accessing paging out page) */ -@@ -2594,6 +2594,11 @@ void p2m_mem_paging_populate(struct doma +@@ -2590,6 +2590,11 @@ void p2m_mem_paging_populate(struct doma vcpu_pause_nosync(v); req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED; } diff --git a/xenpaging.p2m_mem_paging_populate_if_p2m_ram_paged.patch b/xenpaging.p2m_mem_paging_populate_if_p2m_ram_paged.patch index 0833c26..bdee266 100644 --- a/xenpaging.p2m_mem_paging_populate_if_p2m_ram_paged.patch +++ b/xenpaging.p2m_mem_paging_populate_if_p2m_ram_paged.patch @@ -10,6 +10,8 @@ process of being still paged-out or already paged-in. In fact, p2m state p2m_ram_paged is the only state where the mfn type can be invalidated. +(xen-unstable changeset: 22443:48b10f9a436e) + Signed-off-by: Olaf Hering --- @@ -18,7 +20,7 @@ Signed-off-by: Olaf Hering --- xen-4.0.1-testing.orig/xen/arch/x86/mm/p2m.c +++ xen-4.0.1-testing/xen/arch/x86/mm/p2m.c -@@ -2581,7 +2581,7 @@ void p2m_mem_paging_populate(struct doma +@@ -2577,7 +2577,7 @@ void p2m_mem_paging_populate(struct doma /* XXX: It seems inefficient to have this here, as it's only needed * in one case (ept guest accessing paging out page) */ gfn_to_mfn(d, gfn, &p2mt); diff --git a/xenpaging.page_already_populated.patch b/xenpaging.page_already_populated.patch index 67be96a..6411ceb 100644 --- a/xenpaging.page_already_populated.patch +++ b/xenpaging.page_already_populated.patch @@ -2,6 +2,8 @@ Subject: xenpaging: print p2mt for already paged-in pages Add more debug output, print p2mt for pages which were requested more than once. +(xen-unstable changeset: 22440:1b87fbd10f43) + Signed-off-by: Olaf Hering --- @@ -10,7 +12,7 @@ Signed-off-by: Olaf Hering --- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c +++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c -@@ -632,8 +632,10 @@ int main(int argc, char *argv[]) +@@ -634,8 +634,10 @@ int main(int argc, char *argv[]) else { DPRINTF("page already populated (domain = %d; vcpu = %d;" diff --git a/xenpaging.pagefile.patch b/xenpaging.pagefile.patch index 1d779ad..a74b794 100644 --- a/xenpaging.pagefile.patch +++ b/xenpaging.pagefile.patch @@ -4,6 +4,8 @@ Open paging file only if xenpaging_init() succeeds. It can fail if the host does not support the required virtualization features such as EPT or if xenpaging was already started for this domain_id. +(xen-unstable changeset: 22435:7818ea9045fd) + Signed-off-by: Olaf Hering Already-Acked-by: Patrick Colp Already-Acked-by: Keir Fraser diff --git a/xenpaging.paging_prep_enomem.patch b/xenpaging.paging_prep_enomem.patch index a7863e2..1a7e930 100644 --- a/xenpaging.paging_prep_enomem.patch +++ b/xenpaging.paging_prep_enomem.patch @@ -6,6 +6,8 @@ now such condition would stall the guest because the requested page will not come back, xenpaging simply exits. So xenpaging could very well retry the allocation forever to rescue the guest. +(xen-unstable changeset: 22446:08158f001f19) + Signed-off-by: Olaf Hering --- @@ -64,7 +66,7 @@ Signed-off-by: Olaf Hering *gfn = _gfn; --- xen-4.0.1-testing.orig/xen/arch/x86/mm/p2m.c +++ xen-4.0.1-testing/xen/arch/x86/mm/p2m.c -@@ -2614,7 +2614,7 @@ int p2m_mem_paging_prep(struct domain *d +@@ -2611,7 +2611,7 @@ int p2m_mem_paging_prep(struct domain *d /* Get a free page */ page = alloc_domheap_page(d, 0); if ( unlikely(page == NULL) ) diff --git a/xenpaging.policy_linear.patch b/xenpaging.policy_linear.patch index 49ef2b1..1addff8 100644 --- a/xenpaging.policy_linear.patch +++ b/xenpaging.policy_linear.patch @@ -8,6 +8,8 @@ While doing that, xenpaging got into an endless loop because some pages cant be paged out right away. Now the policy reports an error if the gfn number wraps. +(xen-unstable changeset: 22434:0d0a18cd416f) + Signed-off-by: Olaf Hering Already-Acked-by: Patrick Colp Already-Acked-by: Keir Fraser diff --git a/xenpaging.populate_only_if_paged.patch b/xenpaging.populate_only_if_paged.patch index 85c31f1..d5d5453 100644 --- a/xenpaging.populate_only_if_paged.patch +++ b/xenpaging.populate_only_if_paged.patch @@ -6,6 +6,8 @@ will be stopped and later resumed once the page content is usable again. This matches other p2m_mem_paging_populate usage in the source tree. +(xen-unstable changeset: 22437:9a9bcf399856) + Signed-off-by: Olaf Hering --- diff --git a/xenpaging.print-arguments.patch b/xenpaging.print-arguments.patch index 88c12b4..8264b44 100644 --- a/xenpaging.print-arguments.patch +++ b/xenpaging.print-arguments.patch @@ -3,6 +3,8 @@ Subject: xenpaging: print xenpaging cmdline options Print xenpaging arguments to simplify domain_id mapping from xenpaging logfile to other logfiles and Xen console output. +(xen-unstable changeset: 22445:c7b08fc1cb8d) + Signed-off-by: Olaf Hering --- diff --git a/xenpaging.signal_handling.patch b/xenpaging.signal_handling.patch index c8b168e..881ea56 100644 --- a/xenpaging.signal_handling.patch +++ b/xenpaging.signal_handling.patch @@ -3,6 +3,8 @@ Subject: xenpaging: add signal handling Leave paging loop if xenpaging gets a signal. Remove paging file on exit. +(xen-unstable changeset: 22438:d622cf8c372e) + Signed-off-by: Olaf Hering --- diff --git a/xenpaging.tools_xenpaging_cleanup.patch b/xenpaging.tools_xenpaging_cleanup.patch index 36fc987..c0f555e 100644 --- a/xenpaging.tools_xenpaging_cleanup.patch +++ b/xenpaging.tools_xenpaging_cleanup.patch @@ -4,6 +4,7 @@ This isn't directly related to EPT checking, but does some general fix-ups to the xenpaging code (adds some extra frees, etc.) (xen-unstable changeset: 21890:3263d0ff9476) + Already-Signed-off-by: Patrick Colp Signed-off-by: Olaf Hering diff --git a/xenpaging.xenpaging_init.patch b/xenpaging.xenpaging_init.patch index 0283b5c..e967fba 100644 --- a/xenpaging.xenpaging_init.patch +++ b/xenpaging.xenpaging_init.patch @@ -3,6 +3,9 @@ Subject: xenpaging: allow only one xenpaging binary per guest Make sure only one xenpaging binary is active per domain. Print info when the host lacks the required features for xenpaging. +(xen-unstable changeset: 22436:b153d3b71504) +(xen-unstable changeset: 22511:fdf95845c2f8) + Signed-off-by: Olaf Hering Already-Acked-by: Patrick Colp Already-Acked-by: Keir Fraser @@ -29,7 +32,7 @@ v2: use perror for default case + ERROR("EPT not supported for this guest"); + break; + default: -+ perror("Error initialising shared page"); ++ ERROR("Error initialising shared page: %s", strerror(errno)); + break; + } goto err; diff --git a/xenpaging.xs_daemon_close.patch b/xenpaging.xs_daemon_close.patch deleted file mode 100644 index 972e4aa..0000000 --- a/xenpaging.xs_daemon_close.patch +++ /dev/null @@ -1,22 +0,0 @@ -Subject: xenpaging/xenstore: fix fd leak in xenstore - -Missing from commit 'libxl: Backported stuff from unstable' -Without this change, xs_daemon_open/xs_daemon_close will leak filedescriptors. - -Signed-off-by: Olaf Hering - ---- - tools/xenstore/xs.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- xen-4.0.1-testing.orig/tools/xenstore/xs.c -+++ xen-4.0.1-testing/tools/xenstore/xs.c -@@ -285,6 +285,8 @@ void xs_daemon_close(struct xs_handle *h - mutex_unlock(&h->request_mutex); - mutex_unlock(&h->reply_mutex); - mutex_unlock(&h->watch_mutex); -+ -+ close_fds_free(h); - } - - static bool read_all(int fd, void *data, unsigned int len)