diff --git a/5310bac3-mm-ensure-useful-progress-in-decrease_reservation.patch b/5310bac3-mm-ensure-useful-progress-in-decrease_reservation.patch deleted file mode 100644 index 0adf29f..0000000 --- a/5310bac3-mm-ensure-useful-progress-in-decrease_reservation.patch +++ /dev/null @@ -1,32 +0,0 @@ -# Commit 79de2d31f1ff8910231b7ec15519405953e6571a -# Date 2014-02-28 17:35:15 +0100 -# Author Wei Liu -# Committer Jan Beulich -mm: ensure useful progress in decrease_reservation - -During my fun time playing with balloon driver I found that hypervisor's -preemption check kept decrease_reservation from doing any useful work -for 32 bit guests, resulting in hanging the guests. - -As Andrew suggested, we can force the check to fail for the first -iteration to ensure progress. We did this in d3a55d7d9 "x86/mm: Ensure -useful progress in alloc_l2_table()" already. - -After this change I cannot see the hang caused by continuation logic -anymore. - -Signed-off-by: Wei Liu -Reviewed-by: Andrew Cooper -Acked-by: Keir Fraser - ---- a/xen/common/memory.c -+++ b/xen/common/memory.c -@@ -268,7 +268,7 @@ static void decrease_reservation(struct - - for ( i = a->nr_done; i < a->nr_extents; i++ ) - { -- if ( hypercall_preempt_check() ) -+ if ( hypercall_preempt_check() && i != a->nr_done ) - { - a->preempted = 1; - goto out; diff --git a/531d8e34-x86-HVM-consolidate-passthrough-handling-in-epte_get_entry_emt.patch b/531d8e34-x86-HVM-consolidate-passthrough-handling-in-epte_get_entry_emt.patch index 8552bb9..c86a6f4 100644 --- a/531d8e34-x86-HVM-consolidate-passthrough-handling-in-epte_get_entry_emt.patch +++ b/531d8e34-x86-HVM-consolidate-passthrough-handling-in-epte_get_entry_emt.patch @@ -19,9 +19,21 @@ Signed-off-by: Jan Beulich Reviewed-by: "Xu, Dongxiao" Acked-by: Keir Fraser +# Commit 1f8b57779785bf9f55c16312bb1ec679929c314b +# Date 2014-03-28 13:43:25 +0100 +# Author Jan Beulich +# Committer Jan Beulich +x86/EPT: relax treatment of APIC MFN + +There's no point in this being mapped UC by the guest due to using a +respective PAT index - set the ignore-PAT flag to true. + +Signed-off-by: Jan Beulich +Reviewed-by: Tim Deegan + --- a/xen/arch/x86/hvm/mtrr.c +++ b/xen/arch/x86/hvm/mtrr.c -@@ -698,14 +698,20 @@ uint8_t epte_get_entry_emt(struct domain +@@ -698,14 +698,24 @@ uint8_t epte_get_entry_emt(struct domain if ( hvm_get_mem_pinned_cacheattr(d, gfn, &type) ) return type; @@ -39,8 +51,12 @@ Acked-by: Keir Fraser if ( direct_mmio ) - return MTRR_TYPE_UNCACHABLE; -+ return mfn_x(mfn) != d->arch.hvm_domain.vmx.apic_access_mfn -+ ? MTRR_TYPE_UNCACHABLE : MTRR_TYPE_WRBACK; ++ { ++ if ( mfn_x(mfn) != d->arch.hvm_domain.vmx.apic_access_mfn ) ++ return MTRR_TYPE_UNCACHABLE; ++ *ipat = 1; ++ return MTRR_TYPE_WRBACK; ++ } if ( iommu_snoop ) { diff --git a/53206661-pygrub-support-linux16-and-initrd16.patch b/53206661-pygrub-support-linux16-and-initrd16.patch new file mode 100644 index 0000000..bf4f89a --- /dev/null +++ b/53206661-pygrub-support-linux16-and-initrd16.patch @@ -0,0 +1,165 @@ +Subject: xen/pygrub: grub2/grub.cfg from RHEL 7 has new commands in menuentry +From: Joby Poriyath joby.poriyath@citrix.com Tue Feb 4 18:10:35 2014 +0000 +Date: Wed Mar 12 13:51:29 2014 +0000: +Git: dd03048708af072374963d6d0721cc6d4c5f52cf + +menuentry in grub2/grub.cfg uses linux16 and initrd16 commands +instead of linux and initrd. Due to this RHEL 7 (beta) guest failed to +boot after the installation. + +In addition to this, RHEL 7 menu entries have two different single-quote +delimited strings on the same line, and the greedy grouping for menuentry +parsing gets both strings, and the options inbetween. + +Signed-off-by: Joby Poriyath +Reviewed-by: Andrew Cooper +Acked-by: Ian Campbell +Cc: george.dunlap@citrix.com + +diff --git a/tools/pygrub/examples/rhel-7-beta.grub2 b/tools/pygrub/examples/rhel-7-beta.grub2 +new file mode 100644 +index 0000000..88f0f99 +--- /dev/null ++++ b/tools/pygrub/examples/rhel-7-beta.grub2 +@@ -0,0 +1,118 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++set timeout=5 ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'Red Hat Enterprise Linux Everything, with Linux 3.10.0-54.0.1.el7.x86_64' --class red --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-3.10.0-54.0.1.el7.x86_64-advanced-d23b8b49-4cfe-4900-8ef1-ec80bc633163' { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod xfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 89ffef78-82b3-457c-bc57-42cccc373851 ++ else ++ search --no-floppy --fs-uuid --set=root 89ffef78-82b3-457c-bc57-42cccc373851 ++ fi ++ linux16 /vmlinuz-3.10.0-54.0.1.el7.x86_64 root=/dev/mapper/rhel-root ro rd.lvm.lv=rhel/swap vconsole.keymap=uk crashkernel=auto rd.lvm.lv=rhel/root vconsole.font=latarcyrheb-sun16 LANG=en_GB.UTF-8 ++ initrd16 /initramfs-3.10.0-54.0.1.el7.x86_64.img ++} ++menuentry 'Red Hat Enterprise Linux Everything, with Linux 0-rescue-af34f0b8cf364cdbbe6d093f8228a37f' --class red --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-0-rescue-af34f0b8cf364cdbbe6d093f8228a37f-advanced-d23b8b49-4cfe-4900-8ef1-ec80bc633163' { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod xfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 89ffef78-82b3-457c-bc57-42cccc373851 ++ else ++ search --no-floppy --fs-uuid --set=root 89ffef78-82b3-457c-bc57-42cccc373851 ++ fi ++ linux16 /vmlinuz-0-rescue-af34f0b8cf364cdbbe6d093f8228a37f root=/dev/mapper/rhel-root ro rd.lvm.lv=rhel/swap vconsole.keymap=uk crashkernel=auto rd.lvm.lv=rhel/root vconsole.font=latarcyrheb-sun16 ++ initrd16 /initramfs-0-rescue-af34f0b8cf364cdbbe6d093f8228a37f.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### END /etc/grub.d/30_os-prober ### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py +index cb853c9..974cded 100644 +--- a/tools/pygrub/src/GrubConf.py ++++ b/tools/pygrub/src/GrubConf.py +@@ -348,7 +348,9 @@ class Grub2Image(_GrubImage): + + commands = {'set:root': 'root', + 'linux': 'kernel', ++ 'linux16': 'kernel', + 'initrd': 'initrd', ++ 'initrd16': 'initrd', + 'echo': None, + 'insmod': None, + 'search': None} +@@ -394,7 +396,7 @@ class Grub2ConfigFile(_GrubConfigFile): + continue + + # new image +- title_match = re.match('^menuentry ["\'](.*)["\'] (.*){', l) ++ title_match = re.match('^menuentry ["\'](.*?)["\'] (.*){', l) + if title_match: + if img is not None: + raise RuntimeError, "syntax error: cannot nest menuentry (%d %s)" % (len(img),img) diff --git a/5321b20b-common-make-hypercall-preemption-checks-consistent.patch b/5321b20b-common-make-hypercall-preemption-checks-consistent.patch new file mode 100644 index 0000000..c12ec08 --- /dev/null +++ b/5321b20b-common-make-hypercall-preemption-checks-consistent.patch @@ -0,0 +1,81 @@ +# Commit 8c0eed2cc8d8a2ccccdffe4c386b625b672dc12a +# Date 2014-03-13 14:26:35 +0100 +# Author Jan Beulich +# Committer Jan Beulich +common: make hypercall preemption checks consistent + +- never preempt on the first iteration (ensure forward progress) +- do cheap checks first + +Signed-off-by: Jan Beulich +Reviewed-by: Andrew Cooper +Reviewed-by: Tim Deegan +Acked-by: Keir Fraser + +--- a/xen/common/memory.c ++++ b/xen/common/memory.c +@@ -63,7 +63,7 @@ static void increase_reservation(struct + + for ( i = a->nr_done; i < a->nr_extents; i++ ) + { +- if ( hypercall_preempt_check() ) ++ if ( i != a->nr_done && hypercall_preempt_check() ) + { + a->preempted = 1; + goto out; +@@ -109,7 +109,7 @@ static void populate_physmap(struct memo + + for ( i = a->nr_done; i < a->nr_extents; i++ ) + { +- if ( hypercall_preempt_check() ) ++ if ( i != a->nr_done && hypercall_preempt_check() ) + { + a->preempted = 1; + goto out; +@@ -268,7 +268,7 @@ static void decrease_reservation(struct + + for ( i = a->nr_done; i < a->nr_extents; i++ ) + { +- if ( hypercall_preempt_check() ) ++ if ( i != a->nr_done && hypercall_preempt_check() ) + { + a->preempted = 1; + goto out; +@@ -398,7 +398,8 @@ static long memory_exchange(XEN_GUEST_HA + i < (exch.in.nr_extents >> in_chunk_order); + i++ ) + { +- if ( hypercall_preempt_check() ) ++ if ( i != (exch.nr_exchanged >> in_chunk_order) && ++ hypercall_preempt_check() ) + { + exch.nr_exchanged = i << in_chunk_order; + rcu_unlock_domain(d); +--- a/xen/common/multicall.c ++++ b/xen/common/multicall.c +@@ -52,7 +52,7 @@ do_multicall( + + for ( i = 0; !rc && i < nr_calls; i++ ) + { +- if ( hypercall_preempt_check() ) ++ if ( i && hypercall_preempt_check() ) + goto preempted; + + if ( unlikely(__copy_from_guest(&mcs->call, call_list, 1)) ) +--- a/xen/drivers/char/console.c ++++ b/xen/drivers/char/console.c +@@ -375,12 +375,12 @@ static DECLARE_SOFTIRQ_TASKLET(notify_do + static long guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer, int count) + { + char kbuf[128]; +- int kcount; ++ int kcount = 0; + struct domain *cd = current->domain; + + while ( count > 0 ) + { +- if ( hypercall_preempt_check() ) ++ if ( kcount && hypercall_preempt_check() ) + return hypercall_create_continuation( + __HYPERVISOR_console_io, "iih", + CONSOLEIO_write, count, buffer); diff --git a/5321b257-x86-make-hypercall-preemption-checks-consistent.patch b/5321b257-x86-make-hypercall-preemption-checks-consistent.patch new file mode 100644 index 0000000..d18f28d --- /dev/null +++ b/5321b257-x86-make-hypercall-preemption-checks-consistent.patch @@ -0,0 +1,156 @@ +# Commit fd7bfce0395ace266159760e35dc49f7af3b90ce +# Date 2014-03-13 14:27:51 +0100 +# Author Jan Beulich +# Committer Jan Beulich +x86: make hypercall preemption checks consistent + +- never preempt on the first iteration (ensure forward progress) +- never preempt on the last iteration (pointless/wasteful) + +Signed-off-by: Jan Beulich +Reviewed-by: Andrew Cooper +Reviewed-by: Tim Deegan +Acked-by: Keir Fraser + +--- a/xen/arch/x86/mm.c ++++ b/xen/arch/x86/mm.c +@@ -2934,7 +2934,7 @@ long do_mmuext_op( + + for ( i = 0; i < count; i++ ) + { +- if ( curr->arch.old_guest_table || hypercall_preempt_check() ) ++ if ( curr->arch.old_guest_table || (i && hypercall_preempt_check()) ) + { + rc = -EAGAIN; + break; +@@ -3481,7 +3481,7 @@ long do_mmu_update( + + for ( i = 0; i < count; i++ ) + { +- if ( curr->arch.old_guest_table || hypercall_preempt_check() ) ++ if ( curr->arch.old_guest_table || (i && hypercall_preempt_check()) ) + { + rc = -EAGAIN; + break; +--- a/xen/arch/x86/mm/hap/hap.c ++++ b/xen/arch/x86/mm/hap/hap.c +@@ -326,7 +326,7 @@ hap_set_allocation(struct domain *d, uns + else + pages -= d->arch.paging.hap.p2m_pages; + +- while ( d->arch.paging.hap.total_pages != pages ) ++ for ( ; ; ) + { + if ( d->arch.paging.hap.total_pages < pages ) + { +@@ -355,6 +355,8 @@ hap_set_allocation(struct domain *d, uns + d->arch.paging.hap.total_pages--; + free_domheap_page(pg); + } ++ else ++ break; + + /* Check to see if we need to yield and try again */ + if ( preempted && hypercall_preempt_check() ) +--- a/xen/arch/x86/mm/p2m-pod.c ++++ b/xen/arch/x86/mm/p2m-pod.c +@@ -242,7 +242,8 @@ p2m_pod_set_cache_target(struct p2m_doma + + p2m_pod_cache_add(p2m, page, order); + +- if ( hypercall_preempt_check() && preemptible ) ++ if ( preemptible && pod_target != p2m->pod.count && ++ hypercall_preempt_check() ) + { + ret = -EAGAIN; + goto out; +@@ -286,7 +287,8 @@ p2m_pod_set_cache_target(struct p2m_doma + + put_page(page+i); + +- if ( hypercall_preempt_check() && preemptible ) ++ if ( preemptible && pod_target != p2m->pod.count && ++ hypercall_preempt_check() ) + { + ret = -EAGAIN; + goto out; +--- a/xen/arch/x86/mm/shadow/common.c ++++ b/xen/arch/x86/mm/shadow/common.c +@@ -1674,7 +1674,7 @@ static unsigned int sh_set_allocation(st + SHADOW_PRINTK("current %i target %i\n", + d->arch.paging.shadow.total_pages, pages); + +- while ( d->arch.paging.shadow.total_pages != pages ) ++ for ( ; ; ) + { + if ( d->arch.paging.shadow.total_pages < pages ) + { +@@ -1709,6 +1709,8 @@ static unsigned int sh_set_allocation(st + d->arch.paging.shadow.total_pages--; + free_domheap_page(sp); + } ++ else ++ break; + + /* Check to see if we need to yield and try again */ + if ( preempted && hypercall_preempt_check() ) +--- a/xen/arch/x86/traps.c ++++ b/xen/arch/x86/traps.c +@@ -3595,13 +3595,6 @@ long do_set_trap_table(XEN_GUEST_HANDLE_ + + for ( ; ; ) + { +- if ( hypercall_preempt_check() ) +- { +- rc = hypercall_create_continuation( +- __HYPERVISOR_set_trap_table, "h", traps); +- break; +- } +- + if ( copy_from_guest(&cur, traps, 1) ) + { + rc = -EFAULT; +@@ -3622,6 +3615,13 @@ long do_set_trap_table(XEN_GUEST_HANDLE_ + init_int80_direct_trap(curr); + + guest_handle_add_offset(traps, 1); ++ ++ if ( hypercall_preempt_check() ) ++ { ++ rc = hypercall_create_continuation( ++ __HYPERVISOR_set_trap_table, "h", traps); ++ break; ++ } + } + + return rc; +--- a/xen/arch/x86/x86_64/compat/traps.c ++++ b/xen/arch/x86/x86_64/compat/traps.c +@@ -329,13 +329,6 @@ int compat_set_trap_table(XEN_GUEST_HAND + + for ( ; ; ) + { +- if ( hypercall_preempt_check() ) +- { +- rc = hypercall_create_continuation( +- __HYPERVISOR_set_trap_table, "h", traps); +- break; +- } +- + if ( copy_from_guest(&cur, traps, 1) ) + { + rc = -EFAULT; +@@ -353,6 +346,13 @@ int compat_set_trap_table(XEN_GUEST_HAND + init_int80_direct_trap(current); + + guest_handle_add_offset(traps, 1); ++ ++ if ( hypercall_preempt_check() ) ++ { ++ rc = hypercall_create_continuation( ++ __HYPERVISOR_set_trap_table, "h", traps); ++ break; ++ } + } + + return rc; diff --git a/53271880-VT-d-fix-RMRR-handling.patch b/53271880-VT-d-fix-RMRR-handling.patch new file mode 100644 index 0000000..f8cb05e --- /dev/null +++ b/53271880-VT-d-fix-RMRR-handling.patch @@ -0,0 +1,255 @@ +# Commit dd527061770789d8152b1dea68056987b202d87a +# Date 2014-03-17 16:45:04 +0100 +# Author Jan Beulich +# Committer Jan Beulich +VT-d: fix RMRR handling + +Removing mapped RMRR tracking structures in dma_pte_clear_one() is +wrong for two reasons: First, these regions may cover more than a +single page. And second, multiple devices (and hence multiple devices +assigned to any particular guest) may share a single RMRR (whether +assigning such devices to distinct guests is a safe thing to do is +another question). + +Therefore move the removal of the tracking structures into the +counterpart function to the one doing the insertion - +intel_iommu_remove_device(), and add a reference count to the tracking +structure. + +Further, for the handling of the mappings of the respective memory +regions to be correct, RMRRs must not overlap. Add a respective check +to acpi_parse_one_rmrr(). + +And finally, with all of this being VT-d specific, move the cleanup +of the list as well as the structure type definition where it belongs - +in VT-d specific rather than IOMMU generic code. + +Note that this doesn't address yet another issue associated with RMRR +handling: The purpose of the RMRRs as well as the way the respective +IOMMU page table mappings get inserted both suggest that these regions +would need to be marked E820_RESERVED in all (HVM?) guests' memory +maps, yet nothing like this is being done in hvmloader. (For PV guests +this would also seem to be necessary, but may conflict with PV guests +possibly assuming there to be just a single E820 entry representing all +of its RAM.) + +Signed-off-by: Jan Beulich +Acked-by: Xiantao Zhang + +--- a/xen/drivers/passthrough/iommu.c ++++ b/xen/drivers/passthrough/iommu.c +@@ -412,9 +412,8 @@ static int iommu_populate_page_table(str + void iommu_domain_destroy(struct domain *d) + { + struct hvm_iommu *hd = domain_hvm_iommu(d); +- struct list_head *ioport_list, *rmrr_list, *tmp; ++ struct list_head *ioport_list, *tmp; + struct g2m_ioport *ioport; +- struct mapped_rmrr *mrmrr; + + if ( !iommu_enabled || !hd->platform_ops ) + return; +@@ -428,13 +427,6 @@ void iommu_domain_destroy(struct domain + list_del(&ioport->list); + xfree(ioport); + } +- +- list_for_each_safe ( rmrr_list, tmp, &hd->mapped_rmrrs ) +- { +- mrmrr = list_entry(rmrr_list, struct mapped_rmrr, list); +- list_del(&mrmrr->list); +- xfree(mrmrr); +- } + } + + int iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn, +--- a/xen/drivers/passthrough/vtd/dmar.c ++++ b/xen/drivers/passthrough/vtd/dmar.c +@@ -580,6 +580,16 @@ acpi_parse_one_rmrr(struct acpi_dmar_hea + if ( (ret = acpi_dmar_check_length(header, sizeof(*rmrr))) != 0 ) + return ret; + ++ list_for_each_entry(rmrru, &acpi_rmrr_units, list) ++ if ( base_addr <= rmrru->end_address && rmrru->base_address <= end_addr ) ++ { ++ printk(XENLOG_ERR VTDPREFIX ++ "Overlapping RMRRs [%"PRIx64",%"PRIx64"] and [%"PRIx64",%"PRIx64"]\n", ++ rmrru->base_address, rmrru->end_address, ++ base_addr, end_addr); ++ return -EEXIST; ++ } ++ + /* This check is here simply to detect when RMRR values are + * not properly represented in the system memory map and + * inform the user +--- a/xen/drivers/passthrough/vtd/iommu.c ++++ b/xen/drivers/passthrough/vtd/iommu.c +@@ -42,6 +42,12 @@ + #include "vtd.h" + #include "../ats.h" + ++struct mapped_rmrr { ++ struct list_head list; ++ u64 base, end; ++ unsigned int count; ++}; ++ + /* Possible unfiltered LAPIC/MSI messages from untrusted sources? */ + bool_t __read_mostly untrusted_msi; + +@@ -619,7 +625,6 @@ static void dma_pte_clear_one(struct dom + struct hvm_iommu *hd = domain_hvm_iommu(domain); + struct dma_pte *page = NULL, *pte = NULL; + u64 pg_maddr; +- struct mapped_rmrr *mrmrr; + + spin_lock(&hd->mapping_lock); + /* get last level pte */ +@@ -648,21 +653,6 @@ static void dma_pte_clear_one(struct dom + __intel_iommu_iotlb_flush(domain, addr >> PAGE_SHIFT_4K, 1, 1); + + unmap_vtd_domain_page(page); +- +- /* if the cleared address is between mapped RMRR region, +- * remove the mapped RMRR +- */ +- spin_lock(&hd->mapping_lock); +- list_for_each_entry ( mrmrr, &hd->mapped_rmrrs, list ) +- { +- if ( addr >= mrmrr->base && addr <= mrmrr->end ) +- { +- list_del(&mrmrr->list); +- xfree(mrmrr); +- break; +- } +- } +- spin_unlock(&hd->mapping_lock); + } + + static void iommu_free_pagetable(u64 pt_maddr, int level) +@@ -1700,10 +1690,17 @@ static int reassign_device_ownership( + void iommu_domain_teardown(struct domain *d) + { + struct hvm_iommu *hd = domain_hvm_iommu(d); ++ struct mapped_rmrr *mrmrr, *tmp; + + if ( list_empty(&acpi_drhd_units) ) + return; + ++ list_for_each_entry_safe ( mrmrr, tmp, &hd->mapped_rmrrs, list ) ++ { ++ list_del(&mrmrr->list); ++ xfree(mrmrr); ++ } ++ + if ( iommu_use_hap_pt(d) ) + return; + +@@ -1848,14 +1845,17 @@ static int rmrr_identity_mapping(struct + ASSERT(rmrr->base_address < rmrr->end_address); + + /* +- * No need to acquire hd->mapping_lock, as the only theoretical race is +- * with the insertion below (impossible due to holding pcidevs_lock). ++ * No need to acquire hd->mapping_lock: Both insertion and removal ++ * get done while holding pcidevs_lock. + */ + list_for_each_entry( mrmrr, &hd->mapped_rmrrs, list ) + { + if ( mrmrr->base == rmrr->base_address && + mrmrr->end == rmrr->end_address ) ++ { ++ ++mrmrr->count; + return 0; ++ } + } + + base = rmrr->base_address & PAGE_MASK_4K; +@@ -1876,9 +1876,8 @@ static int rmrr_identity_mapping(struct + return -ENOMEM; + mrmrr->base = rmrr->base_address; + mrmrr->end = rmrr->end_address; +- spin_lock(&hd->mapping_lock); ++ mrmrr->count = 1; + list_add_tail(&mrmrr->list, &hd->mapped_rmrrs); +- spin_unlock(&hd->mapping_lock); + + return 0; + } +@@ -1940,17 +1939,52 @@ static int intel_iommu_remove_device(u8 + if ( !pdev->domain ) + return -EINVAL; + +- /* If the device belongs to dom0, and it has RMRR, don't remove it +- * from dom0, because BIOS may use RMRR at booting time. +- */ +- if ( pdev->domain->domain_id == 0 ) ++ for_each_rmrr_device ( rmrr, bdf, i ) + { +- for_each_rmrr_device ( rmrr, bdf, i ) ++ struct hvm_iommu *hd; ++ struct mapped_rmrr *mrmrr, *tmp; ++ ++ if ( rmrr->segment != pdev->seg || ++ PCI_BUS(bdf) != pdev->bus || ++ PCI_DEVFN2(bdf) != devfn ) ++ continue; ++ ++ /* ++ * If the device belongs to dom0, and it has RMRR, don't remove ++ * it from dom0, because BIOS may use RMRR at booting time. ++ */ ++ if ( is_hardware_domain(pdev->domain) ) ++ return 0; ++ ++ hd = domain_hvm_iommu(pdev->domain); ++ ++ /* ++ * No need to acquire hd->mapping_lock: Both insertion and removal ++ * get done while holding pcidevs_lock. ++ */ ++ ASSERT(spin_is_locked(&pcidevs_lock)); ++ list_for_each_entry_safe ( mrmrr, tmp, &hd->mapped_rmrrs, list ) + { +- if ( rmrr->segment == pdev->seg && +- PCI_BUS(bdf) == pdev->bus && +- PCI_DEVFN2(bdf) == devfn ) +- return 0; ++ unsigned long base_pfn, end_pfn; ++ ++ if ( rmrr->base_address != mrmrr->base || ++ rmrr->end_address != mrmrr->end ) ++ continue; ++ ++ if ( --mrmrr->count ) ++ break; ++ ++ base_pfn = (mrmrr->base & PAGE_MASK_4K) >> PAGE_SHIFT_4K; ++ end_pfn = PAGE_ALIGN_4K(mrmrr->end) >> PAGE_SHIFT_4K; ++ while ( base_pfn < end_pfn ) ++ { ++ if ( intel_iommu_unmap_page(pdev->domain, base_pfn) ) ++ return -ENXIO; ++ base_pfn++; ++ } ++ ++ list_del(&mrmrr->list); ++ xfree(mrmrr); + } + } + +--- a/xen/include/xen/hvm/iommu.h ++++ b/xen/include/xen/hvm/iommu.h +@@ -29,12 +29,6 @@ struct g2m_ioport { + unsigned int np; + }; + +-struct mapped_rmrr { +- struct list_head list; +- u64 base; +- u64 end; +-}; +- + struct hvm_iommu { + u64 pgd_maddr; /* io page directory machine address */ + spinlock_t mapping_lock; /* io page table lock */ diff --git a/5327190a-x86-Intel-work-around-Xeon-7400-series-erratum-AAI65.patch b/5327190a-x86-Intel-work-around-Xeon-7400-series-erratum-AAI65.patch new file mode 100644 index 0000000..0ce50cf --- /dev/null +++ b/5327190a-x86-Intel-work-around-Xeon-7400-series-erratum-AAI65.patch @@ -0,0 +1,62 @@ +# Commit 96d1b237ae9b2f2718bb1c59820701f17d3d86e0 +# Date 2014-03-17 16:47:22 +0100 +# Author Jan Beulich +# Committer Jan Beulich +x86/Intel: work around Xeon 7400 series erratum AAI65 + +Linux commit 40e2d7f9b5dae048789c64672bf3027fbb663ffa ("x86 idle: +Repair large-server 50-watt idle-power regression") tells us that this +applies not just to the named Xeon 7400 series, but also NHM-EX and +WSM-EX; sadly Intel's documentation is so badly searchable that I +wasn't able to locate the respective errata (and hence can't quote +their numbers here). + +Signed-off-by: Jan Beulich +Reviewed-by: Andrew Cooper +Acked-by: Kevin Tian + +--- a/xen/arch/x86/acpi/cpu_idle.c ++++ b/xen/arch/x86/acpi/cpu_idle.c +@@ -296,6 +296,9 @@ void mwait_idle_with_hints(unsigned int + unsigned int cpu = smp_processor_id(); + s_time_t expires = per_cpu(timer_deadline, cpu); + ++ if ( boot_cpu_has(X86_FEATURE_CLFLUSH_MONITOR) ) ++ clflush((void *)&mwait_wakeup(cpu)); ++ + __monitor((void *)&mwait_wakeup(cpu), 0, 0); + smp_mb(); + +--- a/xen/arch/x86/cpu/intel.c ++++ b/xen/arch/x86/cpu/intel.c +@@ -147,6 +147,9 @@ void __devinit early_intel_workaround(st + /* + * P4 Xeon errata 037 workaround. + * Hardware prefetcher may cause stale data to be loaded into the cache. ++ * ++ * Xeon 7400 erratum AAI65 (and further newer Xeons) ++ * MONITOR/MWAIT may have excessive false wakeups + */ + static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c) + { +@@ -161,6 +164,10 @@ static void __devinit Intel_errata_worka + wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); + } + } ++ ++ if (c->x86 == 6 && cpu_has_clflush && ++ (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47)) ++ set_bit(X86_FEATURE_CLFLUSH_MONITOR, c->x86_capability); + } + + +--- a/xen/include/asm-x86/cpufeature.h ++++ b/xen/include/asm-x86/cpufeature.h +@@ -71,6 +71,7 @@ + #define X86_FEATURE_TSC_RELIABLE (3*32+12) /* TSC is known to be reliable */ + #define X86_FEATURE_XTOPOLOGY (3*32+13) /* cpu topology enum extensions */ + #define X86_FEATURE_CPUID_FAULTING (3*32+14) /* cpuid faulting */ ++#define X86_FEATURE_CLFLUSH_MONITOR (3*32+15) /* clflush reqd with monitor */ + + /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ + #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ diff --git a/53299d8f-xenconsole-reset-tty-on-failure.patch b/53299d8f-xenconsole-reset-tty-on-failure.patch new file mode 100644 index 0000000..be70997 --- /dev/null +++ b/53299d8f-xenconsole-reset-tty-on-failure.patch @@ -0,0 +1,54 @@ +Subject: tools/console: reset tty when xenconsole fails +From: Ian Jackson ian.jackson@eu.citrix.com Mon Feb 24 15:16:19 2014 +0000 +Date: Wed Mar 19 13:37:19 2014 +0000: +Git: 111931f36885874103d65685ab15ea3d25d93da7 + +If xenconsole (the client program) fails, it calls err. This would +previously neglect to reset the user's terminal to sanity. Use atexit +to do so. + +This routinely happens in Xen 4.4 RC5 with pygrub because libxl +writes the value "" to the tty xenstore key when using xenconsole. +After this patch this just results in a harmless error message. + +Reported-by: M A Young +Signed-off-by: Ian Jackson +CC: M A Young +CC: Ian Campbell +Acked-by: George Dunlap +Acked-by: Ian Campbell + +--- +v2: Fix whitespace error (reintroduce hard tab) + Fix commit message not to claim ignorance about root cause + +Index: xen-4.4.0-testing/tools/console/client/main.c +=================================================================== +--- xen-4.4.0-testing.orig/tools/console/client/main.c ++++ xen-4.4.0-testing/tools/console/client/main.c +@@ -258,6 +258,13 @@ typedef enum { + CONSOLE_SERIAL, + } console_type; + ++static struct termios stdin_old_attr; ++ ++static void restore_term_stdin(void) ++{ ++ restore_term(STDIN_FILENO, &stdin_old_attr); ++} ++ + int main(int argc, char **argv) + { + struct termios attr; +@@ -384,9 +391,9 @@ int main(int argc, char **argv) + } + + init_term(spty, &attr); +- init_term(STDIN_FILENO, &attr); ++ init_term(STDIN_FILENO, &stdin_old_attr); ++ atexit(restore_term_stdin); /* if this fails, oh dear */ + console_loop(spty, xs, path); +- restore_term(STDIN_FILENO, &attr); + + free(path); + free(dom_path); diff --git a/53299d8f-xenconsole-tolerate-tty-errors.patch b/53299d8f-xenconsole-tolerate-tty-errors.patch new file mode 100644 index 0000000..0406c8c --- /dev/null +++ b/53299d8f-xenconsole-tolerate-tty-errors.patch @@ -0,0 +1,49 @@ +Subject: tools/console: xenconsole tolerate tty errors +From: Ian Jackson ian.jackson@eu.citrix.com Thu Feb 27 17:46:49 2014 +0000 +Date: Wed Mar 19 13:37:19 2014 +0000: +Git: 39ba2989b10b6a1852e253b204eb010f8e7026f1 + +Since 28d386fc4341 (XSA-57), libxl writes an empty value for the +console tty node, with read-only permission for the guest, when +setting up pv console "frontends". (The actual tty value is later set +by xenconsoled.) Writing an empty node is not strictly necessary to +stop the frontend from writing dangerous values here, but it is a good +belt-and-braces approach. + +Unfortunately this confuses xenconsole. It reads the empty value, and +tries to open it as the tty. xenconsole then exits. + +Fix this by having xenconsole treat an empty value the same way as no +value at all. + +Also, make the error opening the tty be nonfatal: we just print a +warning, but do not exit. I think this is helpful in theoretical +situations where xenconsole is racing with libxl and/or xenconsoled. + +Signed-off-by: Ian Jackson +Acked-by: Ian Campbell +CC: George Dunlap + +--- +v2: Combine two conditions and move the free + +Index: xen-4.4.0-testing/tools/console/client/main.c +=================================================================== +--- xen-4.4.0-testing.orig/tools/console/client/main.c ++++ xen-4.4.0-testing/tools/console/client/main.c +@@ -115,12 +115,12 @@ static int get_pty_fd(struct xs_handle * + /* We only watch for one thing, so no need to + * disambiguate: just read the pty path */ + pty_path = xs_read(xs, XBT_NULL, path, &len); +- if (pty_path != NULL) { ++ if (pty_path != NULL && pty_path[0] != '\0') { + pty_fd = open(pty_path, O_RDWR | O_NOCTTY); + if (pty_fd == -1) +- err(errno, "Could not open tty `%s'", pty_path); +- free(pty_path); ++ warn("Could not open tty `%s'", pty_path); + } ++ free(pty_path); + } + } while (pty_fd == -1 && (now = time(NULL)) < start + seconds); + diff --git a/532fff53-x86-fix-determination-of-bit-count-for-struct-domain-allocations.patch b/532fff53-x86-fix-determination-of-bit-count-for-struct-domain-allocations.patch new file mode 100644 index 0000000..e21750e --- /dev/null +++ b/532fff53-x86-fix-determination-of-bit-count-for-struct-domain-allocations.patch @@ -0,0 +1,57 @@ +# Commit b3d2f8b2cba9fce5bc8995612d0d13fcefec7769 +# Date 2014-03-24 10:48:03 +0100 +# Author Jan Beulich +# Committer Jan Beulich +x86: fix determination of bit count for struct domain allocations + +We can't just add in the hole shift value, as the hole may be at or +above the 44-bit boundary. Instead we need to determine the total bit +count until reaching 32 significant (not squashed out) bits in PFN +representations. + +Signed-off-by: Jan Beulich +Acked-by: Keir Fraser + +--- a/xen/arch/x86/domain.c ++++ b/xen/arch/x86/domain.c +@@ -180,6 +180,28 @@ void dump_pageframe_info(struct domain * + spin_unlock(&d->page_alloc_lock); + } + ++/* ++ * The hole may be at or above the 44-bit boundary, so we need to determine ++ * the total bit count until reaching 32 significant (not squashed out) bits ++ * in PFN representations. ++ * Note that the way "bits" gets initialized/updated/bounds-checked guarantees ++ * that the function will never return zero, and hence will never be called ++ * more than once (which is important due to it being deliberately placed in ++ * .init.text). ++ */ ++static unsigned int __init noinline _domain_struct_bits(void) ++{ ++ unsigned int bits = 32 + PAGE_SHIFT; ++ unsigned int sig = hweight32(~pfn_hole_mask); ++ unsigned int mask = pfn_hole_mask >> 32; ++ ++ for ( ; bits < BITS_PER_LONG && sig < 32; ++bits, mask >>= 1 ) ++ if ( !(mask & 1) ) ++ ++sig; ++ ++ return bits; ++} ++ + struct domain *alloc_domain_struct(void) + { + struct domain *d; +@@ -187,7 +209,10 @@ struct domain *alloc_domain_struct(void) + * We pack the PDX of the domain structure into a 32-bit field within + * the page_info structure. Hence the MEMF_bits() restriction. + */ +- unsigned int bits = 32 + PAGE_SHIFT + pfn_pdx_hole_shift; ++ static unsigned int __read_mostly bits; ++ ++ if ( unlikely(!bits) ) ++ bits = _domain_struct_bits(); + + BUILD_BUG_ON(sizeof(*d) > PAGE_SIZE); + d = alloc_xenheap_pages(0, MEMF_bits(bits)); diff --git a/5331917d-x86-enforce-preemption-in-HVM_set_mem_access-p2m_set_mem_access.patch b/5331917d-x86-enforce-preemption-in-HVM_set_mem_access-p2m_set_mem_access.patch new file mode 100644 index 0000000..2d91aeb --- /dev/null +++ b/5331917d-x86-enforce-preemption-in-HVM_set_mem_access-p2m_set_mem_access.patch @@ -0,0 +1,102 @@ +References: bnc#867910 CVE-2014-2599 XSA-89 + +# Commit 0fe53c4f279e1a8ef913e71ed000236d21ce96de +# Date 2014-03-25 15:23:57 +0100 +# Author Jan Beulich +# Committer Jan Beulich +x86: enforce preemption in HVM_set_mem_access / p2m_set_mem_access() + +Processing up to 4G PFNs may take almost arbitrarily long, so +preemption is needed here. + +This is CVE-2014-2599 / XSA-89. + +Signed-off-by: Jan Beulich +Reviewed-by: Tim Deegan + +--- a/xen/arch/x86/hvm/hvm.c ++++ b/xen/arch/x86/hvm/hvm.c +@@ -4465,6 +4465,15 @@ long do_hvm_op(unsigned long op, XEN_GUE + goto param_fail5; + + rc = p2m_set_mem_access(d, a.first_pfn, a.nr, a.hvmmem_access); ++ if ( rc > 0 ) ++ { ++ a.first_pfn += a.nr - rc; ++ a.nr = rc; ++ if ( __copy_to_guest(arg, &a, 1) ) ++ rc = -EFAULT; ++ else ++ rc = -EAGAIN; ++ } + + param_fail5: + rcu_unlock_domain(d); +--- a/xen/arch/x86/mm/p2m.c ++++ b/xen/arch/x86/mm/p2m.c +@@ -1366,15 +1366,14 @@ void p2m_mem_access_resume(struct domain + + /* Set access type for a region of pfns. + * If start_pfn == -1ul, sets the default access type */ +-int p2m_set_mem_access(struct domain *d, unsigned long start_pfn, +- uint32_t nr, hvmmem_access_t access) ++long p2m_set_mem_access(struct domain *d, unsigned long pfn, uint32_t nr, ++ hvmmem_access_t access) + { + struct p2m_domain *p2m = p2m_get_hostp2m(d); +- unsigned long pfn; + p2m_access_t a, _a; + p2m_type_t t; + mfn_t mfn; +- int rc = 0; ++ long rc; + + /* N.B. _not_ static: initializer depends on p2m->default_access */ + p2m_access_t memaccess[] = { +@@ -1397,14 +1396,17 @@ int p2m_set_mem_access(struct domain *d, + a = memaccess[access]; + + /* If request to set default access */ +- if ( start_pfn == ~0ull ) ++ if ( pfn == ~0ul ) + { + p2m->default_access = a; + return 0; + } + ++ if ( !nr ) ++ return 0; ++ + p2m_lock(p2m); +- for ( pfn = start_pfn; pfn < start_pfn + nr; pfn++ ) ++ for ( ; ; ++pfn ) + { + mfn = p2m->get_entry(p2m, pfn, &t, &_a, 0, NULL); + if ( p2m->set_entry(p2m, pfn, mfn, PAGE_ORDER_4K, t, a) == 0 ) +@@ -1412,6 +1414,13 @@ int p2m_set_mem_access(struct domain *d, + rc = -ENOMEM; + break; + } ++ ++ /* Check for continuation if it's not the last interation. */ ++ if ( !--nr || hypercall_preempt_check() ) ++ { ++ rc = nr; ++ break; ++ } + } + p2m_unlock(p2m); + return rc; +--- a/xen/include/asm-x86/p2m.h ++++ b/xen/include/asm-x86/p2m.h +@@ -576,8 +576,8 @@ void p2m_mem_access_resume(struct domain + + /* Set access type for a region of pfns. + * If start_pfn == -1ul, sets the default access type */ +-int p2m_set_mem_access(struct domain *d, unsigned long start_pfn, +- uint32_t nr, hvmmem_access_t access); ++long p2m_set_mem_access(struct domain *d, unsigned long start_pfn, ++ uint32_t nr, hvmmem_access_t access); + + /* Get access type for a pfn + * If pfn == -1ul, gets the default access type */ diff --git a/53356c1e-x86-HVM-correct-CPUID-leaf-80000008-handling.patch b/53356c1e-x86-HVM-correct-CPUID-leaf-80000008-handling.patch new file mode 100644 index 0000000..5942d61 --- /dev/null +++ b/53356c1e-x86-HVM-correct-CPUID-leaf-80000008-handling.patch @@ -0,0 +1,141 @@ +# Commit ef437690af8b75e6758dce77af75a22b63982883 +# Date 2014-03-28 13:33:34 +0100 +# Author Jan Beulich +# Committer Jan Beulich +x86/HVM: correct CPUID leaf 80000008 handling + +CPUID[80000008].EAX[23:16] have been given the meaning of the guest +physical address restriction (in case it needs to be smaller than the +host's), hence we need to mirror that into vCPUID[80000008].EAX[7:0]. + +Enforce a lower limit at the same time, as well as a fixed value for +the virtual address bits, and zero for the guest physical address ones. + +In order for the vMTRR code to see these overrides we need to make it +call hvm_cpuid() instead of domain_cpuid(), which in turn requires +special casing (and relaxing) the controlling domain. + +This additionally should hide an ordering problem in the tools: Both +xend and xl appear to be restoring a guest from its image before +setting up the CPUID policy in the hypervisor, resulting in +domain_cpuid() returning all zeros and hence the check in +mtrr_var_range_msr_set() failing if the guest previously had more than +the minimum 36 physical address bits. + +Signed-off-by: Jan Beulich +Reviewed-by: Tim Deegan + +--- a/xen/arch/x86/hvm/hvm.c ++++ b/xen/arch/x86/hvm/hvm.c +@@ -2885,6 +2885,8 @@ void hvm_cpuid(unsigned int input, unsig + + switch ( input ) + { ++ unsigned int sub_leaf, _eax, _ebx, _ecx, _edx; ++ + case 0x1: + /* Fix up VLAPIC details. */ + *ebx &= 0x00FFFFFFu; +@@ -2918,8 +2920,6 @@ void hvm_cpuid(unsigned int input, unsig + *edx = v->vcpu_id * 2; + break; + case 0xd: +- { +- unsigned int sub_leaf, _eax, _ebx, _ecx, _edx; + /* EBX value of main leaf 0 depends on enabled xsave features */ + if ( count == 0 && v->arch.xcr0 ) + { +@@ -2936,7 +2936,7 @@ void hvm_cpuid(unsigned int input, unsig + } + } + break; +- } ++ + case 0x80000001: + /* We expose RDTSCP feature to guest only when + tsc_mode == TSC_MODE_DEFAULT and host_tsc_is_safe() returns 1 */ +@@ -2950,6 +2950,23 @@ void hvm_cpuid(unsigned int input, unsig + if ( !(hvm_pae_enabled(v) || hvm_long_mode_enabled(v)) ) + *edx &= ~cpufeat_mask(X86_FEATURE_PSE36); + break; ++ ++ case 0x80000008: ++ count = cpuid_eax(0x80000008); ++ count = (count >> 16) & 0xff ?: count & 0xff; ++ if ( (*eax & 0xff) > count ) ++ *eax = (*eax & ~0xff) | count; ++ ++ hvm_cpuid(1, NULL, NULL, NULL, &_edx); ++ count = _edx & (cpufeat_mask(X86_FEATURE_PAE) | ++ cpufeat_mask(X86_FEATURE_PSE36)) ? 36 : 32; ++ if ( (*eax & 0xff) < count ) ++ *eax = (*eax & ~0xff) | count; ++ ++ hvm_cpuid(0x80000001, NULL, NULL, NULL, &_edx); ++ *eax = (*eax & ~0xffff00) | (_edx & cpufeat_mask(X86_FEATURE_LM) ++ ? 0x3000 : 0x2000); ++ break; + } + } + +--- a/xen/arch/x86/hvm/mtrr.c ++++ b/xen/arch/x86/hvm/mtrr.c +@@ -145,7 +145,7 @@ bool_t is_var_mtrr_overlapped(struct mtr + + static int hvm_mtrr_pat_init(void) + { +- unsigned int i, j, phys_addr; ++ unsigned int i, j; + + memset(&mtrr_epat_tbl, INVALID_MEM_TYPE, sizeof(mtrr_epat_tbl)); + for ( i = 0; i < MTRR_NUM_TYPES; i++ ) +@@ -172,11 +172,7 @@ static int hvm_mtrr_pat_init(void) + } + } + +- phys_addr = 36; +- if ( cpuid_eax(0x80000000) >= 0x80000008 ) +- phys_addr = (uint8_t)cpuid_eax(0x80000008); +- +- size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1); ++ size_or_mask = ~((1 << (paddr_bits - PAGE_SHIFT)) - 1); + + return 0; + } +@@ -455,7 +451,7 @@ bool_t mtrr_fix_range_msr_set(struct mtr + bool_t mtrr_var_range_msr_set( + struct domain *d, struct mtrr_state *m, uint32_t msr, uint64_t msr_content) + { +- uint32_t index, type, phys_addr, eax, ebx, ecx, edx; ++ uint32_t index, type, phys_addr, eax; + uint64_t msr_mask; + uint64_t *var_range_base = (uint64_t*)m->var_ranges; + +@@ -468,16 +464,21 @@ bool_t mtrr_var_range_msr_set( + type == 4 || type == 5 || type == 6)) ) + return 0; + +- phys_addr = 36; +- domain_cpuid(d, 0x80000000, 0, &eax, &ebx, &ecx, &edx); +- if ( eax >= 0x80000008 ) ++ if ( d == current->domain ) + { +- domain_cpuid(d, 0x80000008, 0, &eax, &ebx, &ecx, &edx); +- phys_addr = (uint8_t)eax; ++ phys_addr = 36; ++ hvm_cpuid(0x80000000, &eax, NULL, NULL, NULL); ++ if ( eax >= 0x80000008 ) ++ { ++ hvm_cpuid(0x80000008, &eax, NULL, NULL, NULL); ++ phys_addr = (uint8_t)eax; ++ } + } ++ else ++ phys_addr = paddr_bits; + msr_mask = ~((((uint64_t)1) << phys_addr) - 1); + msr_mask |= (index & 1) ? 0x7ffUL : 0xf00UL; +- if ( unlikely(msr_content && (msr_content & msr_mask)) ) ++ if ( unlikely(msr_content & msr_mask) ) + { + HVM_DBG_LOG(DBG_LEVEL_MSR, "invalid msr content:%"PRIx64"\n", + msr_content); diff --git a/533ad1ee-VMX-fix-PAT-value-seen-by-guest.patch b/533ad1ee-VMX-fix-PAT-value-seen-by-guest.patch new file mode 100644 index 0000000..401a22f --- /dev/null +++ b/533ad1ee-VMX-fix-PAT-value-seen-by-guest.patch @@ -0,0 +1,34 @@ +# Commit fce79f8ce91dc45f3a4d699ee67c49e6cbeb1197 +# Date 2014-04-01 16:49:18 +0200 +# Author Jan Beulich +# Committer Jan Beulich +VMX: fix PAT value seen by guest + +The XSA-60 fixes introduced a window during which the guest PAT gets +forced to all zeros. This shouldn't be visible to the guest. Therefore +we need to intercept PAT MSR accesses during that time period. + +Signed-off-by: Jan Beulich +Reviewed-by: Liu Jinsong + +--- a/xen/arch/x86/hvm/vmx/vmx.c ++++ b/xen/arch/x86/hvm/vmx/vmx.c +@@ -984,6 +984,8 @@ static void vmx_handle_cd(struct vcpu *v + + vmx_get_guest_pat(v, pat); + vmx_set_guest_pat(v, uc_pat); ++ vmx_enable_intercept_for_msr(v, MSR_IA32_CR_PAT, ++ MSR_TYPE_R | MSR_TYPE_W); + + wbinvd(); /* flush possibly polluted cache */ + hvm_asid_flush_vcpu(v); /* invalidate memory type cached in TLB */ +@@ -993,6 +995,9 @@ static void vmx_handle_cd(struct vcpu *v + { + v->arch.hvm_vcpu.cache_mode = NORMAL_CACHE_MODE; + vmx_set_guest_pat(v, *pat); ++ if ( !iommu_enabled || iommu_snoop ) ++ vmx_disable_intercept_for_msr(v, MSR_IA32_CR_PAT, ++ MSR_TYPE_R | MSR_TYPE_W); + hvm_asid_flush_vcpu(v); /* no need to flush cache */ + } + } diff --git a/533d413b-x86-mm-fix-checks-against-max_mapped_pfn.patch b/533d413b-x86-mm-fix-checks-against-max_mapped_pfn.patch new file mode 100644 index 0000000..7f9d93d --- /dev/null +++ b/533d413b-x86-mm-fix-checks-against-max_mapped_pfn.patch @@ -0,0 +1,38 @@ +# Commit 088ee1d47b65d6bb92de61b404805f4ca92e3240 +# Date 2014-04-03 12:08:43 +0100 +# Author Jan Beulich +# Committer Tim Deegan +x86/mm: fix checks against max_mapped_pfn + +This value is an inclusive one, i.e. this fixes an off-by-one in memory +sharing and an off-by-two in shadow code. + +Signed-off-by: Jan Beulich +Reviewed-by: Tim Deegan + +--- a/xen/arch/x86/mm/mem_sharing.c ++++ b/xen/arch/x86/mm/mem_sharing.c +@@ -1268,8 +1268,8 @@ int relinquish_shared_pages(struct domai + return 0; + + p2m_lock(p2m); +- for (gfn = p2m->next_shared_gfn_to_relinquish; +- gfn < p2m->max_mapped_pfn; gfn++ ) ++ for ( gfn = p2m->next_shared_gfn_to_relinquish; ++ gfn <= p2m->max_mapped_pfn; gfn++ ) + { + p2m_access_t a; + p2m_type_t t; +--- a/xen/arch/x86/mm/shadow/common.c ++++ b/xen/arch/x86/mm/shadow/common.c +@@ -3489,9 +3489,7 @@ int shadow_track_dirty_vram(struct domai + struct sh_dirty_vram *dirty_vram = d->arch.hvm_domain.dirty_vram; + struct p2m_domain *p2m = p2m_get_hostp2m(d); + +- if (end_pfn < begin_pfn +- || begin_pfn > p2m->max_mapped_pfn +- || end_pfn >= p2m->max_mapped_pfn) ++ if ( end_pfn < begin_pfn || end_pfn > p2m->max_mapped_pfn + 1 ) + return -EINVAL; + + /* We perform p2m lookups, so lock the p2m upfront to avoid deadlock */ diff --git a/qemu-xen-upstream-megasas-buildtime.patch b/qemu-xen-upstream-megasas-buildtime.patch new file mode 100644 index 0000000..9a109c5 --- /dev/null +++ b/qemu-xen-upstream-megasas-buildtime.patch @@ -0,0 +1,21 @@ +Causes rebuilds. +Says rpmlint. +--- + tools/qemu-xen-dir-remote/hw/scsi/megasas.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: xen-4.4.0-testing/tools/qemu-xen-dir-remote/hw/scsi/megasas.c +=================================================================== +--- xen-4.4.0-testing.orig/tools/qemu-xen-dir-remote/hw/scsi/megasas.c ++++ xen-4.4.0-testing/tools/qemu-xen-dir-remote/hw/scsi/megasas.c +@@ -712,8 +712,8 @@ static int megasas_ctrl_get_info(Megasas + snprintf(info.package_version, 0x60, "%s-QEMU", QEMU_VERSION); + memcpy(info.image_component[0].name, "APP", 3); + memcpy(info.image_component[0].version, MEGASAS_VERSION "-QEMU", 9); +- memcpy(info.image_component[0].build_date, __DATE__, 11); +- memcpy(info.image_component[0].build_time, __TIME__, 8); ++ memcpy(info.image_component[0].build_date, "Apr 1 2014", 11); ++ memcpy(info.image_component[0].build_time, "12:34:56", 8); + info.image_component_count = 1; + if (pci_dev->has_rom) { + uint8_t biosver[32]; diff --git a/xen.changes b/xen.changes index 0979dac..9490a29 100644 --- a/xen.changes +++ b/xen.changes @@ -1,6 +1,79 @@ +------------------------------------------------------------------- +Wed Apr 9 08:07:03 MDT 2014 - carnold@suse.com + +- Upstream patches from Jan + 53356c1e-x86-HVM-correct-CPUID-leaf-80000008-handling.patch + 533ad1ee-VMX-fix-PAT-value-seen-by-guest.patch + 533d413b-x86-mm-fix-checks-against-max_mapped_pfn.patch + +------------------------------------------------------------------- +Thu Apr 3 16:21:03 UTC 2014 - carnold@suse.com + +- bnc#862608 - SLES 11 SP3 vm-install should get RHEL 7 support + when released + 53206661-pygrub-support-linux16-and-initrd16.patch +- Upstream bug fixes + 53299d8f-xenconsole-reset-tty-on-failure.patch + 53299d8f-xenconsole-tolerate-tty-errors.patch + +------------------------------------------------------------------- +Thu Apr 3 16:21:03 UTC 2014 - dmueller@suse.com + +- fix build for armv7l and aarch64 + +------------------------------------------------------------------- +Thu Apr 3 15:40:31 CEST 2014 - ohering@suse.de + +- Remove compiletime strings from qemu-upstream + qemu-xen-upstream-megasas-buildtime.patch + +------------------------------------------------------------------- +Wed Apr 2 08:47:27 MDT 2014 - carnold@suse.com + +- bnc#871546 - KMPs are not signed in SUSE:SLE-12:GA? + xen.spec + +------------------------------------------------------------------- +Tue Apr 1 08:14:29 MDT 2014 - carnold@suse.com + +- Upstream patches from Jan + 532fff53-x86-fix-determination-of-bit-count-for-struct-domain-allocations.patch + 5331917d-x86-enforce-preemption-in-HVM_set_mem_access-p2m_set_mem_access.patch +- Drop xsa89.patch for upstream version (see bnc#867910, 5331917d-x86-enforce...) + +------------------------------------------------------------------- +Fri Mar 28 11:00:07 MDT 2014 - carnold@suse.com + +- bnc#863821 - Xen unable to boot paravirtualized VMs installed + with btrfs. Add 'Requires: grub2-x86_64-xen' to xen-tools. +- Restore soft links for qemu-system-i386 and qemu-dm +- Cleanup inconsistency in which version of qemu-system-i386 is + being used (Xen vs qemu-x86). Use only Xen's version. + xen.spec + +------------------------------------------------------------------- +Wed Mar 27 14:18:06 MDT 2014 - carnold@suse.com + +- Add conditionals for SLE12 when defining xend and max_cpus + xen.spec + +------------------------------------------------------------------- +Wed Mar 19 14:18:06 MDT 2014 - carnold@suse.com + +- Upstream patches from Jan + 5321b20b-common-make-hypercall-preemption-checks-consistent.patch + 5321b257-x86-make-hypercall-preemption-checks-consistent.patch + 53271880-VT-d-fix-RMRR-handling.patch + 5327190a-x86-Intel-work-around-Xeon-7400-series-erratum-AAI65.patch +- Dropped the following as now part of 5321b257 + 5310bac3-mm-ensure-useful-progress-in-decrease_reservation.patch + ------------------------------------------------------------------- Wed Mar 12 08:20:42 MDT 2014 - carnold@suse.com +- bnc#867910 - VUL-0: EMBARGOED: xen: XSA-89: HVMOP_set_mem_access + is not preemptible + xsa89.patch - Upstream patches from Jan 530b27fd-x86-MCE-Fix-race-condition-in-mctelem_reserve.patch 530b2880-Nested-VMX-update-nested-paging-mode-on-vmexit.patch diff --git a/xen.spec b/xen.spec index ce4feb1..eaa6667 100644 --- a/xen.spec +++ b/xen.spec @@ -41,10 +41,18 @@ ExclusiveArch: %ix86 x86_64 %arm aarch64 %define with_qemu_traditional 1 %define with_xend_tools_pkg 0 %if %suse_version > 1230 +%if %suse_version == 1315 +%define with_xend_tools_pkg 0 +%else %define with_xend_tools_pkg 1 %endif +%endif %if %suse_version > 1230 +%if %suse_version == 1315 +%define with_xend 0 +%else %define with_xend 1 +%endif %else %define with_xend 1 %endif @@ -56,8 +64,12 @@ ExclusiveArch: %ix86 x86_64 %arm aarch64 # %define max_cpus 4 %ifarch x86_64 +%if %suse_version == 1315 +%define max_cpus 1024 +%else %define max_cpus 512 %endif +%endif # %define xen_install_suffix %{nil} %ifarch x86_64 @@ -84,19 +96,19 @@ BuildRequires: libfdt1-devel %ifarch %ix86 x86_64 BuildRequires: dev86 %endif -BuildRequires: flex BuildRequires: bison BuildRequires: fdupes +BuildRequires: flex BuildRequires: glib2-devel BuildRequires: libaio-devel BuildRequires: libbz2-devel +BuildRequires: libpixman-1-0-devel BuildRequires: libuuid-devel BuildRequires: libxml2-devel BuildRequires: libyajl-devel -BuildRequires: libpixman-1-0-devel %if %{?with_qemu_traditional}0 -BuildRequires: pciutils-devel BuildRequires: SDL-devel +BuildRequires: pciutils-devel %endif %if %{?with_stubdom}0 %if 0%{?suse_version} < 1230 @@ -134,12 +146,13 @@ BuildRequires: kernel-syms BuildRequires: module-init-tools %if %suse_version >= 1230 BuildRequires: lndir +BuildRequires: pesign-obs-integration %else BuildRequires: xorg-x11-util-devel %endif %endif -Version: 4.4.0_08 +Version: 4.4.0_14 Release: 0 PreReq: %insserv_prereq %fillup_prereq Summary: Xen Virtualization: Hypervisor (aka VMM aka Microkernel) @@ -202,15 +215,26 @@ Patch1: 530b27fd-x86-MCE-Fix-race-condition-in-mctelem_reserve.patch Patch2: 530b2880-Nested-VMX-update-nested-paging-mode-on-vmexit.patch Patch3: 530b28c5-x86-MSI-don-t-risk-division-by-zero.patch Patch4: 530c54c3-x86-mce-Reduce-boot-time-logspam.patch -Patch5: 5310bac3-mm-ensure-useful-progress-in-decrease_reservation.patch -Patch6: 5315a254-IOMMU-generalize-and-correct-softirq-processing.patch -Patch7: 5315a3bb-x86-don-t-propagate-acpi_skip_timer_override-do-Dom0.patch -Patch8: 5315a43a-x86-ACPI-also-print-address-space-for-PM1x-fields.patch -Patch9: 531d8db1-x86-hvm-refine-the-judgment-on-IDENT_PT-for-EMT.patch -Patch10: 531d8e09-x86-HVM-fix-memory-type-merging-in-epte_get_entry_emt.patch -Patch11: 531d8e34-x86-HVM-consolidate-passthrough-handling-in-epte_get_entry_emt.patch -Patch12: 531d8fd0-kexec-identify-which-cpu-the-kexec-image-is-being-executed-on.patch -Patch13: 531dc0e2-xmalloc-handle-correctly-page-allocation-when-align-size.patch +Patch5: 5315a254-IOMMU-generalize-and-correct-softirq-processing.patch +Patch6: 5315a3bb-x86-don-t-propagate-acpi_skip_timer_override-do-Dom0.patch +Patch7: 5315a43a-x86-ACPI-also-print-address-space-for-PM1x-fields.patch +Patch8: 531d8db1-x86-hvm-refine-the-judgment-on-IDENT_PT-for-EMT.patch +Patch9: 531d8e09-x86-HVM-fix-memory-type-merging-in-epte_get_entry_emt.patch +Patch10: 531d8e34-x86-HVM-consolidate-passthrough-handling-in-epte_get_entry_emt.patch +Patch11: 531d8fd0-kexec-identify-which-cpu-the-kexec-image-is-being-executed-on.patch +Patch12: 531dc0e2-xmalloc-handle-correctly-page-allocation-when-align-size.patch +Patch13: 53206661-pygrub-support-linux16-and-initrd16.patch +Patch14: 5321b20b-common-make-hypercall-preemption-checks-consistent.patch +Patch15: 5321b257-x86-make-hypercall-preemption-checks-consistent.patch +Patch16: 53271880-VT-d-fix-RMRR-handling.patch +Patch17: 5327190a-x86-Intel-work-around-Xeon-7400-series-erratum-AAI65.patch +Patch18: 53299d8f-xenconsole-reset-tty-on-failure.patch +Patch19: 53299d8f-xenconsole-tolerate-tty-errors.patch +Patch20: 532fff53-x86-fix-determination-of-bit-count-for-struct-domain-allocations.patch +Patch21: 5331917d-x86-enforce-preemption-in-HVM_set_mem_access-p2m_set_mem_access.patch +Patch22: 53356c1e-x86-HVM-correct-CPUID-leaf-80000008-handling.patch +Patch23: 533ad1ee-VMX-fix-PAT-value-seen-by-guest.patch +Patch24: 533d413b-x86-mm-fix-checks-against-max_mapped_pfn.patch # Upstream qemu Patch250: VNC-Support-for-ExtendedKeyEvent-client-message.patch Patch251: 0001-net-move-the-tap-buffer-into-TAPState.patch @@ -277,6 +301,7 @@ Patch385: xen_pvonhvm.xen_emul_unplug.patch Patch386: libxc-pass-errno-to-callers-of-xc_domain_save.patch Patch387: libxl.set-migration-constraints-from-cmdline.patch Patch388: libxl.honor-more-top-level-vfb-options.patch +Patch389: qemu-xen-upstream-megasas-buildtime.patch # Xend Patch400: xend-set-migration-constraints-from-cmdline.patch Patch402: xen.migrate.tools-xend_move_assert_to_exception_block.patch @@ -425,6 +450,7 @@ Authors: Summary: Xen Virtualization: Control tools for domain 0 Group: System/Kernel Requires: bridge-utils +Requires: grub2-x86_64-xen Requires: multipath-tools Requires: python Requires: python-curses @@ -529,6 +555,9 @@ Authors: Summary: Xen para-virtual device drivers for fully virtualized guests Group: System/Kernel Conflicts: xen +%if %suse_version >= 1230 +Requires: pesign-obs-integration +%endif %description KMP Xen is a virtual machine monitor for x86 that supports execution of @@ -577,6 +606,17 @@ Authors: %patch11 -p1 %patch12 -p1 %patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 # Upstream qemu patches %patch250 -p1 %patch251 -p1 @@ -642,6 +682,7 @@ Authors: %patch386 -p1 %patch387 -p1 %patch388 -p1 +%patch389 -p1 # Xend %patch400 -p1 %patch402 -p1 @@ -786,6 +827,7 @@ export EXTRA_CFLAGS_QEMU_TRADITIONAL="$RPM_OPT_FLAGS" export EXTRA_CFLAGS_QEMU_XEN="$RPM_OPT_FLAGS" # EFI %if %{?with_dom0_support}0 +export BRP_PESIGN_FILES="*.ko *.efi /lib/firmware" make -C xen install \ %if %{?with_gcc47}0 CC=gcc-4.7 \ @@ -832,6 +874,8 @@ then echo %{_libdir}/efi >> xen.files.txt fi %ifarch x86_64 +ln -s /usr/lib/xen/bin/qemu-dm $RPM_BUILD_ROOT/%{_libdir}/xen/bin/qemu-dm +ln -s /usr/lib/xen/bin/qemu-system-i386 $RPM_BUILD_ROOT/%{_libdir}/xen/bin/qemu-system-i386 cp -avL xenalyze.hg/dump-raw $RPM_BUILD_ROOT/%{_bindir}/xenalyze.dump-raw cp -avL xenalyze.hg/xenalyze $RPM_BUILD_ROOT/%{_bindir} %endif @@ -1340,14 +1384,6 @@ fi %{fillup_and_insserv -y -n xendomains xendomains} %{fillup_only -n pciback} %endif -if [ -f /usr/bin/qemu-system-i386 ]; then - rm -f /usr/lib/xen/bin/qemu-system-i386 - ln -s /usr/bin/qemu-system-i386 /usr/lib/xen/bin/qemu-system-i386 -fi -if [ -f /usr/bin/qemu-system-x86_64 ]; then - rm -f /usr/lib/xen/bin/qemu-system-x86_64 - ln -s /usr/bin/qemu-system-x86_64 /usr/lib/xen/bin/qemu-system-x86_64 -fi if [ -f /usr/bin/qemu-img ]; then if [ -f /usr/bin/qemu-img-xen ]; then rm /usr/bin/qemu-img-xen diff --git a/xen2libvirt.py b/xen2libvirt.py index aeeee9b..cc735db 100644 --- a/xen2libvirt.py +++ b/xen2libvirt.py @@ -1,113 +1,113 @@ -#!/usr/bin/env python -# -# Copyright (C) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library. If not, see -# . -# -# Authors: -# Jim Fehlig -# -# Read native Xen configuration format, convert to libvirt domXML, and -# import (virsh define ) into libvirt. - -import sys -import os -import argparse -import re - -try: - import libvirt -except ImportError: - print 'Unable to import the libvirt module. Is libvirt-python installed?' - sys.exit(1) - -parser = argparse.ArgumentParser(description='Import Xen domain configuration into libvirt') -parser.add_argument('-c', '--convert-only', help='Convert Xen domain configuration into libvirt domXML, but do not import into libvirt', action='store_true', dest='convert_only') -parser.add_argument('-r', '--recursive', help='Operate recursivelly on all Xen domain configuration rooted at path', action='store_true') -parser.add_argument('-f', '--format', help='Format of Xen domain configuration. Supported formats are xm and sexpr', choices=['xm', 'sexpr'], default=None) -parser.add_argument('-v', '--verbose', help='Print information about the import process', action='store_true') -parser.add_argument('path', help='Path to Xen domain configuration') - - -def print_verbose(msg): - if args.verbose: - print msg - - -def check_config(path, config): - isbinary = os.system('file -b ' + path + ' | grep text > /dev/null') - - if isbinary: - print 'File %s is not a text file containing Xen xm or sexpr configuration' - sys.exit(1) - - if config.find('\(domain'): - return 'sexpr' - return 'xm' - - -def import_domain(conn, path, format=None, convert_only=False): - - f = open(path, 'r') - config = f.read() - print_verbose('Xen domain configuration read from %s:\n %s' % (path, config)) - if format is None: - format = check_config(path, config) - - if format == 'sexpr': - print_verbose('scrubbing domin from configuration') - config = re.sub("\(domid [0-9]*\)", "", config) - print_verbose('scrubbed sexpr:\n %s' % config) - xml = conn.domainXMLFromNative('xen-sxpr', config, 0) - else: - # if format != sexpr, try xm - xml = conn.domainXMLFromNative('xen-xm', config, 0) - - f.close() - - print_verbose('Successfully converted Xen domain configuration to ' - 'libvirt domXML:\n %s' % xml) - if convert_only: - print xml - else: - print_verbose('Importing converted libvirt domXML into libvirt...') - dom = conn.defineXML(xml) - if dom is None: - print 'Failed to define domain from converted domXML' - sys.exit(1) - print_verbose('domXML successfully imported into libvirt') - - -args = parser.parse_args() -path = args.path - -# Connect to libvirt -conn = libvirt.open(None) -if conn is None: - print('Failed to open connection to the hypervisor') - sys.exit(1) - -if args.recursive: - try: - for root, dirs, files in os.walk(path): - for name in files: - abs_name = os.path.join(root, name) - print_verbose('Processing file %s' % abs_name) - import_domain(conn, abs_name, args.format, args.convert_only) - except IOError: - print('Failed to open/read path %s' % path) - sys.exit(1) -else: - import_domain(conn, args.path, args.format, args.convert_only) +#!/usr/bin/env python +# +# Copyright (C) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see +# . +# +# Authors: +# Jim Fehlig +# +# Read native Xen configuration format, convert to libvirt domXML, and +# import (virsh define ) into libvirt. + +import sys +import os +import argparse +import re + +try: + import libvirt +except ImportError: + print 'Unable to import the libvirt module. Is libvirt-python installed?' + sys.exit(1) + +parser = argparse.ArgumentParser(description='Import Xen domain configuration into libvirt') +parser.add_argument('-c', '--convert-only', help='Convert Xen domain configuration into libvirt domXML, but do not import into libvirt', action='store_true', dest='convert_only') +parser.add_argument('-r', '--recursive', help='Operate recursivelly on all Xen domain configuration rooted at path', action='store_true') +parser.add_argument('-f', '--format', help='Format of Xen domain configuration. Supported formats are xm and sexpr', choices=['xm', 'sexpr'], default=None) +parser.add_argument('-v', '--verbose', help='Print information about the import process', action='store_true') +parser.add_argument('path', help='Path to Xen domain configuration') + + +def print_verbose(msg): + if args.verbose: + print msg + + +def check_config(path, config): + isbinary = os.system('file -b ' + path + ' | grep text > /dev/null') + + if isbinary: + print 'File %s is not a text file containing Xen xm or sexpr configuration' + sys.exit(1) + + if config.find('\(domain'): + return 'sexpr' + return 'xm' + + +def import_domain(conn, path, format=None, convert_only=False): + + f = open(path, 'r') + config = f.read() + print_verbose('Xen domain configuration read from %s:\n %s' % (path, config)) + if format is None: + format = check_config(path, config) + + if format == 'sexpr': + print_verbose('scrubbing domin from configuration') + config = re.sub("\(domid [0-9]*\)", "", config) + print_verbose('scrubbed sexpr:\n %s' % config) + xml = conn.domainXMLFromNative('xen-sxpr', config, 0) + else: + # if format != sexpr, try xm + xml = conn.domainXMLFromNative('xen-xm', config, 0) + + f.close() + + print_verbose('Successfully converted Xen domain configuration to ' + 'libvirt domXML:\n %s' % xml) + if convert_only: + print xml + else: + print_verbose('Importing converted libvirt domXML into libvirt...') + dom = conn.defineXML(xml) + if dom is None: + print 'Failed to define domain from converted domXML' + sys.exit(1) + print_verbose('domXML successfully imported into libvirt') + + +args = parser.parse_args() +path = args.path + +# Connect to libvirt +conn = libvirt.open(None) +if conn is None: + print('Failed to open connection to the hypervisor') + sys.exit(1) + +if args.recursive: + try: + for root, dirs, files in os.walk(path): + for name in files: + abs_name = os.path.join(root, name) + print_verbose('Processing file %s' % abs_name) + import_domain(conn, abs_name, args.format, args.convert_only) + except IOError: + print('Failed to open/read path %s' % path) + sys.exit(1) +else: + import_domain(conn, args.path, args.format, args.convert_only) diff --git a/xenconsole-no-multiple-connections.patch b/xenconsole-no-multiple-connections.patch index 03d6701..c9a74a9 100644 --- a/xenconsole-no-multiple-connections.patch +++ b/xenconsole-no-multiple-connections.patch @@ -10,16 +10,18 @@ Index: xen-4.4.0-testing/tools/console/client/main.c fd_set watch_fdset; int xs_fd = xs_fileno(xs), pty_fd = -1; int start, now; -@@ -119,6 +120,12 @@ static int get_pty_fd(struct xs_handle * +@@ -119,6 +120,14 @@ static int get_pty_fd(struct xs_handle * pty_fd = open(pty_path, O_RDWR | O_NOCTTY); if (pty_fd == -1) - err(errno, "Could not open tty `%s'", pty_path); -+ memset(&lock, 0, sizeof(lock)); -+ lock.l_type = F_WRLCK; -+ lock.l_whence = SEEK_SET; -+ if (fcntl(pty_fd, F_SETLK, &lock) != 0) -+ err(errno, "Could not lock tty '%s'", -+ pty_path); - free(pty_path); + warn("Could not open tty `%s'", pty_path); ++ else { ++ memset(&lock, 0, sizeof(lock)); ++ lock.l_type = F_WRLCK; ++ lock.l_whence = SEEK_SET; ++ if (fcntl(pty_fd, F_SETLK, &lock) != 0) ++ err(errno, "Could not lock tty '%s'", ++ pty_path); ++ } } + free(pty_path); }