diff --git a/19614-x86-emul-lldt-ltr.patch b/19614-x86-emul-lldt-ltr.patch new file mode 100644 index 0000000..bf7e8da --- /dev/null +++ b/19614-x86-emul-lldt-ltr.patch @@ -0,0 +1,106 @@ +# HG changeset patch +# User Keir Fraser +# Date 1250693891 -3600 +# Node ID bea861fb0f20671d41e467557bfdffb67b42f5e7 +# Parent aa9f0b39c021f9c6e2c5cdb225564dd554a727f5 +x86_emulate: Emulate LLDT and LTR instructions. + +Signed-off-by: Keir Fraser +xen-unstable changeset: 19614:e421fd04e150 +xen-unstable date: Tue May 19 02:09:36 2009 +0100 + +Index: xen-3.4.1-testing/xen/arch/x86/x86_emulate/x86_emulate.c +=================================================================== +--- xen-3.4.1-testing.orig/xen/arch/x86/x86_emulate/x86_emulate.c ++++ xen-3.4.1-testing/xen/arch/x86/x86_emulate/x86_emulate.c +@@ -172,7 +172,7 @@ static uint8_t opcode_table[256] = { + + static uint8_t twobyte_table[256] = { + /* 0x00 - 0x07 */ +- 0, ImplicitOps|ModRM, 0, 0, 0, 0, ImplicitOps, 0, ++ SrcMem16|ModRM, ImplicitOps|ModRM, 0, 0, 0, 0, ImplicitOps, 0, + /* 0x08 - 0x0F */ + ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps|ModRM, 0, 0, + /* 0x10 - 0x17 */ +@@ -971,8 +971,8 @@ protmode_load_seg( + struct { uint32_t a, b; } desc; + unsigned long val; + uint8_t dpl, rpl, cpl; +- uint32_t new_desc_b; +- int rc, fault_type = EXC_TS; ++ uint32_t new_desc_b, a_flag = 0x100; ++ int rc, fault_type = EXC_GP; + + /* NULL selector? */ + if ( (sel & 0xfffc) == 0 ) +@@ -983,8 +983,8 @@ protmode_load_seg( + return ops->write_segment(seg, &segr, ctxt); + } + +- /* LDT descriptor must be in the GDT. */ +- if ( (seg == x86_seg_ldtr) && (sel & 4) ) ++ /* System segment descriptors must reside in the GDT. */ ++ if ( !is_x86_user_segment(seg) && (sel & 4) ) + goto raise_exn; + + if ( (rc = ops->read_segment(x86_seg_ss, &ss, ctxt)) || +@@ -1013,8 +1013,8 @@ protmode_load_seg( + goto raise_exn; + } + +- /* LDT descriptor is a system segment. All others are code/data. */ +- if ( (desc.b & (1u<<12)) == ((seg == x86_seg_ldtr) << 12) ) ++ /* System segments must have the system flag (S) set. */ ++ if ( (desc.b & (1u<<12)) == (!is_x86_user_segment(seg) << 12) ) + goto raise_exn; + + dpl = (desc.b >> 13) & 3; +@@ -1043,6 +1043,12 @@ protmode_load_seg( + if ( (desc.b & (15u<<8)) != (2u<<8) ) + goto raise_exn; + goto skip_accessed_flag; ++ case x86_seg_tr: ++ /* Available TSS system segment? */ ++ if ( (desc.b & (15u<<8)) != (9u<<8) ) ++ goto raise_exn; ++ a_flag = 0x200; /* busy flag */ ++ break; + default: + /* Readable code or data segment? */ + if ( (desc.b & (5u<<9)) == (4u<<9) ) +@@ -1055,8 +1061,8 @@ protmode_load_seg( + } + + /* Ensure Accessed flag is set. */ +- new_desc_b = desc.b | 0x100; +- rc = ((desc.b & 0x100) ? X86EMUL_OKAY : ++ new_desc_b = desc.b | a_flag; ++ rc = ((desc.b & a_flag) ? X86EMUL_OKAY : + ops->cmpxchg( + x86_seg_none, desctab.base + (sel & 0xfff8) + 4, + &desc.b, &new_desc_b, 4, ctxt)); +@@ -1066,7 +1072,7 @@ protmode_load_seg( + return rc; + + /* Force the Accessed flag in our local copy. */ +- desc.b |= 0x100; ++ desc.b |= a_flag; + + skip_accessed_flag: + segr.base = (((desc.b << 0) & 0xff000000u) | +@@ -3440,6 +3446,15 @@ x86_emulate( + twobyte_insn: + switch ( b ) + { ++ case 0x00: /* Grp6 */ ++ fail_if((modrm_reg & 6) != 2); ++ generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1); ++ generate_exception_if(!mode_ring0(), EXC_GP, 0); ++ if ( (rc = load_seg((modrm_reg & 1) ? x86_seg_tr : x86_seg_ldtr, ++ src.val, ctxt, ops)) != 0 ) ++ goto done; ++ break; ++ + case 0x01: /* Grp7 */ { + struct segment_register reg; + unsigned long base, limit, cr0, cr0w; diff --git a/20101-hvm-no-compat-virt-start.patch b/20101-hvm-no-compat-virt-start.patch new file mode 100644 index 0000000..eee20f3 --- /dev/null +++ b/20101-hvm-no-compat-virt-start.patch @@ -0,0 +1,26 @@ +# HG changeset patch +# User Keir Fraser +# Date 1250789251 -3600 +# Node ID 100699877583818a54bc16360dfd5cf80daa5dc7 +# Parent 280fff79f7371981bb0bbda34205414fff14737e +x86_64 hvm: Adjust COMPAT_VIRT_START for 32-bit HVM guests. + +The PV limit should not apply as there is no M2P table mapped into an +HVM guest's virtual address space. + +Signed-off-by: Keir Fraser + +Index: xen-3.4.1-testing/xen/arch/x86/domain.c +=================================================================== +--- xen-3.4.1-testing.orig/xen/arch/x86/domain.c ++++ xen-3.4.1-testing/xen/arch/x86/domain.c +@@ -428,7 +428,8 @@ int arch_domain_create(struct domain *d, + #endif /* __x86_64__ */ + + #ifdef CONFIG_COMPAT +- HYPERVISOR_COMPAT_VIRT_START(d) = __HYPERVISOR_COMPAT_VIRT_START; ++ HYPERVISOR_COMPAT_VIRT_START(d) = ++ is_hvm_domain(d) ? ~0u : __HYPERVISOR_COMPAT_VIRT_START; + #endif + + if ( (rc = paging_domain_init(d)) != 0 ) diff --git a/20112-x86-dom0-boot-run-timers.patch b/20112-x86-dom0-boot-run-timers.patch new file mode 100644 index 0000000..4ed864c --- /dev/null +++ b/20112-x86-dom0-boot-run-timers.patch @@ -0,0 +1,47 @@ +References: bnc#491081 +# HG changeset patch +# User Keir Fraser +# Date 1251097328 -3600 +# Node ID 7e194320394244bc5028881b498d2e01574086cd +# Parent 9189afa1f1e6939fcda5525e225843cfd2325c42 +x86: run timers when populating Dom0's P2M table + +When booting Dom0 with huge amounts of memory, and/or memory accesses +being sufficiently slow (due to NUMA effects), and the ACPI PM timer +or a high frequency HPET being used, the time it takes to populate the +M2P table may significantly exceed the overflow time of the platform +timer, screwing up time management to the point where Dom0 boot fails. + +Signed-off-by: Jan Beulich + +Index: xen-3.4.1-testing/xen/arch/x86/domain_build.c +=================================================================== +--- xen-3.4.1-testing.orig/xen/arch/x86/domain_build.c ++++ xen-3.4.1-testing/xen/arch/x86/domain_build.c +@@ -877,6 +877,8 @@ int __init construct_dom0( + else + ((unsigned int *)vphysmap_start)[pfn] = mfn; + set_gpfn_from_mfn(mfn, pfn); ++ if (!(pfn & 0xfffff)) ++ process_pending_timers(); + } + si->first_p2m_pfn = pfn; + si->nr_p2m_frames = d->tot_pages - count; +@@ -895,6 +897,8 @@ int __init construct_dom0( + #ifndef NDEBUG + ++alloc_epfn; + #endif ++ if (!(pfn & 0xfffff)) ++ process_pending_timers(); + } + } + BUG_ON(pfn != d->tot_pages); +@@ -915,6 +919,8 @@ int __init construct_dom0( + set_gpfn_from_mfn(mfn, pfn); + #undef pfn + page++; pfn++; ++ if (!(pfn & 0xfffff)) ++ process_pending_timers(); + } + } +