diff --git a/21333-xentrace-t_info-size.patch b/21333-xentrace-t_info-size.patch index 91b4f9d..f15d9e7 100644 --- a/21333-xentrace-t_info-size.patch +++ b/21333-xentrace-t_info-size.patch @@ -11,10 +11,8 @@ is more than 1024 but less than 2048. Signed-off-by: George Dunlap -Index: xen-4.0.0-testing/xen/common/trace.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/common/trace.c -+++ xen-4.0.0-testing/xen/common/trace.c +--- a/xen/common/trace.c ++++ b/xen/common/trace.c @@ -367,7 +367,7 @@ int tb_control(xen_sysctl_tbuf_op_t *tbc case XEN_SYSCTL_TBUFOP_get_info: tbc->evt_mask = tb_event_mask; diff --git a/21408-amd-erratum-383.patch b/21408-amd-erratum-383.patch index 90cc985..fc705bc 100644 --- a/21408-amd-erratum-383.patch +++ b/21408-amd-erratum-383.patch @@ -1,3 +1,5 @@ +References: bnc#607219 + # HG changeset patch # User Keir Fraser # Date 1274178085 -3600 @@ -15,10 +17,8 @@ Signed-off-by: Wei Huang Signed-off-by: Joerg Roedel Signed-off-by: Christoph Egger -Index: xen-4.0.0-testing/xen/arch/x86/hvm/svm/svm.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/hvm/svm/svm.c -+++ xen-4.0.0-testing/xen/arch/x86/hvm/svm/svm.c +--- a/xen/arch/x86/hvm/svm/svm.c ++++ b/xen/arch/x86/hvm/svm/svm.c @@ -72,6 +72,8 @@ static void *hsa[NR_CPUS] __read_mostly; /* vmcb used for extended host state */ static void *root_vmcb[NR_CPUS] __read_mostly; @@ -28,7 +28,7 @@ Index: xen-4.0.0-testing/xen/arch/x86/hvm/svm/svm.c static void inline __update_guest_eip( struct cpu_user_regs *regs, unsigned int inst_len) { -@@ -822,6 +824,20 @@ static int svm_cpu_prepare(unsigned int +@@ -822,6 +824,20 @@ static int svm_cpu_prepare(unsigned int return 0; } @@ -115,10 +115,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/hvm/svm/svm.c break; case VMEXIT_VINTR: -Index: xen-4.0.0-testing/xen/include/asm-x86/msr-index.h -=================================================================== ---- xen-4.0.0-testing.orig/xen/include/asm-x86/msr-index.h -+++ xen-4.0.0-testing/xen/include/asm-x86/msr-index.h +--- a/xen/include/asm-x86/msr-index.h ++++ b/xen/include/asm-x86/msr-index.h @@ -146,6 +146,11 @@ #define MSR_IA32_MC8_ADDR 0x00000422 #define MSR_IA32_MC8_MISC 0x00000423 diff --git a/21526-x86-nehalem-cpuid-mask.patch b/21526-x86-nehalem-cpuid-mask.patch index a13be19..a4a4594 100644 --- a/21526-x86-nehalem-cpuid-mask.patch +++ b/21526-x86-nehalem-cpuid-mask.patch @@ -8,76 +8,193 @@ Intel: Add CPUID feature mask support for NHM processors. Signed-off-by: Jun Nakajima Signed-off-by: Liping Ke +# HG changeset patch +# User Keir Fraser +# Date 1276604335 -3600 +# Node ID 2501732e291b001711a0dc1c474bb89ce77f3110 +# Parent a2cc1db1af9c8f9b148c80f8b2c3f64bde7542f9 +x86: fix pv cpuid masking + +Invert initial values of the variables parsed into from the command +line, so that completely clearing out one or more of the four bit +fields is possible. + +Further, consolidate the command line parameter specifications into +a single place. + +Finally, as per "Intel Virtualization Technology FlexMigration +Application Note" (http://www.intel.com/Assets/PDF/manual/323850.pdf), +also handle family 6 model 0x1f. + +What remains open is the question whether pv_cpuid() shouldn't also +consume these masks. + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/cpu/amd.c ++++ b/xen/arch/x86/cpu/amd.c +@@ -33,14 +33,6 @@ void start_svm(struct cpuinfo_x86 *c); + static char opt_famrev[14]; + string_param("cpuid_mask_cpu", opt_famrev); + +-/* Finer-grained CPUID feature control. */ +-static unsigned int opt_cpuid_mask_ecx, opt_cpuid_mask_edx; +-integer_param("cpuid_mask_ecx", opt_cpuid_mask_ecx); +-integer_param("cpuid_mask_edx", opt_cpuid_mask_edx); +-static unsigned int opt_cpuid_mask_ext_ecx, opt_cpuid_mask_ext_edx; +-integer_param("cpuid_mask_ext_ecx", opt_cpuid_mask_ext_ecx); +-integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx); +- + static inline void wrmsr_amd(unsigned int index, unsigned int lo, + unsigned int hi) + { +@@ -61,7 +53,7 @@ static inline void wrmsr_amd(unsigned in + * + * The processor revision string parameter has precedene. + */ +-static void __devinit set_cpuidmask(struct cpuinfo_x86 *c) ++static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c) + { + static unsigned int feat_ecx, feat_edx; + static unsigned int extfeat_ecx, extfeat_edx; +@@ -76,12 +68,12 @@ static void __devinit set_cpuidmask(stru + ASSERT((status == not_parsed) && (smp_processor_id() == 0)); + status = no_mask; + +- if (opt_cpuid_mask_ecx | opt_cpuid_mask_edx | +- opt_cpuid_mask_ext_ecx | opt_cpuid_mask_ext_edx) { +- feat_ecx = opt_cpuid_mask_ecx ? : ~0U; +- feat_edx = opt_cpuid_mask_edx ? : ~0U; +- extfeat_ecx = opt_cpuid_mask_ext_ecx ? : ~0U; +- extfeat_edx = opt_cpuid_mask_ext_edx ? : ~0U; ++ if (~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx & ++ opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx)) { ++ feat_ecx = opt_cpuid_mask_ecx; ++ feat_edx = opt_cpuid_mask_edx; ++ extfeat_ecx = opt_cpuid_mask_ext_ecx; ++ extfeat_edx = opt_cpuid_mask_ext_edx; + } else if (*opt_famrev == '\0') { + return; + } else if (!strcmp(opt_famrev, "fam_0f_rev_c")) { +--- a/xen/arch/x86/cpu/common.c ++++ b/xen/arch/x86/cpu/common.c +@@ -22,6 +22,15 @@ static int cachesize_override __cpuinitd + static int disable_x86_fxsr __cpuinitdata; + static int disable_x86_serial_nr __cpuinitdata; + ++unsigned int __devinitdata opt_cpuid_mask_ecx = ~0u; ++integer_param("cpuid_mask_ecx", opt_cpuid_mask_ecx); ++unsigned int __devinitdata opt_cpuid_mask_edx = ~0u; ++integer_param("cpuid_mask_edx", opt_cpuid_mask_edx); ++unsigned int __devinitdata opt_cpuid_mask_ext_ecx = ~0u; ++integer_param("cpuid_mask_ext_ecx", opt_cpuid_mask_ext_ecx); ++unsigned int __devinitdata opt_cpuid_mask_ext_edx = ~0u; ++integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx); ++ + struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; + + /* +--- a/xen/arch/x86/cpu/cpu.h ++++ b/xen/arch/x86/cpu/cpu.h +@@ -21,6 +21,9 @@ struct cpu_dev { + + extern struct cpu_dev * cpu_devs [X86_VENDOR_NUM]; + ++extern unsigned int opt_cpuid_mask_ecx, opt_cpuid_mask_edx; ++extern unsigned int opt_cpuid_mask_ext_ecx, opt_cpuid_mask_ext_edx; ++ + extern int get_model_name(struct cpuinfo_x86 *c); + extern void display_cacheinfo(struct cpuinfo_x86 *c); + --- a/xen/arch/x86/cpu/intel.c +++ b/xen/arch/x86/cpu/intel.c -@@ -29,6 +29,9 @@ extern int trap_init_f00f_bug(void); - static unsigned int opt_cpuid_mask_ecx, opt_cpuid_mask_edx; - integer_param("cpuid_mask_ecx", opt_cpuid_mask_ecx); - integer_param("cpuid_mask_edx", opt_cpuid_mask_edx); -+static unsigned int opt_cpuid_mask_ext_ecx, opt_cpuid_mask_ext_edx; -+integer_param("cpuid_mask_ext_ecx", opt_cpuid_mask_ext_ecx); -+integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx); +@@ -20,16 +20,6 @@ + extern int trap_init_f00f_bug(void); + +-/* +- * opt_cpuid_mask_ecx/edx: cpuid.1[ecx, edx] feature mask. +- * For example, E8400[Intel Core 2 Duo Processor series] ecx = 0x0008E3FD, +- * edx = 0xBFEBFBFF when executing CPUID.EAX = 1 normally. If you want to +- * 'rev down' to E8400, you can set these values in these Xen boot parameters. +- */ +-static unsigned int opt_cpuid_mask_ecx, opt_cpuid_mask_edx; +-integer_param("cpuid_mask_ecx", opt_cpuid_mask_ecx); +-integer_param("cpuid_mask_edx", opt_cpuid_mask_edx); +- static int use_xsave = 1; boolean_param("xsave", use_xsave); -@@ -40,24 +43,46 @@ boolean_param("xsave", use_xsave); + +@@ -40,24 +30,57 @@ boolean_param("xsave", use_xsave); struct movsl_mask movsl_mask __read_mostly; #endif -static void __devinit set_cpuidmask(void) -+static void __devinit set_cpuidmask(struct cpuinfo_x86 *c) ++/* ++ * opt_cpuid_mask_ecx/edx: cpuid.1[ecx, edx] feature mask. ++ * For example, E8400[Intel Core 2 Duo Processor series] ecx = 0x0008E3FD, ++ * edx = 0xBFEBFBFF when executing CPUID.EAX = 1 normally. If you want to ++ * 'rev down' to E8400, you can set these values in these Xen boot parameters. ++ */ ++static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c) { - unsigned int eax, ebx, ecx, edx, model; -+ unsigned int model = c->x86_model; ++ const char *extra = ""; - if (!(opt_cpuid_mask_ecx | opt_cpuid_mask_edx)) -+ if (!(opt_cpuid_mask_ecx | opt_cpuid_mask_edx | -+ opt_cpuid_mask_ext_ecx | opt_cpuid_mask_ext_edx)) ++ if (!~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx & ++ opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx)) return; - cpuid(0x00000001, &eax, &ebx, &ecx, &edx); - model = ((eax & 0xf0000) >> 12) | ((eax & 0xf0) >> 4); - if (!((model == 0x1d) || ((model == 0x17) && ((eax & 0xf) >= 4)))) { -+ if (c->x86 != 0x6) /* Only family 6 supports this feature */ -+ return; -+ -+ if ((model == 0x1d) || ((model == 0x17) && (c->x86_mask >= 4))) { -+ wrmsr(MSR_IA32_CPUID_FEATURE_MASK1, -+ opt_cpuid_mask_ecx ? : ~0u, -+ opt_cpuid_mask_edx ? : ~0u); -+ } -+/* +- printk(XENLOG_ERR "Cannot set CPU feature mask on CPU#%d\n", +- smp_processor_id()); ++ /* Only family 6 supports this feature */ ++ switch ((c->x86 == 6) * c->x86_model) { ++ case 0x17: ++ if ((c->x86_mask & 0x0f) < 4) ++ break; ++ /* fall through */ ++ case 0x1d: ++ wrmsr(MSR_INTEL_CPUID_FEATURE_MASK, ++ opt_cpuid_mask_ecx, ++ opt_cpuid_mask_edx); ++ if (!~(opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx)) ++ return; ++ extra = "extended "; ++ break; ++/* + * CPU supports this feature if the processor signature meets the following: + * (CPUID.(EAX=01h):EAX) > 000106A2h, or + * (CPUID.(EAX=01h):EAX) == 000106Exh, 0002065xh, 000206Cxh, 000206Exh, or 000206Fxh + * + */ -+ else if (((model == 0x1a) && (c->x86_mask > 2)) -+ || model == 0x1e -+ || model == 0x25 -+ || model == 0x2c -+ || model == 0x2e -+ || model == 0x2f) { -+ wrmsr(MSR_IA32_CPUID1_FEATURE_MASK, -+ opt_cpuid_mask_ecx ? : ~0u, -+ opt_cpuid_mask_edx ? : ~0u); -+ wrmsr(MSR_IA32_CPUID80000001_FEATURE_MASK, -+ opt_cpuid_mask_ext_ecx ? : ~0u, -+ opt_cpuid_mask_ext_edx ? : ~0u); -+ } -+ else { - printk(XENLOG_ERR "Cannot set CPU feature mask on CPU#%d\n", - smp_processor_id()); ++ case 0x1a: ++ if ((c->x86_mask & 0x0f) <= 2) ++ break; ++ /* fall through */ ++ case 0x1e: case 0x1f: ++ case 0x25: case 0x2c: case 0x2e: case 0x2f: ++ wrmsr(MSR_INTEL_CPUID1_FEATURE_MASK, ++ opt_cpuid_mask_ecx, ++ opt_cpuid_mask_edx); ++ wrmsr(MSR_INTEL_CPUID80000001_FEATURE_MASK, ++ opt_cpuid_mask_ext_ecx, ++ opt_cpuid_mask_ext_edx); return; } -- + - wrmsr(MSR_IA32_CPUID_FEATURE_MASK1, - opt_cpuid_mask_ecx ? : ~0u, - opt_cpuid_mask_edx ? : ~0u); ++ printk(XENLOG_ERR "Cannot set CPU feature mask on CPU#%d\n", ++ smp_processor_id()); } void __devinit early_intel_workaround(struct cpuinfo_x86 *c) -@@ -179,7 +204,7 @@ static void __devinit init_intel(struct +@@ -179,7 +202,7 @@ static void __devinit init_intel(struct detect_ht(c); @@ -88,12 +205,16 @@ Signed-off-by: Liping Ke Intel_errata_workarounds(c); --- a/xen/include/asm-x86/msr-index.h +++ b/xen/include/asm-x86/msr-index.h -@@ -158,6 +158,8 @@ +@@ -156,8 +156,10 @@ + #define MSR_P6_EVNTSEL0 0x00000186 + #define MSR_P6_EVNTSEL1 0x00000187 - /* MSR for cpuid feature mask */ - #define MSR_IA32_CPUID_FEATURE_MASK1 0x00000478 -+#define MSR_IA32_CPUID1_FEATURE_MASK 0x00000130 -+#define MSR_IA32_CPUID80000001_FEATURE_MASK 0x00000131 +-/* MSR for cpuid feature mask */ +-#define MSR_IA32_CPUID_FEATURE_MASK1 0x00000478 ++/* MSRs for Intel cpuid feature mask */ ++#define MSR_INTEL_CPUID_FEATURE_MASK 0x00000478 ++#define MSR_INTEL_CPUID1_FEATURE_MASK 0x00000130 ++#define MSR_INTEL_CPUID80000001_FEATURE_MASK 0x00000131 /* MSRs & bits used for VMX enabling */ #define MSR_IA32_VMX_BASIC 0x480 diff --git a/21712-amd-osvw.patch b/21712-amd-osvw.patch index 096424b..34cebd3 100644 --- a/21712-amd-osvw.patch +++ b/21712-amd-osvw.patch @@ -17,10 +17,8 @@ Signed-off-by: Wei Huang Signed-off-by: Hans Rosenfeld Acked-by: Jan Beulich -Index: xen-4.0.0-testing/xen/arch/x86/cpu/amd.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/cpu/amd.c -+++ xen-4.0.0-testing/xen/arch/x86/cpu/amd.c +--- a/xen/arch/x86/cpu/amd.c ++++ b/xen/arch/x86/cpu/amd.c @@ -7,11 +7,11 @@ #include #include @@ -34,7 +32,7 @@ Index: xen-4.0.0-testing/xen/arch/x86/cpu/amd.c void start_svm(struct cpuinfo_x86 *c); -@@ -157,6 +157,54 @@ static void __devinit set_cpuidmask(stru +@@ -149,6 +149,54 @@ static void __devinit set_cpuidmask(cons } /* @@ -89,9 +87,7 @@ Index: xen-4.0.0-testing/xen/arch/x86/cpu/amd.c * amd_flush_filter={on,off}. Forcibly Enable or disable the TLB flush * filter on AMD 64-bit processors. */ -Index: xen-4.0.0-testing/xen/arch/x86/cpu/amd.h -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/cpu/amd.h +--- a/xen/arch/x86/cpu/amd.h +++ /dev/null @@ -1,103 +0,0 @@ -/* @@ -197,10 +193,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/cpu/amd.h -#define AMD_EXTFEATURES_FAM11h_REV_B_EDX AMD_EXTFEATURES_K8_REV_G_EDX - -#endif /* __AMD_H__ */ -Index: xen-4.0.0-testing/xen/arch/x86/hvm/svm/asid.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/hvm/svm/asid.c -+++ xen-4.0.0-testing/xen/arch/x86/hvm/svm/asid.c +--- a/xen/arch/x86/hvm/svm/asid.c ++++ b/xen/arch/x86/hvm/svm/asid.c @@ -21,14 +21,14 @@ #include #include @@ -218,10 +212,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/hvm/svm/asid.c nasids = cpuid_ebx(0x8000000A); hvm_asid_init(nasids); -Index: xen-4.0.0-testing/xen/arch/x86/hvm/svm/svm.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/hvm/svm/svm.c -+++ xen-4.0.0-testing/xen/arch/x86/hvm/svm/svm.c +--- a/xen/arch/x86/hvm/svm/svm.c ++++ b/xen/arch/x86/hvm/svm/svm.c @@ -34,6 +34,7 @@ #include #include @@ -230,7 +222,7 @@ Index: xen-4.0.0-testing/xen/arch/x86/hvm/svm/svm.c #include #include #include -@@ -828,8 +829,8 @@ static void svm_init_erratum_383(struct +@@ -828,8 +829,8 @@ static void svm_init_erratum_383(struct { uint64_t msr_content; @@ -241,10 +233,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/hvm/svm/svm.c return; rdmsrl(MSR_AMD64_DC_CFG, msr_content); -Index: xen-4.0.0-testing/xen/include/asm-x86/amd.h -=================================================================== --- /dev/null -+++ xen-4.0.0-testing/xen/include/asm-x86/amd.h ++++ b/xen/include/asm-x86/amd.h @@ -0,0 +1,137 @@ +/* + * amd.h - AMD processor specific definitions @@ -383,10 +373,8 @@ Index: xen-4.0.0-testing/xen/include/asm-x86/amd.h + +int cpu_has_amd_erratum(const struct cpuinfo_x86 *, int, ...); +#endif /* __AMD_H__ */ -Index: xen-4.0.0-testing/xen/include/asm-x86/msr-index.h -=================================================================== ---- xen-4.0.0-testing.orig/xen/include/asm-x86/msr-index.h -+++ xen-4.0.0-testing/xen/include/asm-x86/msr-index.h +--- a/xen/include/asm-x86/msr-index.h ++++ b/xen/include/asm-x86/msr-index.h @@ -251,6 +251,10 @@ #define MSR_AMD_PATCHLEVEL 0x0000008b #define MSR_AMD_PATCHLOADER 0xc0010020 diff --git a/21716-iommu-alloc.patch b/21716-iommu-alloc.patch new file mode 100644 index 0000000..d396aa5 --- /dev/null +++ b/21716-iommu-alloc.patch @@ -0,0 +1,211 @@ +# HG changeset patch +# User Keir Fraser +# Date 1279186958 -3600 +# Node ID 4ba86edf38f816a0d94cfb85b90074a72113e41c +# Parent 57859775f88f5339fa256e43ee2744be7226c093 +x2APIC/VT-d: allocate iommu when create a drhd + +A drhd is created when parse ACPI DMAR table, but drhd->iommu is not +allocated until iommu setup. But iommu is needed by x2APIC which will +enable interrupt remapping before iommu setup. This patch allocates +iommu when create drhd. And then drhd->ecap can be removed because +it's the same as iommu->ecap. + +Signed-off-by: Weidong Han +xen-unstable changeset: 21716:64a80813978f +xen-unstable date: Mon Jul 05 08:29:10 2010 +0100 + +Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/dmar.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/dmar.c ++++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/dmar.c +@@ -32,6 +32,7 @@ + #include "dmar.h" + #include "iommu.h" + #include "extern.h" ++#include "vtd.h" + + #undef PREFIX + #define PREFIX VTDPREFIX "ACPI DMAR:" +@@ -378,7 +379,6 @@ acpi_parse_one_drhd(struct acpi_dmar_ent + struct acpi_table_drhd * drhd = (struct acpi_table_drhd *)header; + void *dev_scope_start, *dev_scope_end; + struct acpi_drhd_unit *dmaru; +- void *addr; + int ret; + static int include_all = 0; + +@@ -397,8 +397,9 @@ acpi_parse_one_drhd(struct acpi_dmar_ent + dprintk(VTDPREFIX, " dmaru->address = %"PRIx64"\n", + dmaru->address); + +- addr = map_to_nocache_virt(0, drhd->address); +- dmaru->ecap = dmar_readq(addr, DMAR_ECAP_REG); ++ ret = iommu_alloc(dmaru); ++ if ( ret ) ++ goto out; + + dev_scope_start = (void *)(drhd + 1); + dev_scope_end = ((void *)drhd) + header->length; +@@ -420,7 +421,7 @@ acpi_parse_one_drhd(struct acpi_dmar_ent + } + + if ( ret ) +- xfree(dmaru); ++ goto out; + else if ( force_iommu || dmaru->include_all ) + acpi_register_drhd_unit(dmaru); + else +@@ -451,14 +452,15 @@ acpi_parse_one_drhd(struct acpi_dmar_ent + + if ( invalid_cnt ) + { +- xfree(dmaru); +- + if ( iommu_workaround_bios_bug && + invalid_cnt == dmaru->scope.devices_cnt ) + { + dprintk(XENLOG_WARNING VTDPREFIX, + " Workaround BIOS bug: ignore the DRHD due to all " + "devices under its scope are not PCI discoverable!\n"); ++ ++ iommu_free(dmaru); ++ xfree(dmaru); + } + else + { +@@ -474,6 +476,12 @@ acpi_parse_one_drhd(struct acpi_dmar_ent + acpi_register_drhd_unit(dmaru); + } + ++out: ++ if ( ret ) ++ { ++ iommu_free(dmaru); ++ xfree(dmaru); ++ } + return ret; + } + +Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/dmar.h +=================================================================== +--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/dmar.h ++++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/dmar.h +@@ -50,7 +50,6 @@ struct acpi_drhd_unit { + struct dmar_scope scope; /* must be first member of struct */ + struct list_head list; + u64 address; /* register base address of the unit */ +- u64 ecap; + u8 include_all:1; + struct iommu *iommu; + struct list_head ioapic_list; +Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/intremap.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/intremap.c ++++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/intremap.c +@@ -135,15 +135,20 @@ int iommu_supports_eim(void) + /* We MUST have a DRHD unit for each IOAPIC. */ + for ( apic = 0; apic < nr_ioapics; apic++ ) + if ( !ioapic_to_drhd(IO_APIC_ID(apic)) ) ++ { ++ dprintk(XENLOG_WARNING VTDPREFIX, ++ "There is not a DRHD for IOAPIC 0x%x (id: 0x%x)!\n", ++ apic, IO_APIC_ID(apic)); + return 0; ++ } + + if ( list_empty(&acpi_drhd_units) ) + return 0; + + for_each_drhd_unit ( drhd ) +- if ( !ecap_queued_inval(drhd->ecap) || +- !ecap_intr_remap(drhd->ecap) || +- !ecap_eim(drhd->ecap) ) ++ if ( !ecap_queued_inval(drhd->iommu->ecap) || ++ !ecap_intr_remap(drhd->iommu->ecap) || ++ !ecap_eim(drhd->iommu->ecap) ) + return 0; + + return 1; +Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/iommu.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/iommu.c ++++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/iommu.c +@@ -143,15 +143,18 @@ struct iommu_flush *iommu_get_flush(stru + return iommu ? &iommu->intel->flush : NULL; + } + +-static unsigned int clflush_size; + static int iommus_incoherent; + static void __iommu_flush_cache(void *addr, unsigned int size) + { + int i; ++ static unsigned int clflush_size = 0; + + if ( !iommus_incoherent ) + return; + ++ if ( clflush_size == 0 ) ++ clflush_size = get_cache_line_size(); ++ + for ( i = 0; i < size; i += clflush_size ) + cacheline_flush((char *)addr + i); + } +@@ -1036,7 +1039,7 @@ static int iommu_set_interrupt(struct io + return irq; + } + +-static int iommu_alloc(struct acpi_drhd_unit *drhd) ++int __init iommu_alloc(struct acpi_drhd_unit *drhd) + { + struct iommu *iommu; + unsigned long sagaw, nr_dom; +@@ -1130,7 +1133,7 @@ static int iommu_alloc(struct acpi_drhd_ + return 0; + } + +-static void iommu_free(struct acpi_drhd_unit *drhd) ++void __init iommu_free(struct acpi_drhd_unit *drhd) + { + struct iommu *iommu = drhd->iommu; + +@@ -1938,8 +1941,6 @@ int intel_vtd_setup(void) + + platform_quirks(); + +- clflush_size = get_cache_line_size(); +- + irq_to_iommu = xmalloc_array(struct iommu*, nr_irqs); + BUG_ON(!irq_to_iommu); + memset(irq_to_iommu, 0, nr_irqs * sizeof(struct iommu*)); +@@ -1953,9 +1954,6 @@ int intel_vtd_setup(void) + */ + for_each_drhd_unit ( drhd ) + { +- if ( iommu_alloc(drhd) != 0 ) +- goto error; +- + iommu = drhd->iommu; + + if ( iommu_snoop && !ecap_snp_ctl(iommu->ecap) ) +@@ -1995,8 +1993,6 @@ int intel_vtd_setup(void) + return 0; + + error: +- for_each_drhd_unit ( drhd ) +- iommu_free(drhd); + iommu_enabled = 0; + iommu_snoop = 0; + iommu_passthrough = 0; +Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/vtd.h +=================================================================== +--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/vtd.h ++++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/vtd.h +@@ -108,4 +108,7 @@ void unmap_vtd_domain_page(void *va); + void iommu_flush_cache_entry(void *addr, unsigned int size); + void iommu_flush_cache_page(void *addr, unsigned long npages); + ++int iommu_alloc(struct acpi_drhd_unit *drhd); ++void iommu_free(struct acpi_drhd_unit *drhd); ++ + #endif // _VTD_H_ diff --git a/21717-ir-qi.patch b/21717-ir-qi.patch new file mode 100644 index 0000000..6afa561 --- /dev/null +++ b/21717-ir-qi.patch @@ -0,0 +1,200 @@ +# HG changeset patch +# User Keir Fraser +# Date 1279186999 -3600 +# Node ID a35e5f33a72eee3d00cec6972bb93585609559e2 +# Parent 4ba86edf38f816a0d94cfb85b90074a72113e41c +x2APIC/VT-d: improve interrupt remapping and queued invalidation enabling and disabling + +x2APIC depends on interrupt remapping, so interrupt remapping needs to +be enabled before x2APIC. Usually x2APIC is not enabled +(x2apic_enabled=0) when enable interrupt remapping, although x2APIC +will be enabled later. So it needs to pass a parameter to set +interrupt mode in intremap_enable, instead of checking +x2apic_enable. This patch adds a parameter "eim" to intremap_enable to +achieve it. Interrupt remapping and queued invalidation are already +enabled when enable x2apic, so it needn't to enable them again when +setup iommu. This patch checks if interrupt remapping and queued +invalidation are already enable or not, and won't enable them if +already enabled. It does the similar in disabling, that's to say don't +disable them if already disabled. + +Signed-off-by: Weidong Han +xen-unstable changeset: 21717:176956d1d2fd +xen-unstable date: Mon Jul 05 08:30:25 2010 +0100 + +Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/extern.h +=================================================================== +--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/extern.h ++++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/extern.h +@@ -33,7 +33,7 @@ extern struct keyhandler dump_iommu_info + + int enable_qinval(struct iommu *iommu); + void disable_qinval(struct iommu *iommu); +-int enable_intremap(struct iommu *iommu); ++int enable_intremap(struct iommu *iommu, int eim); + void disable_intremap(struct iommu *iommu); + int queue_invalidate_context(struct iommu *iommu, + u16 did, u16 source_id, u8 function_mask, u8 granu); +Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/intremap.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/intremap.c ++++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/intremap.c +@@ -709,7 +709,7 @@ void msi_msg_write_remap_rte( + } + #endif + +-int enable_intremap(struct iommu *iommu) ++int enable_intremap(struct iommu *iommu, int eim) + { + struct acpi_drhd_unit *drhd; + struct ir_ctrl *ir_ctrl; +@@ -719,10 +719,25 @@ int enable_intremap(struct iommu *iommu) + ASSERT(ecap_intr_remap(iommu->ecap) && iommu_intremap); + + ir_ctrl = iommu_ir_ctrl(iommu); ++ sts = dmar_readl(iommu->reg, DMAR_GSTS_REG); ++ ++ /* Return if already enabled by Xen */ ++ if ( (sts & DMA_GSTS_IRES) && ir_ctrl->iremap_maddr ) ++ return 0; ++ ++ sts = dmar_readl(iommu->reg, DMAR_GSTS_REG); ++ if ( !(sts & DMA_GSTS_QIES) ) ++ { ++ dprintk(XENLOG_ERR VTDPREFIX, ++ "Queued invalidation is not enabled, should not enable " ++ "interrupt remapping\n"); ++ return -EINVAL; ++ } ++ + if ( ir_ctrl->iremap_maddr == 0 ) + { + drhd = iommu_to_drhd(iommu); +- ir_ctrl->iremap_maddr = alloc_pgtable_maddr(drhd, IREMAP_ARCH_PAGE_NR ); ++ ir_ctrl->iremap_maddr = alloc_pgtable_maddr(drhd, IREMAP_ARCH_PAGE_NR); + if ( ir_ctrl->iremap_maddr == 0 ) + { + dprintk(XENLOG_WARNING VTDPREFIX, +@@ -735,7 +750,7 @@ int enable_intremap(struct iommu *iommu) + #ifdef CONFIG_X86 + /* set extended interrupt mode bit */ + ir_ctrl->iremap_maddr |= +- x2apic_enabled ? (1 << IRTA_REG_EIME_SHIFT) : 0; ++ eim ? (1 << IRTA_REG_EIME_SHIFT) : 0; + #endif + spin_lock_irqsave(&iommu->register_lock, flags); + +@@ -772,13 +787,18 @@ void disable_intremap(struct iommu *iomm + u32 sts; + unsigned long flags; + +- ASSERT(ecap_intr_remap(iommu->ecap) && iommu_intremap); ++ if ( !ecap_intr_remap(iommu->ecap) ) ++ return; + + spin_lock_irqsave(&iommu->register_lock, flags); + sts = dmar_readl(iommu->reg, DMAR_GSTS_REG); ++ if ( !(sts & DMA_GSTS_IRES) ) ++ goto out; ++ + dmar_writel(iommu->reg, DMAR_GCMD_REG, sts & (~DMA_GCMD_IRE)); + + IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl, + !(sts & DMA_GSTS_IRES), sts); ++out: + spin_unlock_irqrestore(&iommu->register_lock, flags); + } +Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/iommu.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/iommu.c ++++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/iommu.c +@@ -1829,24 +1829,20 @@ static int init_vtd_hw(void) + spin_lock_irqsave(&iommu->register_lock, flags); + dmar_writel(iommu->reg, DMAR_FECTL_REG, 0); + spin_unlock_irqrestore(&iommu->register_lock, flags); +- +- /* initialize flush functions */ +- flush = iommu_get_flush(iommu); +- flush->context = flush_context_reg; +- flush->iotlb = flush_iotlb_reg; + } + +- if ( iommu_qinval ) ++ for_each_drhd_unit ( drhd ) + { +- for_each_drhd_unit ( drhd ) ++ iommu = drhd->iommu; ++ /* ++ * If queued invalidation not enabled, use regiser based ++ * invalidation ++ */ ++ if ( enable_qinval(iommu) != 0 ) + { +- iommu = drhd->iommu; +- if ( enable_qinval(iommu) != 0 ) +- { +- dprintk(XENLOG_INFO VTDPREFIX, +- "Failed to enable Queued Invalidation!\n"); +- break; +- } ++ flush = iommu_get_flush(iommu); ++ flush->context = flush_context_reg; ++ flush->iotlb = flush_iotlb_reg; + } + } + +@@ -1872,9 +1868,9 @@ static int init_vtd_hw(void) + for_each_drhd_unit ( drhd ) + { + iommu = drhd->iommu; +- if ( enable_intremap(iommu) != 0 ) ++ if ( enable_intremap(iommu, 0) != 0 ) + { +- dprintk(XENLOG_INFO VTDPREFIX, ++ dprintk(XENLOG_WARNING VTDPREFIX, + "Failed to enable Interrupt Remapping!\n"); + break; + } +Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/qinval.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/qinval.c ++++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/qinval.c +@@ -437,10 +437,16 @@ int enable_qinval(struct iommu *iommu) + u32 sts; + unsigned long flags; + ++ if ( !ecap_queued_inval(iommu->ecap) || !iommu_qinval ) ++ return -ENOENT; ++ + qi_ctrl = iommu_qi_ctrl(iommu); + flush = iommu_get_flush(iommu); + +- ASSERT(ecap_queued_inval(iommu->ecap) && iommu_qinval); ++ /* Return if already enabled by Xen */ ++ sts = dmar_readl(iommu->reg, DMAR_GSTS_REG); ++ if ( (sts & DMA_GSTS_QIES) && qi_ctrl->qinval_maddr ) ++ return 0; + + if ( qi_ctrl->qinval_maddr == 0 ) + { +@@ -488,14 +494,19 @@ void disable_qinval(struct iommu *iommu) + u32 sts; + unsigned long flags; + +- ASSERT(ecap_queued_inval(iommu->ecap) && iommu_qinval); ++ if ( !ecap_queued_inval(iommu->ecap) ) ++ return; + + spin_lock_irqsave(&iommu->register_lock, flags); + sts = dmar_readl(iommu->reg, DMAR_GSTS_REG); ++ if ( !(sts & DMA_GSTS_QIES) ) ++ goto out; ++ + dmar_writel(iommu->reg, DMAR_GCMD_REG, sts & (~DMA_GCMD_QIE)); + + /* Make sure hardware complete it */ + IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl, + !(sts & DMA_GSTS_QIES), sts); ++out: + spin_unlock_irqrestore(&iommu->register_lock, flags); + } diff --git a/21718-x2apic-logic.patch b/21718-x2apic-logic.patch new file mode 100644 index 0000000..c7a44c5 --- /dev/null +++ b/21718-x2apic-logic.patch @@ -0,0 +1,672 @@ +# HG changeset patch +# User Keir Fraser +# Date 1279187030 -3600 +# Node ID d5727c760ff074177ce1d9e7c36dbbe2c1f4f37f +# Parent a35e5f33a72eee3d00cec6972bb93585609559e2 +x2APIC: improve enabling logic + +This patch masks PIC and IOAPIC RTE's before x2APIC enabling, unmask +and restore them after x2APIC enabling. It also really enables +interrupt remapping before x2APIC enabling instead of just checking +interrupt remapping setting. This patch also handles all x2APIC +configuration including BIOS settings and command line +settings. Especially, it handles that BIOS hands over in x2APIC mode +(when there is apic id > 255). It checks if x2APIC is already enabled +by BIOS. If already enabled, it will disable interrupt remapping and +queued invalidation first, then enable them again. + +Signed-off-by: Weidong Han +xen-unstable changeset: 21718:34f612ed4184 +xen-unstable date: Mon Jul 05 08:31:29 2010 +0100 + +Index: xen-4.0.0-testing/xen/arch/x86/apic.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/arch/x86/apic.c ++++ xen-4.0.0-testing/xen/arch/x86/apic.c +@@ -70,6 +70,9 @@ int apic_verbosity; + 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 +@@ -493,6 +496,47 @@ static void apic_pm_activate(void) + apic_pm_state.active = 1; + } + ++static void resume_x2apic(void) ++{ ++ uint64_t msr_content; ++ struct IO_APIC_route_entry **ioapic_entries = NULL; ++ ++ ASSERT(x2apic_enabled); ++ ++ ioapic_entries = alloc_ioapic_entries(); ++ if ( !ioapic_entries ) ++ { ++ printk("Allocate ioapic_entries failed\n"); ++ goto out; ++ } ++ ++ if ( save_IO_APIC_setup(ioapic_entries) ) ++ { ++ printk("Saving IO-APIC state failed\n"); ++ goto out; ++ } ++ ++ mask_8259A(); ++ 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); ++ } ++ ++ restore_IO_APIC_setup(ioapic_entries); ++ unmask_8259A(); ++ ++out: ++ if ( ioapic_entries ) ++ free_ioapic_entries(ioapic_entries); ++} ++ + void __devinit setup_local_APIC(void) + { + unsigned long oldvalue, value, ver, maxlvt; +@@ -731,7 +775,7 @@ int lapic_resume(void) + wrmsr(MSR_IA32_APICBASE, l, h); + } + else +- enable_x2apic(); ++ resume_x2apic(); + + apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); + apic_write(APIC_ID, apic_pm_state.apic_id); +@@ -895,45 +939,152 @@ no_apic: + return -1; + } + +-void enable_x2apic(void) ++void check_x2apic_preenabled(void) + { + u32 lo, hi; + +- if ( smp_processor_id() == 0 ) ++ if ( !x2apic_is_available() ) ++ return; ++ ++ rdmsr(MSR_IA32_APICBASE, lo, hi); ++ if ( lo & MSR_IA32_APICBASE_EXTD ) + { +- if ( !iommu_supports_eim() ) ++ printk("x2APIC mode is already enabled by BIOS.\n"); ++ x2apic_preenabled = 1; ++ x2apic_enabled = 1; ++ } ++} ++ ++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 ( x2apic_preenabled ) ++ { ++ /* ++ * 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"); ++ } ++ ++ x2apic_genapic = apic_x2apic_probe(); ++ if ( x2apic_genapic ) ++ genapic = x2apic_genapic; ++ else ++ { ++ if ( x2apic_cmdline_disable() ) + { +- printk("x2APIC would not be enabled without EIM.\n"); +- return; ++ 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; ++ } + } +- +- if ( apic_x2apic_phys.probe() ) +- genapic = &apic_x2apic_phys; +- else if ( apic_x2apic_cluster.probe() ) +- genapic = &apic_x2apic_cluster; + else + { +- printk("x2APIC would not be enabled due to x2apic=off.\n"); +- return; ++ 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; ++ } ++ } + } ++ } + +- x2apic_enabled = 1; +- printk("Switched to APIC driver %s.\n", genapic->name); ++ ioapic_entries = alloc_ioapic_entries(); ++ if ( !ioapic_entries ) ++ { ++ printk("Allocate ioapic_entries failed\n"); ++ goto out; + } +- else ++ ++ if ( save_IO_APIC_setup(ioapic_entries) ) + { +- BUG_ON(!x2apic_enabled); /* APs only enable x2apic when BSP did so. */ ++ printk("Saving IO-APIC state failed\n"); ++ goto out; + } + ++ mask_8259A(); ++ mask_IO_APIC_setup(ioapic_entries); ++ ++ if ( iommu_enable_IR() ) ++ { ++ printk("Would not enable x2APIC due to interrupt remapping " ++ "cannot be enabled.\n"); ++ goto restore_out; ++ } ++ ++ x2apic_enabled = 1; ++ printk("Switched to APIC driver %s.\n", genapic->name); ++ ++ 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"); ++ } ++ } ++ ++restore_out: ++ restore_IO_APIC_setup(ioapic_entries); ++ unmask_8259A(); ++ ++out: ++ if ( ioapic_entries ) ++ free_ioapic_entries(ioapic_entries); ++} ++ ++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); +- printk("x2APIC mode enabled.\n"); + } ++} ++ ++void enable_x2apic(void) ++{ ++ if ( smp_processor_id() == 0 ) ++ enable_bsp_x2apic(); + else +- printk("x2APIC mode enabled by BIOS.\n"); ++ enable_ap_x2apic(); + } + + void __init init_apic_mappings(void) +Index: xen-4.0.0-testing/xen/arch/x86/genapic/x2apic.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/arch/x86/genapic/x2apic.c ++++ xen-4.0.0-testing/xen/arch/x86/genapic/x2apic.c +@@ -29,6 +29,11 @@ boolean_param("x2apic", x2apic); + 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) + { + return x2apic && x2apic_phys && x2apic_is_available() && +@@ -51,6 +56,20 @@ const struct genapic apic_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; +Index: xen-4.0.0-testing/xen/arch/x86/i8259.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/arch/x86/i8259.c ++++ xen-4.0.0-testing/xen/arch/x86/i8259.c +@@ -175,6 +175,26 @@ int i8259A_irq_pending(unsigned int irq) + return ret; + } + ++void mask_8259A(void) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&i8259A_lock, flags); ++ outb(0xff, 0xA1); ++ outb(0xff, 0x21); ++ spin_unlock_irqrestore(&i8259A_lock, flags); ++} ++ ++void unmask_8259A(void) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&i8259A_lock, flags); ++ outb(cached_A1, 0xA1); ++ outb(cached_21, 0x21); ++ spin_unlock_irqrestore(&i8259A_lock, flags); ++} ++ + /* + * This function assumes to be called rarely. Switching between + * 8259A registers is slow. +Index: xen-4.0.0-testing/xen/arch/x86/io_apic.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/arch/x86/io_apic.c ++++ xen-4.0.0-testing/xen/arch/x86/io_apic.c +@@ -136,6 +136,126 @@ static void __init replace_pin_at_irq(un + } + } + ++struct IO_APIC_route_entry **alloc_ioapic_entries(void) ++{ ++ int apic; ++ struct IO_APIC_route_entry **ioapic_entries; ++ ++ ioapic_entries = xmalloc_array(struct IO_APIC_route_entry *, nr_ioapics); ++ if (!ioapic_entries) ++ return 0; ++ ++ for (apic = 0; apic < nr_ioapics; apic++) { ++ ioapic_entries[apic] = ++ xmalloc_array(struct IO_APIC_route_entry, ++ nr_ioapic_registers[apic]); ++ if (!ioapic_entries[apic]) ++ goto nomem; ++ } ++ ++ return ioapic_entries; ++ ++nomem: ++ while (--apic >= 0) ++ xfree(ioapic_entries[apic]); ++ xfree(ioapic_entries); ++ ++ return 0; ++} ++ ++/* ++ * Saves all the IO-APIC RTE's ++ */ ++int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) ++{ ++ int apic, pin; ++ ++ if (!ioapic_entries) ++ return -ENOMEM; ++ ++ for (apic = 0; apic < nr_ioapics; apic++) { ++ if (!ioapic_entries[apic]) ++ return -ENOMEM; ++ ++ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { ++ *(((int *)&ioapic_entries[apic][pin])+0) = ++ __io_apic_read(apic, 0x10+pin*2); ++ *(((int *)&ioapic_entries[apic][pin])+1) = ++ __io_apic_read(apic, 0x11+pin*2); ++ } ++ } ++ ++ return 0; ++} ++ ++/* ++ * Mask all IO APIC entries. ++ */ ++void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) ++{ ++ int apic, pin; ++ ++ if (!ioapic_entries) ++ return; ++ ++ for (apic = 0; apic < nr_ioapics; apic++) { ++ if (!ioapic_entries[apic]) ++ break; ++ ++ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { ++ struct IO_APIC_route_entry entry; ++ unsigned long flags; ++ ++ entry = ioapic_entries[apic][pin]; ++ if (!entry.mask) { ++ entry.mask = 1; ++ ++ spin_lock_irqsave(&ioapic_lock, flags); ++ __io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); ++ __io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); ++ spin_unlock_irqrestore(&ioapic_lock, flags); ++ } ++ } ++ } ++} ++ ++/* ++ * Restore IO APIC entries which was saved in ioapic_entries. ++ */ ++int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) ++{ ++ int apic, pin; ++ unsigned long flags; ++ struct IO_APIC_route_entry entry; ++ ++ if (!ioapic_entries) ++ return -ENOMEM; ++ ++ for (apic = 0; apic < nr_ioapics; apic++) { ++ if (!ioapic_entries[apic]) ++ return -ENOMEM; ++ ++ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) ++ entry = ioapic_entries[apic][pin]; ++ spin_lock_irqsave(&ioapic_lock, flags); ++ __io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); ++ __io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); ++ spin_unlock_irqrestore(&ioapic_lock, flags); ++ } ++ ++ return 0; ++} ++ ++void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries) ++{ ++ int apic; ++ ++ for (apic = 0; apic < nr_ioapics; apic++) ++ xfree(ioapic_entries[apic]); ++ ++ xfree(ioapic_entries); ++} ++ + static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable) + { + struct irq_pin_list *entry = irq_2_pin + irq; +Index: xen-4.0.0-testing/xen/arch/x86/setup.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/arch/x86/setup.c ++++ xen-4.0.0-testing/xen/arch/x86/setup.c +@@ -981,6 +981,9 @@ 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); + +@@ -999,9 +1002,6 @@ void __init __start_xen(unsigned long mb + + acpi_boot_init(); + +- if ( x2apic_is_available() ) +- enable_x2apic(); +- + init_cpu_to_node(); + + if ( smp_found_config ) +@@ -1014,6 +1014,9 @@ void __init __start_xen(unsigned long mb + + init_apic_mappings(); + ++ if ( x2apic_is_available() ) ++ enable_x2apic(); ++ + percpu_free_unused_areas(); + + init_IRQ(); +Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/intremap.c +=================================================================== +--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/intremap.c ++++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/intremap.c +@@ -132,6 +132,12 @@ int iommu_supports_eim(void) + if ( !iommu_enabled || !iommu_qinval || !iommu_intremap ) + 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)) ) +@@ -142,9 +148,6 @@ int iommu_supports_eim(void) + return 0; + } + +- if ( list_empty(&acpi_drhd_units) ) +- return 0; +- + for_each_drhd_unit ( drhd ) + if ( !ecap_queued_inval(drhd->iommu->ecap) || + !ecap_intr_remap(drhd->iommu->ecap) || +@@ -802,3 +805,80 @@ void disable_intremap(struct iommu *iomm + out: + spin_unlock_irqrestore(&iommu->register_lock, flags); + } ++ ++/* ++ * This function is used to enable Interrutp remapping when ++ * enable x2apic ++ */ ++int iommu_enable_IR(void) ++{ ++ struct acpi_drhd_unit *drhd; ++ struct iommu *iommu; ++ ++ if ( !iommu_supports_eim() ) ++ return -1; ++ ++ for_each_drhd_unit ( drhd ) ++ { ++ struct qi_ctrl *qi_ctrl = NULL; ++ ++ iommu = drhd->iommu; ++ qi_ctrl = iommu_qi_ctrl(iommu); ++ ++ /* Clear previous faults */ ++ clear_fault_bits(iommu); ++ ++ /* ++ * Disable interrupt remapping and queued invalidation if ++ * already enabled by BIOS ++ */ ++ disable_intremap(iommu); ++ disable_qinval(iommu); ++ } ++ ++ /* Enable queue invalidation */ ++ for_each_drhd_unit ( drhd ) ++ { ++ iommu = drhd->iommu; ++ if ( enable_qinval(iommu) != 0 ) ++ { ++ dprintk(XENLOG_INFO VTDPREFIX, ++ "Failed to enable Queued Invalidation!\n"); ++ return -1; ++ } ++ } ++ ++ /* Enable interrupt remapping */ ++ for_each_drhd_unit ( drhd ) ++ { ++ iommu = drhd->iommu; ++ if ( enable_intremap(iommu, 1) ) ++ { ++ dprintk(XENLOG_INFO VTDPREFIX, ++ "Failed to enable Interrupt Remapping!\n"); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++/* ++ * 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; ++} +Index: xen-4.0.0-testing/xen/include/asm-x86/apic.h +=================================================================== +--- xen-4.0.0-testing.orig/xen/include/asm-x86/apic.h ++++ xen-4.0.0-testing/xen/include/asm-x86/apic.h +@@ -25,6 +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) +Index: xen-4.0.0-testing/xen/include/asm-x86/genapic.h +=================================================================== +--- xen-4.0.0-testing.orig/xen/include/asm-x86/genapic.h ++++ xen-4.0.0-testing/xen/include/asm-x86/genapic.h +@@ -70,6 +70,7 @@ 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); +Index: xen-4.0.0-testing/xen/include/asm-x86/io_apic.h +=================================================================== +--- xen-4.0.0-testing.orig/xen/include/asm-x86/io_apic.h ++++ xen-4.0.0-testing/xen/include/asm-x86/io_apic.h +@@ -199,6 +199,12 @@ extern int (*ioapic_renumber_irq)(int io + extern void ioapic_suspend(void); + extern void ioapic_resume(void); + ++extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); ++extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); ++extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); ++extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); ++extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); ++ + #else /* !CONFIG_X86_IO_APIC */ + static inline void init_ioapic_mappings(void) {} + static inline void ioapic_suspend(void) {} +Index: xen-4.0.0-testing/xen/include/asm-x86/irq.h +=================================================================== +--- xen-4.0.0-testing.orig/xen/include/asm-x86/irq.h ++++ xen-4.0.0-testing/xen/include/asm-x86/irq.h +@@ -91,6 +91,8 @@ asmlinkage void do_IRQ(struct cpu_user_r + void disable_8259A_irq(unsigned int irq); + void enable_8259A_irq(unsigned int irq); + int i8259A_irq_pending(unsigned int irq); ++void mask_8259A(void); ++void unmask_8259A(void); + void init_8259A(int aeoi); + int i8259A_suspend(void); + int i8259A_resume(void); +Index: xen-4.0.0-testing/xen/include/xen/iommu.h +=================================================================== +--- xen-4.0.0-testing.orig/xen/include/xen/iommu.h ++++ xen-4.0.0-testing/xen/include/xen/iommu.h +@@ -58,6 +58,8 @@ struct iommu { + + int iommu_setup(void); + int iommu_supports_eim(void); ++int iommu_enable_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/21757-x86-mce-avoid-BUG_ON.patch b/21757-x86-mce-avoid-BUG_ON.patch new file mode 100644 index 0000000..dc3e8bf --- /dev/null +++ b/21757-x86-mce-avoid-BUG_ON.patch @@ -0,0 +1,38 @@ +# HG changeset patch +# User Keir Fraser +# Date 1278674491 -3600 +# Node ID 50cf787b70eb74adfe501a2484a0dffe7d15e567 +# Parent a7a680442b738928eb963b31e22a3e428ac111a0 +mce: Replace BUG() with a console warning in the MCE handler. + +If the hardware reports corrected errors that we didn't see through +the status MSRs, complain on the console but don't BUG() the machine. + +Signed-off-by: Tim Deegan + +--- a/xen/arch/x86/cpu/mcheck/amd_nonfatal.c ++++ b/xen/arch/x86/cpu/mcheck/amd_nonfatal.c +@@ -152,14 +152,19 @@ static void mce_amd_work_fn(void *data) + + /* HW does not count *all* kinds of correctable errors. + * Thus it is possible, that the polling routine finds an +- * correctable error even if the HW reports nothing. +- * However, the other way around is not possible (= BUG). +- */ ++ * correctable error even if the HW reports nothing. */ + if (counter > 0) { + /* HW reported correctable errors, + * the polling routine did not find... + */ +- BUG_ON(adjust == 0); ++ if (adjust == 0) { ++ printk("CPU counter reports %"PRIu32 ++ " correctable hardware error%s that %s" ++ " not reported by the status MSRs\n", ++ counter, ++ (counter == 1 ? "" : "s"), ++ (counter == 1 ? "was" : "were")); ++ } + /* subtract 1 to not double count the error + * from the polling service routine */ + adjust += (counter - 1); diff --git a/21886-kexec-shutdown.patch b/21886-kexec-shutdown.patch new file mode 100644 index 0000000..3da83a9 --- /dev/null +++ b/21886-kexec-shutdown.patch @@ -0,0 +1,288 @@ +# HG changeset patch +# User Keir Fraser +# Date 1280395881 -3600 +# Node ID 578ed14c3c673d734318bcefa4597a7d7d9aee37 +# Parent 2007fd03f53d9a3e8774a6df06beef7c74801b07 +kexec: Clean up shutdown logic. Reinstate ACPI DMAR during kexec. +References: bnc#613529 + +Signed-off-by: Keir Fraser + +--- a/xen/arch/x86/crash.c ++++ b/xen/arch/x86/crash.c +@@ -25,7 +25,6 @@ + #include + #include + #include +-#include + + static atomic_t waiting_for_crash_ipi; + static unsigned int crashing_cpu; +@@ -41,9 +40,10 @@ static int crash_nmi_callback(struct cpu + local_irq_disable(); + + kexec_crash_save_cpu(); +- disable_local_APIC(); ++ ++ __stop_this_cpu(); ++ + atomic_dec(&waiting_for_crash_ipi); +- hvm_cpu_down(); + + for ( ; ; ) + halt(); +@@ -55,7 +55,10 @@ static void nmi_shootdown_cpus(void) + { + unsigned long msecs; + ++ local_irq_disable(); ++ + crashing_cpu = smp_processor_id(); ++ local_irq_count(crashing_cpu) = 0; + + atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); + /* Would it be better to replace the trap vector here? */ +@@ -72,25 +75,18 @@ static void nmi_shootdown_cpus(void) + msecs--; + } + +- /* Leave the nmi callback set */ +- disable_local_APIC(); ++ __stop_this_cpu(); ++ disable_IO_APIC(); ++ ++ local_irq_enable(); + } + + void machine_crash_shutdown(void) + { + crash_xen_info_t *info; + +- local_irq_disable(); +- + nmi_shootdown_cpus(); + +- if ( hpet_broadcast_is_available() ) +- hpet_disable_legacy_broadcast(); +- +- disable_IO_APIC(); +- +- hvm_cpu_down(); +- + info = kexec_crash_save_info(); + info->xen_phys_start = xen_phys_start; + info->dom0_pfn_to_mfn_frame_list_list = +--- a/xen/arch/x86/machine_kexec.c ++++ b/xen/arch/x86/machine_kexec.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + + typedef void (*relocate_new_kernel_t)( + unsigned long indirection_page, +@@ -76,38 +77,11 @@ void machine_kexec_unload(int type, int + { + } + +-static void __machine_reboot_kexec(void *data) ++void machine_reboot_kexec(xen_kexec_image_t *image) + { +- xen_kexec_image_t *image = (xen_kexec_image_t *)data; +- +- watchdog_disable(); +- console_start_sync(); +- ++ BUG_ON(smp_processor_id() != 0); + smp_send_stop(); +- + machine_kexec(image); +-} +- +-void machine_reboot_kexec(xen_kexec_image_t *image) +-{ +- int reboot_cpu_id; +- +- reboot_cpu_id = 0; +- +- if ( !cpu_isset(reboot_cpu_id, cpu_online_map) ) +- reboot_cpu_id = smp_processor_id(); +- +- if ( reboot_cpu_id != smp_processor_id() ) +- { +- on_selected_cpus(cpumask_of(reboot_cpu_id), __machine_reboot_kexec, +- image, 0); +- for (;;) +- ; /* nothing */ +- } +- else +- { +- __machine_reboot_kexec(image); +- } + BUG(); + } + +@@ -118,6 +92,9 @@ void machine_kexec(xen_kexec_image_t *im + .limit = LAST_RESERVED_GDT_BYTE + }; + ++ if ( hpet_broadcast_is_available() ) ++ hpet_disable_legacy_broadcast(); ++ + /* + * compat_machine_kexec() returns to idle pagetables, which requires us + * to be running on a static GDT mapping (idle pagetables have no GDT +--- a/xen/arch/x86/smp.c ++++ b/xen/arch/x86/smp.c +@@ -326,7 +326,7 @@ int on_selected_cpus( + return 0; + } + +-static void __stop_this_cpu(void) ++void __stop_this_cpu(void) + { + ASSERT(!local_irq_is_enabled()); + +--- a/xen/arch/x86/tboot.c ++++ b/xen/arch/x86/tboot.c +@@ -491,7 +491,10 @@ int __init tboot_parse_dmar_table(acpi_t + dmar_table = NULL; + acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_table); + if ( dmar_table != NULL ) +- ((struct acpi_table_dmar *)dmar_table)->header.signature[0] = '\0'; ++ { ++ dmar_table->signature[0] = 'X'; ++ dmar_table->checksum -= 'X'-'D'; ++ } + + return rc; + } +--- a/xen/common/kexec.c ++++ b/xen/common/kexec.c +@@ -6,7 +6,9 @@ + * - Magnus Damm + */ + ++#include + #include ++#include + #include + #include + #include +@@ -201,6 +203,22 @@ crash_xen_info_t *kexec_crash_save_info( + return out; + } + ++static int acpi_dmar_reinstate(struct acpi_table_header *table) ++{ ++ table->signature[0] = 'D'; ++ table->checksum += 'X'-'D'; ++ return 0; ++} ++ ++static void kexec_common_shutdown(void) ++{ ++ watchdog_disable(); ++ console_start_sync(); ++ spin_debug_disable(); ++ one_cpu_only(); ++ acpi_table_parse(ACPI_SIG_DMAR, acpi_dmar_reinstate); ++} ++ + void kexec_crash(void) + { + int pos; +@@ -209,17 +227,25 @@ void kexec_crash(void) + if ( !test_bit(KEXEC_IMAGE_CRASH_BASE + pos, &kexec_flags) ) + return; + +- console_start_sync(); +- +- one_cpu_only(); ++ kexec_common_shutdown(); + kexec_crash_save_cpu(); + machine_crash_shutdown(); +- + machine_kexec(&kexec_image[KEXEC_IMAGE_CRASH_BASE + pos]); + + BUG(); + } + ++static long kexec_reboot(void *_image) ++{ ++ xen_kexec_image_t *image = _image; ++ ++ kexec_common_shutdown(); ++ machine_reboot_kexec(image); ++ ++ BUG(); ++ return 0; ++} ++ + static void do_crashdump_trigger(unsigned char key) + { + printk("'%c' pressed -> triggering crashdump\n", key); +@@ -540,7 +566,7 @@ static int kexec_exec(XEN_GUEST_HANDLE(v + { + xen_kexec_exec_t exec; + xen_kexec_image_t *image; +- int base, bit, pos; ++ int base, bit, pos, ret = -EINVAL; + + if ( unlikely(copy_from_guest(&exec, uarg, 1)) ) + return -EFAULT; +@@ -558,8 +584,7 @@ static int kexec_exec(XEN_GUEST_HANDLE(v + { + case KEXEC_TYPE_DEFAULT: + image = &kexec_image[base + pos]; +- one_cpu_only(); +- machine_reboot_kexec(image); /* Does not return */ ++ ret = continue_hypercall_on_cpu(0, kexec_reboot, image); + break; + case KEXEC_TYPE_CRASH: + kexec_crash(); /* Does not return */ +--- a/xen/drivers/acpi/tables.c ++++ b/xen/drivers/acpi/tables.c +@@ -41,7 +41,7 @@ mps_inti_flags_polarity[] = { "dfl", "hi + static const char *__initdata + mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; + +-static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; ++static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES]; + + static int acpi_apic_instance __initdata; + +@@ -239,7 +239,7 @@ acpi_table_parse_madt(enum acpi_madt_typ + * Scan the ACPI System Descriptor Table (STD) for a table matching @id, + * run @handler on it. Return 0 if table found, return on if not. + */ +-int __init acpi_table_parse(char *id, acpi_table_handler handler) ++int acpi_table_parse(char *id, acpi_table_handler handler) + { + struct acpi_table_header *table = NULL; + +--- a/xen/drivers/passthrough/vtd/dmar.c ++++ b/xen/drivers/passthrough/vtd/dmar.c +@@ -738,7 +738,8 @@ static int __init acpi_parse_dmar(struct + + out: + /* Zap ACPI DMAR signature to prevent dom0 using vt-d HW. */ +- dmar->header.signature[0] = '\0'; ++ dmar->header.signature[0] = 'X'; ++ dmar->header.checksum -= 'X'-'D'; + return ret; + } + +--- a/xen/include/asm-x86/smp.h ++++ b/xen/include/asm-x86/smp.h +@@ -102,6 +102,9 @@ static __inline int logical_smp_processo + + extern int __cpu_disable(void); + extern void __cpu_die(unsigned int cpu); ++ ++void __stop_this_cpu(void); ++ + #endif /* !__ASSEMBLY__ */ + + #else /* CONFIG_SMP */ diff --git a/21926-x86-pv-NMI-inject.patch b/21926-x86-pv-NMI-inject.patch new file mode 100644 index 0000000..96af31e --- /dev/null +++ b/21926-x86-pv-NMI-inject.patch @@ -0,0 +1,43 @@ +# HG changeset patch +# User Keir Fraser +# Date 1281015674 -3600 +# Node ID 6f07d9ac1e7cd145fb2770bb11655ac1161b58da +# Parent 8992134dcfd0b9e1e86f4111e68a8aa48bd33c3c +x86: Fix NMI injection to PV guests +References: bnc#625520 + +Signed-off-by: Juergen Gross + +--- a/xen/arch/x86/x86_32/entry.S ++++ b/xen/arch/x86/x86_32/entry.S +@@ -275,7 +275,7 @@ process_mce: + ALIGN + /* %ebx: struct vcpu */ + process_nmi: +- cmpw $1 << VCPU_TRAP_NMI,VCPU_async_exception_mask(%ebx) ++ testb $1 << VCPU_TRAP_NMI,VCPU_async_exception_mask(%ebx) + jnz test_guest_events + sti + movb $0,VCPU_nmi_pending(%ebx) +--- a/xen/arch/x86/x86_64/compat/entry.S ++++ b/xen/arch/x86/x86_64/compat/entry.S +@@ -148,7 +148,7 @@ compat_process_mce: + ALIGN + /* %rbx: struct vcpu */ + compat_process_nmi: +- cmpw $1 << VCPU_TRAP_NMI,VCPU_async_exception_mask(%rbx) ++ testb $1 << VCPU_TRAP_NMI,VCPU_async_exception_mask(%rbx) + jnz compat_test_guest_events + sti + movb $0,VCPU_nmi_pending(%rbx) +--- a/xen/arch/x86/x86_64/entry.S ++++ b/xen/arch/x86/x86_64/entry.S +@@ -250,7 +250,7 @@ process_mce: + ALIGN + /* %rbx: struct vcpu */ + process_nmi: +- cmpw $1 << VCPU_TRAP_NMI,VCPU_async_exception_mask(%rbx) ++ testb $1 << VCPU_TRAP_NMI,VCPU_async_exception_mask(%rbx) + jnz test_guest_events + sti + movb $0,VCPU_nmi_pending(%rbx) diff --git a/21933-vtd-ioapic-write.patch b/21933-vtd-ioapic-write.patch new file mode 100644 index 0000000..fe554b8 --- /dev/null +++ b/21933-vtd-ioapic-write.patch @@ -0,0 +1,56 @@ +# HG changeset patch +# User Keir Fraser +# Date 1281367965 -3600 +# Node ID add40eb478680b6f8de7102e87fba259f721ce1d +# Parent fe930e1b2ce8f205fb368d0cc86876cc54d761a9 +vt-d: Fix ioapic write order in io_apic_write_remap_rte + +At the end of io_apic_write_remap_rte, it writes new entry (remapped +interrupt) to ioapic. But it writes low 32 bits before high 32 bits, +it unmasks interrupt before writing high 32 bits if 'mask' bit in low +32 bits is cleared. Thus it may result in issues. This patch fixes +this issue by writing high 32 bits before low 32 bits. + +Signed-off-by: Jiang, Yunhong +Signed-off-by: Weidong Han + +# HG changeset patch +# User Keir Fraser +# Date 1281368025 -3600 +# Node ID befd1814c0a262ce0d6c96727a76b907cdeecdc4 +# Parent add40eb478680b6f8de7102e87fba259f721ce1d +vt-d: Fix ioapic_rte_to_remap_entry error path. + +When ioapic_rte_to_remap_entry fails, currently it just writes value +to ioapic. But the 'mask' bit may be changed if it writes to the upper +half of RTE. This patch ensures to recover the original value of 'mask' +bit in this case. + +Signed-off-by: Weidong Han + +--- a/xen/drivers/passthrough/vtd/intremap.c ++++ b/xen/drivers/passthrough/vtd/intremap.c +@@ -438,14 +438,21 @@ void io_apic_write_remap_rte( + { + *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg; + *(IO_APIC_BASE(apic)+4) = value; ++ ++ /* Recover the original value of 'mask' bit */ ++ if ( rte_upper ) ++ { ++ *IO_APIC_BASE(apic) = reg; ++ *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+0); ++ } + return; + } + + /* write new entry to ioapic */ +- *IO_APIC_BASE(apic) = reg; +- *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+0); + *IO_APIC_BASE(apic) = reg + 1; + *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+1); ++ *IO_APIC_BASE(apic) = reg; ++ *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+0); + } + + #if defined(__i386__) || defined(__x86_64__) diff --git a/21953-msi-enable.patch b/21953-msi-enable.patch new file mode 100644 index 0000000..a26ca9a --- /dev/null +++ b/21953-msi-enable.patch @@ -0,0 +1,68 @@ +# HG changeset patch +# User Keir Fraser +# Date 1281542462 -3600 +# Node ID 786b163da49bbf18857b5484cce5e5aed33528b3 +# Parent f45026ec8db5a18131acd924a5b99f3b0e480df1 +msi: Avoid uninitialized msi descriptors + +When __pci_enable_msix() returns early, output parameter (struct +msi_desc **desc) will not be initialized. On my machine, a Broadcom +BCM5709 nic has both MSI and MSIX capability blocks and when guest +tries to enable msix interrupts but __pci_enable_msix() returns early +for encountering a msi block, the whole system will crash for fatal +page fault immediately. + +Signed-off-by: Wei Wang + +--- a/xen/arch/x86/msi.c ++++ b/xen/arch/x86/msi.c +@@ -605,21 +605,25 @@ static int msix_capability_init(struct p + * indicates the successful setup of an entry zero with the new MSI + * irq or non-zero for otherwise. + **/ ++ + static int __pci_enable_msi(struct msi_info *msi, struct msi_desc **desc) + { + int status; + struct pci_dev *pdev; ++ struct msi_desc *old_desc; + + ASSERT(spin_is_locked(&pcidevs_lock)); + pdev = pci_get_pdev(msi->bus, msi->devfn); + if ( !pdev ) + return -ENODEV; + +- if ( find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSI) ) ++ old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSI); ++ if ( old_desc ) + { + dprintk(XENLOG_WARNING, "irq %d has already mapped to MSI on " + "device %02x:%02x.%01x.\n", msi->irq, msi->bus, + PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn)); ++ *desc = old_desc; + return 0; + } + +@@ -669,6 +673,7 @@ static int __pci_enable_msix(struct msi_ + u16 control; + u8 slot = PCI_SLOT(msi->devfn); + u8 func = PCI_FUNC(msi->devfn); ++ struct msi_desc *old_desc; + + ASSERT(spin_is_locked(&pcidevs_lock)); + pdev = pci_get_pdev(msi->bus, msi->devfn); +@@ -681,11 +686,13 @@ static int __pci_enable_msix(struct msi_ + if (msi->entry_nr >= nr_entries) + return -EINVAL; + +- if ( find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSIX) ) ++ old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSIX); ++ if ( old_desc ) + { + dprintk(XENLOG_WARNING, "irq %d has already mapped to MSIX on " + "device %02x:%02x.%01x.\n", msi->irq, msi->bus, + PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn)); ++ *desc = old_desc; + return 0; + } + diff --git a/21971-pod-accounting.patch b/21971-pod-accounting.patch new file mode 100644 index 0000000..320c821 --- /dev/null +++ b/21971-pod-accounting.patch @@ -0,0 +1,58 @@ +References: bnc#626262 + +# HG changeset patch +# User George Dunlap +# Date 1281538581 -3600 +# Node ID 6f059a340cdf60e59f58bbca755a62356f57ea0e +# Parent 3b839375d5bcb3a4b484170a890e340493b4738a +[Xen-devel] [PATCH] PoD: Fix domain build populate-on-demand cache allocation + +Rather than trying to count the number of PoD entries we're putting in, we +simply pass the target # of pages - the vga hole, and let the hypervisor +do the calculation. + +Signed-off-by: George Dunlap +Signed-off-by: Stefano Stabellini + +--- a/tools/libxc/xc_hvm_build.c ++++ b/tools/libxc/xc_hvm_build.c +@@ -107,7 +107,6 @@ static int setup_guest(int xc_handle, + xen_pfn_t *page_array = NULL; + unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT); + unsigned long target_pages = (unsigned long)target << (20 - PAGE_SHIFT); +- unsigned long pod_pages = 0; + unsigned long entry_eip, cur_pages; + struct xen_add_to_physmap xatp; + struct shared_info *shared_info; +@@ -208,11 +207,6 @@ static int setup_guest(int xc_handle, + if ( done > 0 ) + { + done <<= SUPERPAGE_PFN_SHIFT; +- if ( pod_mode && target_pages > cur_pages ) +- { +- int d = target_pages - cur_pages; +- pod_pages += ( done < d ) ? done : d; +- } + cur_pages += done; + count -= done; + } +@@ -224,15 +218,16 @@ static int setup_guest(int xc_handle, + rc = xc_domain_memory_populate_physmap( + xc_handle, dom, count, 0, 0, &page_array[cur_pages]); + cur_pages += count; +- if ( pod_mode ) +- pod_pages -= count; + } + } + ++ /* Subtract 0x20 from target_pages for the VGA "hole". Xen will ++ * adjust the PoD cache size so that domain tot_pages will be ++ * target_pages - 0x20 after this call. */ + if ( pod_mode ) + rc = xc_domain_memory_set_pod_target(xc_handle, + dom, +- pod_pages, ++ target_pages - 0x20, + NULL, NULL, NULL); + + if ( rc != 0 ) diff --git a/README.SuSE b/README.SuSE index c8bd432..f161bbc 100644 --- a/README.SuSE +++ b/README.SuSE @@ -464,9 +464,6 @@ The hypervisor and domain 0 kernel are a matched set, and usually must be upgraded together. Consult the online documentation for a matrix of supported 32- and 64-bit combinations -A 64-bit paravirtualized VM will not run on 32-bit host but a 32-bit -paravirtualized VM will run on a 64-bit host. - On certain machines with 2GB or less of RAM, domain 0 Linux may fail to boot, printing the following messages: PCI-DMA: Using software bounce buffering for IO (SWIOTLB) @@ -498,8 +495,8 @@ file (viewable with the "xm dmesg" command). If problems persist, check if a newer version is available. Well-tested versions will be shipped with SUSE and via YaST Online Update. More frequent -(but less supported) updates are available on the Xen Technical Preview site: - ftp://ftp.novell.com/forge/XenTechnicalPreview/ +(but less supported) updates are available on Novell's Forge site: + http://forge.novell.com/modules/xfmod/project/?xenpreview Known Issues diff --git a/cpupools-core.patch b/cpupools-core.patch index 09fbf44..e4e758e 100644 --- a/cpupools-core.patch +++ b/cpupools-core.patch @@ -1,9 +1,7 @@ From: Juergen Gross -Index: xen-4.0.0-testing/xen/arch/x86/acpi/power.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/acpi/power.c -+++ xen-4.0.0-testing/xen/arch/x86/acpi/power.c +--- a/xen/arch/x86/acpi/power.c ++++ b/xen/arch/x86/acpi/power.c @@ -234,7 +234,7 @@ static int enter_state(u32 state) return error; } @@ -22,10 +20,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/acpi/power.c } static int acpi_get_wake_status(void) -Index: xen-4.0.0-testing/xen/arch/x86/domain.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/domain.c -+++ xen-4.0.0-testing/xen/arch/x86/domain.c +--- a/xen/arch/x86/domain.c ++++ b/xen/arch/x86/domain.c @@ -1518,42 +1518,52 @@ void sync_vcpu_execstate(struct vcpu *v) } @@ -139,10 +135,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/domain.c return 0; } -Index: xen-4.0.0-testing/xen/arch/x86/domain_build.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/domain_build.c -+++ xen-4.0.0-testing/xen/arch/x86/domain_build.c +--- a/xen/arch/x86/domain_build.c ++++ b/xen/arch/x86/domain_build.c @@ -9,6 +9,7 @@ #include #include @@ -183,10 +177,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/domain_build.c /* Set up CR3 value for write_ptbase */ if ( paging_mode_enabled(d) ) -Index: xen-4.0.0-testing/xen/arch/x86/microcode.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/microcode.c -+++ xen-4.0.0-testing/xen/arch/x86/microcode.c +--- a/xen/arch/x86/microcode.c ++++ b/xen/arch/x86/microcode.c @@ -114,7 +114,7 @@ static int microcode_update_cpu(const vo return err; } @@ -214,10 +206,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/microcode.c + return continue_hypercall_on_cpu(info->cpu, NULL, + do_microcode_update, info); } -Index: xen-4.0.0-testing/xen/arch/x86/mm.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/mm.c -+++ xen-4.0.0-testing/xen/arch/x86/mm.c +--- a/xen/arch/x86/mm.c ++++ b/xen/arch/x86/mm.c @@ -242,7 +242,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. @@ -244,10 +234,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/mm.c BUG_ON(dom_cow == NULL); /* First 1MB of RAM is historically marked as I/O. */ -Index: xen-4.0.0-testing/xen/arch/x86/platform_hypercall.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/platform_hypercall.c -+++ xen-4.0.0-testing/xen/arch/x86/platform_hypercall.c +--- a/xen/arch/x86/platform_hypercall.c ++++ b/xen/arch/x86/platform_hypercall.c @@ -19,6 +19,7 @@ #include #include @@ -307,10 +295,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/platform_hypercall.c break; } break; -Index: xen-4.0.0-testing/xen/arch/x86/setup.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/setup.c -+++ xen-4.0.0-testing/xen/arch/x86/setup.c +--- a/xen/arch/x86/setup.c ++++ b/xen/arch/x86/setup.c @@ -2,6 +2,7 @@ #include #include @@ -328,7 +314,7 @@ Index: xen-4.0.0-testing/xen/arch/x86/setup.c if ( idle_domain == NULL ) BUG(); idle_domain->vcpu = idle_vcpu; -@@ -1094,8 +1095,13 @@ void __init __start_xen(unsigned long mb +@@ -1097,8 +1098,13 @@ void __init __start_xen(unsigned long mb if ( !tboot_protect_mem_regions() ) panic("Could not protect TXT memory regions\n"); @@ -343,10 +329,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/setup.c if ( (dom0 == NULL) || (alloc_dom0_vcpu0() == NULL) ) panic("Error creating domain 0\n"); -Index: xen-4.0.0-testing/xen/arch/x86/smpboot.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/smpboot.c -+++ xen-4.0.0-testing/xen/arch/x86/smpboot.c +--- a/xen/arch/x86/smpboot.c ++++ b/xen/arch/x86/smpboot.c @@ -39,6 +39,7 @@ #include #include @@ -468,10 +452,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/smpboot.c cpufreq_add_cpu(cpu); return 0; } -Index: xen-4.0.0-testing/xen/arch/x86/sysctl.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/arch/x86/sysctl.c -+++ xen-4.0.0-testing/xen/arch/x86/sysctl.c +--- a/xen/arch/x86/sysctl.c ++++ b/xen/arch/x86/sysctl.c @@ -29,7 +29,7 @@ #define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) @@ -490,10 +472,8 @@ Index: xen-4.0.0-testing/xen/arch/x86/sysctl.c break; case XEN_SYSCTL_CPU_HOTPLUG_STATUS: ret = 0; -Index: xen-4.0.0-testing/xen/common/Makefile -=================================================================== ---- xen-4.0.0-testing.orig/xen/common/Makefile -+++ xen-4.0.0-testing/xen/common/Makefile +--- a/xen/common/Makefile ++++ b/xen/common/Makefile @@ -1,5 +1,6 @@ obj-y += bitmap.o obj-y += cpu.o @@ -501,10 +481,8 @@ Index: xen-4.0.0-testing/xen/common/Makefile obj-y += domctl.o obj-y += domain.o obj-y += event_channel.o -Index: xen-4.0.0-testing/xen/common/cpupool.c -=================================================================== --- /dev/null -+++ xen-4.0.0-testing/xen/common/cpupool.c ++++ b/xen/common/cpupool.c @@ -0,0 +1,585 @@ +/****************************************************************************** + * cpupool.c @@ -1091,10 +1069,8 @@ Index: xen-4.0.0-testing/xen/common/cpupool.c + * indent-tabs-mode: nil + * End: + */ -Index: xen-4.0.0-testing/xen/common/domain.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/common/domain.c -+++ xen-4.0.0-testing/xen/common/domain.c +--- a/xen/common/domain.c ++++ b/xen/common/domain.c @@ -209,7 +209,7 @@ static void __init parse_extra_guest_irq custom_param("extra_guest_irqs", parse_extra_guest_irqs); @@ -1123,10 +1099,8 @@ Index: xen-4.0.0-testing/xen/common/domain.c sched_destroy_domain(d); /* Free page used by xen oprofile buffer. */ -Index: xen-4.0.0-testing/xen/common/domctl.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/common/domctl.c -+++ xen-4.0.0-testing/xen/common/domctl.c +--- a/xen/common/domctl.c ++++ b/xen/common/domctl.c @@ -11,6 +11,7 @@ #include #include @@ -1202,10 +1176,28 @@ Index: xen-4.0.0-testing/xen/common/domctl.c if ( alloc_vcpu(d, i, cpu) == NULL ) goto maxvcpu_out; -Index: xen-4.0.0-testing/xen/common/sched_credit.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/common/sched_credit.c -+++ xen-4.0.0-testing/xen/common/sched_credit.c +--- a/xen/common/kexec.c ++++ b/xen/common/kexec.c +@@ -235,7 +235,7 @@ void kexec_crash(void) + BUG(); + } + +-static long kexec_reboot(void *_image) ++static long kexec_reboot(void *hdl, void *_image) + { + xen_kexec_image_t *image = _image; + +@@ -584,7 +584,7 @@ static int kexec_exec(XEN_GUEST_HANDLE(v + { + case KEXEC_TYPE_DEFAULT: + image = &kexec_image[base + pos]; +- ret = continue_hypercall_on_cpu(0, kexec_reboot, image); ++ ret = continue_hypercall_on_cpu(0, NULL, kexec_reboot, image); + break; + case KEXEC_TYPE_CRASH: + kexec_crash(); /* Does not return */ +--- a/xen/common/sched_credit.c ++++ b/xen/common/sched_credit.c @@ -70,11 +70,15 @@ /* * Useful macros @@ -2094,7 +2086,7 @@ Index: xen-4.0.0-testing/xen/common/sched_credit.c .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, @@ -2108,10 +2100,8 @@ Index: xen-4.0.0-testing/xen/common/sched_credit.c .tick_suspend = csched_tick_suspend, .tick_resume = csched_tick_resume, -Index: xen-4.0.0-testing/xen/common/sched_sedf.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/common/sched_sedf.c -+++ xen-4.0.0-testing/xen/common/sched_sedf.c +--- a/xen/common/sched_sedf.c ++++ b/xen/common/sched_sedf.c @@ -21,6 +21,9 @@ printk(_a ); \ } while ( 0 ) @@ -2377,7 +2367,7 @@ Index: xen-4.0.0-testing/xen/common/sched_sedf.c .name = "Simple EDF Scheduler", .opt_name = "sedf", .sched_id = XEN_SCHEDULER_SEDF, -@@ -1464,9 +1509,15 @@ const struct scheduler sched_sedf_def = +@@ -1464,9 +1509,15 @@ const struct scheduler sched_sedf_def = .init_domain = sedf_init_domain, .destroy_domain = sedf_destroy_domain, @@ -2394,10 +2384,8 @@ Index: xen-4.0.0-testing/xen/common/sched_sedf.c .do_schedule = sedf_do_schedule, .pick_cpu = sedf_pick_cpu, .dump_cpu_state = sedf_dump_cpu_state, -Index: xen-4.0.0-testing/xen/common/schedule.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/common/schedule.c -+++ xen-4.0.0-testing/xen/common/schedule.c +--- a/xen/common/schedule.c ++++ b/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 */ @@ -2916,10 +2904,8 @@ Index: xen-4.0.0-testing/xen/common/schedule.c } #ifdef CONFIG_COMPAT -Index: xen-4.0.0-testing/xen/common/softirq.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/common/softirq.c -+++ xen-4.0.0-testing/xen/common/softirq.c +--- a/xen/common/softirq.c ++++ b/xen/common/softirq.c @@ -88,9 +88,11 @@ void raise_softirq(unsigned int nr) } @@ -3013,10 +2999,8 @@ Index: xen-4.0.0-testing/xen/common/softirq.c open_softirq(TASKLET_SOFTIRQ, tasklet_action); } -Index: xen-4.0.0-testing/xen/common/sysctl.c -=================================================================== ---- xen-4.0.0-testing.orig/xen/common/sysctl.c -+++ xen-4.0.0-testing/xen/common/sysctl.c +--- a/xen/common/sysctl.c ++++ b/xen/common/sysctl.c @@ -314,6 +314,14 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc } break; @@ -3032,10 +3016,8 @@ Index: xen-4.0.0-testing/xen/common/sysctl.c default: ret = arch_do_sysctl(op, u_sysctl); break; -Index: xen-4.0.0-testing/xen/include/asm-x86/domain.h -=================================================================== ---- xen-4.0.0-testing.orig/xen/include/asm-x86/domain.h -+++ xen-4.0.0-testing/xen/include/asm-x86/domain.h +--- a/xen/include/asm-x86/domain.h ++++ b/xen/include/asm-x86/domain.h @@ -451,7 +451,8 @@ struct arch_vcpu #define hvm_svm hvm_vcpu.u.svm @@ -3046,10 +3028,8 @@ Index: xen-4.0.0-testing/xen/include/asm-x86/domain.h void vcpu_show_execution_state(struct vcpu *); void vcpu_show_registers(const struct vcpu *); -Index: xen-4.0.0-testing/xen/include/asm-x86/smp.h -=================================================================== ---- xen-4.0.0-testing.orig/xen/include/asm-x86/smp.h -+++ xen-4.0.0-testing/xen/include/asm-x86/smp.h +--- a/xen/include/asm-x86/smp.h ++++ b/xen/include/asm-x86/smp.h @@ -56,7 +56,6 @@ extern u32 cpu_2_logical_apicid[]; #define CPU_ONLINE 0x0002 /* CPU is up */ #define CPU_DEAD 0x0004 /* CPU is dead */ @@ -3058,10 +3038,8 @@ Index: xen-4.0.0-testing/xen/include/asm-x86/smp.h #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) extern int cpu_down(unsigned int cpu); -Index: xen-4.0.0-testing/xen/include/public/domctl.h -=================================================================== ---- xen-4.0.0-testing.orig/xen/include/public/domctl.h -+++ xen-4.0.0-testing/xen/include/public/domctl.h +--- a/xen/include/public/domctl.h ++++ b/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 @@ -3090,10 +3068,8 @@ Index: xen-4.0.0-testing/xen/include/public/domctl.h struct xen_domctl { uint32_t cmd; #define XEN_DOMCTL_createdomain 1 -Index: xen-4.0.0-testing/xen/include/public/sysctl.h -=================================================================== ---- xen-4.0.0-testing.orig/xen/include/public/sysctl.h -+++ xen-4.0.0-testing/xen/include/public/sysctl.h +--- a/xen/include/public/sysctl.h ++++ b/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); @@ -3131,10 +3107,8 @@ Index: xen-4.0.0-testing/xen/include/public/sysctl.h uint8_t pad[128]; } u; }; -Index: xen-4.0.0-testing/xen/include/xen/sched-if.h -=================================================================== ---- xen-4.0.0-testing.orig/xen/include/xen/sched-if.h -+++ xen-4.0.0-testing/xen/include/xen/sched-if.h +--- a/xen/include/xen/sched-if.h ++++ b/xen/include/xen/sched-if.h @@ -10,16 +10,29 @@ #include @@ -3229,10 +3203,8 @@ Index: xen-4.0.0-testing/xen/include/xen/sched-if.h +struct scheduler *scheduler_get_by_id(unsigned int id); + #endif /* __XEN_SCHED_IF_H__ */ -Index: xen-4.0.0-testing/xen/include/xen/sched.h -=================================================================== ---- xen-4.0.0-testing.orig/xen/include/xen/sched.h -+++ xen-4.0.0-testing/xen/include/xen/sched.h +--- a/xen/include/xen/sched.h ++++ b/xen/include/xen/sched.h @@ -9,6 +9,7 @@ #include #include @@ -3241,7 +3213,7 @@ Index: xen-4.0.0-testing/xen/include/xen/sched.h #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; @@ -3313,10 +3285,8 @@ Index: xen-4.0.0-testing/xen/include/xen/sched.h #endif /* __SCHED_H__ */ /* -Index: xen-4.0.0-testing/xen/include/xen/softirq.h -=================================================================== ---- xen-4.0.0-testing.orig/xen/include/xen/softirq.h -+++ xen-4.0.0-testing/xen/include/xen/softirq.h +--- a/xen/include/xen/softirq.h ++++ b/xen/include/xen/softirq.h @@ -58,6 +58,7 @@ struct tasklet struct tasklet name = { LIST_HEAD_INIT(name.list), 0, 0, 0, func, data } diff --git a/snapshot-xend.patch b/snapshot-xend.patch index 7a22802..4e0d8b0 100644 --- a/snapshot-xend.patch +++ b/snapshot-xend.patch @@ -647,7 +647,7 @@ Index: xen-4.0.0-testing/tools/python/xen/xm/main.py def xm_save(args): arg_check(args, "save", 2, 4) -@@ -3729,6 +3804,10 @@ commands = { +@@ -3741,6 +3816,10 @@ commands = { "restore": xm_restore, "resume": xm_resume, "save": xm_save, diff --git a/usb-list.patch b/usb-list.patch new file mode 100644 index 0000000..ff4f2b5 --- /dev/null +++ b/usb-list.patch @@ -0,0 +1,45 @@ +"usb-hc-create" does not check usb-ver parameter. It allows 2/2.0/2.0usb/2.0aaa. While low level +driver doing hc create, it gets an integer by vssanf %d from usb-ver string, so there is no problem. +But 2/2.0/2.0usb/2.0aaa will be saved into VM config. + +After that, while doing "usb-list", it cannot handle "2.0/2.0usb/2.0aaa" and will cause error: +Idx BE state usb-ver BE-path +Error: Invalid argument. +Usage: xm usb-list + +This patch is to let "usb-list" handle all usb-ver cases as low level driver does and won't cause error. + +About this problem, I've submitted two patches to upstream before, but got no response. Information +could be referred to: + http://www.gossamer-threads.com/lists/xen/devel/178406?search_string=usb-list;#178406 + http://www.gossamer-threads.com/lists/xen/devel/181021?search_string=usb-list;#181021 + + +Index: xen-4.0.0-testing/tools/python/xen/xm/main.py +=================================================================== +--- xen-4.0.0-testing.orig/tools/python/xen/xm/main.py ++++ xen-4.0.0-testing/tools/python/xen/xm/main.py +@@ -2543,10 +2543,22 @@ def xm_usb_list(args): + ni = parse_dev_info(x[1]) + ni['idx'] = int(x[0]) + usbver = sxp.child_value(x[1], 'usb-ver') ++ ++ substr = re.search("^\d{1,}", usbver) ++ if substr: ++ usbver = substr.group() ++ else: ++ print "Unknown usb-ver" ++ continue ++ + if int(usbver) == 1: + ni['usb-ver'] = 'USB1.1' +- else: ++ elif int(usbver) == 2: + ni['usb-ver'] = 'USB2.0' ++ else: ++ print "Unknown usb-ver" ++ continue ++ + print "%(idx)-3d %(backend-id)-3d %(state)-5d %(usb-ver)-7s %(be-path)-30s " % ni + + ports = sxp.child(x[1], 'port') diff --git a/x86-extra-trap-info.patch b/x86-extra-trap-info.patch index 2339519..ac39213 100644 --- a/x86-extra-trap-info.patch +++ b/x86-extra-trap-info.patch @@ -1,5 +1,5 @@ ---- 2010-01-06.orig/xen/arch/x86/x86_32/entry.S 2009-12-02 10:02:49.000000000 +0100 -+++ 2010-01-06/xen/arch/x86/x86_32/entry.S 2010-01-06 11:23:45.000000000 +0100 +--- a/xen/arch/x86/x86_32/entry.S ++++ b/xen/arch/x86/x86_32/entry.S @@ -403,21 +403,33 @@ ring1: /* obtain ss/esp from oldss/olde movl %eax,UREGS_eip+4(%esp) ret @@ -44,8 +44,8 @@ domain_crash_synchronous: pushl $domain_crash_synchronous_string call printk ---- 2010-01-06.orig/xen/arch/x86/x86_64/entry.S 2009-12-02 10:02:49.000000000 +0100 -+++ 2010-01-06/xen/arch/x86/x86_64/entry.S 2010-01-06 11:23:45.000000000 +0100 +--- a/xen/arch/x86/x86_64/entry.S ++++ b/xen/arch/x86/x86_64/entry.S @@ -421,17 +421,30 @@ create_bounce_frame: movq %rax,UREGS_rip+8(%rsp) ret diff --git a/x86-ioapic-ack-default.patch b/x86-ioapic-ack-default.patch index cb989d6..15fa40e 100644 --- a/x86-ioapic-ack-default.patch +++ b/x86-ioapic-ack-default.patch @@ -4,7 +4,7 @@ Index: xen-4.0.0-testing/xen/arch/x86/io_apic.c =================================================================== --- xen-4.0.0-testing.orig/xen/arch/x86/io_apic.c +++ xen-4.0.0-testing/xen/arch/x86/io_apic.c -@@ -1442,7 +1442,7 @@ static unsigned int startup_level_ioapic +@@ -1562,7 +1562,7 @@ static unsigned int startup_level_ioapic return 0; /* don't check for pending */ } @@ -13,7 +13,7 @@ Index: xen-4.0.0-testing/xen/arch/x86/io_apic.c static void setup_ioapic_ack(char *s) { if ( !strcmp(s, "old") ) -@@ -1946,6 +1946,8 @@ void __init setup_IO_APIC(void) +@@ -2066,6 +2066,8 @@ void __init setup_IO_APIC(void) else io_apic_irqs = ~PIC_IRQS; diff --git a/xen.changes b/xen.changes index 4bfe29f..7799f54 100644 --- a/xen.changes +++ b/xen.changes @@ -1,22 +1,56 @@ ------------------------------------------------------------------- -Tue Jul 27 16:32:57 MDT 2010 - jfehlig@novell.com +Mon Aug 16 18:35:11 MDT 2010 - carnold@novell.com + +- bnc#626262 - Populate-on-demand memory problem on xen with hvm + guest + 21971-pod-accounting.patch + +------------------------------------------------------------------- +Mon Aug 16 17:03:58 CST 2010 - cyliu@novell.com + +- bnc#584204 - xm usb-list broken + usb-list.patch + +------------------------------------------------------------------- +Thu Aug 12 06:13:44 MDT 2010 - carnold@novell.com + +- bnc#625520 - TP-L3: NMI cannot be triggered for xen kernel + 21926-x86-pv-NMI-inject.patch + +------------------------------------------------------------------- +Mon Aug 9 09:47:09 MDT 2010 - carnold@novell.com + +- bnc#613529 - TP-L3: kdump kernel hangs when crash was initiated + from xen kernel + 21886-kexec-shutdown.patch + +------------------------------------------------------------------- +Mon Aug 2 16:42:41 MDT 2010 - carnold@novell.com + +- Upstream Intel patches to improve X2APIC handling. + 21716-iommu-alloc.patch + 21717-ir-qi.patch + 21718-x2apic-logic.patch + +------------------------------------------------------------------- +Tue Jul 27 16:23:09 MDT 2010 - jfehlig@novell.com - bnc#623833 - Error in Xend-API method VM_set_actions_after_crash 21866-xenapi.patch ------------------------------------------------------------------- -Tue Jul 27 15:39:17 MDT 2010 - jfehlig@novell.com +Tue Jul 27 15:37:51 MDT 2010 - jfehlig@novell.com - bnc#625003 - Fix vm config options coredump-{restart,destroy} Added hunk to xm-create-xflag.patch ------------------------------------------------------------------- -Mon Jul 26 16:49:39 MDT 2010 - jfehlig@novell.com +Mon Jul 26 16:53:02 MDT 2010 - jfehlig@novell.com - bnc#605186 - Squelch harmless error messages in block-iscsi ------------------------------------------------------------------- -Mon Jul 26 16:45:21 MDT 2010 - jfehlig@novell.com +Mon Jul 26 16:22:56 MDT 2010 - jfehlig@novell.com - bnc#623438 - Add ability to control SCSI device path scanning in xend @@ -67,6 +101,8 @@ Tue Jul 6 11:31:33 MDT 2010 - carnold@novell.com 21706-trace-security.patch 21712-amd-osvw.patch 21744-x86-cpufreq-range-check.patch + 21933-vtd-ioapic-write.patch + 21953-msi-enable.patch ------------------------------------------------------------------- Fri Jun 25 15:43:35 CST 2010 - jsong@novell.com diff --git a/xen.spec b/xen.spec index 4fb35ef..04a18e7 100644 --- a/xen.spec +++ b/xen.spec @@ -133,10 +133,19 @@ Patch55: 21700-32on64-vm86-gpf.patch Patch56: 21705-trace-printk.patch Patch57: 21706-trace-security.patch Patch58: 21712-amd-osvw.patch -Patch59: 21723-get-domu-state.patch -Patch60: 21744-x86-cpufreq-range-check.patch -Patch61: 21847-pscsi.patch -Patch62: 21866-xenapi.patch +Patch59: 21716-iommu-alloc.patch +Patch60: 21717-ir-qi.patch +Patch61: 21718-x2apic-logic.patch +Patch62: 21723-get-domu-state.patch +Patch63: 21744-x86-cpufreq-range-check.patch +Patch64: 21757-x86-mce-avoid-BUG_ON.patch +Patch65: 21847-pscsi.patch +Patch66: 21866-xenapi.patch +Patch67: 21886-kexec-shutdown.patch +Patch68: 21926-x86-pv-NMI-inject.patch +Patch69: 21933-vtd-ioapic-write.patch +Patch70: 21953-msi-enable.patch +Patch71: 21971-pod-accounting.patch # Our patches Patch300: xen-config.diff Patch301: xend-config.diff @@ -200,6 +209,7 @@ Patch369: cpu-pools-docs.patch Patch370: xend-sysconfig.patch Patch371: domu-usb-controller.patch Patch372: popen2-argument-fix.patch +Patch373: usb-list.patch # Patches for snapshot support Patch400: snapshot-ioemu-save.patch Patch401: snapshot-ioemu-restore.patch @@ -645,6 +655,15 @@ Authors: %patch60 -p1 %patch61 -p1 %patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 %patch300 -p1 %patch301 -p1 %patch302 -p1 @@ -706,6 +725,7 @@ Authors: %patch370 -p1 %patch371 -p1 %patch372 -p1 +%patch373 -p1 %patch400 -p1 %patch401 -p1 %patch402 -p1