From Dom0 there is no way to guess the number and, or the complete
Hello community,
here is the log from the commit of package xen.2603 for openSUSE:12.3:Update checked in at 2014-04-04 15:11:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:12.3:Update/xen.2603 (Old)
and /work/SRC/openSUSE:12.3:Update/.xen.2603.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "xen.2603"
Changes:
--------
New Changes file:
--- /dev/null 2014-02-13 01:09:38.344032506 +0100
+++ /work/SRC/openSUSE:12.3:Update/.xen.2603.new/xen.changes 2014-04-04 15:11:15.000000000 +0200
@@ -0,0 +1,7656 @@
+-------------------------------------------------------------------
+Wed Feb 19 08:10:28 MST 2014 - carnold@suse.com
+
+- Upstream patch from Jan
+ 27691-x86-percpu-Force-INVALID_PERCPU_AREA-into-the-non-canonical-address-region.patch
+ 28304-x86-don-t-drop-guest-visible-state-updates-when-64-bit-PV-guest-is-in-user-mode.patch
+
+-------------------------------------------------------------------
+Tue Feb 18 13:53:10 MST 2014 - carnold@suse.com
+
+- Update to Xen version 4.2.4 c/s 26280
+ xen-4.2.4-testing-src.tar.bz2
+ qemu-xen-traditional-dir-remote.tar.bz2
+ qemu-xen-dir-remote.tar.bz2
+- bnc#861256 - VUL-0: xen: XSA-88: use-after-free in xc_cpupool_getinfo()
+ under memory pressure. (fix included with update)
+- Dropped 45 patches now found in the tarballs.
+
+-------------------------------------------------------------------
+Tue Feb 11 16:14:08 CET 2014 - ohering@suse.de
+
+- bnc#863297: xend/pvscsi: recognize also SCSI CDROM devices
+ xend-pvscsi-recognize-also-SCSI-CDROM-devices.patch
+
+-------------------------------------------------------------------
+Wed Jan 29 08:15:37 MST 2014 - carnold@suse.com
+
+- bnc#858496 - Xen: XSA-83: Out-of-memory condition yielding memory
+ corruption during IRQ setup
+ 28305-x86-irq-avoid-use-after-free-on-error-path-in-pirq_guest_bind.patch (Replaces xsa83.patch)
+- bnc#860163 - VUL-0: xen: XSA-84: integer overflow in several
+ XSM/Flask hypercalls
+ xsa84.patch
+- bnc#860165 - VUL-0: xen: XSA-85: Off-by-one error in
+ FLASK_AVC_CACHESTAT hypercall
+ xsa85.patch
+- bnc#860300 - VUL-1: xen: XSA-86: libvchan failure handling
+ malicious ring indexes
+ xsa86.patch
+- bnc#860302 - VUL-0: CVE-2014-1666: xen: XSA-87:
+ PHYSDEVOP_{prepare,release}_msix exposed to unprivileged guests
+ 28307-x86-PHYSDEVOP-prepare-release-msix-are-privileged.patch
+- Upstream patches from Jan
+ 28296-mce-fix-race-condition-in-mctelem_xchg_head.patch
+ 28297-nested-EPT-fixing-wrong-handling-for-L2-guest-s-direct-mmio-access.patch
+ 28299-common-sysctl-Don-t-leak-status-in-SYSCTL_page_offline_op.patch
+ 28302-Nested-VMX-prohibit-virtual-vmentry-vmexit-during-IO-emulation.patch
+
+-------------------------------------------------------------------
+Fri Jan 10 15:43:10 MST 2014 - carnold@suse.com
+
+- bnc#858311 - L3: Server is not booting in kernel XEN after latest
+ updates - (XEN) setup 0000:00:18.0 for d0 failed (-19)
+ 28068-x86-properly-handle-MSI-X-unmask-operation-from-guests.patch
+
+-------------------------------------------------------------------
+Fri Jan 10 10:06:30 MST 2014 - carnold@suse.com
+
+- bnc#858496 - Xen: XSA-83: Out-of-memory condition yielding memory
+ corruption during IRQ setup
+ xsa83.patch
+- Upstream patches from Jan
+ 28201-x86-mm-Prevent-leaking-domain-mappings-in-paging_log_dirty_op.patch
+ 28229-Nested-VMX-Setup-the-virtual-NMI-exiting-info.patch
+ 28235-VMX-apicv-Set-NMI-window-exiting-for-NMI.patch
+ 28248-VTD-DMAR-free-correct-pointer-on-error-from-acpi_parse_one_atsr.patch
+ 28249-AMD-IOMMU-fix-infinite-loop-due-to-ivrs_bdf_entries-larger-than-16-bit-value.patch
+ 28272-hvm_save_one-return-correct-data.patch
+
+-------------------------------------------------------------------
+Mon Dec 16 17:06:34 MST 2013 - carnold@suse.com
+
+- bnc#853049 - VUL-0: CVE-2013-6885: xen: XSA-82: Guest triggerable
+ AMD CPU erratum may cause host hang
+ 28102-x86-AMD-work-around-erratum-793.patch
+- bnc#853048 - VUL-0: CVE-2013-6400: xen: XSA-80: IOMMU TLB
+ flushing may be inadvertently suppressed
+ 28164-IOMMU-clear-don-t-flush-override-on-error-paths.patch
+- bnc#831120 - VUL-0: CVE-2013-2212: xen: XSA-60: Excessive time to
+ disable caching with HVM guests with PCI passthrough
+ 27852-VMX-disable-EPT-when-cpu_has_vmx_pat.patch
+ 27853-VMX-remove-the-problematic-set_uc_mode-logic.patch
+ 27854-VMX-fix-cr0.cd-handling.patch
+- bnc#848014 - [HP HPS] Xen hypervisor panics on 8-blades nPar with
+ 46-bit memory addressing
+ 27829-x86-ACPI-x2APIC-guard-against-out-of-range-ACPI-or-APIC-IDs.patch
+ 27965-x86-consider-modules-when-cutting-off-memory.patch
+- bnc#833251 - [HP BCS SLES11 Bug]: In HP’s UEFI x86_64 platform
+ and with xen environment, in booting stage ,xen hypervisor will
+ panic.
+ 28167-x86-cpuidle-publish-new-states-only-after-fully-initializing-them.patch
+- Upstream patches from Jan
+ 27961-credit-Update-other-parameters-when-setting-tslice_ms.patch
+ 27962-fix-leaking-of-v-cpu_affinity_saved-on-domain-destruction.patch
+ 27963-nested-VMX-don-t-ignore-mapping-errors.patch
+ 28022-x86-hvm-reset-TSC-to-0-after-domain-resume-from-S3.patch
+ 28023-x86-crash-disable-the-watchdog-NMIs-on-the-crashing-cpu.patch
+ 28041-x86-xsave-fix-nonlazy-state-handling.patch
+ 28057-x86-hvm-fix-segment-validation.patch
+ 28065-x86-restrict-XEN_DOMCTL_getmemlist.patch (Replaces CVE-2013-4553-xsa74.patch)
+ 28066-x86-HVM-only-allow-ring-0-guest-code-to-make-hypercalls.patch (Replaces CVE-2013-4554-xsa76.patch)
+ 28068-x86-properly-handle-MSI-X-unmask-operation-from-guests.patch
+ 28092-Fix-ptr-calculation-when-converting-from-a-VA.patch
+ 28103-nested-vmx-fix-I-O-port-bitmap-indexing-arithmetic.patch
+ 28108-fix-locking-in-offline_page.patch
+ 28112-nested-VMX-fix-I-O-port-exit-emulation.patch
+ 28113-x86-fix-early-boot-command-line-parsing.patch
+ 28131-Nested-VMX-CR-emulation-fix-up.patch
+ 28133-x86-boot-fix-BIOS-memory-corruption-on-certain-IBM-systems.patch
+ 28144-defer-the-domain-mapping-in-scrub_one_page.patch
+ 28168-x86-PV-don-t-commit-debug-register-values-early-in-arch_set_info_guest.patch
+ 28169-kexec-x86-do-not-map-crash-kernel-area.patch
+ 28183-x86-p2m-restrict-auditing-to-debug-builds.patch
+
+-------------------------------------------------------------------
+Tue Dec 10 14:47:30 MST 2013 - carnold@suse.com
+
+- pygrub: Support (/dev/xvda) style disk specifications
+ 27756-pygrub-xvda-style-disk.patch
+
+-------------------------------------------------------------------
+Tue Nov 19 11:52:31 MST 2013 - carnold@suse.com
+
+- bnc#849667 - VUL-0: xen: XSA-74: Lock order reversal between
+ page_alloc_lock and mm_rwlock
+ CVE-2013-4553-xsa74.patch
+- bnc#849668 - VUL-0: xen: XSA-76: Hypercalls exposed to privilege
+ rings 1 and 2 of HVM guests
+ CVE-2013-4554-xsa76.patch
+- Fix for XSA-78
+ 27964-TLB-flushing-in-dma_pte_clear_one.patch
+
+-------------------------------------------------------------------
+Wed Nov 13 09:28:28 MST 2013 - carnold@suse.com
+
+- bnc#842417 - In HP’s UEFI x86_64 platform and sles11sp3 with xen
+ environment, dom0 will soft lockup on multiple blades nPar.
+ 27870-x86-idle-reduce-contention-on-ACPI-register-accesses.patch
+- bnc#848014 - [HP HPS] Xen hypervisor panics on 8-blades nPar with
+ 46-bit memory addressing
+ 27926-VMX-don-t-crash-processing-d-debug-key.patch
+- bnc#846849 - L3: Soft lockup with PCI passthrough and many VCPUs
+ 27926-VMX-don-t-crash-processing-d-debug-key.patch
+- bnc#833483 - Boot Failure with xen kernel in UEFI mode with error
+ "No memory for trampoline"
+ 27864-x86-EFI-make-trampoline-allocation-more-flexible.patch
+ (Replaces x86-EFI-trampoline-fallback.patch)
+- Upstream patches from Jan
+ 27736-scheduler-adjust-internal-locking-interface.patch
+ 27737-sched-fix-race-between-sched_move_domain-and-vcpu_wake.patch
+ 27759-credit-unpause-parked-vcpu-before-destroying-it.patch
+ 27764-x86-print-relevant-tail-part-of-filename-for-warnings-and-crashes.patch
+ 27766-x86-xsave-also-save-restore-XCR0-across-suspend-ACPI-S3.patch
+ 27785-x86-refine-address-validity-checks-before-accessing-page-tables.patch
+ 27792-fix-locking-in-cpu_disable_scheduler.patch
+ 27848-x86-HVM-32-bit-IN-result-must-be-zero-extended-to-64-bits.patch
+ 27925-nested-SVM-adjust-guest-handling-of-structure-mappings.patch
+ 27928-x86-eliminate-has_arch_mmios.patch
+
+-------------------------------------------------------------------
+Mon Nov 11 10:22:20 MST 2013 - carnold@suse.com
+
+- bnc#849665 - VUL-0: CVE-2013-4551: xen: XSA-75: Host crash due to
+ guest VMX instruction execution
+ 27868-nested-VMX-VMLANUCH-VMRESUME-emulation-must-check-permission-1st.patch
+
+-------------------------------------------------------------------
+Fri Nov 8 11:01:09 MST 2013 - carnold@suse.com
+
+- The upstream version of checking for xend when using the 'xl'
+ command is used is not working.
+ disable-xl-when-using-xend-fix.patch
+
+-------------------------------------------------------------------
+Wed Nov 6 14:47:34 MST 2013 - carnold@suse.com
+
+- bnc#840997 - It is possible to start a VM twice on the same node.
+ xend-xm-reboot-fix.patch
+
+-------------------------------------------------------------------
+Wed Nov 4 09:42:36 MDT 2013 - carnold@suse.com
+
+- bnc#848657 - VUL-0: xen: CVE-2013-4494: XSA-73: Lock order
+ reversal between page allocation and grant table locks
+ 27828-gnttab-correct-locking-order-reversal.patch
+
+-------------------------------------------------------------------
+Mon Oct 14 09:19:13 MDT 2013 - carnold@suse.com
+
+- bnc#845520 - VUL-0: CVE-2013-4416: xen: ocaml xenstored
+ mishandles oversized message replies
+ CVE-2013-4416-xsa72.patch
+- bnc#833483 - Boot Failure with xen kernel in UEFI mode with error
+ "No memory for trampoline"
+ x86-EFI-trampoline-fallback.patch
+- Upstream patches from Jan
+ 27678-x86-properly-handle-hvm_copy_from_guest_-phys-virt-errors.patch (Replaces CVE-2013-4355-xsa63.patch)
++++ 7459 more lines (skipped)
++++ between /dev/null
++++ and /work/SRC/openSUSE:12.3:Update/.xen.2603.new/xen.changes
New:
----
0001-net-move-the-tap-buffer-into-TAPState.patch
0002-net-increase-tap-buffer-size.patch
0003-e1000-fix-access-4-bytes-beyond-buffer-end.patch
0004-e1000-secrc-support.patch
0005-e1000-multi-buffer-packet-support.patch
0006-e1000-clear-EOP-for-multi-buffer-descriptors.patch
0007-e1000-verify-we-have-buffers-upfront.patch
0008-e1000-check-buffer-availability.patch
25861-x86-early-fixmap.patch
25862-sercon-non-com.patch
25863-sercon-ehci-dbgp.patch
25864-sercon-unused.patch
25866-sercon-ns16550-pci-irq.patch
25867-sercon-ns16550-parse.patch
25874-x86-EFI-chain-cfg.patch
25909-xenpm-consistent.patch
25920-x86-APICV-enable.patch
25921-x86-APICV-delivery.patch
25922-x86-APICV-x2APIC.patch
25957-x86-TSC-adjust-HVM.patch
25958-x86-TSC-adjust-sr.patch
25959-x86-TSC-adjust-expose.patch
26077-stubdom_fix_compile_errors_in_grub.patch
26078-hotplug-Linux_remove_hotplug_support_rely_on_udev_instead.patch
26079-hotplug-Linux_close_lockfd_after_lock_attempt.patch
26081-stubdom_fix_rpmlint_warning_spurious-executable-perm.patch
26082-blktap2-libvhd_fix_rpmlint_warning_spurious-executable-perm.patch
26083-blktap_fix_rpmlint_warning_spurious-executable-perm.patch
26084-hotplug_install_hotplugpath.sh_as_data_file.patch
26085-stubdom_install_stubdompath.sh_as_data_file.patch
26086-hotplug-Linux_correct_sysconfig_tag_in_xendomains.patch
26087-hotplug-Linux_install_sysconfig_files_as_data_files.patch
26114-pygrub-list-entries.patch
26129-ACPI-BGRT-invalidate.patch
26133-IOMMU-defer-BM-disable.patch
26189-xenstore-chmod.patch
26262-x86-EFI-secure-shim.patch
26324-IOMMU-assign-params.patch
26325-IOMMU-add-remove-params.patch
26326-VT-d-context-map-params.patch
26327-AMD-IOMMU-flush-params.patch
26328-IOMMU-pdev-type.patch
26329-IOMMU-phantom-dev.patch
26330-VT-d-phantom-MSI.patch
26331-IOMMU-phantom-dev-quirk.patch
26341-hvm-firmware-passthrough.patch
26342-hvm-firmware-passthrough.patch
26343-hvm-firmware-passthrough.patch
26344-hvm-firmware-passthrough.patch
26369-libxl-devid.patch
26370-libxc-x86-initial-mapping-fit.patch
26372-tools-paths.patch
26404-x86-forward-both-NMI-kinds.patch
26418-x86-trampoline-consider-multiboot.patch
26532-AMD-IOMMU-phantom-MSI.patch
26547-tools-xc_fix_logic_error_in_stdiostream_progress.patch
26548-tools-xc_handle_tty_output_differently_in_stdiostream_progress.patch
26549-tools-xc_turn_XCFLAGS__into_shifts.patch
26550-tools-xc_restore_logging_in_xc_save.patch
26551-tools-xc_log_pid_in_xc_save-xc_restore_output.patch
26554-hvm-firmware-passthrough.patch
26555-hvm-firmware-passthrough.patch
26556-hvm-firmware-passthrough.patch
26576-x86-APICV-migration.patch
26577-x86-APICV-x2APIC.patch
26675-tools-xentoollog_update_tty_detection_in_stdiostream_progress.patch
26754-hvm-Improve-APIC-INIT-SIPI-emulation.patch
26878-VMX-Detect-posted-interrupt-capability.patch
26879-VMX-Turn-on-posted-interrupt-bit-in-vmcs.patch
26880-VMX-Add-posted-interrupt-supporting.patch
26881-x86-HVM-Call-vlapic_set_irq-to-delivery-virtual-interrupt.patch
26882-VMX-Use-posted-interrupt-to-deliver-virtual-interrupt.patch
26902-x86-EFI-pass-boot-services-variable-info-to-runtime-code.patch
26953-x86-allow-Dom0-read-only-access-to-IO-APICs.patch
27179-VMX-Viridian-suppress-MSR-based-APIC-suggestion-when-having-APIC-V.patch
27184-libxl-devid-fix.patch
27249-VMX-fix-interaction-of-APIC-V-and-Viridian-emulation.patch
27353-VMX-add-boot-parameter-to-enable-disable-APIC-v-dynamically.patch
27405-Nested-VMX-Check-whether-interrupt-is-blocked-by-TPR.patch
27406-Nested-VMX-Force-check-ISR-when-L2-is-running.patch
27407-Nested-VMX-Clear-APIC-v-control-bit-in-vmcs02.patch
27408-Nested-VMX-Update-APIC-v-RVI-SVI-when-vmexit-to-L1.patch
27431-x86-don-t-allow-Dom0-access-to-the-HT-address-range.patch
27511-x86-fix-memory-cut-off-when-using-PFN-compression.patch
27512-libxc-x86-fix-page-table-creation-for-huge-guests.patch
27515-cpufreq-missing-check-of-copy_from_guest.patch
27519-x86-machine_restart-must-not-call-acpi_dmar_reinstate-twice.patch
27549-set-mtu-from-bridge-for-tap-interface.patch
27582-x86-HVM-fix-failure-path-in-hvm_vcpu_initialise.patch
27583-VMX-fix-failure-path-in-construct_vmcs.patch
27586-x86-HVM-properly-handle-wide-MMIO.patch
27611-x86-HVM-linear-address-must-be-canonical-for-the-whole-accessed-range.patch
27612-x86-HVM-refuse-doing-string-operations-in-certain-situations.patch
27691-x86-percpu-Force-INVALID_PERCPU_AREA-into-the-non-canonical-address-region.patch
27692-Nested-VMX-check-VMX-capability-before-read-VMX-related-MSRs.patch
27694-Nested-VMX-fix-IA32_VMX_CR4_FIXED1-msr-emulation.patch
27756-pygrub-xvda-style-disk.patch
27764-x86-print-relevant-tail-part-of-filename-for-warnings-and-crashes.patch
27870-x86-idle-reduce-contention-on-ACPI-register-accesses.patch
27925-nested-SVM-adjust-guest-handling-of-structure-mappings.patch
27963-nested-VMX-don-t-ignore-mapping-errors.patch
28103-nested-vmx-fix-I-O-port-bitmap-indexing-arithmetic.patch
28112-nested-VMX-fix-I-O-port-exit-emulation.patch
28131-Nested-VMX-CR-emulation-fix-up.patch
28229-Nested-VMX-Setup-the-virtual-NMI-exiting-info.patch
28235-VMX-apicv-Set-NMI-window-exiting-for-NMI.patch
28297-nested-EPT-fixing-wrong-handling-for-L2-guest-s-direct-mmio-access.patch
28302-Nested-VMX-prohibit-virtual-vmentry-vmexit-during-IO-emulation.patch
28304-x86-don-t-drop-guest-visible-state-updates-when-64-bit-PV-guest-is-in-user-mode.patch
32on64-extra-mem.patch
README.SuSE
VNC-Support-for-ExtendedKeyEvent-client-message.patch
altgr_2.patch
baselibs.conf
bdrv_default_rwflag.patch
bdrv_open2_fix_flags.patch
bdrv_open2_flags_2.patch
blktap-close-fifos.patch
blktap-disable-debug-printf.patch
blktap-pv-cdrom.patch
blktap.patch
blktapctrl-default-to-ioemu.patch
block-dmmd
block-iscsi
block-nbd
block-npiv
block-npiv-common.sh
block-npiv-vport
boot.local.xenU
boot.xen
bridge-bonding.diff
bridge-opensuse.patch
bridge-record-creation.patch
bridge-vlan.diff
build-tapdisk-ioemu.patch
capslock_enable.patch
cdrom-removable.patch
change-vnc-passwd.patch
change_home_server.patch
check_device_status.patch
checkpoint-rename.patch
del_usb_xend_entry.patch
disable-xl-when-using-xend-fix.patch
disable_emulated_device.diff
domUloader.py
domu-usb-controller.patch
etc_pam.d_xen-api
hibernate.patch
hv_extid_compatibility.patch
init.pciback
init.xen_loop
init.xend
init.xendomains
ioemu-7615-qcow2-fix-alloc_cluster_link_l2.patch
ioemu-bdrv-open-CACHE_WB.patch
ioemu-blktap-barriers.patch
ioemu-blktap-fv-init.patch
ioemu-blktap-image-format.patch
ioemu-blktap-zero-size.patch
ioemu-debuginfo.patch
ioemu-disable-emulated-ide-if-pv.patch
ioemu-disable-scsi.patch
ioemu-vnc-resize.patch
ioemu-watchdog-ib700-timer.patch
ioemu-watchdog-linkage.patch
ioemu-watchdog-support.patch
ipxe-enable-nics.patch
ipxe.tar.bz2
kernel-boot-hvm.patch
kmp_filelist
libxen_permissive.patch
log-guest-console.patch
logrotate.conf
magic_ioport_compat.patch
minios-fixups.patch
multi-xvdp.patch
network-nat-open-SuSEfirewall2-FORWARD.patch
pvdrv-import-shared-info.patch
pvdrv_emulation_control.patch
pygrub-netware-xnloader.patch
qemu-dm-segfault.patch
qemu-ifup-set-mtu.patch
qemu-security-etch1.diff
qemu-xen-dir-remote.tar.bz2
qemu-xen-traditional-dir-remote.tar.bz2
seabios-dir-remote.tar.bz2
serial-split.patch
stdvga-cache.patch
stubdom.tar.bz2
supported_module.diff
suspend_evtchn_lock.patch
sysconfig.pciback
tapdisk-ioemu-logfile.patch
tapdisk-ioemu-shutdown-fix.patch
tmp-initscript-modprobe.patch
tmp_build.patch
tools-watchdog-support.patch
udev-rules.patch
usb-list.patch
vif-bridge-no-iptables.patch
vif-bridge-tap-fix.patch
vif-route-ifup.patch
x86-cpufreq-report.patch
x86-dom-print.patch
x86-extra-trap-info.patch
x86-ioapic-ack-default.patch
xen-4.2.4-testing-src.tar.bz2
xen-api-auth.patch
xen-changeset.diff
xen-cpupool-xl-config-format.patch
xen-destdir.diff
xen-disable-qemu-monitor.diff
xen-domUloader.diff
xen-fixme-doc.diff
xen-hvm-default-bridge.diff
xen-hvm-default-pae.diff
xen-ioemu-hvm-pv-support.diff
xen-managed-pci-device.patch
xen-max-free-mem.diff
xen-migration-bridge-check.patch
xen-minimum-restart-time.patch
xen-no-dummy-nfs-ip.diff
xen-paths.diff
xen-qemu-iscsi-fix.patch
xen-updown.sh
xen-utils-0.1.tar.bz2
xen-xm-top-needs-root.diff
xen-xmexample-vti.diff
xen-xmexample.diff
xen.changes
xen.migrate.tools-libxc_print_stats_if_migration_is_aborted.patch
xen.migrate.tools-xc_document_printf_calls_in_xc_restore.patch
xen.migrate.tools-xc_print_messages_from_xc_save_with_xc_report.patch
xen.migrate.tools-xc_rework_xc_save.cswitch_qemu_logdirty.patch
xen.migrate.tools-xend_move_assert_to_exception_block.patch
xen.migrate.tools_add_xm_migrate_--log_progress_option.patch
xen.migrate.tools_set_migration_constraints_from_cmdline.patch
xen.migrate.tools_set_number_of_dirty_pages_during_migration.patch
xen.sles11sp1.fate311487.xen_platform_pci.dmistring.patch
xen.spec
xen_pvdrivers.conf
xenalyze.hg.tar.bz2
xenapi-console-protocol.patch
xenapiusers
xenconsole-no-multiple-connections.patch
xend-config-enable-dump-comment.patch
xend-config.diff
xend-console-port-restore.patch
xend-core-dump-loc.diff
xend-cpuid.patch
xend-devid-or-name.patch
xend-disable-internal-logrotate.patch
xend-domain-lock-sfex.patch
xend-domain-lock.patch
xend-hvm-firmware-passthrough.patch
xend-migration-domname-fix.patch
xend-pvscsi-recognize-also-SCSI-CDROM-devices.patch
xend-relocation-server.fw
xend-relocation.sh
xend-sysconfig.patch
xend-vcpu-affinity-fix.patch
xend-xm-reboot-fix.patch
xenpaging.autostart.patch
xenpaging.doc.patch
xenpaging.qemu.flush-cache.patch
xm-create-maxmem.patch
xm-create-xflag.patch
xm-save-check-file.patch
xmclone.sh
xmexample.disks
xmexample.domUloader
xnloader.py
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ xen.spec ++++++
++++ 1503 lines (skipped)
++++++ 0001-net-move-the-tap-buffer-into-TAPState.patch ++++++
From: Mark McLoughlin
Date: Mon, 18 May 2009 12:05:44 +0100
Subject: net: move the tap buffer into TAPState
Patch-mainline: v0.11.0-rc0
Git-commit: 5b01e886d9eb4d5e94384a79634dcb43848e7bbf
References: bnc#840196
KVM uses a 64k buffer for reading from tapfd (for GSO support)
and allocates the buffer with TAPState rather than on the stack.
Not allocating it on the stack probably makes sense for qemu
anyway, so merge it in advance of GSO support.
Signed-off-by: Mark McLoughlin
Signed-off-by: Michal Kubecek
---
tools/qemu-xen-traditional-dir-remote/net.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/tools/qemu-xen-traditional-dir-remote/net.c b/tools/qemu-xen-traditional-dir-remote/net.c
index 0e7c77c..2ca85a3 100644
--- a/tools/qemu-xen-traditional-dir-remote/net.c
+++ b/tools/qemu-xen-traditional-dir-remote/net.c
@@ -700,6 +700,7 @@ typedef struct TAPState {
char down_script[1024];
char down_script_arg[128];
char script_arg[1024];
+ uint8_t buf[4096];
} TAPState;
#ifndef CONFIG_STUBDOM
@@ -735,20 +736,19 @@ static void tap_receive(void *opaque, const uint8_t *buf, int size)
static void tap_send(void *opaque)
{
TAPState *s = opaque;
- uint8_t buf[4096];
int size;
#ifdef __sun__
struct strbuf sbuf;
int f = 0;
- sbuf.maxlen = sizeof(buf);
- sbuf.buf = buf;
+ sbuf.maxlen = sizeof(s->buf);
+ sbuf.buf = s->buf;
size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
#else
- size = read(s->fd, buf, sizeof(buf));
+ size = read(s->fd, s->buf, sizeof(s->buf));
#endif
if (size > 0) {
- qemu_send_packet(s->vc, buf, size);
+ qemu_send_packet(s->vc, s->buf, size);
}
}
--
1.8.1.4
++++++ 0002-net-increase-tap-buffer-size.patch ++++++
From: Michal Kubecek
Date: Fri, 27 Sep 2013 19:05:45 +0200
Subject: net: increase tap buffer size
Patch-mainline: v0.12.0-rc0
Git-commit: 8e0f8e5bf8fd483dd28329055336cf895b74c89f (partial)
References: bnc#840196
Increase size of buffere embedded in struct TAPState to allow
jumbo frames longer then 4096 bytes.
Part of upstream qemu commit
8e0f8e5b net: enable IFF_VNET_HDR on tap fds if available
Signed-off-by: Michal Kubecek
---
tools/qemu-xen-traditional-dir-remote/net.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tools/qemu-xen-traditional-dir-remote/net.c b/tools/qemu-xen-traditional-dir-remote/net.c
index 2ca85a3..502a691 100644
--- a/tools/qemu-xen-traditional-dir-remote/net.c
+++ b/tools/qemu-xen-traditional-dir-remote/net.c
@@ -693,6 +693,11 @@ static void vmchannel_read(void *opaque, const uint8_t *buf, int size)
#if !defined(_WIN32)
+/* Maximum GSO packet size (64k) plus plenty of room for
+ * the ethernet and virtio_net headers
+ */
+#define TAP_BUFSIZE (4096 + 65536)
+
typedef struct TAPState {
VLANClientState *vc;
int fd;
@@ -700,7 +705,7 @@ typedef struct TAPState {
char down_script[1024];
char down_script_arg[128];
char script_arg[1024];
- uint8_t buf[4096];
+ uint8_t buf[TAP_BUFSIZE];
} TAPState;
#ifndef CONFIG_STUBDOM
--
1.8.1.4
++++++ 0003-e1000-fix-access-4-bytes-beyond-buffer-end.patch ++++++
From: "Michael S. Tsirkin"
Date: Mon, 12 Jul 2010 20:24:59 +0300
Subject: e1000: fix access 4 bytes beyond buffer end
Patch-mainline: v0.13.0-rc0
Git-commit: b0b900070c7cb29bbefb732ec00397abe5de6d73
References: bnc#840196
We do range check for size, and get size as buffer,
but copy size + 4 bytes (4 is for FCS).
Let's copy size bytes but put size + 4 in length.
Signed-off-by: Michael S. Tsirkin
Acked-by: Michal Kubecek
---
tools/qemu-xen-traditional-dir-remote/hw/e1000.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
index c75bc5e..9b062db 100644
--- a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
+++ b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
@@ -659,7 +659,6 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
}
rdh_start = s->mac_reg[RDH];
- size += 4; // for the header
do {
if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
set_ics(s, 0, E1000_ICS_RXO);
@@ -673,7 +672,7 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
if (desc.buffer_addr) {
cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),
(void *)(buf + vlan_offset), size);
- desc.length = cpu_to_le16(size);
+ desc.length = cpu_to_le16(size + 4 /* for FCS */);
desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM;
} else // as per intel docs; skip descriptors with null buf addr
DBGOUT(RX, "Null RX descriptor!!\n");
--
1.8.1.4
++++++ 0004-e1000-secrc-support.patch ++++++
From: "Michael S. Tsirkin"
Date: Mon, 12 Jul 2010 20:41:02 +0300
Subject: e1000: secrc support
Patch-mainline: v0.13.0-rc0
Git-commit: 55e8d1ce6b09300cc5f3adcd9a705156d168381d
References: bnc#840196
Add support for secrc field. Reportedly needed by old RHEL guests.
Signed-off-by: Michael S. Tsirkin
Acked-by: Michal Kubecek
---
tools/qemu-xen-traditional-dir-remote/hw/e1000.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
index 9b062db..07e681d 100644
--- a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
+++ b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
@@ -338,6 +338,15 @@ is_vlan_txd(uint32_t txd_lower)
return ((txd_lower & E1000_TXD_CMD_VLE) != 0);
}
+/* FCS aka Ethernet CRC-32. We don't get it from backends and can't
+ * fill it in, just pad descriptor length by 4 bytes unless guest
+ * told us to trip it off the packet. */
+static inline int
+fcs_len(E1000State *s)
+{
+ return (s->mac_reg[RCTL] & E1000_RCTL_SECRC) ? 0 : 4;
+}
+
static void
xmit_seg(E1000State *s)
{
@@ -672,7 +681,7 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
if (desc.buffer_addr) {
cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),
(void *)(buf + vlan_offset), size);
- desc.length = cpu_to_le16(size + 4 /* for FCS */);
+ desc.length = cpu_to_le16(size + fcs_len(s));
desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM;
} else // as per intel docs; skip descriptors with null buf addr
DBGOUT(RX, "Null RX descriptor!!\n");
--
1.8.1.4
++++++ 0005-e1000-multi-buffer-packet-support.patch ++++++
From: "Michael S. Tsirkin"
Date: Tue, 15 Feb 2011 18:27:48 +0200
Subject: e1000: multi-buffer packet support
Patch-mainline: v0.15.0-rc0
Git-commit: b19487e27ed3009df7f555998a454ba19aefd4b8
References: bnc#840196
e1000 supports multi-buffer packets larger than rxbuf_size.
This fixes the following (on linux):
- in guest: ifconfig eth1 mtu 16110
- in host: ifconfig tap0 mtu 16110
ping -s 16082 <guest-ip>
Signed-off-by: Michael S. Tsirkin
Reviewed-by: Stefan Hajnoczi
Acked-by: Alex Williamson
Acked-by: Kevin Wolf
Signed-off-by: Aurelien Jarno
Signed-off-by: Michal Kubecek
---
tools/qemu-xen-traditional-dir-remote/hw/e1000.c | 39 +++++++++++++++++-------
1 file changed, 28 insertions(+), 11 deletions(-)
diff --git a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
index 07e681d..34818e0 100644
--- a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
+++ b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
@@ -632,16 +632,13 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
uint32_t rdh_start;
uint16_t vlan_special = 0;
uint8_t vlan_status = 0, vlan_offset = 0;
+ size_t desc_offset;
+ size_t desc_size;
+ size_t total_size;
if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
return;
- if (size > s->rxbuf_size) {
- DBGOUT(RX, "packet too large for buffers (%d > %d)\n", size,
- s->rxbuf_size);
- return;
- }
-
/* Discard oversized packets if !LPE and !SBP. */
if ((size > MAXIMUM_ETHERNET_LPE_SIZE ||
(size > MAXIMUM_ETHERNET_VLAN_SIZE
@@ -668,8 +665,16 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
}
rdh_start = s->mac_reg[RDH];
+ desc_offset = 0;
+ total_size = size + fcs_len(s);
do {
+ desc_size = total_size - desc_offset;
+ if (desc_size > s->rxbuf_size) {
+ desc_size = s->rxbuf_size;
+ }
if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
+ /* Discard all data written so far */
+ s->mac_reg[RDH] = rdh_start;
set_ics(s, 0, E1000_ICS_RXO);
return;
}
@@ -679,10 +684,22 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
desc.special = vlan_special;
desc.status |= (vlan_status | E1000_RXD_STAT_DD);
if (desc.buffer_addr) {
- cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),
- (void *)(buf + vlan_offset), size);
- desc.length = cpu_to_le16(size + fcs_len(s));
- desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM;
+ if (desc_offset < size) {
+ size_t copy_size = size - desc_offset;
+ if (copy_size > s->rxbuf_size) {
+ copy_size = s->rxbuf_size;
+ }
+ cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),
+ (void *)(buf + desc_offset + vlan_offset),
+ copy_size);
+ }
+ desc_offset += desc_size;
+ if (desc_offset >= total_size) {
+ desc.length = cpu_to_le16(desc_size);
+ desc.status |= E1000_RXD_STAT_EOP | E1000_RXD_STAT_IXSM;
+ } else {
+ desc.length = cpu_to_le16(desc_size);
+ }
} else // as per intel docs; skip descriptors with null buf addr
DBGOUT(RX, "Null RX descriptor!!\n");
cpu_physical_memory_write(base, (void *)&desc, sizeof(desc));
@@ -697,7 +714,7 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
set_ics(s, 0, E1000_ICS_RXO);
return;
}
- } while (desc.buffer_addr == 0);
+ } while (desc_offset < total_size);
s->mac_reg[GPRC]++;
s->mac_reg[TPR]++;
--
1.8.1.4
++++++ 0006-e1000-clear-EOP-for-multi-buffer-descriptors.patch ++++++
From: "Michael S. Tsirkin"
Date: Tue, 15 Feb 2011 18:27:52 +0200
Subject: e1000: clear EOP for multi-buffer descriptors
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Patch-mainline: v0.15.0-rc0
Git-commit: ee912ccfa007351a62ba42bd60499769f6c02c1e
References: bnc#840196
The e1000 spec says: if software statically allocates
buffers, and uses memory read to check for completed descriptors, it
simply has to zero the status byte in the descriptor to make it ready
for reuse by hardware. This is not a hardware requirement (moving the
hardware tail pointer is), but is necessary for performing an in–memory
scan.
Thus the guest does not have to clear the status byte. In case it
doesn't we need to clear EOP for all descriptors
except the last. While I don't know of any such guests,
it's probably a good idea to stick to the spec.
Signed-off-by: Michael S. Tsirkin
Reported-by: Juan Quintela
Acked-by: Alex Williamson
Acked-by: Kevin Wolf
Signed-off-by: Aurelien Jarno
Acked-by: Michal Kubecek
---
tools/qemu-xen-traditional-dir-remote/hw/e1000.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
index 34818e0..7e791dc 100644
--- a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
+++ b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
@@ -694,11 +694,13 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
copy_size);
}
desc_offset += desc_size;
+ desc.length = cpu_to_le16(desc_size);
if (desc_offset >= total_size) {
- desc.length = cpu_to_le16(desc_size);
desc.status |= E1000_RXD_STAT_EOP | E1000_RXD_STAT_IXSM;
} else {
- desc.length = cpu_to_le16(desc_size);
+ /* Guest zeroing out status is not a hardware requirement.
+ Clear EOP in case guest didn't do it. */
+ desc.status &= ~E1000_RXD_STAT_EOP;
}
} else // as per intel docs; skip descriptors with null buf addr
DBGOUT(RX, "Null RX descriptor!!\n");
--
1.8.1.4
++++++ 0007-e1000-verify-we-have-buffers-upfront.patch ++++++
From: "Michael S. Tsirkin"
Date: Tue, 15 Feb 2011 18:27:55 +0200
Subject: e1000: verify we have buffers, upfront
Patch-mainline: v0.15.0-rc0
Git-commit: 322fd48afbed1ef7b834ac343a0c8687bcb33695
References: bnc#840196
The spec says: Any descriptor with a non-zero status byte has been
processed by the hardware, and is ready to be handled by the software.
Thus, once we change a descriptor status to non-zero we should
never move the head backwards and try to reuse this
descriptor from hardware.
This actually happened with a multibuffer packet
that arrives when we don't have enough buffers.
Fix by checking that we have enough buffers upfront
so we never need to discard the packet midway through.
Signed-off-by: Michael S. Tsirkin
Acked-by: Alex Williamson
Acked-by: Kevin Wolf
Signed-off-by: Aurelien Jarno
Acked-by: Michal Kubecek
---
tools/qemu-xen-traditional-dir-remote/hw/e1000.c | 28 +++++++++++++++++++-----
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
index 7e791dc..18d7597 100644
--- a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
+++ b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
@@ -622,6 +622,24 @@ e1000_can_receive(void *opaque)
return (s->mac_reg[RCTL] & E1000_RCTL_EN && s->mac_reg[RDLEN] != 0);
}
+static bool e1000_has_rxbufs(E1000State *s, size_t total_size)
+{
+ int bufs;
+ /* Fast-path short packets */
+ if (total_size <= s->rxbuf_size) {
+ return s->mac_reg[RDH] != s->mac_reg[RDT] || !s->check_rxov;
+ }
+ if (s->mac_reg[RDH] < s->mac_reg[RDT]) {
+ bufs = s->mac_reg[RDT] - s->mac_reg[RDH];
+ } else if (s->mac_reg[RDH] > s->mac_reg[RDT] || !s->check_rxov) {
+ bufs = s->mac_reg[RDLEN] / sizeof(struct e1000_rx_desc) +
+ s->mac_reg[RDT] - s->mac_reg[RDH];
+ } else {
+ return false;
+ }
+ return total_size <= bufs * s->rxbuf_size;
+}
+
static void
e1000_receive(void *opaque, const uint8_t *buf, int size)
{
@@ -667,17 +685,15 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
rdh_start = s->mac_reg[RDH];
desc_offset = 0;
total_size = size + fcs_len(s);
+ if (!e1000_has_rxbufs(s, total_size)) {
+ set_ics(s, 0, E1000_ICS_RXO);
+ return;
+ }
do {
desc_size = total_size - desc_offset;
if (desc_size > s->rxbuf_size) {
desc_size = s->rxbuf_size;
}
- if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
- /* Discard all data written so far */
- s->mac_reg[RDH] = rdh_start;
- set_ics(s, 0, E1000_ICS_RXO);
- return;
- }
base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
sizeof(desc) * s->mac_reg[RDH];
cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
--
1.8.1.4
++++++ 0008-e1000-check-buffer-availability.patch ++++++
From: "Michael S. Tsirkin"
Date: Sun, 27 Mar 2011 13:37:35 +0200
Subject: e1000: check buffer availability
Patch-mainline: v0.15.0-rc0
Git-commit: 6cdfab2868dd593902e2b7db3ba9f49f2cc03e3f
References: bnc#840196
Reduce spurious packet drops on RX ring empty
by verifying that we have at least 1 buffer
ahead of the time.
Signed-off-by: Michael S. Tsirkin
Acked-by: Michal Kubecek
---
tools/qemu-xen-traditional-dir-remote/hw/e1000.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
index 18d7597..b07c6cb 100644
--- a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
+++ b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
@@ -614,14 +614,6 @@ e1000_set_link_status(VLANClientState *vc)
set_ics(s, 0, E1000_ICR_LSC);
}
-static int
-e1000_can_receive(void *opaque)
-{
- E1000State *s = opaque;
-
- return (s->mac_reg[RCTL] & E1000_RCTL_EN && s->mac_reg[RDLEN] != 0);
-}
-
static bool e1000_has_rxbufs(E1000State *s, size_t total_size)
{
int bufs;
@@ -640,6 +632,15 @@ static bool e1000_has_rxbufs(E1000State *s, size_t total_size)
return total_size <= bufs * s->rxbuf_size;
}
+static int
+e1000_can_receive(void *opaque)
+{
+ E1000State *s = opaque;
+
+ return (s->mac_reg[RCTL] & E1000_RCTL_EN) && (s->mac_reg[RDLEN] != 0) &&
+ e1000_has_rxbufs(s, 1);
+}
+
static void
e1000_receive(void *opaque, const uint8_t *buf, int size)
{
--
1.8.1.4
++++++ 25861-x86-early-fixmap.patch ++++++
# HG changeset patch
# User Jan Beulich
# Date 1347371120 -7200
# Node ID 51c2d7c83cbc2a0357ce112a463f91d354dcdba9
# Parent e4cb8411161043c726f699252cc761e77853e820
x86: allow early use of fixmaps
As a prerequisite for adding an EHCI debug port based console
implementation, set up the page tables needed for (a sub-portion of)
the fixmaps together with other boot time page table construction.
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Index: xen-4.2.4-testing/xen/arch/x86/boot/head.S
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/boot/head.S
+++ xen-4.2.4-testing/xen/arch/x86/boot/head.S
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include
#include
@@ -136,6 +137,9 @@ __start:
add $8,%edx
add $(1<
#include
#include
+#define __ASSEMBLY__ /* avoid pulling in ACPI stuff (conflicts with EFI) */
+#include
+#undef __ASSEMBLY__
#include
#include
#include
@@ -1131,14 +1134,19 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
slot &= L2_PAGETABLE_ENTRIES - 1;
l2_bootmap[slot] = l2e_from_paddr(addr, __PAGE_HYPERVISOR|_PAGE_PSE);
}
+ /* Initialise L2 fixmap page directory entry. */
+ l2_fixmap[l2_table_offset(FIXADDR_TOP - 1)] =
+ l2e_from_paddr((UINTN)l1_fixmap, __PAGE_HYPERVISOR);
/* Initialise L3 identity-map page directory entries. */
for ( i = 0; i < ARRAY_SIZE(l2_identmap) / L2_PAGETABLE_ENTRIES; ++i )
l3_identmap[i] = l3e_from_paddr((UINTN)(l2_identmap +
i * L2_PAGETABLE_ENTRIES),
__PAGE_HYPERVISOR);
- /* Initialise L3 xen-map page directory entry. */
+ /* Initialise L3 xen-map and fixmap page directory entries. */
l3_xenmap[l3_table_offset(XEN_VIRT_START)] =
l3e_from_paddr((UINTN)l2_xenmap, __PAGE_HYPERVISOR);
+ l3_xenmap[l3_table_offset(FIXADDR_TOP - 1)] =
+ l3e_from_paddr((UINTN)l2_fixmap, __PAGE_HYPERVISOR);
/* Initialise L3 boot-map page directory entries. */
l3_bootmap[l3_table_offset(xen_phys_start)] =
l3e_from_paddr((UINTN)l2_bootmap, __PAGE_HYPERVISOR);
Index: xen-4.2.4-testing/xen/arch/x86/mm.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/mm.c
+++ xen-4.2.4-testing/xen/arch/x86/mm.c
@@ -131,6 +131,10 @@
l1_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
l1_identmap[L1_PAGETABLE_ENTRIES];
+/* Mapping of the fixmap space needed early. */
+l1_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
+ l1_fixmap[L1_PAGETABLE_ENTRIES];
+
#define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
/*
Index: xen-4.2.4-testing/xen/arch/x86/x86_64/mm.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/x86_64/mm.c
+++ xen-4.2.4-testing/xen/arch/x86/x86_64/mm.c
@@ -65,6 +65,10 @@ l3_pgentry_t __attribute__ ((__section__
l2_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
l2_xenmap[L2_PAGETABLE_ENTRIES];
+/* Enough page directories to map the early fixmap space. */
+l2_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
+ l2_fixmap[L2_PAGETABLE_ENTRIES];
+
/* Enough page directories to map into the bottom 1GB. */
l3_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
l3_bootmap[L3_PAGETABLE_ENTRIES];
Index: xen-4.2.4-testing/xen/include/asm-x86/config.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/config.h
+++ xen-4.2.4-testing/xen/include/asm-x86/config.h
@@ -317,7 +317,7 @@ extern unsigned char boot_edid_info[128]
#define MACHPHYS_MBYTES 16 /* 1 MB needed per 1 GB memory */
#define FRAMETABLE_MBYTES (MACHPHYS_MBYTES * 6)
-#define IOREMAP_VIRT_END 0UL
+#define IOREMAP_VIRT_END _AC(0,UL)
#define IOREMAP_VIRT_START (IOREMAP_VIRT_END - (IOREMAP_MBYTES<<20))
#define DIRECTMAP_VIRT_END IOREMAP_VIRT_START
#define DIRECTMAP_VIRT_START (DIRECTMAP_VIRT_END - (DIRECTMAP_MBYTES<<20))
Index: xen-4.2.4-testing/xen/include/asm-x86/fixmap.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/fixmap.h
+++ xen-4.2.4-testing/xen/include/asm-x86/fixmap.h
@@ -13,12 +13,17 @@
#define _ASM_FIXMAP_H
#include
+#include
+
+#define FIXADDR_TOP (IOREMAP_VIRT_END - PAGE_SIZE)
+
+#ifndef __ASSEMBLY__
+
#include
#include
#include
#include
#include
-#include
#include
#include
#include
@@ -68,7 +73,6 @@ enum fixed_addresses {
__end_of_fixed_addresses
};
-#define FIXADDR_TOP (IOREMAP_VIRT_END - PAGE_SIZE)
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
@@ -92,4 +96,6 @@ static inline unsigned long virt_to_fix(
return __virt_to_fix(vaddr);
}
+#endif /* __ASSEMBLY__ */
+
#endif
Index: xen-4.2.4-testing/xen/include/asm-x86/page.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/page.h
+++ xen-4.2.4-testing/xen/include/asm-x86/page.h
@@ -1,6 +1,8 @@
#ifndef __X86_PAGE_H__
#define __X86_PAGE_H__
+#include
+
/*
* It is important that the masks are signed quantities. This ensures that
* the compiler sign-extends a 32-bit mask to 64 bits if that is required.
@@ -306,13 +308,15 @@ extern l2_pgentry_t idle_pg_table_l2[
extern l2_pgentry_t *compat_idle_pg_table_l2;
extern unsigned int m2p_compat_vstart;
extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES],
+ l2_fixmap[L2_PAGETABLE_ENTRIES],
l2_bootmap[L2_PAGETABLE_ENTRIES];
extern l3_pgentry_t l3_xenmap[L3_PAGETABLE_ENTRIES],
l3_identmap[L3_PAGETABLE_ENTRIES],
l3_bootmap[L3_PAGETABLE_ENTRIES];
#endif
extern l2_pgentry_t l2_identmap[4*L2_PAGETABLE_ENTRIES];
-extern l1_pgentry_t l1_identmap[L1_PAGETABLE_ENTRIES];
+extern l1_pgentry_t l1_identmap[L1_PAGETABLE_ENTRIES],
+ l1_fixmap[L1_PAGETABLE_ENTRIES];
void paging_init(void);
void setup_idle_pagetable(void);
#endif /* !defined(__ASSEMBLY__) */
Index: xen-4.2.4-testing/xen/include/xen/const.h
===================================================================
--- /dev/null
+++ xen-4.2.4-testing/xen/include/xen/const.h
@@ -0,0 +1,24 @@
+/* const.h: Macros for dealing with constants. */
+
+#ifndef __XEN_CONST_H__
+#define __XEN_CONST_H__
+
+/* Some constant macros are used in both assembler and
+ * C code. Therefore we cannot annotate them always with
+ * 'UL' and other type specifiers unilaterally. We
+ * use the following macros to deal with this.
+ *
+ * Similarly, _AT() will cast an expression with a type in C, but
+ * leave it unchanged in asm.
+ */
+
+#ifdef __ASSEMBLY__
+#define _AC(X,Y) X
+#define _AT(T,X) X
+#else
+#define __AC(X,Y) (X##Y)
+#define _AC(X,Y) __AC(X,Y)
+#define _AT(T,X) ((T)(X))
+#endif
+
+#endif /* __XEN_CONST_H__ */
++++++ 25862-sercon-non-com.patch ++++++
# HG changeset patch
# User Jan Beulich
# Date 1347371236 -7200
# Node ID 776a23fa0e938e4cf3307fc2e3b3f1a9488a5927
# Parent 51c2d7c83cbc2a0357ce112a463f91d354dcdba9
console: prepare for non-COMn port support
Widen SERHND_IDX (and use it where needed), introduce a flush low level
driver method, and remove unnecessary peeking of the common code at the
(driver specific) serial port identification string in the "console="
command line option value.
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Index: xen-4.2.4-testing/xen/arch/x86/smpboot.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/smpboot.c
+++ xen-4.2.4-testing/xen/arch/x86/smpboot.c
@@ -1017,7 +1017,7 @@ void __init smp_intr_init(void)
* Also ensure serial interrupts are high priority. We do not
* want them to be blocked by unacknowledged guest-bound interrupts.
*/
- for ( seridx = 0; seridx < 2; seridx++ )
+ for ( seridx = 0; seridx <= SERHND_IDX; seridx++ )
{
if ( (irq = serial_irq(seridx)) < 0 )
continue;
Index: xen-4.2.4-testing/xen/drivers/char/console.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/char/console.c
+++ xen-4.2.4-testing/xen/drivers/char/console.c
@@ -542,6 +542,7 @@ void printk(const char *fmt, ...)
void __init console_init_preirq(void)
{
char *p;
+ int sh;
serial_init_preirq();
@@ -554,8 +555,9 @@ void __init console_init_preirq(void)
vga_init();
else if ( !strncmp(p, "none", 4) )
continue;
- else if ( strncmp(p, "com", 3) ||
- (sercon_handle = serial_parse_handle(p)) == -1 )
+ else if ( (sh = serial_parse_handle(p)) >= 0 )
+ sercon_handle = sh;
+ else
{
char *q = strchr(p, ',');
if ( q != NULL )
Index: xen-4.2.4-testing/xen/drivers/char/serial.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/char/serial.c
+++ xen-4.2.4-testing/xen/drivers/char/serial.c
@@ -22,9 +22,11 @@ size_param("serial_tx_buffer", serial_tx
#define mask_serial_rxbuf_idx(_i) ((_i)&(serial_rxbufsz-1))
#define mask_serial_txbuf_idx(_i) ((_i)&(serial_txbufsz-1))
-static struct serial_port com[2] = {
- { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED },
- { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED }
+static struct serial_port com[SERHND_IDX + 1] = {
+ [0 ... SERHND_IDX] = {
+ .rx_lock = SPIN_LOCK_UNLOCKED,
+ .tx_lock = SPIN_LOCK_UNLOCKED
+ }
};
void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
@@ -81,6 +83,8 @@ void serial_tx_interrupt(struct serial_p
port->driver->putc(
port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
}
+ if ( i && port->driver->flush )
+ port->driver->flush(port);
}
spin_unlock(&port->tx_lock);
@@ -175,6 +179,9 @@ void serial_putc(int handle, char c)
__serial_putc(port, c);
+ if ( port->driver->flush )
+ port->driver->flush(port);
+
spin_unlock_irqrestore(&port->tx_lock, flags);
}
@@ -206,6 +213,9 @@ void serial_puts(int handle, const char
__serial_putc(port, c);
}
+ if ( port->driver->flush )
+ port->driver->flush(port);
+
spin_unlock_irqrestore(&port->tx_lock, flags);
}
@@ -261,10 +271,10 @@ int __init serial_parse_handle(char *con
switch ( conf[3] )
{
case '1':
- handle = 0;
+ handle = SERHND_COM1;
break;
case '2':
- handle = 1;
+ handle = SERHND_COM2;
break;
default:
goto fail;
@@ -365,6 +375,8 @@ void serial_start_sync(int handle)
port->driver->putc(
port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
}
+ if ( port->driver->flush )
+ port->driver->flush(port);
}
spin_unlock_irqrestore(&port->tx_lock, flags);
Index: xen-4.2.4-testing/xen/include/xen/serial.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/xen/serial.h
+++ xen-4.2.4-testing/xen/include/xen/serial.h
@@ -60,6 +60,8 @@ struct uart_driver {
int (*tx_empty)(struct serial_port *);
/* Put a character onto the serial line. */
void (*putc)(struct serial_port *, char);
+ /* Flush accumulated characters. */
+ void (*flush)(struct serial_port *);
/* Get a character from the serial line: returns 0 if none available. */
int (*getc)(struct serial_port *, char *);
/* Get IRQ number for this port's serial line: returns -1 if none. */
@@ -67,10 +69,12 @@ struct uart_driver {
};
/* 'Serial handles' are composed from the following fields. */
-#define SERHND_IDX (1<<0) /* COM1 or COM2? */
-#define SERHND_HI (1<<1) /* Mux/demux each transferred char by MSB. */
-#define SERHND_LO (1<<2) /* Ditto, except that the MSB is cleared. */
-#define SERHND_COOKED (1<<3) /* Newline/carriage-return translation? */
+#define SERHND_IDX (3<<0) /* COM1 or COM2? */
+# define SERHND_COM1 (0<<0)
+# define SERHND_COM2 (1<<0)
+#define SERHND_HI (1<<2) /* Mux/demux each transferred char by MSB. */
+#define SERHND_LO (1<<3) /* Ditto, except that the MSB is cleared. */
+#define SERHND_COOKED (1<<4) /* Newline/carriage-return translation? */
/* Two-stage initialisation (before/after IRQ-subsystem initialisation). */
void serial_init_preirq(void);
++++++ 25863-sercon-ehci-dbgp.patch ++++++
++++ 1798 lines (skipped)
++++++ 25864-sercon-unused.patch ++++++
# HG changeset patch
# User Jan Beulich
# Date 1347371512 -7200
# Node ID e1380b5311ccee14eb47d7badb75339933d42249
# Parent 0d0c55a1975db9c6cac2e9259b5ebea7a7bdbaec
serial: avoid fully initializing unused consoles
Defer calling the drivers' post-IRQ initialization functions (generally
doing allocation of transmit buffers) until it is known that the
respective console is actually going to be used.
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
--- a/xen/drivers/char/ehci-dbgp.c
+++ b/xen/drivers/char/ehci-dbgp.c
@@ -1391,7 +1391,8 @@ static int ehci_dbgp_check_release(struc
printk(XENLOG_INFO "Releasing EHCI debug port at %02x:%02x.%u\n",
dbgp->bus, dbgp->slot, dbgp->func);
- kill_timer(&dbgp->timer);
+ if ( dbgp->timer.function )
+ kill_timer(&dbgp->timer);
dbgp->ehci_debug = NULL;
ctrl = readl(&ehci_debug->control);
--- a/xen/drivers/char/serial.c
+++ b/xen/drivers/char/serial.c
@@ -29,6 +29,8 @@ static struct serial_port com[SERHND_IDX
}
};
+static bool_t __read_mostly post_irq;
+
void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
{
char c;
@@ -263,14 +265,12 @@ char serial_getc(int handle)
int __init serial_parse_handle(char *conf)
{
- int handle;
+ int handle, flags = 0;
if ( !strncmp(conf, "dbgp", 4) && (!conf[4] || conf[4] == ',') )
{
- if ( !com[SERHND_DBGP].driver )
- goto fail;
-
- return SERHND_DBGP | SERHND_COOKED;
+ handle = SERHND_DBGP;
+ goto common;
}
if ( strncmp(conf, "com", 3) )
@@ -288,17 +288,25 @@ int __init serial_parse_handle(char *con
goto fail;
}
- if ( !com[handle].driver )
- goto fail;
-
if ( conf[4] == 'H' )
- handle |= SERHND_HI;
+ flags |= SERHND_HI;
else if ( conf[4] == 'L' )
- handle |= SERHND_LO;
+ flags |= SERHND_LO;
- handle |= SERHND_COOKED;
+ common:
+ if ( !com[handle].driver )
+ goto fail;
+
+ if ( !post_irq )
+ com[handle].state = serial_parsed;
+ else if ( com[handle].state != serial_initialized )
+ {
+ if ( com[handle].driver->init_postirq )
+ com[handle].driver->init_postirq(&com[handle]);
+ com[handle].state = serial_initialized;
+ }
- return handle;
+ return handle | flags | SERHND_COOKED;
fail:
return -1;
@@ -450,8 +458,13 @@ void __init serial_init_postirq(void)
{
int i;
for ( i = 0; i < ARRAY_SIZE(com); i++ )
- if ( com[i].driver && com[i].driver->init_postirq )
- com[i].driver->init_postirq(&com[i]);
+ if ( com[i].state == serial_parsed )
+ {
+ if ( com[i].driver->init_postirq )
+ com[i].driver->init_postirq(&com[i]);
+ com[i].state = serial_initialized;
+ }
+ post_irq = 1;
}
void __init serial_endboot(void)
@@ -475,7 +488,7 @@ void serial_suspend(void)
{
int i;
for ( i = 0; i < ARRAY_SIZE(com); i++ )
- if ( com[i].driver && com[i].driver->suspend )
+ if ( com[i].state == serial_initialized && com[i].driver->suspend )
com[i].driver->suspend(&com[i]);
}
@@ -483,7 +496,7 @@ void serial_resume(void)
{
int i;
for ( i = 0; i < ARRAY_SIZE(com); i++ )
- if ( com[i].driver && com[i].driver->resume )
+ if ( com[i].state == serial_initialized && com[i].driver->resume )
com[i].driver->resume(&com[i]);
}
--- a/xen/include/xen/serial.h
+++ b/xen/include/xen/serial.h
@@ -25,10 +25,17 @@ extern unsigned int serial_txbufsz;
struct uart_driver;
+enum serial_port_state {
+ serial_unused,
+ serial_parsed,
+ serial_initialized
+};
+
struct serial_port {
/* Uart-driver parameters. */
struct uart_driver *driver;
void *uart;
+ enum serial_port_state state;
/* Number of characters the port can hold for transmit. */
int tx_fifo_size;
/* Transmit data buffer (interrupt-driven uart). */
++++++ 25866-sercon-ns16550-pci-irq.patch ++++++
# HG changeset patch
# User Jan Beulich
# Date 1347371733 -7200
# Node ID ee12dc357fbecbb0517798f395d14bf1764c6766
# Parent 5fb5b3b70e34ef278d06aff27878b4b8e6d9145f
ns16550: PCI initialization adjustments
Besides single-port serial cards, also accept multi-port ones and such
providing mixed functionality (e.g. also having a parallel port).
Reading PCI_INTERRUPT_PIN before ACPI gets enabled generally produces
an incorrect IRQ (below 16, whereas after enabling ACPI it frequently
would end up at a higher one), so this is useful (almost) only when a
system already boots in ACPI mode.
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Index: xen-4.2.3-testing/xen/drivers/char/ns16550.c
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/char/ns16550.c
+++ xen-4.2.3-testing/xen/drivers/char/ns16550.c
@@ -504,7 +504,6 @@ static int __init check_existence(struct
static int
pci_uart_config (struct ns16550 *uart, int skip_amt, int bar_idx)
{
- uint16_t class;
uint32_t bar, len;
int b, d, f;
@@ -515,9 +514,15 @@ pci_uart_config (struct ns16550 *uart, i
{
for ( f = 0; f < 0x8; f++ )
{
- class = pci_conf_read16(0, b, d, f, PCI_CLASS_DEVICE);
- if ( class != 0x700 )
+ switch ( pci_conf_read16(0, b, d, f, PCI_CLASS_DEVICE) )
+ {
+ case 0x0700: /* single port serial */
+ case 0x0702: /* multi port serial */
+ case 0x0780: /* other (e.g serial+parallel) */
+ break;
+ default:
continue;
+ }
bar = pci_conf_read32(0, b, d, f,
PCI_BASE_ADDRESS_0 + bar_idx*4);
@@ -540,7 +545,8 @@ pci_uart_config (struct ns16550 *uart, i
uart->bar = bar;
uart->bar_idx = bar_idx;
uart->io_base = bar & 0xfffe;
- uart->irq = 0;
+ uart->irq = pci_conf_read8(0, b, d, f, PCI_INTERRUPT_PIN) ?
+ pci_conf_read8(0, b, d, f, PCI_INTERRUPT_LINE) : 0;
return 0;
}
++++++ 25867-sercon-ns16550-parse.patch ++++++
# HG changeset patch
# User Jan Beulich
# Date 1347371805 -7200
# Node ID b22f184e1a3cac03abeed92ec4b74235fd0881f4
# Parent ee12dc357fbecbb0517798f395d14bf1764c6766
ns16550: command line parsing adjustments
Allow intermediate parts of the command line options to be absent
(expressed by two immediately succeeding commas).
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Index: xen-4.2.3-testing/docs/misc/xen-command-line.markdown
===================================================================
--- xen-4.2.3-testing.orig/docs/misc/xen-command-line.markdown
+++ xen-4.2.3-testing/docs/misc/xen-command-line.markdown
@@ -199,7 +199,7 @@ If set, override Xen's calculation of th
If set, override Xen's default choice for the platform timer.
### com1,com2
-> `= <baud>[/][,DPS[,<io-base>[,<irq>[,<port-bdf>[,<bridge-bdf>]]]] | pci | amt ] `
+> `= <baud>[/][,[DPS][,[<io-base>|pci|amt][,[<irq>][,[<port-bdf>][,[<bridge-bdf>]]]]]]`
Both option `com1` and `com2` follow the same format.
Index: xen-4.2.3-testing/xen/drivers/char/ns16550.c
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/char/ns16550.c
+++ xen-4.2.3-testing/xen/drivers/char/ns16550.c
@@ -591,26 +591,23 @@ static void __init ns16550_parse_port_co
else if ( (baud = simple_strtoul(conf, &conf, 10)) != 0 )
uart->baud = baud;
- if ( *conf == '/')
+ if ( *conf == '/' )
{
conf++;
uart->clock_hz = simple_strtoul(conf, &conf, 0) << 4;
}
- if ( *conf != ',' )
- goto config_parsed;
- conf++;
-
- uart->data_bits = simple_strtoul(conf, &conf, 10);
+ if ( *conf == ',' && *++conf != ',' )
+ {
+ uart->data_bits = simple_strtoul(conf, &conf, 10);
- uart->parity = parse_parity_char(*conf);
- conf++;
+ uart->parity = parse_parity_char(*conf);
- uart->stop_bits = simple_strtoul(conf, &conf, 10);
+ uart->stop_bits = simple_strtoul(conf + 1, &conf, 10);
+ }
- if ( *conf == ',' )
+ if ( *conf == ',' && *++conf != ',' )
{
- conf++;
if ( strncmp(conf, "pci", 3) == 0 )
{
if ( pci_uart_config(uart, 1/* skip AMT */, uart - ns16550_com) )
@@ -627,24 +624,21 @@ static void __init ns16550_parse_port_co
{
uart->io_base = simple_strtoul(conf, &conf, 0);
}
+ }
- if ( *conf == ',' )
- {
- conf++;
- uart->irq = simple_strtoul(conf, &conf, 10);
- if ( *conf == ',' )
- {
- conf++;
- uart->ps_bdf_enable = 1;
- parse_pci_bdf(&conf, &uart->ps_bdf[0]);
- if ( *conf == ',' )
- {
- conf++;
- uart->pb_bdf_enable = 1;
- parse_pci_bdf(&conf, &uart->pb_bdf[0]);
- }
- }
- }
+ if ( *conf == ',' && *++conf != ',' )
+ uart->irq = simple_strtol(conf, &conf, 10);
+
+ if ( *conf == ',' && *++conf != ',' )
+ {
+ uart->ps_bdf_enable = 1;
+ parse_pci_bdf(&conf, &uart->ps_bdf[0]);
+ }
+
+ if ( *conf == ',' && *++conf != ',' )
+ {
+ uart->pb_bdf_enable = 1;
+ parse_pci_bdf(&conf, &uart->pb_bdf[0]);
}
config_parsed:
++++++ 25874-x86-EFI-chain-cfg.patch ++++++
# HG changeset patch
# User Jan Beulich
# Date 1347437974 -7200
# Node ID 8c0aa97d529a55de2ab96be1a5a6e9ed6a9c6bf0
# Parent ac8f4afccd6c6786a3fd5691e8b0c9b38c47e994
x86-64/EFI: allow chaining of config files
Namely when making use the CONFIG_XEN_COMPAT_* options in the legacy
Linux kernels, newer kernels may not be compatible with older
hypervisors, so trying to boot such a combination makes little sense.
Booting older kernels on newer hypervisors, however, has to always
work.
With the way xen.efi looks for its configuration file, allowing
individual configuration files to refer only to compatible kernels,
and referring from an older- to a newer-hypervisor one (the kernels
of which will, as said, necessarily be compatible with the older
hypervisor) allows to greatly reduce redundancy at least in
development environments where one frequently wants multiple
hypervisors and kernles to be installed in parallel.
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Index: xen-4.2.4-testing/docs/misc/efi.markdown
===================================================================
--- xen-4.2.4-testing.orig/docs/misc/efi.markdown
+++ xen-4.2.4-testing/docs/misc/efi.markdown
@@ -75,6 +75,13 @@ Specifies an XSM module to load.
Specifies a CPU microcode blob to load.
+###`chain=<filename>`
+
+Specifies an alternate configuration file to use in case the specified section
+(and in particular its `kernel=` setting) can't be found in the default (or
+specified) configuration file. This is only meaningful in the [global] section
+and really not meant to be used together with the `-cfg=` command line option.
+
Filenames must be specified relative to the location of the EFI binary.
Extra options to be passed to Xen can also be specified on the command line,
Index: xen-4.2.4-testing/xen/arch/x86/efi/boot.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/efi/boot.c
+++ xen-4.2.4-testing/xen/arch/x86/efi/boot.c
@@ -815,7 +815,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
else
section.s = get_value(&cfg, "global", "default");
- name.s = get_value(&cfg, section.s, "kernel");
+ for ( ; ; )
+ {
+ name.s = get_value(&cfg, section.s, "kernel");
+ if ( name.s )
+ break;
+ name.s = get_value(&cfg, "global", "chain");
+ if ( !name.s )
+ break;
+ efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
+ cfg.addr = 0;
+ if ( !read_file(dir_handle, s2w(&name), &cfg) )
+ {
+ PrintStr(L"Chained configuration file '");
+ PrintStr(name.w);
+ efi_bs->FreePool(name.w);
+ blexit(L"'not found\r\n");
+ }
+ pre_parse(&cfg);
+ efi_bs->FreePool(name.w);
+ }
if ( !name.s )
blexit(L"No Dom0 kernel image specified\r\n");
split_value(name.s);
++++++ 25909-xenpm-consistent.patch ++++++
++++ 630 lines (skipped)
++++++ 25920-x86-APICV-enable.patch ++++++
References: FATE#313605
# HG changeset patch
# User Jiongxi Li
# Date 1347912248 -3600
# Node ID ec60de627945f17ec2ce5c14e1224b59403875f7
# Parent 62de66cec48a1716bb700912da451a26296b8d1e
xen: enable APIC-Register Virtualization
Add APIC register virtualization support
- APIC read doesn't cause VM-Exit
- APIC write becomes trap-like
Signed-off-by: Gang Wei
Signed-off-by: Yang Zhang
Signed-off-by: Jiongxi Li
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vlapic.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
@@ -836,6 +836,12 @@ static int vlapic_write(struct vcpu *v,
return rc;
}
+int vlapic_apicv_write(struct vcpu *v, unsigned int offset)
+{
+ uint32_t val = vlapic_get_reg(vcpu_vlapic(v), offset);
+ return vlapic_reg_write(v, offset, val);
+}
+
int hvm_x2apic_msr_write(struct vcpu *v, unsigned int msr, uint64_t msr_content)
{
struct vlapic *vlapic = vcpu_vlapic(v);
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
@@ -89,6 +89,7 @@ static void __init vmx_display_features(
P(cpu_has_vmx_vnmi, "Virtual NMI");
P(cpu_has_vmx_msr_bitmap, "MSR direct-access bitmap");
P(cpu_has_vmx_unrestricted_guest, "Unrestricted Guest");
+ P(cpu_has_vmx_apic_reg_virt, "APIC Register Virtualization");
#undef P
if ( !printed )
@@ -186,6 +187,14 @@ static int vmx_init_vmcs_config(void)
if ( opt_unrestricted_guest_enabled )
opt |= SECONDARY_EXEC_UNRESTRICTED_GUEST;
+ /*
+ * "APIC Register Virtualization"
+ * can be set only when "use TPR shadow" is set
+ */
+ if ( _vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW )
+ opt |= SECONDARY_EXEC_APIC_REGISTER_VIRT;
+
+
_vmx_secondary_exec_control = adjust_vmx_controls(
"Secondary Exec Control", min, opt,
MSR_IA32_VMX_PROCBASED_CTLS2, &mismatch);
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
@@ -2356,6 +2356,16 @@ static void vmx_idtv_reinject(unsigned l
}
}
+static int vmx_handle_apic_write(void)
+{
+ unsigned long exit_qualification = __vmread(EXIT_QUALIFICATION);
+ unsigned int offset = exit_qualification & 0xfff;
+
+ ASSERT(cpu_has_vmx_apic_reg_virt);
+
+ return vlapic_apicv_write(current, offset);
+}
+
void vmx_vmexit_handler(struct cpu_user_regs *regs)
{
unsigned int exit_reason, idtv_info, intr_info = 0, vector = 0;
@@ -2816,6 +2826,11 @@ void vmx_vmexit_handler(struct cpu_user_
update_guest_eip(); /* Safe: XSETBV */
break;
+ case EXIT_REASON_APIC_WRITE:
+ if ( vmx_handle_apic_write() )
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
+ break;
+
case EXIT_REASON_ACCESS_GDTR_OR_IDTR:
case EXIT_REASON_ACCESS_LDTR_OR_TR:
case EXIT_REASON_VMX_PREEMPTION_TIMER_EXPIRED:
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vlapic.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vlapic.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vlapic.h
@@ -103,6 +103,8 @@ void vlapic_EOI_set(struct vlapic *vlapi
int vlapic_ipi(struct vlapic *vlapic, uint32_t icr_low, uint32_t icr_high);
+int vlapic_apicv_write(struct vcpu *v, unsigned int offset);
+
struct vlapic *vlapic_lowest_prio(
struct domain *d, struct vlapic *source,
int short_hand, uint8_t dest, uint8_t dest_mode);
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -183,6 +183,7 @@ extern u32 vmx_vmentry_control;
#define SECONDARY_EXEC_ENABLE_VPID 0x00000020
#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
#define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080
+#define SECONDARY_EXEC_APIC_REGISTER_VIRT 0x00000100
#define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400
#define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000
extern u32 vmx_secondary_exec_control;
@@ -231,6 +232,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
SECONDARY_EXEC_UNRESTRICTED_GUEST)
#define cpu_has_vmx_ple \
(vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING)
+#define cpu_has_vmx_apic_reg_virt \
+ (vmx_secondary_exec_control & SECONDARY_EXEC_APIC_REGISTER_VIRT)
/* GUEST_INTERRUPTIBILITY_INFO flags. */
#define VMX_INTR_SHADOW_STI 0x00000001
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmx.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmx.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -129,6 +129,7 @@ void vmx_update_cpu_exec_control(struct
#define EXIT_REASON_INVVPID 53
#define EXIT_REASON_WBINVD 54
#define EXIT_REASON_XSETBV 55
+#define EXIT_REASON_APIC_WRITE 56
#define EXIT_REASON_INVPCID 58
/*
++++++ 25921-x86-APICV-delivery.patch ++++++
References: FATE#313605
# HG changeset patch
# User Jiongxi Li
# Date 1347912311 -3600
# Node ID 713b8849b11afa05f1dde157a3f5086fa3aaad08
# Parent ec60de627945f17ec2ce5c14e1224b59403875f7
xen: enable Virtual-interrupt delivery
Virtual interrupt delivery avoids Xen to inject vAPIC interrupts
manually, which is fully taken care of by the hardware. This needs
some special awareness into existing interrupr injection path:
For pending interrupt from vLAPIC, instead of direct injection, we may
need update architecture specific indicators before resuming to guest.
Before returning to guest, RVI should be updated if any pending IRRs
EOI exit bitmap controls whether an EOI write should cause VM-Exit. If
set, a trap-like induced EOI VM-Exit is triggered. The approach here
is to manipulate EOI exit bitmap based on value of TMR. Level
triggered irq requires a hook in vLAPIC EOI write, so that vIOAPIC EOI
is triggered and emulated
Signed-off-by: Gang Wei
Signed-off-by: Yang Zhang
Signed-off-by: Jiongxi Li
Committed-by: Keir Fraser
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vlapic.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
@@ -145,6 +145,9 @@ int vlapic_set_irq(struct vlapic *vlapic
if ( trig )
vlapic_set_vector(vec, &vlapic->regs->data[APIC_TMR]);
+ if ( hvm_funcs.update_eoi_exit_bitmap )
+ hvm_funcs.update_eoi_exit_bitmap(vlapic_vcpu(vlapic), vec ,trig);
+
/* We may need to wake up target vcpu, besides set pending bit here */
return !vlapic_test_and_set_irr(vec, vlapic);
}
@@ -413,6 +416,14 @@ void vlapic_EOI_set(struct vlapic *vlapi
hvm_dpci_msi_eoi(current->domain, vector);
}
+void vlapic_handle_EOI_induced_exit(struct vlapic *vlapic, int vector)
+{
+ if ( vlapic_test_and_clear_vector(vector, &vlapic->regs->data[APIC_TMR]) )
+ vioapic_update_EOI(vlapic_domain(vlapic), vector);
+
+ hvm_dpci_msi_eoi(current->domain, vector);
+}
+
int vlapic_ipi(
struct vlapic *vlapic, uint32_t icr_low, uint32_t icr_high)
{
@@ -1017,6 +1028,14 @@ void vlapic_adjust_i8259_target(struct d
pt_adjust_global_vcpu_target(v);
}
+int vlapic_virtual_intr_delivery_enabled(void)
+{
+ if ( hvm_funcs.virtual_intr_delivery_enabled )
+ return hvm_funcs.virtual_intr_delivery_enabled();
+ else
+ return 0;
+}
+
int vlapic_has_pending_irq(struct vcpu *v)
{
struct vlapic *vlapic = vcpu_vlapic(v);
@@ -1029,6 +1048,9 @@ int vlapic_has_pending_irq(struct vcpu *
if ( irr == -1 )
return -1;
+ if ( vlapic_virtual_intr_delivery_enabled() )
+ return irr;
+
isr = vlapic_find_highest_isr(vlapic);
isr = (isr != -1) ? isr : 0;
if ( (isr & 0xf0) >= (irr & 0xf0) )
@@ -1041,6 +1063,9 @@ int vlapic_ack_pending_irq(struct vcpu *
{
struct vlapic *vlapic = vcpu_vlapic(v);
+ if ( vlapic_virtual_intr_delivery_enabled() )
+ return 1;
+
vlapic_set_vector(vector, &vlapic->regs->data[APIC_ISR]);
vlapic_clear_irr(vector, vlapic);
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/intr.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/intr.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/intr.c
@@ -209,6 +209,7 @@ void vmx_intr_assist(void)
struct vcpu *v = current;
unsigned int tpr_threshold = 0;
enum hvm_intblk intblk;
+ int pt_vector = -1;
/* Block event injection when single step with MTF. */
if ( unlikely(v->arch.hvm_vcpu.single_step) )
@@ -219,7 +220,7 @@ void vmx_intr_assist(void)
}
/* Crank the handle on interrupt state. */
- pt_update_irq(v);
+ pt_vector = pt_update_irq(v);
do {
intack = hvm_vcpu_has_pending_irq(v);
@@ -230,16 +231,34 @@ void vmx_intr_assist(void)
goto out;
intblk = hvm_interrupt_blocked(v, intack);
- if ( intblk == hvm_intblk_tpr )
+ if ( cpu_has_vmx_virtual_intr_delivery )
+ {
+ /* Set "Interrupt-window exiting" for ExtINT */
+ if ( (intblk != hvm_intblk_none) &&
+ ( (intack.source == hvm_intsrc_pic) ||
+ ( intack.source == hvm_intsrc_vector) ) )
+ {
+ enable_intr_window(v, intack);
+ goto out;
+ }
+
+ if ( __vmread(VM_ENTRY_INTR_INFO) & INTR_INFO_VALID_MASK )
+ {
+ if ( (intack.source == hvm_intsrc_pic) ||
+ (intack.source == hvm_intsrc_nmi) ||
+ (intack.source == hvm_intsrc_mce) )
+ enable_intr_window(v, intack);
+
+ goto out;
+ }
+ } else if ( intblk == hvm_intblk_tpr )
{
ASSERT(vlapic_enabled(vcpu_vlapic(v)));
ASSERT(intack.source == hvm_intsrc_lapic);
tpr_threshold = intack.vector >> 4;
goto out;
- }
-
- if ( (intblk != hvm_intblk_none) ||
- (__vmread(VM_ENTRY_INTR_INFO) & INTR_INFO_VALID_MASK) )
+ } else if ( (intblk != hvm_intblk_none) ||
+ (__vmread(VM_ENTRY_INTR_INFO) & INTR_INFO_VALID_MASK) )
{
enable_intr_window(v, intack);
goto out;
@@ -256,6 +275,44 @@ void vmx_intr_assist(void)
{
hvm_inject_hw_exception(TRAP_machine_check, HVM_DELIVER_NO_ERROR_CODE);
}
+ else if ( cpu_has_vmx_virtual_intr_delivery &&
+ intack.source != hvm_intsrc_pic &&
+ intack.source != hvm_intsrc_vector )
+ {
+ unsigned long status = __vmread(GUEST_INTR_STATUS);
+
+ /*
+ * Set eoi_exit_bitmap for periodic timer interrup to cause EOI-induced VM
+ * exit, then pending periodic time interrups have the chance to be injected
+ * for compensation
+ */
+ if (pt_vector != -1)
+ vmx_set_eoi_exit_bitmap(v, pt_vector);
+
+ /* we need update the RVI field */
+ status &= ~(unsigned long)0x0FF;
+ status |= (unsigned long)0x0FF &
+ intack.vector;
+ __vmwrite(GUEST_INTR_STATUS, status);
+ if (v->arch.hvm_vmx.eoi_exitmap_changed) {
+#ifdef __i386__
+#define UPDATE_EOI_EXITMAP(v, e) { \
+ if (test_and_clear_bit(e, &v->arch.hvm_vmx.eoi_exitmap_changed)) { \
+ __vmwrite(EOI_EXIT_BITMAP##e, v->arch.hvm_vmx.eoi_exit_bitmap[e]); \
+ __vmwrite(EOI_EXIT_BITMAP##e##_HIGH, v->arch.hvm_vmx.eoi_exit_bitmap[e] >> 32);}}
+#else
+#define UPDATE_EOI_EXITMAP(v, e) { \
+ if (test_and_clear_bit(e, &v->arch.hvm_vmx.eoi_exitmap_changed)) { \
+ __vmwrite(EOI_EXIT_BITMAP##e, v->arch.hvm_vmx.eoi_exit_bitmap[e]);}}
+#endif
+ UPDATE_EOI_EXITMAP(v, 0);
+ UPDATE_EOI_EXITMAP(v, 1);
+ UPDATE_EOI_EXITMAP(v, 2);
+ UPDATE_EOI_EXITMAP(v, 3);
+ }
+
+ pt_intr_post(v, intack);
+ }
else
{
HVMTRACE_2D(INJ_VIRQ, intack.vector, /*fake=*/ 0);
@@ -265,11 +322,16 @@ void vmx_intr_assist(void)
/* Is there another IRQ to queue up behind this one? */
intack = hvm_vcpu_has_pending_irq(v);
- if ( unlikely(intack.source != hvm_intsrc_none) )
- enable_intr_window(v, intack);
+ if ( !cpu_has_vmx_virtual_intr_delivery ||
+ intack.source == hvm_intsrc_pic ||
+ intack.source == hvm_intsrc_vector )
+ {
+ if ( unlikely(intack.source != hvm_intsrc_none) )
+ enable_intr_window(v, intack);
+ }
out:
- if ( cpu_has_vmx_tpr_shadow )
+ if ( !cpu_has_vmx_virtual_intr_delivery && cpu_has_vmx_tpr_shadow )
__vmwrite(TPR_THRESHOLD, tpr_threshold);
}
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
@@ -90,6 +90,7 @@ static void __init vmx_display_features(
P(cpu_has_vmx_msr_bitmap, "MSR direct-access bitmap");
P(cpu_has_vmx_unrestricted_guest, "Unrestricted Guest");
P(cpu_has_vmx_apic_reg_virt, "APIC Register Virtualization");
+ P(cpu_has_vmx_virtual_intr_delivery, "Virtual Interrupt Delivery");
#undef P
if ( !printed )
@@ -188,11 +189,12 @@ static int vmx_init_vmcs_config(void)
opt |= SECONDARY_EXEC_UNRESTRICTED_GUEST;
/*
- * "APIC Register Virtualization"
+ * "APIC Register Virtualization" and "Virtual Interrupt Delivery"
* can be set only when "use TPR shadow" is set
*/
if ( _vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW )
- opt |= SECONDARY_EXEC_APIC_REGISTER_VIRT;
+ opt |= SECONDARY_EXEC_APIC_REGISTER_VIRT |
+ SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY;
_vmx_secondary_exec_control = adjust_vmx_controls(
@@ -797,6 +799,22 @@ static int construct_vmcs(struct vcpu *v
__vmwrite(IO_BITMAP_A, virt_to_maddr((char *)hvm_io_bitmap + 0));
__vmwrite(IO_BITMAP_B, virt_to_maddr((char *)hvm_io_bitmap + PAGE_SIZE));
+ if ( cpu_has_vmx_virtual_intr_delivery )
+ {
+ /* EOI-exit bitmap */
+ v->arch.hvm_vmx.eoi_exit_bitmap[0] = (uint64_t)0;
+ v->arch.hvm_vmx.eoi_exit_bitmap[1] = (uint64_t)0;
+ v->arch.hvm_vmx.eoi_exit_bitmap[2] = (uint64_t)0;
+ v->arch.hvm_vmx.eoi_exit_bitmap[3] = (uint64_t)0;
+ __vmwrite(EOI_EXIT_BITMAP0, 0);
+ __vmwrite(EOI_EXIT_BITMAP1, 0);
+ __vmwrite(EOI_EXIT_BITMAP2, 0);
+ __vmwrite(EOI_EXIT_BITMAP3, 0);
+
+ /* Initialise Guest Interrupt Status (RVI and SVI) to 0 */
+ __vmwrite(GUEST_INTR_STATUS, 0);
+ }
+
/* Host data selectors. */
__vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS);
__vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS);
@@ -1037,6 +1055,30 @@ int vmx_add_host_load_msr(u32 msr)
return 0;
}
+void vmx_set_eoi_exit_bitmap(struct vcpu *v, u8 vector)
+{
+ int index, offset, changed;
+
+ index = vector >> 6;
+ offset = vector & 63;
+ changed = !test_and_set_bit(offset,
+ (uint64_t *)&v->arch.hvm_vmx.eoi_exit_bitmap[index]);
+ if (changed)
+ set_bit(index, &v->arch.hvm_vmx.eoi_exitmap_changed);
+}
+
+void vmx_clear_eoi_exit_bitmap(struct vcpu *v, u8 vector)
+{
+ int index, offset, changed;
+
+ index = vector >> 6;
+ offset = vector & 63;
+ changed = test_and_clear_bit(offset,
+ (uint64_t *)&v->arch.hvm_vmx.eoi_exit_bitmap[index]);
+ if (changed)
+ set_bit(index, &v->arch.hvm_vmx.eoi_exitmap_changed);
+}
+
int vmx_create_vmcs(struct vcpu *v)
{
struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
@@ -1572,6 +1572,22 @@ static void vmx_set_info_guest(struct vc
vmx_vmcs_exit(v);
}
+static void vmx_update_eoi_exit_bitmap(struct vcpu *v, u8 vector, u8 trig)
+{
+ if ( cpu_has_vmx_virtual_intr_delivery )
+ {
+ if (trig)
+ vmx_set_eoi_exit_bitmap(v, vector);
+ else
+ vmx_clear_eoi_exit_bitmap(v, vector);
+ }
+}
+
+static int vmx_virtual_intr_delivery_enabled(void)
+{
+ return cpu_has_vmx_virtual_intr_delivery;
+}
+
static struct hvm_function_table __read_mostly vmx_function_table = {
.name = "VMX",
.cpu_up_prepare = vmx_cpu_up_prepare,
@@ -1618,7 +1634,9 @@ static struct hvm_function_table __read_
.nhvm_vmcx_guest_intercepts_trap = nvmx_intercepts_exception,
.nhvm_vcpu_vmexit_trap = nvmx_vmexit_trap,
.nhvm_intr_blocked = nvmx_intr_blocked,
- .nhvm_domain_relinquish_resources = nvmx_domain_relinquish_resources
+ .nhvm_domain_relinquish_resources = nvmx_domain_relinquish_resources,
+ .update_eoi_exit_bitmap = vmx_update_eoi_exit_bitmap,
+ .virtual_intr_delivery_enabled = vmx_virtual_intr_delivery_enabled
};
struct hvm_function_table * __init start_vmx(void)
@@ -2366,6 +2384,17 @@ static int vmx_handle_apic_write(void)
return vlapic_apicv_write(current, offset);
}
+/*
+ * When "Virtual Interrupt Delivery" is enabled, this function is used
+ * to handle EOI-induced VM exit
+ */
+void vmx_handle_EOI_induced_exit(struct vlapic *vlapic, int vector)
+{
+ ASSERT(cpu_has_vmx_virtual_intr_delivery);
+
+ vlapic_handle_EOI_induced_exit(vlapic, vector);
+}
+
void vmx_vmexit_handler(struct cpu_user_regs *regs)
{
unsigned int exit_reason, idtv_info, intr_info = 0, vector = 0;
@@ -2766,6 +2795,16 @@ void vmx_vmexit_handler(struct cpu_user_
hvm_inject_hw_exception(TRAP_gp_fault, 0);
break;
+ case EXIT_REASON_EOI_INDUCED:
+ {
+ int vector;
+ exit_qualification = __vmread(EXIT_QUALIFICATION);
+ vector = exit_qualification & 0xff;
+
+ vmx_handle_EOI_induced_exit(vcpu_vlapic(current), vector);
+ break;
+ }
+
case EXIT_REASON_IO_INSTRUCTION:
exit_qualification = __vmread(EXIT_QUALIFICATION);
if ( exit_qualification & 0x10 )
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vpt.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vpt.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vpt.c
@@ -224,7 +224,7 @@ static void pt_timer_fn(void *data)
pt_unlock(pt);
}
-void pt_update_irq(struct vcpu *v)
+int pt_update_irq(struct vcpu *v)
{
struct list_head *head = &v->arch.hvm_vcpu.tm_list;
struct periodic_time *pt, *temp, *earliest_pt = NULL;
@@ -257,7 +257,7 @@ void pt_update_irq(struct vcpu *v)
if ( earliest_pt == NULL )
{
spin_unlock(&v->arch.hvm_vcpu.tm_lock);
- return;
+ return -1;
}
earliest_pt->irq_issued = 1;
@@ -275,6 +275,17 @@ void pt_update_irq(struct vcpu *v)
hvm_isa_irq_deassert(v->domain, irq);
hvm_isa_irq_assert(v->domain, irq);
}
+
+ /*
+ * If periodic timer interrut is handled by lapic, its vector in
+ * IRR is returned and used to set eoi_exit_bitmap for virtual
+ * interrupt delivery case. Otherwise return -1 to do nothing.
+ */
+ if ( vlapic_accept_pic_intr(v) &&
+ (&v->domain->arch.hvm_domain)->vpic[0].int_output )
+ return -1;
+ else
+ return pt_irq_vector(earliest_pt, hvm_intsrc_lapic);
}
static struct periodic_time *is_pt_irq(
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/hvm.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/hvm.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/hvm.h
@@ -180,6 +180,10 @@ struct hvm_function_table {
enum hvm_intblk (*nhvm_intr_blocked)(struct vcpu *v);
void (*nhvm_domain_relinquish_resources)(struct domain *d);
+
+ /* Virtual interrupt delivery */
+ void (*update_eoi_exit_bitmap)(struct vcpu *v, u8 vector, u8 trig);
+ int (*virtual_intr_delivery_enabled)(void);
};
extern struct hvm_function_table hvm_funcs;
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vlapic.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vlapic.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vlapic.h
@@ -100,6 +100,7 @@ int vlapic_accept_pic_intr(struct vcpu *
void vlapic_adjust_i8259_target(struct domain *d);
void vlapic_EOI_set(struct vlapic *vlapic);
+void vlapic_handle_EOI_induced_exit(struct vlapic *vlapic, int vector);
int vlapic_ipi(struct vlapic *vlapic, uint32_t icr_low, uint32_t icr_high);
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -110,6 +110,9 @@ struct arch_vmx_struct {
unsigned int host_msr_count;
struct vmx_msr_entry *host_msr_area;
+ uint32_t eoi_exitmap_changed;
+ uint64_t eoi_exit_bitmap[4];
+
unsigned long host_cr0;
/* Is the guest in real mode? */
@@ -184,6 +187,7 @@ extern u32 vmx_vmentry_control;
#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
#define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080
#define SECONDARY_EXEC_APIC_REGISTER_VIRT 0x00000100
+#define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY 0x00000200
#define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400
#define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000
extern u32 vmx_secondary_exec_control;
@@ -234,6 +238,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
(vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING)
#define cpu_has_vmx_apic_reg_virt \
(vmx_secondary_exec_control & SECONDARY_EXEC_APIC_REGISTER_VIRT)
+#define cpu_has_vmx_virtual_intr_delivery \
+ (vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY)
/* GUEST_INTERRUPTIBILITY_INFO flags. */
#define VMX_INTR_SHADOW_STI 0x00000001
@@ -252,6 +258,7 @@ enum vmcs_field {
GUEST_GS_SELECTOR = 0x0000080a,
GUEST_LDTR_SELECTOR = 0x0000080c,
GUEST_TR_SELECTOR = 0x0000080e,
+ GUEST_INTR_STATUS = 0x00000810,
HOST_ES_SELECTOR = 0x00000c00,
HOST_CS_SELECTOR = 0x00000c02,
HOST_SS_SELECTOR = 0x00000c04,
@@ -279,6 +286,14 @@ enum vmcs_field {
APIC_ACCESS_ADDR_HIGH = 0x00002015,
EPT_POINTER = 0x0000201a,
EPT_POINTER_HIGH = 0x0000201b,
+ EOI_EXIT_BITMAP0 = 0x0000201c,
+ EOI_EXIT_BITMAP0_HIGH = 0x0000201d,
+ EOI_EXIT_BITMAP1 = 0x0000201e,
+ EOI_EXIT_BITMAP1_HIGH = 0x0000201f,
+ EOI_EXIT_BITMAP2 = 0x00002020,
+ EOI_EXIT_BITMAP2_HIGH = 0x00002021,
+ EOI_EXIT_BITMAP3 = 0x00002022,
+ EOI_EXIT_BITMAP3_HIGH = 0x00002023,
GUEST_PHYSICAL_ADDRESS = 0x00002400,
GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401,
VMCS_LINK_POINTER = 0x00002800,
@@ -399,6 +414,8 @@ int vmx_write_guest_msr(u32 msr, u64 val
int vmx_add_guest_msr(u32 msr);
int vmx_add_host_load_msr(u32 msr);
void vmx_vmcs_switch(struct vmcs_struct *from, struct vmcs_struct *to);
+void vmx_set_eoi_exit_bitmap(struct vcpu *v, u8 vector);
+void vmx_clear_eoi_exit_bitmap(struct vcpu *v, u8 vector);
#endif /* ASM_X86_HVM_VMX_VMCS_H__ */
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmx.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmx.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -119,6 +119,7 @@ void vmx_update_cpu_exec_control(struct
#define EXIT_REASON_MCE_DURING_VMENTRY 41
#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
#define EXIT_REASON_APIC_ACCESS 44
+#define EXIT_REASON_EOI_INDUCED 45
#define EXIT_REASON_ACCESS_GDTR_OR_IDTR 46
#define EXIT_REASON_ACCESS_LDTR_OR_TR 47
#define EXIT_REASON_EPT_VIOLATION 48
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vpt.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vpt.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vpt.h
@@ -141,7 +141,7 @@ struct pl_time { /* platform time */
void pt_save_timer(struct vcpu *v);
void pt_restore_timer(struct vcpu *v);
-void pt_update_irq(struct vcpu *v);
+int pt_update_irq(struct vcpu *v);
void pt_intr_post(struct vcpu *v, struct hvm_intack intack);
void pt_migrate(struct vcpu *v);
++++++ 25922-x86-APICV-x2APIC.patch ++++++
References: FATE#313605
# HG changeset patch
# User Jiongxi Li
# Date 1347912362 -3600
# Node ID c2578dd96b8318e108fff0f340411135dedaa47d
# Parent 713b8849b11afa05f1dde157a3f5086fa3aaad08
xen: add virtual x2apic support for apicv
basically to benefit from apicv, we need clear MSR bitmap for
corresponding x2apic MSRs:
0x800 - 0x8ff: no read intercept for apicv register virtualization
TPR,EOI,SELF-IPI: no write intercept for virtual interrupt
delivery
Signed-off-by: Jiongxi Li
Committed-by: Keir Fraser
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -667,7 +667,7 @@ static void vmx_set_host_env(struct vcpu
(unsigned long)&get_cpu_info()->guest_cpu_user_regs.error_code);
}
-void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr)
+void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr, int type)
{
unsigned long *msr_bitmap = v->arch.hvm_vmx.msr_bitmap;
@@ -682,14 +682,18 @@ void vmx_disable_intercept_for_msr(struc
*/
if ( msr <= 0x1fff )
{
- __clear_bit(msr, msr_bitmap + 0x000/BYTES_PER_LONG); /* read-low */
- __clear_bit(msr, msr_bitmap + 0x800/BYTES_PER_LONG); /* write-low */
+ if (type & MSR_TYPE_R)
+ __clear_bit(msr, msr_bitmap + 0x000/BYTES_PER_LONG); /* read-low */
+ if (type & MSR_TYPE_W)
+ __clear_bit(msr, msr_bitmap + 0x800/BYTES_PER_LONG); /* write-low */
}
else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
{
msr &= 0x1fff;
- __clear_bit(msr, msr_bitmap + 0x400/BYTES_PER_LONG); /* read-high */
- __clear_bit(msr, msr_bitmap + 0xc00/BYTES_PER_LONG); /* write-high */
+ if (type & MSR_TYPE_R)
+ __clear_bit(msr, msr_bitmap + 0x400/BYTES_PER_LONG); /* read-high */
+ if (type & MSR_TYPE_W)
+ __clear_bit(msr, msr_bitmap + 0xc00/BYTES_PER_LONG); /* write-high */
}
}
@@ -785,14 +789,26 @@ static int construct_vmcs(struct vcpu *v
v->arch.hvm_vmx.msr_bitmap = msr_bitmap;
__vmwrite(MSR_BITMAP, virt_to_maddr(msr_bitmap));
- vmx_disable_intercept_for_msr(v, MSR_FS_BASE);
- vmx_disable_intercept_for_msr(v, MSR_GS_BASE);
- vmx_disable_intercept_for_msr(v, MSR_SHADOW_GS_BASE);
- vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_CS);
- vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_ESP);
- vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_EIP);
+ vmx_disable_intercept_for_msr(v, MSR_FS_BASE, MSR_TYPE_R | MSR_TYPE_W);
+ vmx_disable_intercept_for_msr(v, MSR_GS_BASE, MSR_TYPE_R | MSR_TYPE_W);
+ vmx_disable_intercept_for_msr(v, MSR_SHADOW_GS_BASE, MSR_TYPE_R | MSR_TYPE_W);
+ vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_CS, MSR_TYPE_R | MSR_TYPE_W);
+ vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_ESP, MSR_TYPE_R | MSR_TYPE_W);
+ vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_EIP, MSR_TYPE_R | MSR_TYPE_W);
if ( paging_mode_hap(d) && (!iommu_enabled || iommu_snoop) )
- vmx_disable_intercept_for_msr(v, MSR_IA32_CR_PAT);
+ vmx_disable_intercept_for_msr(v, MSR_IA32_CR_PAT, MSR_TYPE_R | MSR_TYPE_W);
+ if ( cpu_has_vmx_apic_reg_virt )
+ {
+ int msr;
+ for (msr = MSR_IA32_APICBASE_MSR; msr <= MSR_IA32_APICBASE_MSR + 0xff; msr++)
+ vmx_disable_intercept_for_msr(v, msr, MSR_TYPE_R);
+ }
+ if ( cpu_has_vmx_virtual_intr_delivery )
+ {
+ vmx_disable_intercept_for_msr(v, MSR_IA32_APICTPR_MSR, MSR_TYPE_W);
+ vmx_disable_intercept_for_msr(v, MSR_IA32_APICEOI_MSR, MSR_TYPE_W);
+ vmx_disable_intercept_for_msr(v, MSR_IA32_APICSELF_MSR, MSR_TYPE_W);
+ }
}
/* I/O access bitmap. */
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2112,7 +2112,7 @@ static int vmx_msr_write_intercept(unsig
for ( ; (rc == 0) && lbr->count; lbr++ )
for ( i = 0; (rc == 0) && (i < lbr->count); i++ )
if ( (rc = vmx_add_guest_msr(lbr->base + i)) == 0 )
- vmx_disable_intercept_for_msr(v, lbr->base + i);
+ vmx_disable_intercept_for_msr(v, lbr->base + i, MSR_TYPE_R | MSR_TYPE_W);
}
if ( (rc < 0) ||
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -408,7 +408,9 @@ enum vmcs_field {
#define VMCS_VPID_WIDTH 16
-void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr);
+#define MSR_TYPE_R 1
+#define MSR_TYPE_W 2
+void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr, int type);
int vmx_read_guest_msr(u32 msr, u64 *val);
int vmx_write_guest_msr(u32 msr, u64 val);
int vmx_add_guest_msr(u32 msr);
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -294,6 +294,9 @@
#define MSR_IA32_APICBASE_ENABLE (1<<11)
#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
#define MSR_IA32_APICBASE_MSR 0x800
+#define MSR_IA32_APICTPR_MSR 0x808
+#define MSR_IA32_APICEOI_MSR 0x80b
+#define MSR_IA32_APICSELF_MSR 0x83f
#define MSR_IA32_UCODE_WRITE 0x00000079
#define MSR_IA32_UCODE_REV 0x0000008b
++++++ 25957-x86-TSC-adjust-HVM.patch ++++++
References: FATE#313633
# HG changeset patch
# User Liu, Jinsong
# Date 1348654362 -7200
# Node ID c47ef9592fb39325e33f8406b4bd736cc84482e5
# Parent 5d63c633a60b9a1d695594f9c17cf933240bec81
x86: Implement TSC adjust feature for HVM guest
IA32_TSC_ADJUST MSR is maintained separately for each logical
processor. A logical processor maintains and uses the IA32_TSC_ADJUST
MSR as follows:
1). On RESET, the value of the IA32_TSC_ADJUST MSR is 0;
2). If an execution of WRMSR to the IA32_TIME_STAMP_COUNTER MSR adds
(or subtracts) value X from the TSC, the logical processor also
adds (or subtracts) value X from the IA32_TSC_ADJUST MSR;
3). If an execution of WRMSR to the IA32_TSC_ADJUST MSR adds (or
subtracts) value X from that MSR, the logical processor also adds
(or subtracts) value X from the TSC.
This patch provides tsc adjust support for hvm guest, with it guest OS
would be happy when sync tsc.
Signed-off-by: Liu, Jinsong
Committed-by: Jan Beulich
Index: xen-4.2.4-testing/xen/arch/x86/hvm/hvm.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/hvm.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/hvm.c
@@ -245,6 +245,7 @@ int hvm_set_guest_pat(struct vcpu *v, u6
void hvm_set_guest_tsc(struct vcpu *v, u64 guest_tsc)
{
uint64_t tsc;
+ uint64_t delta_tsc;
if ( v->domain->arch.vtsc )
{
@@ -256,10 +257,22 @@ void hvm_set_guest_tsc(struct vcpu *v, u
rdtscll(tsc);
}
- v->arch.hvm_vcpu.cache_tsc_offset = guest_tsc - tsc;
+ delta_tsc = guest_tsc - tsc;
+ v->arch.hvm_vcpu.msr_tsc_adjust += delta_tsc
+ - v->arch.hvm_vcpu.cache_tsc_offset;
+ v->arch.hvm_vcpu.cache_tsc_offset = delta_tsc;
+
hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset);
}
+void hvm_set_guest_tsc_adjust(struct vcpu *v, u64 tsc_adjust)
+{
+ v->arch.hvm_vcpu.cache_tsc_offset += tsc_adjust
+ - v->arch.hvm_vcpu.msr_tsc_adjust;
+ hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset);
+ v->arch.hvm_vcpu.msr_tsc_adjust = tsc_adjust;
+}
+
u64 hvm_get_guest_tsc(struct vcpu *v)
{
uint64_t tsc;
@@ -278,6 +291,11 @@ u64 hvm_get_guest_tsc(struct vcpu *v)
return tsc + v->arch.hvm_vcpu.cache_tsc_offset;
}
+u64 hvm_get_guest_tsc_adjust(struct vcpu *v)
+{
+ return v->arch.hvm_vcpu.msr_tsc_adjust;
+}
+
void hvm_migrate_timers(struct vcpu *v)
{
rtc_migrate_timers(v);
@@ -2852,6 +2870,10 @@ int hvm_msr_read_intercept(unsigned int
*msr_content = hvm_get_guest_tsc(v);
break;
+ case MSR_IA32_TSC_ADJUST:
+ *msr_content = hvm_get_guest_tsc_adjust(v);
+ break;
+
case MSR_TSC_AUX:
*msr_content = hvm_msr_tsc_aux(v);
break;
@@ -2965,6 +2987,10 @@ int hvm_msr_write_intercept(unsigned int
hvm_set_guest_tsc(v, msr_content);
break;
+ case MSR_IA32_TSC_ADJUST:
+ hvm_set_guest_tsc_adjust(v, msr_content);
+ break;
+
case MSR_TSC_AUX:
v->arch.hvm_vcpu.msr_tsc_aux = (uint32_t)msr_content;
if ( cpu_has_rdtscp
@@ -3531,6 +3557,8 @@ void hvm_vcpu_reset_state(struct vcpu *v
v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset;
hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset);
+ v->arch.hvm_vcpu.msr_tsc_adjust = 0;
+
paging_update_paging_modes(v);
v->arch.flags |= TF_kernel_mode;
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vcpu.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vcpu.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vcpu.h
@@ -139,6 +139,7 @@ struct hvm_vcpu {
struct hvm_vcpu_asid n1asid;
u32 msr_tsc_aux;
+ u64 msr_tsc_adjust;
/* VPMU */
struct vpmu_struct vpmu;
Index: xen-4.2.4-testing/xen/include/asm-x86/msr-index.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/msr-index.h
+++ xen-4.2.4-testing/xen/include/asm-x86/msr-index.h
@@ -287,6 +287,7 @@
#define MSR_IA32_PLATFORM_ID 0x00000017
#define MSR_IA32_EBL_CR_POWERON 0x0000002a
#define MSR_IA32_EBC_FREQUENCY_ID 0x0000002c
+#define MSR_IA32_TSC_ADJUST 0x0000003b
#define MSR_IA32_APICBASE 0x0000001b
#define MSR_IA32_APICBASE_BSP (1<<8)
++++++ 25958-x86-TSC-adjust-sr.patch ++++++
References: FATE#313633
# HG changeset patch
# User Liu, Jinsong
# Date 1348654418 -7200
# Node ID 56fb977ce6eb4626a02d4a7a34e85009bb8ee3e0
# Parent c47ef9592fb39325e33f8406b4bd736cc84482e5
x86: Save/restore TSC adjust during HVM guest migration
Signed-off-by: Liu, Jinsong
Committed-by: Jan Beulich
Index: xen-4.2.4-testing/tools/misc/xen-hvmctx.c
===================================================================
--- xen-4.2.4-testing.orig/tools/misc/xen-hvmctx.c
+++ xen-4.2.4-testing/tools/misc/xen-hvmctx.c
@@ -390,6 +390,13 @@ static void dump_vmce_vcpu(void)
printf(" VMCE_VCPU: caps %" PRIx64 "\n", p.caps);
}
+static void dump_tsc_adjust(void)
+{
+ HVM_SAVE_TYPE(TSC_ADJUST) p;
+ READ(p);
+ printf(" TSC_ADJUST: tsc_adjust %" PRIx64 "\n", p.tsc_adjust);
+}
+
int main(int argc, char **argv)
{
int entry, domid;
@@ -457,6 +464,7 @@ int main(int argc, char **argv)
case HVM_SAVE_CODE(VIRIDIAN_DOMAIN): dump_viridian_domain(); break;
case HVM_SAVE_CODE(VIRIDIAN_VCPU): dump_viridian_vcpu(); break;
case HVM_SAVE_CODE(VMCE_VCPU): dump_vmce_vcpu(); break;
+ case HVM_SAVE_CODE(TSC_ADJUST): dump_tsc_adjust(); break;
case HVM_SAVE_CODE(END): break;
default:
printf(" ** Don't understand type %u: skipping\n",
Index: xen-4.2.4-testing/xen/arch/x86/hvm/hvm.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/hvm.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/hvm.c
@@ -611,6 +611,46 @@ void hvm_domain_destroy(struct domain *d
hvm_destroy_cacheattr_region_list(d);
}
+static int hvm_save_tsc_adjust(struct domain *d, hvm_domain_context_t *h)
+{
+ struct vcpu *v;
+ struct hvm_tsc_adjust ctxt;
+ int err = 0;
+
+ for_each_vcpu ( d, v )
+ {
+ ctxt.tsc_adjust = v->arch.hvm_vcpu.msr_tsc_adjust;
+ err = hvm_save_entry(TSC_ADJUST, v->vcpu_id, h, &ctxt);
+ if ( err )
+ break;
+ }
+
+ return err;
+}
+
+static int hvm_load_tsc_adjust(struct domain *d, hvm_domain_context_t *h)
+{
+ unsigned int vcpuid = hvm_load_instance(h);
+ struct vcpu *v;
+ struct hvm_tsc_adjust ctxt;
+
+ if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
+ {
+ dprintk(XENLOG_G_ERR, "HVM restore: dom%d has no vcpu%u\n",
+ d->domain_id, vcpuid);
+ return -EINVAL;
+ }
+
+ if ( hvm_load_entry(TSC_ADJUST, h, &ctxt) != 0 )
+ return -EINVAL;
+
+ v->arch.hvm_vcpu.msr_tsc_adjust = ctxt.tsc_adjust;
+ return 0;
+}
+
+HVM_REGISTER_SAVE_RESTORE(TSC_ADJUST, hvm_save_tsc_adjust,
+ hvm_load_tsc_adjust, 1, HVMSR_PER_VCPU);
+
static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
{
struct vcpu *v;
Index: xen-4.2.4-testing/xen/include/public/arch-x86/hvm/save.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/public/arch-x86/hvm/save.h
+++ xen-4.2.4-testing/xen/include/public/arch-x86/hvm/save.h
@@ -581,9 +581,15 @@ struct hvm_vmce_vcpu {
DECLARE_HVM_SAVE_TYPE(VMCE_VCPU, 18, struct hvm_vmce_vcpu);
+struct hvm_tsc_adjust {
+ uint64_t tsc_adjust;
+};
+
+DECLARE_HVM_SAVE_TYPE(TSC_ADJUST, 19, struct hvm_tsc_adjust);
+
/*
* Largest type-code in use
*/
-#define HVM_SAVE_CODE_MAX 18
+#define HVM_SAVE_CODE_MAX 19
#endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */
++++++ 25959-x86-TSC-adjust-expose.patch ++++++
References: FATE#313633
# HG changeset patch
# User Liu, Jinsong
# Date 1348654470 -7200
# Node ID 3aa66543a51ba77cb73e8c874e2416d065426a22
# Parent 56fb977ce6eb4626a02d4a7a34e85009bb8ee3e0
x86: Expose TSC adjust to HVM guest
Intel latest SDM (17.13.3) release a new MSR CPUID.7.0.EBX[1]=1
indicates TSC_ADJUST MSR 0x3b is supported.
This patch expose it to hvm guest.
Signed-off-by: Liu, Jinsong
Committed-by: Jan Beulich
Index: xen-4.2.4-testing/tools/libxc/xc_cpufeature.h
===================================================================
--- xen-4.2.4-testing.orig/tools/libxc/xc_cpufeature.h
+++ xen-4.2.4-testing/tools/libxc/xc_cpufeature.h
@@ -128,6 +128,7 @@
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx) */
#define X86_FEATURE_FSGSBASE 0 /* {RD,WR}{FS,GS}BASE instructions */
+#define X86_FEATURE_TSC_ADJUST 1 /* Tsc thread offset */
#define X86_FEATURE_BMI1 3 /* 1st group bit manipulation extensions */
#define X86_FEATURE_HLE 4 /* Hardware Lock Elision */
#define X86_FEATURE_AVX2 5 /* AVX2 instructions */
Index: xen-4.2.4-testing/tools/libxc/xc_cpuid_x86.c
===================================================================
--- xen-4.2.4-testing.orig/tools/libxc/xc_cpuid_x86.c
+++ xen-4.2.4-testing/tools/libxc/xc_cpuid_x86.c
@@ -362,7 +362,8 @@ static void xc_cpuid_hvm_policy(
case 0x00000007: /* Intel-defined CPU features */
if ( input[1] == 0 ) {
- regs[1] &= (bitmaskof(X86_FEATURE_BMI1) |
+ regs[1] &= (bitmaskof(X86_FEATURE_TSC_ADJUST) |
+ bitmaskof(X86_FEATURE_BMI1) |
bitmaskof(X86_FEATURE_HLE) |
bitmaskof(X86_FEATURE_AVX2) |
bitmaskof(X86_FEATURE_SMEP) |
++++++ 26077-stubdom_fix_compile_errors_in_grub.patch ++++++
changeset: 26077:33348baecf37
user: Olaf Hering
date: Thu Oct 18 09:34:59 2012 +0100
files: stubdom/grub.patches/70compiler_warnings.diff
description:
stubdom: fix compile errors in grub
Building xen.rpm in SLES11 started to fail due to these compiler
warnings:
[ 1436s] ../grub-upstream/netboot/fsys_tftp.c:213: warning: operation on 'block' may be undefined
[ 1437s] ../grub-upstream/netboot/main.c:444: warning: operation on 'block' may be undefined
[ 1234s] E: xen sequence-point ../grub-upstream/netboot/fsys_tftp.c:213
[ 1234s] E: xen sequence-point ../grub-upstream/netboot/main.c:444
The reason for this is that the assignment is done twice:
tp.u.ack.block = ((uint16_t)( (((uint16_t)((block = prevblock)) & (uint16_t)0x00ffU) << 8) | (((uint16_t)((block = prevblock)) & (uint16_t)0xff00U) >> 8)));
Fix this package build error by adding another patch for grub, which
moves the assignment out of the macro usage.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r 8dcab28b8081 -r 33348baecf37 stubdom/grub.patches/70compiler_warnings.diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub.patches/70compiler_warnings.diff Thu Oct 18 09:34:59 2012 +0100
@@ -0,0 +1,45 @@
+[ 1436s] ../grub-upstream/netboot/fsys_tftp.c:213: warning: operation on 'block' may be undefined
+[ 1437s] ../grub-upstream/netboot/main.c:444: warning: operation on 'block' may be undefined
+
+[ 1234s] E: xen sequence-point ../grub-upstream/netboot/fsys_tftp.c:213
+[ 1234s] E: xen sequence-point ../grub-upstream/netboot/main.c:444
+
+---
+ netboot/fsys_tftp.c | 5 ++++-
+ netboot/main.c | 5 ++++-
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+Index: grub-0.97/netboot/fsys_tftp.c
+===================================================================
+--- grub-0.97.orig/netboot/fsys_tftp.c
++++ grub-0.97/netboot/fsys_tftp.c
+@@ -209,8 +209,11 @@ buf_fill (int abort)
+ break;
+
+ if ((block || bcounter) && (block != prevblock + (unsigned short) 1))
++ {
++ block = prevblock;
+ /* Block order should be continuous */
+- tp.u.ack.block = htons (block = prevblock);
++ tp.u.ack.block = htons (block);
++ }
+
+ /* Should be continuous. */
+ tp.opcode = abort ? htons (TFTP_ERROR) : htons (TFTP_ACK);
+Index: grub-0.97/netboot/main.c
+===================================================================
+--- grub-0.97.orig/netboot/main.c
++++ grub-0.97/netboot/main.c
+@@ -440,8 +440,11 @@ tftp (const char *name, int (*fnc) (unsi
+ break;
+
+ if ((block || bcounter) && (block != prevblock + 1))
++ {
++ block = prevblock;
+ /* Block order should be continuous */
+- tp.u.ack.block = htons (block = prevblock);
++ tp.u.ack.block = htons (block);
++ }
+
+ /* Should be continuous. */
+ tp.opcode = htons (TFTP_ACK);
++++++ 26078-hotplug-Linux_remove_hotplug_support_rely_on_udev_instead.patch ++++++
changeset: 26078:019ca95dfa34
user: Olaf Hering
date: Thu Oct 18 09:35:00 2012 +0100
files: Makefile README install.sh tools/hotplug/Linux/Makefile tools/hotplug/Linux/xen-backend.agent
description:
hotplug/Linux: remove hotplug support, rely on udev instead
Hotplug has been replaced by udev since several years. Remove the
hotplug related files and install udev unconditionally.
This makes it possible to remove udev from rpm BuildRequires which
reduces the buildtime dependency chain. For openSuSE:Factory it was
done just now:
http://lists.opensuse.org/opensuse-buildservice/2012-10/msg00085.html
The patch by itself will have no practical impact unless someone
attempts to build and run a Xen dom0 on a really old base system. e.g.
circa SLES9/2007 or earlier
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r 33348baecf37 -r 019ca95dfa34 Makefile
--- a/Makefile Thu Oct 18 09:34:59 2012 +0100
+++ b/Makefile Thu Oct 18 09:35:00 2012 +0100
@@ -223,7 +223,6 @@ uninstall:
$(MAKE) -C xen uninstall
rm -rf $(D)$(CONFIG_DIR)/init.d/xendomains $(D)$(CONFIG_DIR)/init.d/xend
rm -rf $(D)$(CONFIG_DIR)/init.d/xencommons $(D)$(CONFIG_DIR)/init.d/xen-watchdog
- rm -rf $(D)$(CONFIG_DIR)/hotplug/xen-backend.agent
rm -f $(D)$(CONFIG_DIR)/udev/rules.d/xen-backend.rules
rm -f $(D)$(CONFIG_DIR)/udev/rules.d/xend.rules
rm -f $(D)$(SYSCONFIG_DIR)/xendomains
diff -r 33348baecf37 -r 019ca95dfa34 README
--- a/README Thu Oct 18 09:34:59 2012 +0100
+++ b/README Thu Oct 18 09:35:00 2012 +0100
@@ -54,7 +54,7 @@ provided by your OS distributor:
* pkg-config
* bridge-utils package (/sbin/brctl)
* iproute package (/sbin/ip)
- * hotplug or udev
+ * udev
* GNU bison and GNU flex
* GNU gettext
* 16-bit x86 assembler, loader and compiler (dev86 rpm or bin86 & bcc debs)
@@ -120,9 +120,9 @@ 4. To rebuild an existing tree without m
make install and make dist differ in that make install does the
right things for your local machine (installing the appropriate
- version of hotplug or udev scripts, for example), but make dist
- includes all versions of those scripts, so that you can copy the dist
- directory to another machine and install from that distribution.
+ version of udev scripts, for example), but make dist includes all
+ versions of those scripts, so that you can copy the dist directory
+ to another machine and install from that distribution.
Python Runtime Libraries
========================
diff -r 33348baecf37 -r 019ca95dfa34 install.sh
--- a/install.sh Thu Oct 18 09:34:59 2012 +0100
+++ b/install.sh Thu Oct 18 09:35:00 2012 +0100
@@ -27,20 +27,6 @@ echo "Installing Xen from '$src' to '$ds
echo "Installing Xen from '$src' to '$dst'..."
(cd $src; tar -cf - * ) | tar -C "$tmp" -xf -
-[ -x "$(which udevinfo)" ] && \
- UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
-
-[ -z "$UDEV_VERSION" -a -x /sbin/udevadm ] && \
- UDEV_VERSION=$(/sbin/udevadm info -V | awk '{print $NF}')
-
-if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -ge 059 ]; then
- echo " - installing for udev-based system"
- rm -rf "$tmp/etc/hotplug"
-else
- echo " - installing for hotplug-based system"
- rm -rf "$tmp/etc/udev"
-fi
-
echo " - modifying permissions"
chmod -R a+rX "$tmp"
diff -r 33348baecf37 -r 019ca95dfa34 tools/hotplug/Linux/Makefile
--- a/tools/hotplug/Linux/Makefile Thu Oct 18 09:34:59 2012 +0100
+++ b/tools/hotplug/Linux/Makefile Thu Oct 18 09:35:00 2012 +0100
@@ -27,31 +27,8 @@ XEN_SCRIPT_DATA += block-common.sh vtpm-
XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh
XEN_SCRIPT_DATA += vtpm-migration.sh vtpm-impl
-XEN_HOTPLUG_DIR = $(CONFIG_DIR)/hotplug
-XEN_HOTPLUG_SCRIPTS = xen-backend.agent
-
-UDEVVER = 0
-ifeq ($(shell [ -x /sbin/udevadm ] && echo 1),1)
-UDEVVER = $(shell /sbin/udevadm info -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/' )
-endif
-ifeq ($(shell [ -x /usr/bin/udevinfo ] && echo 1),1)
-UDEVVER = $(shell /usr/bin/udevinfo -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/' )
-endif
-
UDEV_RULES_DIR = $(CONFIG_DIR)/udev
UDEV_RULES = xen-backend.rules xend.rules
-
-DI = $(if $(DISTDIR),$(shell readlink -f $(DISTDIR)),)
-DE = $(if $(DESTDIR),$(shell readlink -f $(DESTDIR)),)
-ifeq ($(findstring $(DI),$(DE)),$(DI))
-HOTPLUGS=install-hotplug install-udev
-else
-ifeq ($(shell [ $(UDEVVER) -ge 059 ] && echo 1),1)
-HOTPLUGS=install-udev
-else
-HOTPLUGS=install-hotplug
-endif
-endif
.PHONY: all
all:
@@ -60,7 +37,7 @@ build:
build:
.PHONY: install
-install: all install-initd install-scripts $(HOTPLUGS)
+install: all install-initd install-scripts install-udev
# See docs/misc/distro_mapping.txt for INITD_DIR location
.PHONY: install-initd
@@ -87,15 +64,6 @@ install-scripts:
$(INSTALL_DATA) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
done
-.PHONY: install-hotplug
-install-hotplug:
- [ -d $(DESTDIR)$(XEN_HOTPLUG_DIR) ] || \
- $(INSTALL_DIR) $(DESTDIR)$(XEN_HOTPLUG_DIR)
- set -e; for i in $(XEN_HOTPLUG_SCRIPTS); \
- do \
- $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_HOTPLUG_DIR); \
- done
-
.PHONY: install-udev
install-udev:
[ -d $(DESTDIR)$(UDEV_RULES_DIR) ] || \
diff -r 33348baecf37 -r 019ca95dfa34 tools/hotplug/Linux/xen-backend.agent
--- a/tools/hotplug/Linux/xen-backend.agent Thu Oct 18 09:34:59 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-#! /bin/bash
-
-PATH=/etc/xen/scripts:$PATH
-
-. /etc/xen/scripts/locking.sh
-
-claim_lock xenbus_hotplug_global
-
-case "$XENBUS_TYPE" in
- tap)
- /etc/xen/scripts/blktap "$ACTION"
- ;;
- vbd)
- /etc/xen/scripts/block "$ACTION"
- ;;
- vtpm)
- /etc/xen/scripts/vtpm "$ACTION"
- ;;
- vif)
- [ -n "$script" ] && $script "$ACTION"
- ;;
- vscsi)
- /etc/xen/scripts/vscsi "$ACTION"
- ;;
-esac
-
-case "$ACTION" in
- add)
- ;;
- remove)
- /etc/xen/scripts/xen-hotplug-cleanup
- ;;
- online)
- ;;
- offline)
- ;;
-esac
-
-release_lock xenbus_hotplug_global
++++++ 26079-hotplug-Linux_close_lockfd_after_lock_attempt.patch ++++++
changeset: 26079:b3b03536789a
user: Olaf Hering
date: Thu Oct 18 09:35:01 2012 +0100
files: tools/hotplug/Linux/locking.sh
description:
hotplug/Linux: close lockfd after lock attempt
When a HVM guest is shutdown some of the 'remove' events can not claim
the lock for some reason. Instead they try to grab the lock in a busy
loop, until udev reaps the xen-hotplug-cleanup helper.
After analyzing the resulting logfile its not obvious what the cause is.
The only explanation is that bash (?) gets confused if the same lockfd
is opened again and again. Closing it in each iteration seem to fix the
issue.
This was observed with sles11sp2 (bash 3.2) and 4.2 xend.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
[ ijc -- added the comment ]
Committed-by: Ian Campbell
diff -r 019ca95dfa34 -r b3b03536789a tools/hotplug/Linux/locking.sh
--- a/tools/hotplug/Linux/locking.sh Thu Oct 18 09:35:00 2012 +0100
+++ b/tools/hotplug/Linux/locking.sh Thu Oct 18 09:35:01 2012 +0100
@@ -59,6 +59,9 @@ claim_lock()
print "y\n" if $fd_inum eq $file_inum;
' "$_lockfile" )
if [ x$rightfile = xy ]; then break; fi
+ # Some versions of bash appear to be buggy if the same
+ # $_lockfile is opened repeatedly. Close the current fd here.
+ eval "exec $_lockfd<&-"
done
}
++++++ 26081-stubdom_fix_rpmlint_warning_spurious-executable-perm.patch ++++++
changeset: 26081:02064298ebcb
user: Olaf Hering
date: Thu Oct 18 09:35:03 2012 +0100
files: stubdom/Makefile
description:
stubdom: fix rpmlint warning spurious-executable-perm
[ 1758s] xen-tools.x86_64: E: spurious-executable-perm (Badness: 50) /usr/lib/xen/boot/xenstore-stubdom.gz
[ 1758s] The file is installed with executable permissions, but was identified as one
[ 1758s] that probably should not be executable. Verify if the executable bits are
[ 1758s] desired, and remove if not. NOTE: example scripts should be packaged under
[ 1758s] %docdir/examples, which will avoid this warning.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
Index: xen-4.2.3-testing/stubdom/Makefile
===================================================================
--- xen-4.2.3-testing.orig/stubdom/Makefile
+++ xen-4.2.3-testing/stubdom/Makefile
@@ -391,7 +391,7 @@ install-grub: pv-grub
install-xenstore: xenstore-stubdom
$(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot"
- $(INSTALL_PROG) mini-os-$(XEN_TARGET_ARCH)-xenstore/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/xenstore-stubdom.gz"
+ $(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-xenstore/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/xenstore-stubdom.gz"
#######
# clean
++++++ 26082-blktap2-libvhd_fix_rpmlint_warning_spurious-executable-perm.patch ++++++
changeset: 26082:8cf26ace9ca0
user: Olaf Hering
date: Thu Oct 18 09:35:03 2012 +0100
files: tools/blktap2/vhd/lib/Makefile
description:
blktap2/libvhd: fix rpmlint warning spurious-executable-perm
[ 1758s] xen-devel.x86_64: E: spurious-executable-perm (Badness: 50) /usr/lib64/libvhd.a
[ 1758s] The file is installed with executable permissions, but was identified as one
[ 1758s] that probably should not be executable. Verify if the executable bits are
[ 1758s] desired, and remove if not. NOTE: example scripts should be packaged under
[ 1758s] %docdir/examples, which will avoid this warning.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r 02064298ebcb -r 8cf26ace9ca0 tools/blktap2/vhd/lib/Makefile
--- a/tools/blktap2/vhd/lib/Makefile Thu Oct 18 09:35:03 2012 +0100
+++ b/tools/blktap2/vhd/lib/Makefile Thu Oct 18 09:35:03 2012 +0100
@@ -68,7 +68,7 @@ libvhd.so.$(LIBVHD-MAJOR).$(LIBVHD-MINOR
install: all
$(INSTALL_DIR) -p $(DESTDIR)$(INST-DIR)
- $(INSTALL_PROG) libvhd.a $(DESTDIR)$(INST-DIR)
+ $(INSTALL_DATA) libvhd.a $(DESTDIR)$(INST-DIR)
$(INSTALL_PROG) libvhd.so.$(LIBVHD-MAJOR).$(LIBVHD-MINOR) $(DESTDIR)$(INST-DIR)
ln -sf libvhd.so.$(LIBVHD-MAJOR).$(LIBVHD-MINOR) $(DESTDIR)$(INST-DIR)/libvhd.so.$(LIBVHD-MAJOR)
ln -sf libvhd.so.$(LIBVHD-MAJOR) $(DESTDIR)$(INST-DIR)/libvhd.so
++++++ 26083-blktap_fix_rpmlint_warning_spurious-executable-perm.patch ++++++
changeset: 26083:3fbeb019d522
user: Olaf Hering
date: Thu Oct 18 09:35:04 2012 +0100
files: tools/blktap/lib/Makefile
description:
blktap: fix rpmlint warning spurious-executable-perm
[ 1758s] xen-devel.x86_64: E: spurious-executable-perm (Badness: 50) /usr/lib64/libblktap.a
[ 1758s] The file is installed with executable permissions, but was identified as one
[ 1758s] that probably should not be executable. Verify if the executable bits are
[ 1758s] desired, and remove if not. NOTE: example scripts should be packaged under
[ 1758s] %docdir/examples, which will avoid this warning.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r 8cf26ace9ca0 -r 3fbeb019d522 tools/blktap/lib/Makefile
--- a/tools/blktap/lib/Makefile Thu Oct 18 09:35:03 2012 +0100
+++ b/tools/blktap/lib/Makefile Thu Oct 18 09:35:04 2012 +0100
@@ -23,23 +23,25 @@ OBJS_PIC = $(SRCS:.c=.opic)
OBJS_PIC = $(SRCS:.c=.opic)
IBINS :=
-LIB = libblktap.a libblktap.so.$(MAJOR).$(MINOR)
+LIB = libblktap.a
+LIB_SO = libblktap.so.$(MAJOR).$(MINOR)
.PHONY: all
-all: $(LIB)
+all: $(LIB) $(LIB_SO)
.PHONY: install
install: all
$(INSTALL_DIR) $(DESTDIR)$(LIBDIR)
$(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)
- $(INSTALL_PROG) $(LIB) $(DESTDIR)$(LIBDIR)
+ $(INSTALL_PROG) $(LIB_SO) $(DESTDIR)$(LIBDIR)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(LIBDIR)
ln -sf libblktap.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libblktap.so.$(MAJOR)
ln -sf libblktap.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libblktap.so
$(INSTALL_DATA) blktaplib.h $(DESTDIR)$(INCLUDEDIR)
.PHONY: clean
clean:
- rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen TAGS
+ rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) $(LIB_SO) *~ $(DEPS) xen TAGS
libblktap.so.$(MAJOR).$(MINOR): $(OBJS_PIC)
$(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,$(SONAME) $(SHLIB_LDFLAGS) \
++++++ 26084-hotplug_install_hotplugpath.sh_as_data_file.patch ++++++
changeset: 26084:fe9a0eb9aaaa
user: Olaf Hering
date: Thu Oct 18 09:35:05 2012 +0100
files: tools/hotplug/common/Makefile
description:
hotplug: install hotplugpath.sh as data file
rpmlint complains a script helper which is only sourced:
[ 1875s] xen-tools.i586: W: script-without-shebang /etc/xen/scripts/hotplugpath.sh
[ 1875s] This text file has executable bits set or is located in a path dedicated for
[ 1875s] executables, but lacks a shebang and cannot thus be executed. If the file is
[ 1875s] meant to be an executable script, add the shebang, otherwise remove the
[ 1875s] executable bits or move the file elsewhere.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r 3fbeb019d522 -r fe9a0eb9aaaa tools/hotplug/common/Makefile
--- a/tools/hotplug/common/Makefile Thu Oct 18 09:35:04 2012 +0100
+++ b/tools/hotplug/common/Makefile Thu Oct 18 09:35:05 2012 +0100
@@ -6,8 +6,8 @@ HOTPLUGPATH="hotplugpath.sh"
# OS-independent hotplug scripts go in this directory
# Xen scripts to go there.
-XEN_SCRIPTS = $(HOTPLUGPATH)
-XEN_SCRIPT_DATA =
+XEN_SCRIPTS =
+XEN_SCRIPT_DATA = $(HOTPLUGPATH)
genpath-target = $(call buildmakevars2file,$(HOTPLUGPATH))
$(eval $(genpath-target))
++++++ 26085-stubdom_install_stubdompath.sh_as_data_file.patch ++++++
changeset: 26085:e32f4301f384
user: Olaf Hering
date: Thu Oct 18 09:35:06 2012 +0100
files: stubdom/Makefile
description:
stubdom: install stubdompath.sh as data file
rpmlint complains a script helper which is only sourced:
[ 1875s] xen-tools.i586: W: script-without-shebang /usr/lib/xen/bin/stubdompath.sh
[ 1875s] This text file has executable bits set or is located in a path dedicated for
[ 1875s] executables, but lacks a shebang and cannot thus be executed. If the file is
[ 1875s] meant to be an executable script, add the shebang, otherwise remove the
[ 1875s] executable bits or move the file elsewhere.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
Index: xen-4.2.3-testing/stubdom/Makefile
===================================================================
--- xen-4.2.3-testing.orig/stubdom/Makefile
+++ xen-4.2.3-testing/stubdom/Makefile
@@ -381,7 +381,8 @@ install-readme:
install-ioemu: ioemu-stubdom
$(INSTALL_DIR) "$(DESTDIR)$(LIBEXEC)"
- $(INSTALL_PROG) stubdompath.sh stubdom-dm "$(DESTDIR)$(LIBEXEC)"
+ $(INSTALL_PROG) stubdom-dm "$(DESTDIR)$(LIBEXEC)"
+ $(INSTALL_DATA) stubdompath.sh "$(DESTDIR)$(LIBEXEC)"
$(INSTALL_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)"
$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-ioemu/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/ioemu-stubdom.gz"
++++++ 26086-hotplug-Linux_correct_sysconfig_tag_in_xendomains.patch ++++++
changeset: 26086:ba6b1db89ec8
user: Olaf Hering
date: Thu Oct 18 09:35:07 2012 +0100
files: tools/hotplug/Linux/init.d/sysconfig.xendomains
description:
hotplug/Linux: correct sysconfig tag in xendomains
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r e32f4301f384 -r ba6b1db89ec8 tools/hotplug/Linux/init.d/sysconfig.xendomains
--- a/tools/hotplug/Linux/init.d/sysconfig.xendomains Thu Oct 18 09:35:06 2012 +0100
+++ b/tools/hotplug/Linux/init.d/sysconfig.xendomains Thu Oct 18 09:35:07 2012 +0100
@@ -1,4 +1,4 @@
-## Path: System/xen
+## Path: System/Virtualization
## Description: xen domain start/stop on boot
## Type: string
## Default:
++++++ 26087-hotplug-Linux_install_sysconfig_files_as_data_files.patch ++++++
changeset: 26087:6239ace16749
user: Olaf Hering
date: Thu Oct 18 09:35:07 2012 +0100
files: tools/hotplug/Linux/Makefile
description:
hotplug/Linux: install sysconfig files as data files
rpmlint complains about wrong permissions of config files:
[ 455s] xen-tools.i586: W: script-without-shebang /var/adm/fillup-templates/sysconfig.xendomains
[ 455s] xen-tools.i586: W: script-without-shebang /var/adm/fillup-templates/sysconfig.xencommons
[ 455s] This text file has executable bits set or is located in a path dedicated for
[ 455s] executables, but lacks a shebang and cannot thus be executed. If the file is
[ 455s] meant to be an executable script, add the shebang, otherwise remove the
[ 455s] executable bits or move the file elsewhere.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r ba6b1db89ec8 -r 6239ace16749 tools/hotplug/Linux/Makefile
--- a/tools/hotplug/Linux/Makefile Thu Oct 18 09:35:07 2012 +0100
+++ b/tools/hotplug/Linux/Makefile Thu Oct 18 09:35:07 2012 +0100
@@ -46,9 +46,9 @@ install-initd:
[ -d $(DESTDIR)$(SYSCONFIG_DIR) ] || $(INSTALL_DIR) $(DESTDIR)$(SYSCONFIG_DIR)
$(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)$(INITD_DIR)
$(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)$(INITD_DIR)
- $(INSTALL_PROG) $(XENDOMAINS_SYSCONFIG) $(DESTDIR)$(SYSCONFIG_DIR)/xendomains
+ $(INSTALL_DATA) $(XENDOMAINS_SYSCONFIG) $(DESTDIR)$(SYSCONFIG_DIR)/xendomains
$(INSTALL_PROG) $(XENCOMMONS_INITD) $(DESTDIR)$(INITD_DIR)
- $(INSTALL_PROG) $(XENCOMMONS_SYSCONFIG) $(DESTDIR)$(SYSCONFIG_DIR)/xencommons
+ $(INSTALL_DATA) $(XENCOMMONS_SYSCONFIG) $(DESTDIR)$(SYSCONFIG_DIR)/xencommons
$(INSTALL_PROG) init.d/xen-watchdog $(DESTDIR)$(INITD_DIR)
.PHONY: install-scripts
++++++ 26114-pygrub-list-entries.patch ++++++
# HG changeset patch
# User Charles Arnold
# Date 1351249508 -3600
# Node ID 6f9e46917eb8771914041b98f714e8f485fca5ef
# Parent 03af0abd2b72dfab3f2e50dd502108de8603f741
pygrub: Add option to list grub entries
The argument to "--entry" allows 2 syntaxes, either directly the entry
number in menu.lst, or the whole string behind the "title" key word.
This poses the following issue:
title string because this string contains the kernel version, which
will change with a kernel update.
This patch adds [-l|--list-entries] as an argument to pygrub.
Signed-off-by: Charles Arnold
Acked-by: Ian Jackson
Committed-by: Ian Jackson
Index: xen-4.2.3-testing/tools/pygrub/src/pygrub
===================================================================
--- xen-4.2.3-testing.orig/tools/pygrub/src/pygrub
+++ xen-4.2.3-testing/tools/pygrub/src/pygrub
@@ -596,7 +596,17 @@ def run_grub(file, entry, fs, cfg_args):
sel = g.run()
g = Grub(file, fs)
- if interactive:
+
+ if list_entries:
+ for i in range(len(g.cf.images)):
+ img = g.cf.images[i]
+ print "title: %s" % img.title
+ print " root: %s" % img.root
+ print " kernel: %s" % img.kernel[1]
+ print " args: %s" % img.args
+ print " initrd: %s" % img.initrd[1]
+
+ if interactive and not list_entries:
curses.wrapper(run_main)
else:
sel = g.cf.default
@@ -703,7 +713,7 @@ if __name__ == "__main__":
sel = None
def usage():
- print >> sys.stderr, "Usage: %s [-q|--quiet] [-i|--interactive] [-n|--not-really] [--output=] [--kernel=] [--ramdisk=] [--args=] [--entry=] [--output-directory=] [--output-format=sxp|simple|simple0] <image>" %(sys.argv[0],)
+ print >> sys.stderr, "Usage: %s [-q|--quiet] [-i|--interactive] [-l|--list-entries] [-n|--not-really] [--output=] [--kernel=] [--ramdisk=] [--args=] [--entry=] [--output-directory=] [--output-format=sxp|simple|simple0] <image>" %(sys.argv[0],)
def copy_from_image(fs, file_to_read, file_type, output_directory,
not_really):
@@ -737,8 +747,8 @@ if __name__ == "__main__":
dataoff += len(data)
try:
- opts, args = getopt.gnu_getopt(sys.argv[1:], 'qinh::',
- ["quiet", "interactive", "not-really", "help",
+ opts, args = getopt.gnu_getopt(sys.argv[1:], 'qilnh::',
+ ["quiet", "interactive", "list-entries", "not-really", "help",
"output=", "output-format=", "output-directory=",
"entry=", "kernel=",
"ramdisk=", "args=", "isconfig", "debug"])
@@ -754,6 +764,7 @@ if __name__ == "__main__":
output = None
entry = None
interactive = True
+ list_entries = False
isconfig = False
debug = False
not_really = False
@@ -772,6 +783,8 @@ if __name__ == "__main__":
interactive = False
elif o in ("-i", "--interactive"):
interactive = True
+ elif o in ("-l", "--list-entries"):
+ list_entries = True
elif o in ("-n", "--not-really"):
not_really = True
elif o in ("-h", "--help"):
@@ -856,6 +869,9 @@ if __name__ == "__main__":
fs = None
continue
+ if list_entries:
+ sys.exit(0)
+
# Did looping through partitions find us a kernel?
if not fs:
raise RuntimeError, "Unable to find partition containing kernel"
++++++ 26129-ACPI-BGRT-invalidate.patch ++++++
++++ 649 lines (skipped)
++++++ 26133-IOMMU-defer-BM-disable.patch ++++++
References: bnc#787169
# HG changeset patch
# User Jan Beulich
# Date 1352709367 -3600
# Node ID fdb69dd527cd01a46f87efb380050559dcf12d37
# Parent 286ef4ced2164f4e9bf52fd0c52248182e69a6e6
IOMMU: don't immediately disable bus mastering on faults
Instead, give the owning domain at least a small opportunity of fixing
things up, and allow for rare faults to not bring down the device at
all.
Signed-off-by: Jan Beulich
Acked-by: Tim Deegan
Acked-by: Dario Faggioli
Index: xen-4.2.4-testing/xen/drivers/passthrough/amd/iommu_init.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/amd/iommu_init.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/amd/iommu_init.c
@@ -561,7 +561,7 @@ static hw_irq_controller iommu_msi_type
static void parse_event_log_entry(struct amd_iommu *iommu, u32 entry[])
{
- u16 domain_id, device_id, cword;
+ u16 domain_id, device_id;
unsigned int bdf;
u32 code;
u64 *addr;
@@ -613,18 +613,10 @@ static void parse_event_log_entry(struct
"fault address = 0x%"PRIx64"\n",
event_str[code-1], domain_id, device_id, *addr);
- /* Tell the device to stop DMAing; we can't rely on the guest to
- * control it for us. */
for ( bdf = 0; bdf < ivrs_bdf_entries; bdf++ )
if ( get_dma_requestor_id(iommu->seg, bdf) == device_id )
- {
- cword = pci_conf_read16(iommu->seg, PCI_BUS(bdf),
- PCI_SLOT(bdf), PCI_FUNC(bdf),
- PCI_COMMAND);
- pci_conf_write16(iommu->seg, PCI_BUS(bdf), PCI_SLOT(bdf),
- PCI_FUNC(bdf), PCI_COMMAND,
- cword & ~PCI_COMMAND_MASTER);
- }
+ pci_check_disable_device(iommu->seg, PCI_BUS(bdf),
+ PCI_DEVFN2(bdf));
}
else
{
Index: xen-4.2.4-testing/xen/drivers/passthrough/iommu.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/iommu.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/iommu.c
@@ -218,6 +218,7 @@ static int device_assigned(u16 seg, u8 b
static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
{
struct hvm_iommu *hd = domain_hvm_iommu(d);
+ struct pci_dev *pdev;
int rc = 0;
if ( !iommu_enabled || !hd->platform_ops )
@@ -231,6 +232,10 @@ static int assign_device(struct domain *
return -EXDEV;
spin_lock(&pcidevs_lock);
+ pdev = pci_get_pdev(seg, bus, devfn);
+ if ( pdev )
+ pdev->fault.count = 0;
+
if ( (rc = hd->platform_ops->assign_device(d, seg, bus, devfn)) )
goto done;
@@ -384,6 +389,8 @@ int deassign_device(struct domain *d, u1
return ret;
}
+ pdev->fault.count = 0;
+
if ( !has_arch_pdevs(d) && need_iommu(d) )
{
d->need_iommu = 0;
Index: xen-4.2.4-testing/xen/drivers/passthrough/pci.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/pci.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/pci.c
@@ -637,6 +637,36 @@ int __init pci_device_detect(u16 seg, u8
return 1;
}
+void pci_check_disable_device(u16 seg, u8 bus, u8 devfn)
+{
+ struct pci_dev *pdev;
+ s_time_t now = NOW();
+ u16 cword;
+
+ spin_lock(&pcidevs_lock);
+ pdev = pci_get_pdev(seg, bus, devfn);
+ if ( pdev )
+ {
+ if ( now < pdev->fault.time ||
+ now - pdev->fault.time > MILLISECS(10) )
+ pdev->fault.count >>= 1;
+ pdev->fault.time = now;
+ if ( ++pdev->fault.count < PT_FAULT_THRESHOLD )
+ pdev = NULL;
+ }
+ spin_unlock(&pcidevs_lock);
+
+ if ( !pdev )
+ return;
+
+ /* Tell the device to stop DMAing; we can't rely on the guest to
+ * control it for us. */
+ cword = pci_conf_read16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ PCI_COMMAND);
+ pci_conf_write16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ PCI_COMMAND, cword & ~PCI_COMMAND_MASTER);
+}
+
/*
* scan pci devices to add all existed PCI devices to alldevs_list,
* and setup pci hierarchy in array bus2bridge.
Index: xen-4.2.4-testing/xen/drivers/passthrough/vtd/iommu.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/vtd/iommu.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/vtd/iommu.c
@@ -936,7 +936,7 @@ static void __do_iommu_page_fault(struct
while (1)
{
u8 fault_reason;
- u16 source_id, cword;
+ u16 source_id;
u32 data;
u64 guest_addr;
int type;
@@ -969,14 +969,8 @@ static void __do_iommu_page_fault(struct
iommu_page_fault_do_one(iommu, type, fault_reason,
source_id, guest_addr);
- /* Tell the device to stop DMAing; we can't rely on the guest to
- * control it for us. */
- cword = pci_conf_read16(iommu->intel->drhd->segment,
- PCI_BUS(source_id), PCI_SLOT(source_id),
- PCI_FUNC(source_id), PCI_COMMAND);
- pci_conf_write16(iommu->intel->drhd->segment, PCI_BUS(source_id),
- PCI_SLOT(source_id), PCI_FUNC(source_id),
- PCI_COMMAND, cword & ~PCI_COMMAND_MASTER);
+ pci_check_disable_device(iommu->intel->drhd->segment,
+ PCI_BUS(source_id), PCI_DEVFN2(source_id));
fault_index++;
if ( fault_index > cap_num_fault_regs(iommu->cap) )
Index: xen-4.2.4-testing/xen/include/xen/pci.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/xen/pci.h
+++ xen-4.2.4-testing/xen/include/xen/pci.h
@@ -65,6 +65,11 @@ struct pci_dev {
const u8 devfn;
struct pci_dev_info info;
struct arch_pci_dev arch;
+ struct {
+ s_time_t time;
+ unsigned int count;
+#define PT_FAULT_THRESHOLD 10
+ } fault;
u64 vf_rlen[6];
};
@@ -107,6 +112,7 @@ void arch_pci_ro_device(int seg, int bdf
struct pci_dev *pci_get_pdev(int seg, int bus, int devfn);
struct pci_dev *pci_get_pdev_by_domain(
struct domain *, int seg, int bus, int devfn);
+void pci_check_disable_device(u16 seg, u8 bus, u8 devfn);
uint8_t pci_conf_read8(
unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
++++++ 26189-xenstore-chmod.patch ++++++
# HG changeset patch
# Parent 8b93ac0c93f3fb8a140b4688ba71841ac927d4e3
xenstore-chmod: handle arbitrary number of perms rather than MAX_PERMS constant
Constant MAX_PERMS 16 is too small to use in some occasions, e.g. if
there are more than 16 domU(s) on one hypervisor (it's easy to
achieve) and one wants to do xenstore-chmod PATH to all domU(s). So,
remove MAX_PERMS limitation and make it as arbitrary number of perms.
Signed-off-by: Chunyan Liu
Acked-by: Ian Campbell
diff -r 8b93ac0c93f3 tools/xenstore/xenstore_client.c
--- a/tools/xenstore/xenstore_client.c Tue Nov 13 11:19:17 2012 +0000
+++ b/tools/xenstore/xenstore_client.c Mon Nov 26 11:33:38 2012 +0800
@@ -25,7 +25,6 @@
#define PATH_SEP '/'
#define MAX_PATH_LEN 256
-#define MAX_PERMS 16
enum mode {
MODE_unknown,
@@ -407,44 +406,41 @@ perform(enum mode mode, int optind, int
output("%s\n", list[i]);
}
free(list);
- optind++;
- break;
- }
- case MODE_ls: {
- do_ls(xsh, argv[optind], 0, prefix);
- optind++;
- break;
+ optind++;
+ break;
+ }
+ case MODE_ls: {
+ do_ls(xsh, argv[optind], 0, prefix);
+ optind++;
+ break;
}
case MODE_chmod: {
- struct xs_permissions perms[MAX_PERMS];
- int nperms = 0;
/* save path pointer: */
char *path = argv[optind++];
- for (; argv[optind]; optind++, nperms++)
+ int nperms = argc - optind;
+ struct xs_permissions perms[nperms];
+ int i;
+ for (i = 0; argv[optind]; optind++, i++)
{
- if (MAX_PERMS <= nperms)
- errx(1, "Too many permissions specified. "
- "Maximum per invocation is %d.", MAX_PERMS);
-
- perms[nperms].id = atoi(argv[optind]+1);
+ perms[i].id = atoi(argv[optind]+1);
switch (argv[optind][0])
{
case 'n':
- perms[nperms].perms = XS_PERM_NONE;
+ perms[i].perms = XS_PERM_NONE;
break;
case 'r':
- perms[nperms].perms = XS_PERM_READ;
+ perms[i].perms = XS_PERM_READ;
break;
case 'w':
- perms[nperms].perms = XS_PERM_WRITE;
+ perms[i].perms = XS_PERM_WRITE;
break;
case 'b':
- perms[nperms].perms = XS_PERM_READ | XS_PERM_WRITE;
+ perms[i].perms = XS_PERM_READ | XS_PERM_WRITE;
break;
default:
errx(1, "Invalid permission specification: '%c'",
- argv[optind][0]);
+ argv[optind][0]);
}
}
++++++ 26262-x86-EFI-secure-shim.patch ++++++
# HG changeset patch
# User Jan Beulich
# Date 1354884272 -3600
# Node ID b62bd62b26836fafe19cf41fec194bcf33e2ead6
# Parent cb542e58da25211843eb79998ea8568ebe9c8056
x86/EFI: add code interfacing with the secure boot shim
... to validate the kernel image (which is required to be in PE
format, as is e.g. the case for the Linux bzImage when built with
CONFIG_EFI_STUB).
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Index: xen-4.2.4-testing/xen/arch/x86/efi/boot.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/efi/boot.c
+++ xen-4.2.4-testing/xen/arch/x86/efi/boot.c
@@ -27,6 +27,18 @@
/* Using SetVirtualAddressMap() is incompatible with kexec: */
#undef USE_SET_VIRTUAL_ADDRESS_MAP
+#define SHIM_LOCK_PROTOCOL_GUID \
+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
+
+typedef EFI_STATUS
+(/* _not_ EFIAPI */ *EFI_SHIM_LOCK_VERIFY) (
+ IN VOID *Buffer,
+ IN UINT32 Size);
+
+typedef struct {
+ EFI_SHIM_LOCK_VERIFY Verify;
+} EFI_SHIM_LOCK_PROTOCOL;
+
extern char start[];
extern u32 cpuid_ext_features;
@@ -647,12 +659,14 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
static EFI_GUID __initdata gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
static EFI_GUID __initdata bio_guid = BLOCK_IO_PROTOCOL;
static EFI_GUID __initdata devp_guid = DEVICE_PATH_PROTOCOL;
+ static EFI_GUID __initdata shim_lock_guid = SHIM_LOCK_PROTOCOL_GUID;
EFI_LOADED_IMAGE *loaded_image;
EFI_STATUS status;
unsigned int i, argc;
CHAR16 **argv, *file_name, *cfg_file_name = NULL;
UINTN cols, rows, depth, size, map_key, info_size, gop_mode = ~0;
EFI_HANDLE *handles = NULL;
+ EFI_SHIM_LOCK_PROTOCOL *shim_lock;
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
EFI_FILE_HANDLE dir_handle;
@@ -841,6 +855,11 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
read_file(dir_handle, s2w(&name), &kernel);
efi_bs->FreePool(name.w);
+ if ( !EFI_ERROR(efi_bs->LocateProtocol(&shim_lock_guid, NULL,
+ (void **)&shim_lock)) &&
+ shim_lock->Verify(kernel.ptr, kernel.size) != EFI_SUCCESS )
+ blexit(L"Dom0 kernel image could not be verified\r\n");
+
name.s = get_value(&cfg, section.s, "ramdisk");
if ( name.s )
{
++++++ 26324-IOMMU-assign-params.patch ++++++
References: bnc#787169
# HG changeset patch
# User Jan Beulich
# Date 1357559364 -3600
# Node ID 62dd78a4e3fc9d190840549f13b4d613f2d19c41
# Parent 64b36dde26bc3c4fc80312cc9eeb0e511f0cf94b
IOMMU: adjust (re)assign operation parameters
... to use a (struct pci_dev *, devfn) pair.
Signed-off-by: Jan Beulich
Acked-by: "Zhang, Xiantao"
Index: xen-4.2.4-testing/xen/drivers/passthrough/amd/pci_amd_iommu.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -348,34 +348,31 @@ void amd_iommu_disable_domain_device(str
disable_ats_device(iommu->seg, bus, devfn);
}
-static int reassign_device( struct domain *source, struct domain *target,
- u16 seg, u8 bus, u8 devfn)
+static int reassign_device(struct domain *source, struct domain *target,
+ u8 devfn, struct pci_dev *pdev)
{
- struct pci_dev *pdev;
struct amd_iommu *iommu;
int bdf;
struct hvm_iommu *t = domain_hvm_iommu(target);
- ASSERT(spin_is_locked(&pcidevs_lock));
- pdev = pci_get_pdev_by_domain(source, seg, bus, devfn);
- if ( !pdev )
- return -ENODEV;
-
- bdf = PCI_BDF2(bus, devfn);
- iommu = find_iommu_for_device(seg, bdf);
+ bdf = PCI_BDF2(pdev->bus, pdev->devfn);
+ iommu = find_iommu_for_device(pdev->seg, bdf);
if ( !iommu )
{
AMD_IOMMU_DEBUG("Fail to find iommu."
" %04x:%02x:%x02.%x cannot be assigned to dom%d\n",
- seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
target->domain_id);
return -ENODEV;
}
amd_iommu_disable_domain_device(source, iommu, bdf);
- list_move(&pdev->domain_list, &target->arch.pdev_list);
- pdev->domain = target;
+ if ( devfn == pdev->devfn )
+ {
+ list_move(&pdev->domain_list, &target->arch.pdev_list);
+ pdev->domain = target;
+ }
/* IO page tables might be destroyed after pci-detach the last device
* In this case, we have to re-allocate root table for next pci-attach.*/
@@ -384,17 +381,18 @@ static int reassign_device( struct domai
amd_iommu_setup_domain_device(target, iommu, bdf);
AMD_IOMMU_DEBUG("Re-assign %04x:%02x:%02x.%u from dom%d to dom%d\n",
- seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
source->domain_id, target->domain_id);
return 0;
}
-static int amd_iommu_assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
+static int amd_iommu_assign_device(struct domain *d, u8 devfn,
+ struct pci_dev *pdev)
{
- struct ivrs_mappings *ivrs_mappings = get_ivrs_mappings(seg);
- int bdf = (bus << 8) | devfn;
- int req_id = get_dma_requestor_id(seg, bdf);
+ struct ivrs_mappings *ivrs_mappings = get_ivrs_mappings(pdev->seg);
+ int bdf = PCI_BDF2(pdev->bus, devfn);
+ int req_id = get_dma_requestor_id(pdev->seg, bdf);
if ( ivrs_mappings[req_id].unity_map_enable )
{
@@ -406,7 +404,7 @@ static int amd_iommu_assign_device(struc
ivrs_mappings[req_id].read_permission);
}
- return reassign_device(dom0, d, seg, bus, devfn);
+ return reassign_device(dom0, d, devfn, pdev);
}
static void deallocate_next_page_table(struct page_info* pg, int level)
@@ -471,12 +469,6 @@ static void amd_iommu_domain_destroy(str
amd_iommu_flush_all_pages(d);
}
-static int amd_iommu_return_device(
- struct domain *s, struct domain *t, u16 seg, u8 bus, u8 devfn)
-{
- return reassign_device(s, t, seg, bus, devfn);
-}
-
static int amd_iommu_add_device(struct pci_dev *pdev)
{
struct amd_iommu *iommu;
@@ -616,7 +608,7 @@ const struct iommu_ops amd_iommu_ops = {
.teardown = amd_iommu_domain_destroy,
.map_page = amd_iommu_map_page,
.unmap_page = amd_iommu_unmap_page,
- .reassign_device = amd_iommu_return_device,
+ .reassign_device = reassign_device,
.get_device_group_id = amd_iommu_group_id,
.update_ire_from_apic = amd_iommu_ioapic_update_ire,
.update_ire_from_msi = amd_iommu_msi_msg_update_ire,
Index: xen-4.2.4-testing/xen/drivers/passthrough/iommu.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/iommu.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/iommu.c
@@ -232,11 +232,16 @@ static int assign_device(struct domain *
return -EXDEV;
spin_lock(&pcidevs_lock);
- pdev = pci_get_pdev(seg, bus, devfn);
- if ( pdev )
- pdev->fault.count = 0;
+ pdev = pci_get_pdev_by_domain(dom0, seg, bus, devfn);
+ if ( !pdev )
+ {
+ rc = pci_get_pdev(seg, bus, devfn) ? -EBUSY : -ENODEV;
+ goto done;
+ }
+
+ pdev->fault.count = 0;
- if ( (rc = hd->platform_ops->assign_device(d, seg, bus, devfn)) )
+ if ( (rc = hd->platform_ops->assign_device(d, devfn, pdev)) )
goto done;
if ( has_arch_pdevs(d) && !need_iommu(d) )
@@ -369,18 +374,11 @@ int deassign_device(struct domain *d, u1
return -EINVAL;
ASSERT(spin_is_locked(&pcidevs_lock));
- pdev = pci_get_pdev(seg, bus, devfn);
+ pdev = pci_get_pdev_by_domain(d, seg, bus, devfn);
if ( !pdev )
return -ENODEV;
- if ( pdev->domain != d )
- {
- dprintk(XENLOG_ERR VTDPREFIX,
- "d%d: deassign a device not owned\n", d->domain_id);
- return -EINVAL;
- }
-
- ret = hd->platform_ops->reassign_device(d, dom0, seg, bus, devfn);
+ ret = hd->platform_ops->reassign_device(d, dom0, devfn, pdev);
if ( ret )
{
dprintk(XENLOG_ERR VTDPREFIX,
Index: xen-4.2.4-testing/xen/drivers/passthrough/vtd/iommu.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/vtd/iommu.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/vtd/iommu.c
@@ -1692,17 +1692,10 @@ out:
static int reassign_device_ownership(
struct domain *source,
struct domain *target,
- u16 seg, u8 bus, u8 devfn)
+ u8 devfn, struct pci_dev *pdev)
{
- struct pci_dev *pdev;
int ret;
- ASSERT(spin_is_locked(&pcidevs_lock));
- pdev = pci_get_pdev_by_domain(source, seg, bus, devfn);
-
- if (!pdev)
- return -ENODEV;
-
/*
* Devices assigned to untrusted domains (here assumed to be any domU)
* can attempt to send arbitrary LAPIC/MSI messages. We are unprotected
@@ -1711,16 +1704,19 @@ static int reassign_device_ownership(
if ( (target != dom0) && !iommu_intremap )
untrusted_msi = 1;
- ret = domain_context_unmap(source, seg, bus, devfn);
+ ret = domain_context_unmap(source, pdev->seg, pdev->bus, devfn);
if ( ret )
return ret;
- ret = domain_context_mapping(target, seg, bus, devfn);
+ ret = domain_context_mapping(target, pdev->seg, pdev->bus, devfn);
if ( ret )
return ret;
- list_move(&pdev->domain_list, &target->arch.pdev_list);
- pdev->domain = target;
+ if ( devfn == pdev->devfn )
+ {
+ list_move(&pdev->domain_list, &target->arch.pdev_list);
+ pdev->domain = target;
+ }
return ret;
}
@@ -2225,36 +2221,26 @@ int __init intel_vtd_setup(void)
}
static int intel_iommu_assign_device(
- struct domain *d, u16 seg, u8 bus, u8 devfn)
+ struct domain *d, u8 devfn, struct pci_dev *pdev)
{
struct acpi_rmrr_unit *rmrr;
int ret = 0, i;
- struct pci_dev *pdev;
- u16 bdf;
+ u16 bdf, seg;
+ u8 bus;
if ( list_empty(&acpi_drhd_units) )
return -ENODEV;
- ASSERT(spin_is_locked(&pcidevs_lock));
- pdev = pci_get_pdev(seg, bus, devfn);
- if (!pdev)
- return -ENODEV;
-
- if (pdev->domain != dom0)
- {
- dprintk(XENLOG_ERR VTDPREFIX,
- "IOMMU: assign a assigned device\n");
- return -EBUSY;
- }
-
- ret = reassign_device_ownership(dom0, d, seg, bus, devfn);
+ ret = reassign_device_ownership(dom0, d, devfn, pdev);
if ( ret )
goto done;
/* FIXME: Because USB RMRR conflicts with guest bios region,
* ignore USB RMRR temporarily.
*/
- if ( is_usb_device(seg, bus, devfn) )
+ seg = pdev->seg;
+ bus = pdev->bus;
+ if ( is_usb_device(seg, bus, pdev->devfn) )
{
ret = 0;
goto done;
Index: xen-4.2.4-testing/xen/include/xen/iommu.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/xen/iommu.h
+++ xen-4.2.4-testing/xen/include/xen/iommu.h
@@ -123,13 +123,13 @@ struct iommu_ops {
int (*add_device)(struct pci_dev *pdev);
int (*enable_device)(struct pci_dev *pdev);
int (*remove_device)(struct pci_dev *pdev);
- int (*assign_device)(struct domain *d, u16 seg, u8 bus, u8 devfn);
+ int (*assign_device)(struct domain *, u8 devfn, struct pci_dev *);
void (*teardown)(struct domain *d);
int (*map_page)(struct domain *d, unsigned long gfn, unsigned long mfn,
unsigned int flags);
int (*unmap_page)(struct domain *d, unsigned long gfn);
int (*reassign_device)(struct domain *s, struct domain *t,
- u16 seg, u8 bus, u8 devfn);
+ u8 devfn, struct pci_dev *);
int (*get_device_group_id)(u16 seg, u8 bus, u8 devfn);
void (*update_ire_from_apic)(unsigned int apic, unsigned int reg, unsigned int value);
void (*update_ire_from_msi)(struct msi_desc *msi_desc, struct msi_msg *msg);
++++++ 26325-IOMMU-add-remove-params.patch ++++++
References: bnc#787169
# HG changeset patch
# User Jan Beulich
# Date 1357559482 -3600
# Node ID 75cc4943b1ff509c4074800a23ff51d773233b8a
# Parent 62dd78a4e3fc9d190840549f13b4d613f2d19c41
IOMMU: adjust add/remove operation parameters
... to use a (struct pci_dev *, devfn) pair.
Signed-off-by: Jan Beulich
Acked-by: "Zhang, Xiantao"
Index: xen-4.2.3-testing/xen/drivers/passthrough/amd/pci_amd_iommu.c
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ xen-4.2.3-testing/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -83,14 +83,14 @@ static void disable_translation(u32 *dte
}
static void amd_iommu_setup_domain_device(
- struct domain *domain, struct amd_iommu *iommu, int bdf)
+ struct domain *domain, struct amd_iommu *iommu,
+ u8 devfn, struct pci_dev *pdev)
{
void *dte;
unsigned long flags;
int req_id, valid = 1;
int dte_i = 0;
- u8 bus = PCI_BUS(bdf);
- u8 devfn = PCI_DEVFN2(bdf);
+ u8 bus = pdev->bus;
struct hvm_iommu *hd = domain_hvm_iommu(domain);
@@ -103,7 +103,7 @@ static void amd_iommu_setup_domain_devic
dte_i = 1;
/* get device-table entry */
- req_id = get_dma_requestor_id(iommu->seg, bdf);
+ req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(bus, devfn));
dte = iommu->dev_table.buffer + (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE);
spin_lock_irqsave(&iommu->lock, flags);
@@ -115,7 +115,7 @@ static void amd_iommu_setup_domain_devic
(u32 *)dte, page_to_maddr(hd->root_table), hd->domain_id,
hd->paging_mode, valid);
- if ( pci_ats_device(iommu->seg, bus, devfn) &&
+ if ( pci_ats_device(iommu->seg, bus, pdev->devfn) &&
iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) )
iommu_dte_set_iotlb((u32 *)dte, dte_i);
@@ -132,32 +132,31 @@ static void amd_iommu_setup_domain_devic
ASSERT(spin_is_locked(&pcidevs_lock));
- if ( pci_ats_device(iommu->seg, bus, devfn) &&
- !pci_ats_enabled(iommu->seg, bus, devfn) )
+ if ( pci_ats_device(iommu->seg, bus, pdev->devfn) &&
+ !pci_ats_enabled(iommu->seg, bus, pdev->devfn) )
{
- struct pci_dev *pdev;
+ if ( devfn == pdev->devfn )
+ enable_ats_device(iommu->seg, bus, devfn);
- enable_ats_device(iommu->seg, bus, devfn);
-
- ASSERT(spin_is_locked(&pcidevs_lock));
- pdev = pci_get_pdev(iommu->seg, bus, devfn);
-
- ASSERT( pdev != NULL );
amd_iommu_flush_iotlb(pdev, INV_IOMMU_ALL_PAGES_ADDRESS, 0);
}
}
-static void __init amd_iommu_setup_dom0_device(struct pci_dev *pdev)
+static int __init amd_iommu_setup_dom0_device(u8 devfn, struct pci_dev *pdev)
{
int bdf = PCI_BDF2(pdev->bus, pdev->devfn);
struct amd_iommu *iommu = find_iommu_for_device(pdev->seg, bdf);
- if ( likely(iommu != NULL) )
- amd_iommu_setup_domain_device(pdev->domain, iommu, bdf);
- else
+ if ( unlikely(!iommu) )
+ {
AMD_IOMMU_DEBUG("No iommu for device %04x:%02x:%02x.%u\n",
pdev->seg, pdev->bus,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+ PCI_SLOT(devfn), PCI_FUNC(devfn));
+ return -ENODEV;
+ }
+
+ amd_iommu_setup_domain_device(pdev->domain, iommu, devfn, pdev);
+ return 0;
}
int __init amd_iov_detect(void)
@@ -311,16 +310,16 @@ static void __init amd_iommu_dom0_init(s
}
void amd_iommu_disable_domain_device(struct domain *domain,
- struct amd_iommu *iommu, int bdf)
+ struct amd_iommu *iommu,
+ u8 devfn, struct pci_dev *pdev)
{
void *dte;
unsigned long flags;
int req_id;
- u8 bus = PCI_BUS(bdf);
- u8 devfn = PCI_DEVFN2(bdf);
+ u8 bus = pdev->bus;
BUG_ON ( iommu->dev_table.buffer == NULL );
- req_id = get_dma_requestor_id(iommu->seg, bdf);
+ req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(bus, devfn));
dte = iommu->dev_table.buffer + (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE);
spin_lock_irqsave(&iommu->lock, flags);
@@ -328,7 +327,7 @@ void amd_iommu_disable_domain_device(str
{
disable_translation((u32 *)dte);
- if ( pci_ats_device(iommu->seg, bus, devfn) &&
+ if ( pci_ats_device(iommu->seg, bus, pdev->devfn) &&
iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) )
iommu_dte_set_iotlb((u32 *)dte, 0);
@@ -343,7 +342,8 @@ void amd_iommu_disable_domain_device(str
ASSERT(spin_is_locked(&pcidevs_lock));
- if ( pci_ats_device(iommu->seg, bus, devfn) &&
+ if ( devfn == pdev->devfn &&
+ pci_ats_device(iommu->seg, bus, devfn) &&
pci_ats_enabled(iommu->seg, bus, devfn) )
disable_ats_device(iommu->seg, bus, devfn);
}
@@ -366,7 +366,7 @@ static int reassign_device(struct domain
return -ENODEV;
}
- amd_iommu_disable_domain_device(source, iommu, bdf);
+ amd_iommu_disable_domain_device(source, iommu, devfn, pdev);
if ( devfn == pdev->devfn )
{
@@ -379,7 +379,7 @@ static int reassign_device(struct domain
if ( t->root_table == NULL )
allocate_domain_resources(t);
- amd_iommu_setup_domain_device(target, iommu, bdf);
+ amd_iommu_setup_domain_device(target, iommu, devfn, pdev);
AMD_IOMMU_DEBUG("Re-assign %04x:%02x:%02x.%u from dom%d to dom%d\n",
pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
source->domain_id, target->domain_id);
@@ -469,7 +469,7 @@ static void amd_iommu_domain_destroy(str
amd_iommu_flush_all_pages(d);
}
-static int amd_iommu_add_device(struct pci_dev *pdev)
+static int amd_iommu_add_device(u8 devfn, struct pci_dev *pdev)
{
struct amd_iommu *iommu;
u16 bdf;
@@ -482,16 +482,16 @@ static int amd_iommu_add_device(struct p
{
AMD_IOMMU_DEBUG("Fail to find iommu."
" %04x:%02x:%02x.%u cannot be assigned to dom%d\n",
- pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn), pdev->domain->domain_id);
+ pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ pdev->domain->domain_id);
return -ENODEV;
}
- amd_iommu_setup_domain_device(pdev->domain, iommu, bdf);
+ amd_iommu_setup_domain_device(pdev->domain, iommu, devfn, pdev);
return 0;
}
-static int amd_iommu_remove_device(struct pci_dev *pdev)
+static int amd_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
{
struct amd_iommu *iommu;
u16 bdf;
@@ -504,12 +504,12 @@ static int amd_iommu_remove_device(struc
{
AMD_IOMMU_DEBUG("Fail to find iommu."
" %04x:%02x:%02x.%u cannot be removed from dom%d\n",
- pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn), pdev->domain->domain_id);
+ pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ pdev->domain->domain_id);
return -ENODEV;
}
- amd_iommu_disable_domain_device(pdev->domain, iommu, bdf);
+ amd_iommu_disable_domain_device(pdev->domain, iommu, devfn, pdev);
return 0;
}
Index: xen-4.2.3-testing/xen/drivers/passthrough/iommu.c
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/passthrough/iommu.c
+++ xen-4.2.3-testing/xen/drivers/passthrough/iommu.c
@@ -167,7 +167,7 @@ int iommu_add_device(struct pci_dev *pde
if ( !iommu_enabled || !hd->platform_ops )
return 0;
- return hd->platform_ops->add_device(pdev);
+ return hd->platform_ops->add_device(pdev->devfn, pdev);
}
int iommu_enable_device(struct pci_dev *pdev)
@@ -197,7 +197,7 @@ int iommu_remove_device(struct pci_dev *
if ( !iommu_enabled || !hd->platform_ops )
return 0;
- return hd->platform_ops->remove_device(pdev);
+ return hd->platform_ops->remove_device(pdev->devfn, pdev);
}
/*
Index: xen-4.2.3-testing/xen/drivers/passthrough/pci.c
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/passthrough/pci.c
+++ xen-4.2.3-testing/xen/drivers/passthrough/pci.c
@@ -715,7 +715,7 @@ int __init scan_pci_devices(void)
struct setup_dom0 {
struct domain *d;
- void (*handler)(struct pci_dev *);
+ int (*handler)(u8 devfn, struct pci_dev *);
};
static int __init _setup_dom0_pci_devices(struct pci_seg *pseg, void *arg)
@@ -734,7 +734,7 @@ static int __init _setup_dom0_pci_device
pdev->domain = ctxt->d;
list_add(&pdev->domain_list, &ctxt->d->arch.pdev_list);
- ctxt->handler(pdev);
+ ctxt->handler(devfn, pdev);
}
}
@@ -742,7 +742,7 @@ static int __init _setup_dom0_pci_device
}
void __init setup_dom0_pci_devices(
- struct domain *d, void (*handler)(struct pci_dev *))
+ struct domain *d, int (*handler)(u8 devfn, struct pci_dev *))
{
struct setup_dom0 ctxt = { .d = d, .handler = handler };
Index: xen-4.2.3-testing/xen/drivers/passthrough/vtd/iommu.c
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/passthrough/vtd/iommu.c
+++ xen-4.2.3-testing/xen/drivers/passthrough/vtd/iommu.c
@@ -52,7 +52,7 @@ int nr_iommus;
static struct tasklet vtd_fault_tasklet;
-static void setup_dom0_device(struct pci_dev *);
+static int setup_dom0_device(u8 devfn, struct pci_dev *);
static void setup_dom0_rmrr(struct domain *d);
static int domain_iommu_domid(struct domain *d,
@@ -1907,7 +1907,7 @@ static int rmrr_identity_mapping(struct
return 0;
}
-static int intel_iommu_add_device(struct pci_dev *pdev)
+static int intel_iommu_add_device(u8 devfn, struct pci_dev *pdev)
{
struct acpi_rmrr_unit *rmrr;
u16 bdf;
@@ -1918,8 +1918,7 @@ static int intel_iommu_add_device(struct
if ( !pdev->domain )
return -EINVAL;
- ret = domain_context_mapping(pdev->domain, pdev->seg, pdev->bus,
- pdev->devfn);
+ ret = domain_context_mapping(pdev->domain, pdev->seg, pdev->bus, devfn);
if ( ret )
{
dprintk(XENLOG_ERR VTDPREFIX, "d%d: context mapping failed\n",
@@ -1931,7 +1930,7 @@ static int intel_iommu_add_device(struct
{
if ( rmrr->segment == pdev->seg &&
PCI_BUS(bdf) == pdev->bus &&
- PCI_DEVFN2(bdf) == pdev->devfn )
+ PCI_DEVFN2(bdf) == devfn )
{
ret = rmrr_identity_mapping(pdev->domain, rmrr);
if ( ret )
@@ -1956,7 +1955,7 @@ static int intel_iommu_enable_device(str
return ret >= 0 ? 0 : ret;
}
-static int intel_iommu_remove_device(struct pci_dev *pdev)
+static int intel_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
{
struct acpi_rmrr_unit *rmrr;
u16 bdf;
@@ -1974,19 +1973,22 @@ static int intel_iommu_remove_device(str
{
if ( rmrr->segment == pdev->seg &&
PCI_BUS(bdf) == pdev->bus &&
- PCI_DEVFN2(bdf) == pdev->devfn )
+ PCI_DEVFN2(bdf) == devfn )
return 0;
}
}
- return domain_context_unmap(pdev->domain, pdev->seg, pdev->bus,
- pdev->devfn);
+ return domain_context_unmap(pdev->domain, pdev->seg, pdev->bus, devfn);
}
-static void __init setup_dom0_device(struct pci_dev *pdev)
+static int __init setup_dom0_device(u8 devfn, struct pci_dev *pdev)
{
- domain_context_mapping(pdev->domain, pdev->seg, pdev->bus, pdev->devfn);
- pci_vtd_quirk(pdev);
+ int err;
+
+ err = domain_context_mapping(pdev->domain, pdev->seg, pdev->bus, devfn);
+ if ( !err && devfn == pdev->devfn )
+ pci_vtd_quirk(pdev);
+ return err;
}
void clear_fault_bits(struct iommu *iommu)
Index: xen-4.2.3-testing/xen/include/xen/iommu.h
===================================================================
--- xen-4.2.3-testing.orig/xen/include/xen/iommu.h
+++ xen-4.2.3-testing/xen/include/xen/iommu.h
@@ -120,9 +120,9 @@ bool_t pt_irq_need_timer(uint32_t flags)
struct iommu_ops {
int (*init)(struct domain *d);
void (*dom0_init)(struct domain *d);
- int (*add_device)(struct pci_dev *pdev);
+ int (*add_device)(u8 devfn, struct pci_dev *);
int (*enable_device)(struct pci_dev *pdev);
- int (*remove_device)(struct pci_dev *pdev);
+ int (*remove_device)(u8 devfn, struct pci_dev *);
int (*assign_device)(struct domain *, u8 devfn, struct pci_dev *);
void (*teardown)(struct domain *d);
int (*map_page)(struct domain *d, unsigned long gfn, unsigned long mfn,
Index: xen-4.2.3-testing/xen/include/xen/pci.h
===================================================================
--- xen-4.2.3-testing.orig/xen/include/xen/pci.h
+++ xen-4.2.3-testing/xen/include/xen/pci.h
@@ -101,7 +101,8 @@ struct pci_dev *pci_lock_pdev(int seg, i
struct pci_dev *pci_lock_domain_pdev(
struct domain *, int seg, int bus, int devfn);
-void setup_dom0_pci_devices(struct domain *, void (*)(struct pci_dev *));
+void setup_dom0_pci_devices(struct domain *,
+ int (*)(u8 devfn, struct pci_dev *));
void pci_release_devices(struct domain *d);
int pci_add_segment(u16 seg);
const unsigned long *pci_get_ro_map(u16 seg);
++++++ 26326-VT-d-context-map-params.patch ++++++
References: bnc#787169
# HG changeset patch
# User Jan Beulich
# Date 1357559549 -3600
# Node ID afb598bd0f5436bea15b7ef842e8ad5c6adefa1a
# Parent 75cc4943b1ff509c4074800a23ff51d773233b8a
VT-d: adjust context map/unmap parameters
... to use a (struct pci_dev *, devfn) pair.
Signed-off-by: Jan Beulich
Acked-by: "Zhang, Xiantao"
Index: xen-4.2.3-testing/xen/drivers/passthrough/vtd/extern.h
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/passthrough/vtd/extern.h
+++ xen-4.2.3-testing/xen/drivers/passthrough/vtd/extern.h
@@ -95,7 +95,7 @@ void free_pgtable_maddr(u64 maddr);
void *map_vtd_domain_page(u64 maddr);
void unmap_vtd_domain_page(void *va);
int domain_context_mapping_one(struct domain *domain, struct iommu *iommu,
- u8 bus, u8 devfn);
+ u8 bus, u8 devfn, const struct pci_dev *);
int domain_context_unmap_one(struct domain *domain, struct iommu *iommu,
u8 bus, u8 devfn);
Index: xen-4.2.3-testing/xen/drivers/passthrough/vtd/iommu.c
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/passthrough/vtd/iommu.c
+++ xen-4.2.3-testing/xen/drivers/passthrough/vtd/iommu.c
@@ -1311,7 +1311,7 @@ static void __init intel_iommu_dom0_init
int domain_context_mapping_one(
struct domain *domain,
struct iommu *iommu,
- u8 bus, u8 devfn)
+ u8 bus, u8 devfn, const struct pci_dev *pdev)
{
struct hvm_iommu *hd = domain_hvm_iommu(domain);
struct context_entry *context, *context_entries;
@@ -1328,11 +1328,9 @@ int domain_context_mapping_one(
if ( context_present(*context) )
{
int res = 0;
- struct pci_dev *pdev = NULL;
- /* First try to get domain ownership from device structure. If that's
+ /* Try to get domain ownership from device structure. If that's
* not available, try to read it from the context itself. */
- pdev = pci_get_pdev(seg, bus, devfn);
if ( pdev )
{
if ( pdev->domain != domain )
@@ -1451,13 +1449,12 @@ int domain_context_mapping_one(
}
static int domain_context_mapping(
- struct domain *domain, u16 seg, u8 bus, u8 devfn)
+ struct domain *domain, u8 devfn, const struct pci_dev *pdev)
{
struct acpi_drhd_unit *drhd;
int ret = 0;
u32 type;
- u8 secbus;
- struct pci_dev *pdev = pci_get_pdev(seg, bus, devfn);
+ u8 seg = pdev->seg, bus = pdev->bus, secbus;
drhd = acpi_find_matched_drhd_unit(pdev);
if ( !drhd )
@@ -1478,8 +1475,9 @@ static int domain_context_mapping(
dprintk(VTDPREFIX, "d%d:PCIe: map %04x:%02x:%02x.%u\n",
domain->domain_id, seg, bus,
PCI_SLOT(devfn), PCI_FUNC(devfn));
- ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn);
- if ( !ret && ats_device(pdev, drhd) > 0 )
+ ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn,
+ pdev);
+ if ( !ret && devfn == pdev->devfn && ats_device(pdev, drhd) > 0 )
enable_ats_device(seg, bus, devfn);
break;
@@ -1490,14 +1488,16 @@ static int domain_context_mapping(
domain->domain_id, seg, bus,
PCI_SLOT(devfn), PCI_FUNC(devfn));
- ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn);
+ ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn,
+ pdev);
if ( ret )
break;
if ( find_upstream_bridge(seg, &bus, &devfn, &secbus) < 1 )
break;
- ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn);
+ ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn,
+ pci_get_pdev(seg, bus, devfn));
/*
* Devices behind PCIe-to-PCI/PCIx bridge may generate different
@@ -1506,7 +1506,8 @@ static int domain_context_mapping(
*/
if ( !ret && pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE &&
(secbus != pdev->bus || pdev->devfn != 0) )
- ret = domain_context_mapping_one(domain, drhd->iommu, secbus, 0);
+ ret = domain_context_mapping_one(domain, drhd->iommu, secbus, 0,
+ pci_get_pdev(seg, secbus, 0));
break;
@@ -1579,18 +1580,15 @@ int domain_context_unmap_one(
}
static int domain_context_unmap(
- struct domain *domain, u16 seg, u8 bus, u8 devfn)
+ struct domain *domain, u8 devfn, const struct pci_dev *pdev)
{
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
int ret = 0;
u32 type;
- u8 tmp_bus, tmp_devfn, secbus;
- struct pci_dev *pdev = pci_get_pdev(seg, bus, devfn);
+ u8 seg = pdev->seg, bus = pdev->bus, tmp_bus, tmp_devfn, secbus;
int found = 0;
- BUG_ON(!pdev);
-
drhd = acpi_find_matched_drhd_unit(pdev);
if ( !drhd )
return -ENODEV;
@@ -1610,7 +1608,7 @@ static int domain_context_unmap(
domain->domain_id, seg, bus,
PCI_SLOT(devfn), PCI_FUNC(devfn));
ret = domain_context_unmap_one(domain, iommu, bus, devfn);
- if ( !ret && ats_device(pdev, drhd) > 0 )
+ if ( !ret && devfn == pdev->devfn && ats_device(pdev, drhd) > 0 )
disable_ats_device(seg, bus, devfn);
break;
@@ -1704,11 +1702,11 @@ static int reassign_device_ownership(
if ( (target != dom0) && !iommu_intremap )
untrusted_msi = 1;
- ret = domain_context_unmap(source, pdev->seg, pdev->bus, devfn);
+ ret = domain_context_unmap(source, devfn, pdev);
if ( ret )
return ret;
- ret = domain_context_mapping(target, pdev->seg, pdev->bus, devfn);
+ ret = domain_context_mapping(target, devfn, pdev);
if ( ret )
return ret;
@@ -1918,7 +1916,7 @@ static int intel_iommu_add_device(u8 dev
if ( !pdev->domain )
return -EINVAL;
- ret = domain_context_mapping(pdev->domain, pdev->seg, pdev->bus, devfn);
+ ret = domain_context_mapping(pdev->domain, devfn, pdev);
if ( ret )
{
dprintk(XENLOG_ERR VTDPREFIX, "d%d: context mapping failed\n",
@@ -1978,14 +1976,14 @@ static int intel_iommu_remove_device(u8
}
}
- return domain_context_unmap(pdev->domain, pdev->seg, pdev->bus, devfn);
+ return domain_context_unmap(pdev->domain, devfn, pdev);
}
static int __init setup_dom0_device(u8 devfn, struct pci_dev *pdev)
{
int err;
- err = domain_context_mapping(pdev->domain, pdev->seg, pdev->bus, devfn);
+ err = domain_context_mapping(pdev->domain, devfn, pdev);
if ( !err && devfn == pdev->devfn )
pci_vtd_quirk(pdev);
return err;
Index: xen-4.2.3-testing/xen/drivers/passthrough/vtd/quirks.c
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/passthrough/vtd/quirks.c
+++ xen-4.2.3-testing/xen/drivers/passthrough/vtd/quirks.c
@@ -319,7 +319,7 @@ static void map_me_phantom_function(stru
/* map or unmap ME phantom function */
if ( map )
domain_context_mapping_one(domain, drhd->iommu, 0,
- PCI_DEVFN(dev, 7));
+ PCI_DEVFN(dev, 7), NULL);
else
domain_context_unmap_one(domain, drhd->iommu, 0,
PCI_DEVFN(dev, 7));
++++++ 26327-AMD-IOMMU-flush-params.patch ++++++
References: bnc#787169
# HG changeset patch
# User Jan Beulich
# Date 1357559599 -3600
# Node ID 2a2c63f641ee3bda4ad552eb0b3ea479d37590cc
# Parent afb598bd0f5436bea15b7ef842e8ad5c6adefa1a
AMD IOMMU: adjust flush function parameters
... to use a (struct pci_dev *, devfn) pair.
Signed-off-by: Jan Beulich
Acked-by: "Zhang, Xiantao"
Index: xen-4.2.3-testing/xen/drivers/passthrough/amd/iommu_cmd.c
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/passthrough/amd/iommu_cmd.c
+++ xen-4.2.3-testing/xen/drivers/passthrough/amd/iommu_cmd.c
@@ -285,12 +285,12 @@ void invalidate_iommu_all(struct amd_iom
send_iommu_command(iommu, cmd);
}
-void amd_iommu_flush_iotlb(struct pci_dev *pdev,
+void amd_iommu_flush_iotlb(u8 devfn, const struct pci_dev *pdev,
uint64_t gaddr, unsigned int order)
{
unsigned long flags;
struct amd_iommu *iommu;
- unsigned int bdf, req_id, queueid, maxpend;
+ unsigned int req_id, queueid, maxpend;
struct pci_ats_dev *ats_pdev;
if ( !ats_enabled )
@@ -303,8 +303,8 @@ void amd_iommu_flush_iotlb(struct pci_de
if ( !pci_ats_enabled(ats_pdev->seg, ats_pdev->bus, ats_pdev->devfn) )
return;
- bdf = PCI_BDF2(ats_pdev->bus, ats_pdev->devfn);
- iommu = find_iommu_for_device(ats_pdev->seg, bdf);
+ iommu = find_iommu_for_device(ats_pdev->seg,
+ PCI_BDF2(ats_pdev->bus, ats_pdev->devfn));
if ( !iommu )
{
@@ -317,7 +317,7 @@ void amd_iommu_flush_iotlb(struct pci_de
if ( !iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) )
return;
- req_id = get_dma_requestor_id(iommu->seg, bdf);
+ req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(ats_pdev->bus, devfn));
queueid = req_id;
maxpend = ats_pdev->ats_queue_depth & 0xff;
@@ -337,7 +337,7 @@ static void amd_iommu_flush_all_iotlbs(s
return;
for_each_pdev( d, pdev )
- amd_iommu_flush_iotlb(pdev, gaddr, order);
+ amd_iommu_flush_iotlb(pdev->devfn, pdev, gaddr, order);
}
/* Flush iommu cache after p2m changes. */
Index: xen-4.2.3-testing/xen/drivers/passthrough/amd/pci_amd_iommu.c
===================================================================
--- xen-4.2.3-testing.orig/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ xen-4.2.3-testing/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -138,7 +138,7 @@ static void amd_iommu_setup_domain_devic
if ( devfn == pdev->devfn )
enable_ats_device(iommu->seg, bus, devfn);
- amd_iommu_flush_iotlb(pdev, INV_IOMMU_ALL_PAGES_ADDRESS, 0);
+ amd_iommu_flush_iotlb(devfn, pdev, INV_IOMMU_ALL_PAGES_ADDRESS, 0);
}
}
Index: xen-4.2.3-testing/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
===================================================================
--- xen-4.2.3-testing.orig/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
+++ xen-4.2.3-testing/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
@@ -78,8 +78,8 @@ void iommu_dte_set_guest_cr3(u32 *dte, u
void amd_iommu_flush_all_pages(struct domain *d);
void amd_iommu_flush_pages(struct domain *d, unsigned long gfn,
unsigned int order);
-void amd_iommu_flush_iotlb(struct pci_dev *pdev, uint64_t gaddr,
- unsigned int order);
+void amd_iommu_flush_iotlb(u8 devfn, const struct pci_dev *pdev,
+ uint64_t gaddr, unsigned int order);
void amd_iommu_flush_device(struct amd_iommu *iommu, uint16_t bdf);
void amd_iommu_flush_intremap(struct amd_iommu *iommu, uint16_t bdf);
void amd_iommu_flush_all_caches(struct amd_iommu *iommu);
++++++ 26328-IOMMU-pdev-type.patch ++++++
References: bnc#787169
# HG changeset patch
# User Jan Beulich
# Date 1357559679 -3600
# Node ID 11fa145c880ee814aaf56a7f47f47ee3e5560c7c
# Parent 2a2c63f641ee3bda4ad552eb0b3ea479d37590cc
IOMMU/PCI: consolidate pdev_type() and cache its result for a given device
Add an "unknown" device types as well as one for PCI-to-PCIe bridges
(the latter of which other IOMMU code with or without this patch
doesn't appear to handle properly).
Make sure we don't mistake a device for which we can't access its
config space as a legacy PCI device (after all we in fact don't know
how to deal with such a device, and hence shouldn't try to).
Signed-off-by: Jan Beulich
Acked-by: "Zhang, Xiantao"
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -144,7 +144,7 @@ static struct pci_dev *alloc_pdev(struct
spin_lock_init(&pdev->msix_table_lock);
/* update bus2bridge */
- switch ( pdev_type(pseg->nr, bus, devfn) )
+ switch ( pdev->type = pdev_type(pseg->nr, bus, devfn) )
{
u8 sec_bus, sub_bus;
@@ -184,7 +184,7 @@ static struct pci_dev *alloc_pdev(struct
static void free_pdev(struct pci_seg *pseg, struct pci_dev *pdev)
{
/* update bus2bridge */
- switch ( pdev_type(pseg->nr, pdev->bus, pdev->devfn) )
+ switch ( pdev->type )
{
u8 dev, func, sec_bus, sub_bus;
@@ -202,6 +202,9 @@ static void free_pdev(struct pci_seg *ps
pseg->bus2bridge[sec_bus] = pseg->bus2bridge[pdev->bus];
spin_unlock(&pseg->bus2bridge_lock);
break;
+
+ default:
+ break;
}
list_del(&pdev->alldevs_list);
@@ -563,20 +566,30 @@ void pci_release_devices(struct domain *
#define PCI_CLASS_BRIDGE_PCI 0x0604
-int pdev_type(u16 seg, u8 bus, u8 devfn)
+enum pdev_type pdev_type(u16 seg, u8 bus, u8 devfn)
{
u16 class_device, creg;
u8 d = PCI_SLOT(devfn), f = PCI_FUNC(devfn);
int pos = pci_find_cap_offset(seg, bus, d, f, PCI_CAP_ID_EXP);
class_device = pci_conf_read16(seg, bus, d, f, PCI_CLASS_DEVICE);
- if ( class_device == PCI_CLASS_BRIDGE_PCI )
+ switch ( class_device )
{
+ case PCI_CLASS_BRIDGE_PCI:
if ( !pos )
return DEV_TYPE_LEGACY_PCI_BRIDGE;
creg = pci_conf_read16(seg, bus, d, f, pos + PCI_EXP_FLAGS);
- return ((creg & PCI_EXP_FLAGS_TYPE) >> 4) == PCI_EXP_TYPE_PCI_BRIDGE ?
- DEV_TYPE_PCIe2PCI_BRIDGE : DEV_TYPE_PCIe_BRIDGE;
+ switch ( (creg & PCI_EXP_FLAGS_TYPE) >> 4 )
+ {
+ case PCI_EXP_TYPE_PCI_BRIDGE:
+ return DEV_TYPE_PCIe2PCI_BRIDGE;
+ case PCI_EXP_TYPE_PCIE_BRIDGE:
+ return DEV_TYPE_PCI2PCIe_BRIDGE;
+ }
+ return DEV_TYPE_PCIe_BRIDGE;
+
+ case 0x0000: case 0xffff:
+ return DEV_TYPE_PCI_UNKNOWN;
}
return pos ? DEV_TYPE_PCIe_ENDPOINT : DEV_TYPE_PCI;
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -426,7 +426,6 @@ void io_apic_write_remap_rte(
static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire)
{
- int type;
u16 seg;
u8 bus, devfn, secbus;
int ret;
@@ -437,8 +436,7 @@ static void set_msi_source_id(struct pci
seg = pdev->seg;
bus = pdev->bus;
devfn = pdev->devfn;
- type = pdev_type(seg, bus, devfn);
- switch ( type )
+ switch ( pdev->type )
{
case DEV_TYPE_PCIe_ENDPOINT:
case DEV_TYPE_PCIe_BRIDGE:
@@ -448,7 +446,7 @@ static void set_msi_source_id(struct pci
case DEV_TYPE_PCI:
case DEV_TYPE_LEGACY_PCI_BRIDGE:
- /* case DEV_TYPE_PCI2PCIe_BRIDGE: */
+ case DEV_TYPE_PCI2PCIe_BRIDGE:
ret = find_upstream_bridge(seg, &bus, &devfn, &secbus);
if ( ret == 0 ) /* integrated PCI device */
{
@@ -474,7 +472,7 @@ static void set_msi_source_id(struct pci
default:
dprintk(XENLOG_WARNING VTDPREFIX,
"d%d: unknown(%u): %04x:%02x:%02x.%u\n",
- pdev->domain->domain_id, type,
+ pdev->domain->domain_id, pdev->type,
seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
break;
}
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1453,7 +1453,6 @@ static int domain_context_mapping(
{
struct acpi_drhd_unit *drhd;
int ret = 0;
- u32 type;
u8 seg = pdev->seg, bus = pdev->bus, secbus;
drhd = acpi_find_matched_drhd_unit(pdev);
@@ -1462,8 +1461,7 @@ static int domain_context_mapping(
ASSERT(spin_is_locked(&pcidevs_lock));
- type = pdev_type(seg, bus, devfn);
- switch ( type )
+ switch ( pdev->type )
{
case DEV_TYPE_PCIe_BRIDGE:
case DEV_TYPE_PCIe2PCI_BRIDGE:
@@ -1513,7 +1511,7 @@ static int domain_context_mapping(
default:
dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): %04x:%02x:%02x.%u\n",
- domain->domain_id, type,
+ domain->domain_id, pdev->type,
seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
ret = -EINVAL;
break;
@@ -1585,7 +1583,6 @@ static int domain_context_unmap(
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
int ret = 0;
- u32 type;
u8 seg = pdev->seg, bus = pdev->bus, tmp_bus, tmp_devfn, secbus;
int found = 0;
@@ -1594,8 +1591,7 @@ static int domain_context_unmap(
return -ENODEV;
iommu = drhd->iommu;
- type = pdev_type(seg, bus, devfn);
- switch ( type )
+ switch ( pdev->type )
{
case DEV_TYPE_PCIe_BRIDGE:
case DEV_TYPE_PCIe2PCI_BRIDGE:
@@ -1642,7 +1638,7 @@ static int domain_context_unmap(
default:
dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): %04x:%02x:%02x.%u\n",
- domain->domain_id, type,
+ domain->domain_id, pdev->type,
seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
ret = -EINVAL;
goto out;
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -63,6 +63,17 @@ struct pci_dev {
const u16 seg;
const u8 bus;
const u8 devfn;
+
+ enum pdev_type {
+ DEV_TYPE_PCI_UNKNOWN,
+ DEV_TYPE_PCIe_ENDPOINT,
+ DEV_TYPE_PCIe_BRIDGE, // PCIe root port, switch
+ DEV_TYPE_PCIe2PCI_BRIDGE, // PCIe-to-PCI/PCIx bridge
+ DEV_TYPE_PCI2PCIe_BRIDGE, // PCI/PCIx-to-PCIe bridge
+ DEV_TYPE_LEGACY_PCI_BRIDGE, // Legacy PCI bridge
+ DEV_TYPE_PCI,
+ } type;
+
struct pci_dev_info info;
struct arch_pci_dev arch;
struct {
@@ -84,18 +95,10 @@ struct pci_dev {
extern spinlock_t pcidevs_lock;
-enum {
- DEV_TYPE_PCIe_ENDPOINT,
- DEV_TYPE_PCIe_BRIDGE, // PCIe root port, switch
- DEV_TYPE_PCIe2PCI_BRIDGE, // PCIe-to-PCI/PCIx bridge
- DEV_TYPE_LEGACY_PCI_BRIDGE, // Legacy PCI bridge
- DEV_TYPE_PCI,
-};
-
bool_t pci_known_segment(u16 seg);
int pci_device_detect(u16 seg, u8 bus, u8 dev, u8 func);
int scan_pci_devices(void);
-int pdev_type(u16 seg, u8 bus, u8 devfn);
+enum pdev_type pdev_type(u16 seg, u8 bus, u8 devfn);
int find_upstream_bridge(u16 seg, u8 *bus, u8 *devfn, u8 *secbus);
struct pci_dev *pci_lock_pdev(int seg, int bus, int devfn);
struct pci_dev *pci_lock_domain_pdev(
--- a/xen/include/xen/pci_regs.h
+++ b/xen/include/xen/pci_regs.h
@@ -371,6 +371,9 @@
#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
+#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 /* PCI/PCI-X to PCIE Bridge */
+#define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */
+#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
#define PCI_EXP_DEVCAP 4 /* Device capabilities */
++++++ 26329-IOMMU-phantom-dev.patch ++++++
References: bnc#787169
# HG changeset patch
# User Jan Beulich
# Date 1357559742 -3600
# Node ID c9a01b396cb4eaedef30e9a6ed615115a9f8bfc5
# Parent 11fa145c880ee814aaf56a7f47f47ee3e5560c7c
IOMMU: add phantom function support
Apart from generating device context entries for the base function,
all phantom functions also need context entries to be generated for
them.
In order to distinguish different use cases, a variant of
pci_get_pdev() is being introduced that, even when passed a phantom
function number, would return the underlying actual device.
Signed-off-by: Jan Beulich
Acked-by: "Zhang, Xiantao"
Index: xen-4.2.4-testing/xen/drivers/passthrough/amd/iommu_cmd.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/amd/iommu_cmd.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/amd/iommu_cmd.c
@@ -337,7 +337,15 @@ static void amd_iommu_flush_all_iotlbs(s
return;
for_each_pdev( d, pdev )
- amd_iommu_flush_iotlb(pdev->devfn, pdev, gaddr, order);
+ {
+ u8 devfn = pdev->devfn;
+
+ do {
+ amd_iommu_flush_iotlb(devfn, pdev, gaddr, order);
+ devfn += pdev->phantom_stride;
+ } while ( devfn != pdev->devfn &&
+ PCI_SLOT(devfn) == PCI_SLOT(pdev->devfn) );
+ }
}
/* Flush iommu cache after p2m changes. */
Index: xen-4.2.4-testing/xen/drivers/passthrough/amd/iommu_init.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/amd/iommu_init.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/amd/iommu_init.c
@@ -709,7 +709,7 @@ void parse_ppr_log_entry(struct amd_iomm
devfn = PCI_DEVFN2(device_id);
spin_lock(&pcidevs_lock);
- pdev = pci_get_pdev(iommu->seg, bus, devfn);
+ pdev = pci_get_real_pdev(iommu->seg, bus, devfn);
spin_unlock(&pcidevs_lock);
if ( pdev )
Index: xen-4.2.4-testing/xen/drivers/passthrough/amd/iommu_map.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/amd/iommu_map.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/amd/iommu_map.c
@@ -612,7 +612,6 @@ static int update_paging_mode(struct dom
for_each_pdev( d, pdev )
{
bdf = (pdev->bus << 8) | pdev->devfn;
- req_id = get_dma_requestor_id(pdev->seg, bdf);
iommu = find_iommu_for_device(pdev->seg, bdf);
if ( !iommu )
{
@@ -621,16 +620,21 @@ static int update_paging_mode(struct dom
}
spin_lock_irqsave(&iommu->lock, flags);
- device_entry = iommu->dev_table.buffer +
- (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE);
+ do {
+ req_id = get_dma_requestor_id(pdev->seg, bdf);
+ device_entry = iommu->dev_table.buffer +
+ (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE);
- /* valid = 0 only works for dom0 passthrough mode */
- amd_iommu_set_root_page_table((u32 *)device_entry,
- page_to_maddr(hd->root_table),
- hd->domain_id,
- hd->paging_mode, 1);
+ /* valid = 0 only works for dom0 passthrough mode */
+ amd_iommu_set_root_page_table((u32 *)device_entry,
+ page_to_maddr(hd->root_table),
+ hd->domain_id,
+ hd->paging_mode, 1);
- amd_iommu_flush_device(iommu, req_id);
+ amd_iommu_flush_device(iommu, req_id);
+ bdf += pdev->phantom_stride;
+ } while ( PCI_DEVFN2(bdf) != pdev->devfn &&
+ PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
spin_unlock_irqrestore(&iommu->lock, flags);
}
Index: xen-4.2.4-testing/xen/drivers/passthrough/iommu.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/iommu.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/iommu.c
@@ -157,6 +157,8 @@ void __init iommu_dom0_init(struct domai
int iommu_add_device(struct pci_dev *pdev)
{
struct hvm_iommu *hd;
+ int rc;
+ u8 devfn;
if ( !pdev->domain )
return -EINVAL;
@@ -167,7 +169,20 @@ int iommu_add_device(struct pci_dev *pde
if ( !iommu_enabled || !hd->platform_ops )
return 0;
- return hd->platform_ops->add_device(pdev->devfn, pdev);
+ rc = hd->platform_ops->add_device(pdev->devfn, pdev);
+ if ( rc || !pdev->phantom_stride )
+ return rc;
+
+ for ( devfn = pdev->devfn ; ; )
+ {
+ devfn += pdev->phantom_stride;
+ if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+ return 0;
+ rc = hd->platform_ops->add_device(devfn, pdev);
+ if ( rc )
+ printk(XENLOG_WARNING "IOMMU: add %04x:%02x:%02x.%u failed (%d)\n",
+ pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn), rc);
+ }
}
int iommu_enable_device(struct pci_dev *pdev)
@@ -190,6 +205,8 @@ int iommu_enable_device(struct pci_dev *
int iommu_remove_device(struct pci_dev *pdev)
{
struct hvm_iommu *hd;
+ u8 devfn;
+
if ( !pdev->domain )
return -EINVAL;
@@ -197,6 +214,22 @@ int iommu_remove_device(struct pci_dev *
if ( !iommu_enabled || !hd->platform_ops )
return 0;
+ for ( devfn = pdev->devfn ; pdev->phantom_stride; )
+ {
+ int rc;
+
+ devfn += pdev->phantom_stride;
+ if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+ break;
+ rc = hd->platform_ops->remove_device(devfn, pdev);
+ if ( !rc )
+ continue;
+
+ printk(XENLOG_ERR "IOMMU: remove %04x:%02x:%02x.%u failed (%d)\n",
+ pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn), rc);
+ return rc;
+ }
+
return hd->platform_ops->remove_device(pdev->devfn, pdev);
}
@@ -244,6 +277,18 @@ static int assign_device(struct domain *
if ( (rc = hd->platform_ops->assign_device(d, devfn, pdev)) )
goto done;
+ for ( ; pdev->phantom_stride; rc = 0 )
+ {
+ devfn += pdev->phantom_stride;
+ if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+ break;
+ rc = hd->platform_ops->assign_device(d, devfn, pdev);
+ if ( rc )
+ printk(XENLOG_G_WARNING "d%d: assign %04x:%02x:%02x.%u failed (%d)\n",
+ d->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ rc);
+ }
+
if ( has_arch_pdevs(d) && !need_iommu(d) )
{
d->need_iommu = 1;
@@ -378,6 +423,21 @@ int deassign_device(struct domain *d, u1
if ( !pdev )
return -ENODEV;
+ while ( pdev->phantom_stride )
+ {
+ devfn += pdev->phantom_stride;
+ if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+ break;
+ ret = hd->platform_ops->reassign_device(d, dom0, devfn, pdev);
+ if ( !ret )
+ continue;
+
+ printk(XENLOG_G_ERR "d%d: deassign %04x:%02x:%02x.%u failed (%d)\n",
+ d->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), ret);
+ return ret;
+ }
+
+ devfn = pdev->devfn;
ret = hd->platform_ops->reassign_device(d, dom0, devfn, pdev);
if ( ret )
{
Index: xen-4.2.4-testing/xen/drivers/passthrough/pci.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/pci.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/pci.c
@@ -146,6 +146,8 @@ static struct pci_dev *alloc_pdev(struct
/* update bus2bridge */
switch ( pdev->type = pdev_type(pseg->nr, bus, devfn) )
{
+ int pos;
+ u16 cap;
u8 sec_bus, sub_bus;
case DEV_TYPE_PCIe_BRIDGE:
@@ -169,6 +171,20 @@ static struct pci_dev *alloc_pdev(struct
break;
case DEV_TYPE_PCIe_ENDPOINT:
+ pos = pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), PCI_CAP_ID_EXP);
+ BUG_ON(!pos);
+ cap = pci_conf_read16(pseg->nr, bus, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), pos + PCI_EXP_DEVCAP);
+ if ( cap & PCI_EXP_DEVCAP_PHANTOM )
+ {
+ pdev->phantom_stride = 8 >> MASK_EXTR(cap,
+ PCI_EXP_DEVCAP_PHANTOM);
+ if ( PCI_FUNC(devfn) >= pdev->phantom_stride )
+ pdev->phantom_stride = 0;
+ }
+ break;
+
case DEV_TYPE_PCI:
break;
@@ -266,6 +282,27 @@ struct pci_dev *pci_get_pdev(int seg, in
return NULL;
}
+struct pci_dev *pci_get_real_pdev(int seg, int bus, int devfn)
+{
+ struct pci_dev *pdev;
+ int stride;
+
+ if ( seg < 0 || bus < 0 || devfn < 0 )
+ return NULL;
+
+ for ( pdev = pci_get_pdev(seg, bus, devfn), stride = 4;
+ !pdev && stride; stride >>= 1 )
+ {
+ if ( !(devfn & (8 - stride)) )
+ continue;
+ pdev = pci_get_pdev(seg, bus, devfn & ~(8 - stride));
+ if ( pdev && stride != pdev->phantom_stride )
+ pdev = NULL;
+ }
+
+ return pdev;
+}
+
struct pci_dev *pci_get_pdev_by_domain(
struct domain *d, int seg, int bus, int devfn)
{
@@ -464,8 +501,19 @@ int pci_add_device(u16 seg, u8 bus, u8 d
out:
spin_unlock(&pcidevs_lock);
- printk(XENLOG_DEBUG "PCI add %s %04x:%02x:%02x.%u\n", pdev_type,
- seg, bus, slot, func);
+ if ( !ret )
+ {
+ printk(XENLOG_DEBUG "PCI add %s %04x:%02x:%02x.%u\n", pdev_type,
+ seg, bus, slot, func);
+ while ( pdev->phantom_stride )
+ {
+ func += pdev->phantom_stride;
+ if ( PCI_SLOT(func) )
+ break;
+ printk(XENLOG_DEBUG "PCI phantom %04x:%02x:%02x.%u\n",
+ seg, bus, slot, func);
+ }
+ }
return ret;
}
@@ -657,7 +705,7 @@ void pci_check_disable_device(u16 seg, u
u16 cword;
spin_lock(&pcidevs_lock);
- pdev = pci_get_pdev(seg, bus, devfn);
+ pdev = pci_get_real_pdev(seg, bus, devfn);
if ( pdev )
{
if ( now < pdev->fault.time ||
@@ -674,6 +722,7 @@ void pci_check_disable_device(u16 seg, u
/* Tell the device to stop DMAing; we can't rely on the guest to
* control it for us. */
+ devfn = pdev->devfn;
cword = pci_conf_read16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
PCI_COMMAND);
pci_conf_write16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
@@ -731,6 +780,27 @@ struct setup_dom0 {
int (*handler)(u8 devfn, struct pci_dev *);
};
+static void setup_one_dom0_device(const struct setup_dom0 *ctxt,
+ struct pci_dev *pdev)
+{
+ u8 devfn = pdev->devfn;
+
+ do {
+ int err = ctxt->handler(devfn, pdev);
+
+ if ( err )
+ {
+ printk(XENLOG_ERR "setup %04x:%02x:%02x.%u for d%d failed (%d)\n",
+ pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ ctxt->d->domain_id, err);
+ if ( devfn == pdev->devfn )
+ return;
+ }
+ devfn += pdev->phantom_stride;
+ } while ( devfn != pdev->devfn &&
+ PCI_SLOT(devfn) == PCI_SLOT(pdev->devfn) );
+}
+
static int __init _setup_dom0_pci_devices(struct pci_seg *pseg, void *arg)
{
struct setup_dom0 *ctxt = arg;
@@ -747,7 +817,7 @@ static int __init _setup_dom0_pci_device
pdev->domain = ctxt->d;
list_add(&pdev->domain_list, &ctxt->d->arch.pdev_list);
- ctxt->handler(devfn, pdev);
+ setup_one_dom0_device(ctxt, pdev);
}
}
Index: xen-4.2.4-testing/xen/include/xen/lib.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/xen/lib.h
+++ xen-4.2.4-testing/xen/include/xen/lib.h
@@ -58,6 +58,9 @@ do {
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]) + __must_be_array(x))
+#define MASK_EXTR(v, m) (((v) & (m)) / ((m) & -(m)))
+#define MASK_INSR(v, m) (((v) * ((m) & -(m))) & (m))
+
#define reserve_bootmem(_p,_l) ((void)0)
struct domain;
Index: xen-4.2.4-testing/xen/include/xen/pci.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/xen/pci.h
+++ xen-4.2.4-testing/xen/include/xen/pci.h
@@ -64,6 +64,8 @@ struct pci_dev {
const u8 bus;
const u8 devfn;
+ u8 phantom_stride;
+
enum pdev_type {
DEV_TYPE_PCI_UNKNOWN,
DEV_TYPE_PCIe_ENDPOINT,
@@ -114,6 +116,7 @@ int pci_remove_device(u16 seg, u8 bus, u
int pci_ro_device(int seg, int bus, int devfn);
void arch_pci_ro_device(int seg, int bdf);
struct pci_dev *pci_get_pdev(int seg, int bus, int devfn);
+struct pci_dev *pci_get_real_pdev(int seg, int bus, int devfn);
struct pci_dev *pci_get_pdev_by_domain(
struct domain *, int seg, int bus, int devfn);
void pci_check_disable_device(u16 seg, u8 bus, u8 devfn);
++++++ 26330-VT-d-phantom-MSI.patch ++++++
References: bnc#787169
# HG changeset patch
# User Jan Beulich
# Date 1357559812 -3600
# Node ID b514b7118958327605e33dd387944832bc8d734a
# Parent c9a01b396cb4eaedef30e9a6ed615115a9f8bfc5
VT-d: relax source qualifier for MSI of phantom functions
With ordinary requests allowed to come from phantom functions, the
remapping tables ought to be set up to allow for MSI triggers to come
from other than the "real" device too.
Signed-off-by: Jan Beulich
Acked-by: "Zhang, Xiantao"
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -438,10 +438,19 @@ static void set_msi_source_id(struct pci
devfn = pdev->devfn;
switch ( pdev->type )
{
+ unsigned int sq;
+
case DEV_TYPE_PCIe_ENDPOINT:
case DEV_TYPE_PCIe_BRIDGE:
case DEV_TYPE_PCIe2PCI_BRIDGE:
- set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16, PCI_BDF2(bus, devfn));
+ switch ( pdev->phantom_stride )
+ {
+ case 1: sq = SQ_13_IGNORE_3; break;
+ case 2: sq = SQ_13_IGNORE_2; break;
+ case 4: sq = SQ_13_IGNORE_1; break;
+ default: sq = SQ_ALL_16; break;
+ }
+ set_ire_sid(ire, SVT_VERIFY_SID_SQ, sq, PCI_BDF2(bus, devfn));
break;
case DEV_TYPE_PCI:
++++++ 26331-IOMMU-phantom-dev-quirk.patch ++++++
References: bnc#787169
# HG changeset patch
# User Jan Beulich
# Date 1357559889 -3600
# Node ID 23c4bbc0111dd807561b2c62cbc5798220943a0d
# Parent b514b7118958327605e33dd387944832bc8d734a
IOMMU: add option to specify devices behaving like ones using phantom functions
At least certain Marvell SATA controllers are known to issue bus master
requests with a non-zero function as origin, despite themselves being
single function devices.
Signed-off-by: Jan Beulich
Acked-by: "Zhang, Xiantao"
Index: xen-4.2.2-testing/docs/misc/xen-command-line.markdown
===================================================================
--- xen-4.2.2-testing.orig/docs/misc/xen-command-line.markdown
+++ xen-4.2.2-testing/docs/misc/xen-command-line.markdown
@@ -679,6 +679,16 @@ Defaults to booting secondary processors
Default: `on`
+### pci-phantom
+> `=[<seg>:]<bus>:<device>,<stride>`
+
+Mark a group of PCI devices as using phantom functions without actually
+advertising so, so the IOMMU can create translation contexts for them.
+
+All numbers specified must be hexadecimal ones.
+
+This option can be specified more than once (up to 8 times at present).
+
### ple\_gap
`= <integer>`
Index: xen-4.2.2-testing/xen/drivers/passthrough/pci.c
===================================================================
--- xen-4.2.2-testing.orig/xen/drivers/passthrough/pci.c
+++ xen-4.2.2-testing/xen/drivers/passthrough/pci.c
@@ -123,6 +123,49 @@ const unsigned long *pci_get_ro_map(u16
return pseg ? pseg->ro_map : NULL;
}
+static struct phantom_dev {
+ u16 seg;
+ u8 bus, slot, stride;
+} phantom_devs[8];
+static unsigned int nr_phantom_devs;
+
+static void __init parse_phantom_dev(char *str) {
+ const char *s = str;
+ struct phantom_dev phantom;
+
+ if ( !s || !*s || nr_phantom_devs >= ARRAY_SIZE(phantom_devs) )
+ return;
+
+ phantom.seg = simple_strtol(s, &s, 16);
+ if ( *s != ':' )
+ return;
+
+ phantom.bus = simple_strtol(s + 1, &s, 16);
+ if ( *s == ',' )
+ {
+ phantom.slot = phantom.bus;
+ phantom.bus = phantom.seg;
+ phantom.seg = 0;
+ }
+ else if ( *s == ':' )
+ phantom.slot = simple_strtol(s + 1, &s, 16);
+ else
+ return;
+
+ if ( *s != ',' )
+ return;
+ switch ( phantom.stride = simple_strtol(s + 1, &s, 0) )
+ {
+ case 1: case 2: case 4:
+ if ( *s )
+ default:
+ return;
+ }
+
+ phantom_devs[nr_phantom_devs++] = phantom;
+}
+custom_param("pci-phantom", parse_phantom_dev);
+
static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
{
struct pci_dev *pdev;
@@ -183,6 +226,20 @@ static struct pci_dev *alloc_pdev(struct
if ( PCI_FUNC(devfn) >= pdev->phantom_stride )
pdev->phantom_stride = 0;
}
+ else
+ {
+ unsigned int i;
+
+ for ( i = 0; i < nr_phantom_devs; ++i )
+ if ( phantom_devs[i].seg == pseg->nr &&
+ phantom_devs[i].bus == bus &&
+ phantom_devs[i].slot == PCI_SLOT(devfn) &&
+ phantom_devs[i].stride > PCI_FUNC(devfn) )
+ {
+ pdev->phantom_stride = phantom_devs[i].stride;
+ break;
+ }
+ }
break;
case DEV_TYPE_PCI:
++++++ 26341-hvm-firmware-passthrough.patch ++++++
fate#313584: pass bios information to XEN HVM guest
# HG changeset patch
# User Ross Philipson
# Date 1357838188 0
# Node ID 07bf59a7ce837bd795e2df2f28166cfe41990d3d
# Parent 19fd1237ff0dfa3d97a896d6ed6fbbd33f816a9f
HVM xenstore strings and firmware passthrough header
Add public HVM definitions header for xenstore strings used in
HVMLOADER. In addition this header describes the use of the firmware
passthrough values set using xenstore.
Signed-off-by: Ross Philipson
Committed-by: Keir Fraser
diff -r 19fd1237ff0d -r 07bf59a7ce83 xen/include/public/hvm/hvm_xs_strings.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/public/hvm/hvm_xs_strings.h Thu Jan 10 17:16:28 2013 +0000
@@ -0,0 +1,79 @@
+/******************************************************************************
+ * hvm/hvm_xs_strings.h
+ *
+ * HVM xenstore strings used in HVMLOADER.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_PUBLIC_HVM_HVM_XS_STRINGS_H__
+#define __XEN_PUBLIC_HVM_HVM_XS_STRINGS_H__
+
+#define HVM_XS_HVMLOADER "hvmloader"
+#define HVM_XS_BIOS "hvmloader/bios"
+#define HVM_XS_GENERATION_ID_ADDRESS "hvmloader/generation-id-address"
+
+/* The following values allow additional ACPI tables to be added to the
+ * virtual ACPI BIOS that hvmloader constructs. The values specify the guest
+ * physical address and length of a block of ACPI tables to add. The format of
+ * the block is simply concatenated raw tables (which specify their own length
+ * in the ACPI header).
+ */
+#define HVM_XS_ACPI_PT_ADDRESS "hvmloader/acpi/address"
+#define HVM_XS_ACPI_PT_LENGTH "hvmloader/acpi/length"
+
+/* Any number of SMBIOS types can be passed through to an HVM guest using
+ * the following xenstore values. The values specify the guest physical
+ * address and length of a block of SMBIOS structures for hvmloader to use.
+ * The block is formatted in the following way:
+ *
+ * <length><struct><length><struct>...
+ *
+ * Each length separator is a 32b integer indicating the length of the next
+ * SMBIOS structure. For DMTF defined types (0 - 121), the passed in struct
+ * will replace the default structure in hvmloader. In addition, any
+ * OEM/vendortypes (128 - 255) will all be added.
+ */
+#define HVM_XS_SMBIOS_PT_ADDRESS "hvmloader/smbios/address"
+#define HVM_XS_SMBIOS_PT_LENGTH "hvmloader/smbios/length"
+
+/* Set to 1 to enable SMBIOS default portable battery (type 22) values. */
+#define HVM_XS_SMBIOS_DEFAULT_BATTERY "hvmloader/smbios/default_battery"
+
+/* The following xenstore values are used to override some of the default
+ * string values in the SMBIOS table constructed in hvmloader.
+ */
+#define HVM_XS_BIOS_STRINGS "bios-strings"
+#define HVM_XS_BIOS_VENDOR "bios-strings/bios-vendor"
+#define HVM_XS_BIOS_VERSION "bios-strings/bios-version"
+#define HVM_XS_SYSTEM_MANUFACTURER "bios-strings/system-manufacturer"
+#define HVM_XS_SYSTEM_PRODUCT_NAME "bios-strings/system-product-name"
+#define HVM_XS_SYSTEM_VERSION "bios-strings/system-version"
+#define HVM_XS_SYSTEM_SERIAL_NUMBER "bios-strings/system-serial-number"
+#define HVM_XS_ENCLOSURE_MANUFACTURER "bios-strings/enclosure-manufacturer"
+#define HVM_XS_ENCLOSURE_SERIAL_NUMBER "bios-strings/enclosure-serial-number"
+#define HVM_XS_BATTERY_MANUFACTURER "bios-strings/battery-manufacturer"
+#define HVM_XS_BATTERY_DEVICE_NAME "bios-strings/battery-device-name"
+
+/* 1 to 99 OEM strings can be set in xenstore using values of the form
+ * below. These strings will be loaded into the SMBIOS type 11 structure.
+ */
+#define HVM_XS_OEM_STRINGS "bios-strings/oem-%02d"
+
+#endif /* __XEN_PUBLIC_HVM_HVM_XS_STRINGS_H__ */
++++++ 26342-hvm-firmware-passthrough.patch ++++++
fate#313584: pass bios information to XEN HVM guest
# HG changeset patch
# User Ross Philipson
# Date 1357838241 0
# Node ID cabf395a6c849cc65e56f1640b18db0c3e0faf5d
# Parent 07bf59a7ce837bd795e2df2f28166cfe41990d3d
HVM firmware passthrough control tools support
Xen control tools support for loading the firmware passthrough blocks
during domain construction. SMBIOS and ACPI blocks are passed in using
the new xc_hvm_build_args structure. Each block is read and loaded
into the new domain address space behind the HVMLOADER image. The base
address for the two blocks is returned as an out parameter to the
caller via the args structure.
Signed-off-by: Ross Philipson
Committed-by: Keir Fraser
Index: xen-4.2.3-testing/tools/libxc/xc_hvm_build_arm.c
===================================================================
--- xen-4.2.3-testing.orig/tools/libxc/xc_hvm_build_arm.c
+++ xen-4.2.3-testing/tools/libxc/xc_hvm_build_arm.c
@@ -22,7 +22,7 @@
#include
int xc_hvm_build(xc_interface *xch, uint32_t domid,
- const struct xc_hvm_build_args *hvm_args)
+ struct xc_hvm_build_args *hvm_args)
{
errno = ENOSYS;
return -1;
Index: xen-4.2.3-testing/tools/libxc/xc_hvm_build_x86.c
===================================================================
--- xen-4.2.3-testing.orig/tools/libxc/xc_hvm_build_x86.c
+++ xen-4.2.3-testing/tools/libxc/xc_hvm_build_x86.c
@@ -49,6 +49,40 @@
#define NR_SPECIAL_PAGES 8
#define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x))
+static int modules_init(struct xc_hvm_build_args *args,
+ uint64_t vend, struct elf_binary *elf,
+ uint64_t *mstart_out, uint64_t *mend_out)
+{
+#define MODULE_ALIGN 1UL << 7
+#define MB_ALIGN 1UL << 20
+#define MKALIGN(x, a) (((uint64_t)(x) + (a) - 1) & ~(uint64_t)((a) - 1))
+ uint64_t total_len = 0, offset1 = 0;
+
+ if ( (args->acpi_module.length == 0)&&(args->smbios_module.length == 0) )
+ return 0;
+
+ /* Find the total length for the firmware modules with a reasonable large
+ * alignment size to align each the modules.
+ */
+ total_len = MKALIGN(args->acpi_module.length, MODULE_ALIGN);
+ offset1 = total_len;
+ total_len += MKALIGN(args->smbios_module.length, MODULE_ALIGN);
+
+ /* Want to place the modules 1Mb+change behind the loader image. */
+ *mstart_out = MKALIGN(elf->pend, MB_ALIGN) + (MB_ALIGN);
+ *mend_out = *mstart_out + total_len;
+
+ if ( *mend_out > vend )
+ return -1;
+
+ if ( args->acpi_module.length != 0 )
+ args->acpi_module.guest_addr_out = *mstart_out;
+ if ( args->smbios_module.length != 0 )
+ args->smbios_module.guest_addr_out = *mstart_out + offset1;
+
+ return 0;
+}
+
static void build_hvm_info(void *hvm_info_page, uint64_t mem_size,
uint64_t mmio_start, uint64_t mmio_size)
{
@@ -86,9 +120,8 @@ static void build_hvm_info(void *hvm_inf
hvm_info->checksum = -sum;
}
-static int loadelfimage(
- xc_interface *xch,
- struct elf_binary *elf, uint32_t dom, unsigned long *parray)
+static int loadelfimage(xc_interface *xch, struct elf_binary *elf,
+ uint32_t dom, unsigned long *parray)
{
privcmd_mmap_entry_t *entries = NULL;
unsigned long pfn_start = elf->pstart >> PAGE_SHIFT;
@@ -128,6 +161,66 @@ static int loadelfimage(
return rc;
}
+static int loadmodules(xc_interface *xch,
+ struct xc_hvm_build_args *args,
+ uint64_t mstart, uint64_t mend,
+ uint32_t dom, unsigned long *parray)
+{
+ privcmd_mmap_entry_t *entries = NULL;
+ unsigned long pfn_start;
+ unsigned long pfn_end;
+ size_t pages;
+ uint32_t i;
+ uint8_t *dest;
+ int rc = -1;
+
+ if ( (mstart == 0)||(mend == 0) )
+ return 0;
+
+ pfn_start = (unsigned long)(mstart >> PAGE_SHIFT);
+ pfn_end = (unsigned long)((mend + PAGE_SIZE - 1) >> PAGE_SHIFT);
+ pages = pfn_end - pfn_start;
+
+ /* Map address space for module list. */
+ entries = calloc(pages, sizeof(privcmd_mmap_entry_t));
+ if ( entries == NULL )
+ goto error_out;
+
+ for ( i = 0; i < pages; i++ )
+ entries[i].mfn = parray[(mstart >> PAGE_SHIFT) + i];
+
+ dest = xc_map_foreign_ranges(
+ xch, dom, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, 1 << PAGE_SHIFT,
+ entries, pages);
+ if ( dest == NULL )
+ goto error_out;
+
+ /* Zero the range so padding is clear between modules */
+ memset(dest, 0, pages << PAGE_SHIFT);
+
+ /* Load modules into range */
+ if ( args->acpi_module.length != 0 )
+ {
+ memcpy(dest,
+ args->acpi_module.data,
+ args->acpi_module.length);
+ }
+ if ( args->smbios_module.length != 0 )
+ {
+ memcpy(dest + (args->smbios_module.guest_addr_out - mstart),
+ args->smbios_module.data,
+ args->smbios_module.length);
+ }
+
+ munmap(dest, pages << PAGE_SHIFT);
+ rc = 0;
+
+ error_out:
+ free(entries);
+
+ return rc;
+}
+
/*
* Check whether there exists mmio hole in the specified memory range.
* Returns 1 if exists, else returns 0.
@@ -142,7 +235,7 @@ static int check_mmio_hole(uint64_t star
}
static int setup_guest(xc_interface *xch,
- uint32_t dom, const struct xc_hvm_build_args *args,
+ uint32_t dom, struct xc_hvm_build_args *args,
char *image, unsigned long image_size)
{
xen_pfn_t *page_array = NULL;
@@ -155,6 +248,7 @@ static int setup_guest(xc_interface *xch
uint32_t *ident_pt;
struct elf_binary elf;
uint64_t v_start, v_end;
+ uint64_t m_start = 0, m_end = 0;
int rc;
xen_capabilities_info_t caps;
unsigned long stat_normal_pages = 0, stat_2mb_pages = 0,
@@ -180,11 +274,19 @@ static int setup_guest(xc_interface *xch
goto error_out;
}
+ if ( modules_init(args, v_end, &elf, &m_start, &m_end) != 0 )
+ {
+ ERROR("Insufficient space to load modules.");
+ goto error_out;
+ }
+
IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
" Loader: %016"PRIx64"->%016"PRIx64"\n"
+ " Modules: %016"PRIx64"->%016"PRIx64"\n"
" TOTAL: %016"PRIx64"->%016"PRIx64"\n"
" ENTRY ADDRESS: %016"PRIx64"\n",
elf.pstart, elf.pend,
+ m_start, m_end,
v_start, v_end,
elf_uval(&elf, elf.ehdr, e_entry));
@@ -339,6 +441,9 @@ static int setup_guest(xc_interface *xch
if ( loadelfimage(xch, &elf, dom, page_array) != 0 )
goto error_out;
+ if ( loadmodules(xch, args, m_start, m_end, dom, page_array) != 0 )
+ goto error_out;
+
if ( (hvm_info_page = xc_map_foreign_range(
xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
HVM_INFO_PFN)) == NULL )
@@ -420,7 +525,7 @@ static int setup_guest(xc_interface *xch
* Create a domain for a virtualized Linux, using files/filenames.
*/
int xc_hvm_build(xc_interface *xch, uint32_t domid,
- const struct xc_hvm_build_args *hvm_args)
+ struct xc_hvm_build_args *hvm_args)
{
struct xc_hvm_build_args args = *hvm_args;
void *image;
@@ -448,6 +553,15 @@ int xc_hvm_build(xc_interface *xch, uint
sts = setup_guest(xch, domid, &args, image, image_size);
+ if (!sts)
+ {
+ /* Return module load addresses to caller */
+ hvm_args->acpi_module.guest_addr_out =
+ args.acpi_module.guest_addr_out;
+ hvm_args->smbios_module.guest_addr_out =
+ args.smbios_module.guest_addr_out;
+ }
+
free(image);
return sts;
@@ -468,6 +582,7 @@ int xc_hvm_build_target_mem(xc_interface
{
struct xc_hvm_build_args args = {};
+ memset(&args, 0, sizeof(struct xc_hvm_build_args));
args.mem_size = (uint64_t)memsize << 20;
args.mem_target = (uint64_t)target << 20;
args.image_file_name = image_name;
Index: xen-4.2.3-testing/tools/libxc/xenguest.h
===================================================================
--- xen-4.2.3-testing.orig/tools/libxc/xenguest.h
+++ xen-4.2.3-testing/tools/libxc/xenguest.h
@@ -211,11 +211,23 @@ int xc_linux_build_mem(xc_interface *xch
unsigned int console_evtchn,
unsigned long *console_mfn);
+struct xc_hvm_firmware_module {
+ uint8_t *data;
+ uint32_t length;
+ uint64_t guest_addr_out;
+};
+
struct xc_hvm_build_args {
uint64_t mem_size; /* Memory size in bytes. */
uint64_t mem_target; /* Memory target in bytes. */
uint64_t mmio_size; /* Size of the MMIO hole in bytes. */
const char *image_file_name; /* File name of the image to load. */
+
+ /* Extra ACPI tables passed to HVMLOADER */
+ struct xc_hvm_firmware_module acpi_module;
+
+ /* Extra SMBIOS structures passed to HVMLOADER */
+ struct xc_hvm_firmware_module smbios_module;
};
/**
@@ -228,7 +240,7 @@ struct xc_hvm_build_args {
* are optional.
*/
int xc_hvm_build(xc_interface *xch, uint32_t domid,
- const struct xc_hvm_build_args *hvm_args);
+ struct xc_hvm_build_args *hvm_args);
int xc_hvm_build_target_mem(xc_interface *xch,
uint32_t domid,
Index: xen-4.2.3-testing/tools/libxc/xg_private.c
===================================================================
--- xen-4.2.3-testing.orig/tools/libxc/xg_private.c
+++ xen-4.2.3-testing/tools/libxc/xg_private.c
@@ -192,7 +192,7 @@ unsigned long csum_page(void *page)
__attribute__((weak))
int xc_hvm_build(xc_interface *xch,
uint32_t domid,
- const struct xc_hvm_build_args *hvm_args)
+ struct xc_hvm_build_args *hvm_args)
{
errno = ENOSYS;
return -1;
++++++ 26343-hvm-firmware-passthrough.patch ++++++
++++ 645 lines (skipped)
++++++ 26344-hvm-firmware-passthrough.patch ++++++
fate#313584: pass bios information to XEN HVM guest
# HG changeset patch
# User Ross Philipson
# Date 1357838323 0
# Node ID b9c38bea15b117552ecb51809779c7cfef82dd44
# Parent a7ce196f40444fafbe8f13b2d80e4885d4321806
HVM firmware passthrough ACPI processing
ACPI table passthrough support allowing additional static tables and
SSDTs (AML code) to be loaded. These additional tables are added at
the end of the secondary table list in the RSDT/XSDT tables.
Signed-off-by: Ross Philipson
Committed-by: Keir Fraser
Index: xen-4.2.3-testing/tools/firmware/hvmloader/acpi/build.c
===================================================================
--- xen-4.2.3-testing.orig/tools/firmware/hvmloader/acpi/build.c
+++ xen-4.2.3-testing/tools/firmware/hvmloader/acpi/build.c
@@ -23,6 +23,9 @@
#include "ssdt_pm.h"
#include "../config.h"
#include "../util.h"
+#include
+
+#define ACPI_MAX_SECONDARY_TABLES 16
#define align16(sz) (((sz) + 15) & ~15)
#define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))
@@ -198,6 +201,52 @@ static struct acpi_20_waet *construct_wa
return waet;
}
+static int construct_passthrough_tables(unsigned long *table_ptrs,
+ int nr_tables)
+{
+ const char *s;
+ uint8_t *acpi_pt_addr;
+ uint32_t acpi_pt_length;
+ struct acpi_header *header;
+ int nr_added;
+ int nr_max = (ACPI_MAX_SECONDARY_TABLES - nr_tables - 1);
+ uint32_t total = 0;
+ uint8_t *buffer;
+
+ s = xenstore_read(HVM_XS_ACPI_PT_ADDRESS, NULL);
+ if ( s == NULL )
+ return 0;
+
+ acpi_pt_addr = (uint8_t*)(uint32_t)strtoll(s, NULL, 0);
+ if ( acpi_pt_addr == NULL )
+ return 0;
+
+ s = xenstore_read(HVM_XS_ACPI_PT_LENGTH, NULL);
+ if ( s == NULL )
+ return 0;
+
+ acpi_pt_length = (uint32_t)strtoll(s, NULL, 0);
+
+ for ( nr_added = 0; nr_added < nr_max; nr_added++ )
+ {
+ if ( (acpi_pt_length - total) < sizeof(struct acpi_header) )
+ break;
+
+ header = (struct acpi_header*)acpi_pt_addr;
+
+ buffer = mem_alloc(header->length, 16);
+ if ( buffer == NULL )
+ break;
+ memcpy(buffer, header, header->length);
+
+ table_ptrs[nr_tables++] = (unsigned long)buffer;
+ total += header->length;
+ acpi_pt_addr += header->length;
+ }
+
+ return nr_added;
+}
+
static int construct_secondary_tables(unsigned long *table_ptrs,
struct acpi_info *info)
{
@@ -295,6 +344,9 @@ static int construct_secondary_tables(un
}
}
+ /* Load any additional tables passed through. */
+ nr_tables += construct_passthrough_tables(table_ptrs, nr_tables);
+
table_ptrs[nr_tables] = 0;
return nr_tables;
}
@@ -329,7 +381,7 @@ void acpi_build_tables(struct acpi_confi
struct acpi_10_fadt *fadt_10;
struct acpi_20_facs *facs;
unsigned char *dsdt;
- unsigned long secondary_tables[16];
+ unsigned long secondary_tables[ACPI_MAX_SECONDARY_TABLES];
int nr_secondaries, i;
unsigned long vm_gid_addr;
++++++ 26369-libxl-devid.patch ++++++
commit 5420f26507fc5c9853eb1076401a8658d72669da
Author: Jim Fehlig
Date: Fri Jan 11 12:22:26 2013 +0000
libxl: Set vfb and vkb devid if not done so by the caller
Other devices set a sensible devid if the caller has not done so.
Do the same for vfb and vkb. While at it, factor out the common code
used to determine a sensible devid, so it can be used by other
libxl__device_*_add functions.
Signed-off-by: Jim Fehlig
Acked-by: Ian Campbell
Committed-by: Ian Campbell
Index: xen-4.2.4-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.2.4-testing.orig/tools/libxl/libxl.c
+++ xen-4.2.4-testing/tools/libxl/libxl.c
@@ -1715,6 +1715,26 @@ out:
return;
}
+/* common function to get next device id */
+static int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device)
+{
+ char *dompath, **l;
+ unsigned int nb;
+ int nextid = -1;
+
+ if (!(dompath = libxl__xs_get_dompath(gc, domid)))
+ return nextid;
+
+ l = libxl__xs_directory(gc, XBT_NULL,
+ GCSPRINTF("%s/device/%s", dompath, device), &nb);
+ if (l == NULL || nb == 0)
+ nextid = 0;
+ else
+ nextid = strtoul(l[nb - 1], NULL, 10) + 1;
+
+ return nextid;
+}
+
/******************************************************************************/
int libxl__device_disk_setdefault(libxl__gc *gc, libxl_device_disk *disk)
@@ -2569,8 +2589,7 @@ void libxl__device_nic_add(libxl__egc *e
flexarray_t *front;
flexarray_t *back;
libxl__device *device;
- char *dompath, **l;
- unsigned int nb, rc;
+ unsigned int rc;
rc = libxl__device_nic_setdefault(gc, nic, domid);
if (rc) goto out;
@@ -2587,17 +2606,10 @@ void libxl__device_nic_add(libxl__egc *e
}
if (nic->devid == -1) {
- if (!(dompath = libxl__xs_get_dompath(gc, domid))) {
+ if ((nic->devid = libxl__device_nextid(gc, domid, "vif") < 0)) {
rc = ERROR_FAIL;
goto out_free;
}
- if (!(l = libxl__xs_directory(gc, XBT_NULL,
- libxl__sprintf(gc, "%s/device/vif", dompath), &nb)) ||
- nb == 0) {
- nic->devid = 0;
- } else {
- nic->devid = strtoul(l[nb - 1], NULL, 10) + 1;
- }
}
GCNEW(device);
@@ -2995,6 +3007,13 @@ int libxl__device_vkb_add(libxl__gc *gc,
goto out_free;
}
+ if (vkb->devid == -1) {
+ if ((vkb->devid = libxl__device_nextid(gc, domid, "vkb") < 0)) {
+ rc = ERROR_FAIL;
+ goto out_free;
+ }
+ }
+
rc = libxl__device_from_vkb(gc, domid, vkb, &device);
if (rc != 0) goto out_free;
@@ -3097,6 +3116,13 @@ int libxl__device_vfb_add(libxl__gc *gc,
goto out_free;
}
+ if (vfb->devid == -1) {
+ if ((vfb->devid = libxl__device_nextid(gc, domid, "vfb") < 0)) {
+ rc = ERROR_FAIL;
+ goto out_free;
+ }
+ }
+
rc = libxl__device_from_vfb(gc, domid, vfb, &device);
if (rc != 0) goto out_free;
++++++ 26370-libxc-x86-initial-mapping-fit.patch ++++++
# HG changeset patch
# User Ian Campbell
# Date 1357906947 0
# Node ID ba2d73234d73fc0faa027cd9bdfd3ac90642733c
# Parent 84d87ca765be81c215ef3b67d2ed71acfba73553
libxc: x86: ensure that the initial mapping fits into the guest's memory
In particular we need to check that adding 512KB of slack and
rounding up to a 4MB boundary do not overflow the guest's memory
allocation. Otherwise we run off the end of the p2m when building the
guest's initial page tables and populate them with garbage.
Wei noticed this when build tiny (2MB) mini-os domains.
Reported-by: Wei Liu
Signed-off-by: Ian Campbell
Acked-by: Jan Beulich
Committed-by: Ian Campbell
Index: xen-4.2.4-testing/tools/libxc/xc_dom_core.c
===================================================================
--- xen-4.2.4-testing.orig/tools/libxc/xc_dom_core.c
+++ xen-4.2.4-testing/tools/libxc/xc_dom_core.c
@@ -930,7 +930,8 @@ int xc_dom_build_image(struct xc_dom_ima
goto err;
if ( dom->arch_hooks->count_pgtables )
{
- dom->arch_hooks->count_pgtables(dom);
+ if ( dom->arch_hooks->count_pgtables(dom) != 0 )
+ goto err;
if ( (dom->pgtables > 0) &&
(xc_dom_alloc_segment(dom, &dom->pgtables_seg, "page tables", 0,
dom->pgtables * page_size) != 0) )
Index: xen-4.2.4-testing/tools/libxc/xc_dom_x86.c
===================================================================
--- xen-4.2.4-testing.orig/tools/libxc/xc_dom_x86.c
+++ xen-4.2.4-testing/tools/libxc/xc_dom_x86.c
@@ -82,6 +82,7 @@ static int count_pgtables(struct xc_dom_
{
int pages, extra_pages;
xen_vaddr_t try_virt_end;
+ xen_pfn_t try_pfn_end;
extra_pages = dom->alloc_bootstack ? 1 : 0;
extra_pages += dom->extra_pages;
@@ -91,6 +92,17 @@ static int count_pgtables(struct xc_dom_
{
try_virt_end = round_up(dom->virt_alloc_end + pages * PAGE_SIZE_X86,
bits_to_mask(22)); /* 4MB alignment */
+
+ try_pfn_end = (try_virt_end - dom->parms.virt_base) >> PAGE_SHIFT_X86;
+
+ if ( try_pfn_end > dom->total_pages )
+ {
+ xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
+ "%s: not enough memory for initial mapping (%#"PRIpfn" > %#"PRIpfn")",
+ __FUNCTION__, try_pfn_end, dom->total_pages);
+ return -ENOMEM;
+ }
+
dom->pg_l4 =
nr_page_tables(dom, dom->parms.virt_base, try_virt_end, l4_bits);
dom->pg_l3 =
++++++ 26372-tools-paths.patch ++++++
# HG changeset patch
# User Bamvor Jian Zhang
# Date 1357906948 0
# Node ID 2ad5792b4274d76ced39515cbd3f84898b181768
# Parent ba2d73234d73fc0faa027cd9bdfd3ac90642733c
fix wrong path while calling pygrub and libxl-save-helper
in current xen x86_64, the default libexec directory is /usr/lib/xen/bin,
while the private binder is /usr/lib64/xen/bin. but some commands(pygrub,
libxl-save-helper) located in private binder directory is called from
libexec directory which lead to the following error:
1, for pygrub bootloader:
libxl: debug: libxl_bootloader.c:429:bootloader_disk_attached_cb: /usr/lib/xen/bin/pygrub doesn't exist, falling back to config path
2, for libxl-save-helper:
libxl: cannot execute /usr/lib/xen/bin/libxl-save-helper: No such file or directory
libxl: error: libxl_utils.c:363:libxl_read_exactly: file/stream truncated reading ipc msg header from domain 3 save/restore helper stdout pipe
libxl: error: libxl_exec.c:118:libxl_report_child_exitstatus: domain 3 save/restore helper [10222] exited with error status 255
there are two ways to fix above error. the first one is make such command
store in the /usr/lib/xen/bin and /usr/lib64/xen/bin(symbol link to
previous), e.g. qemu-dm. The second way is using private binder dir
instead of libexec dir. e.g. xenconsole.
For these cases, the latter one is suitable.
Signed-off-by: Bamvor Jian Zhang
Committed-by: Ian Campbell
Index: xen-4.2.1-testing/tools/libxl/libxl_bootloader.c
===================================================================
--- xen-4.2.1-testing.orig/tools/libxl/libxl_bootloader.c
+++ xen-4.2.1-testing/tools/libxl/libxl_bootloader.c
@@ -419,7 +419,7 @@ static void bootloader_disk_attached_cb(
const char *bltmp;
struct stat st;
- bltmp = libxl__abs_path(gc, bootloader, libxl__libexec_path());
+ bltmp = libxl__abs_path(gc, bootloader, libxl__private_bindir_path());
/* Check to see if the file exists in this location; if not,
* fall back to checking the path */
LOG(DEBUG, "Checking for bootloader in libexec path: %s", bltmp);
Index: xen-4.2.1-testing/tools/libxl/libxl_save_callout.c
===================================================================
--- xen-4.2.1-testing.orig/tools/libxl/libxl_save_callout.c
+++ xen-4.2.1-testing/tools/libxl/libxl_save_callout.c
@@ -172,7 +172,7 @@ static void run_helper(libxl__egc *egc,
shs->stdout_what = GCSPRINTF("domain %"PRIu32" save/restore helper"
" stdout pipe", domid);
- *arg++ = getenv("LIBXL_SAVE_HELPER") ?: LIBEXEC "/" "libxl-save-helper";
+ *arg++ = getenv("LIBXL_SAVE_HELPER") ?: PRIVATE_BINDIR "/" "libxl-save-helper";
*arg++ = mode_arg;
const char **stream_fd_arg = arg++;
for (i=0; i
# Date 1358427591 -3600
# Node ID 76598d4bf61ef0c575deba539ff99078c80e651e
# Parent 0dee85c061addb7124d77c5f6cfe2ea7bc03b760
x86: handle both NMI kinds if they occur simultaneously
We shouldn't assume PCI SERR excludes IOCHK.
Once at it, also remove the doubly redundant range restriction on
"reason" - the variable already is "unsigned char".
Signed-off-by: Jan Beulich
Acked-by: Andrew Cooper
Acked-by: Keir Fraser
Index: xen-4.2.4-testing/xen/arch/x86/traps.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/traps.c
+++ xen-4.2.4-testing/xen/arch/x86/traps.c
@@ -3396,10 +3396,10 @@ void do_nmi(struct cpu_user_regs *regs)
reason = inb(0x61);
if ( reason & 0x80 )
pci_serr_error(regs);
- else if ( reason & 0x40 )
+ if ( reason & 0x40 )
io_check_error(regs);
- else if ( !nmi_watchdog )
- unknown_nmi_error(regs, (unsigned char)(reason&0xff));
+ if ( !(reason & 0xc0) && !nmi_watchdog )
+ unknown_nmi_error(regs, reason);
}
}
++++++ 26418-x86-trampoline-consider-multiboot.patch ++++++
# HG changeset patch
# User Paolo Bonzini
# Date 1358505311 -3600
# Node ID 3b59a6c3e9b0fb5009bdfff97c8493bb9f0bec54
# Parent 025f202f3022c30d1ec3b6ffcb72861c43a32cf7
x86: find a better location for the real-mode trampoline
On some machines, the location at 0x40e does not point to the beginning
of the EBDA. Rather, it points to the beginning of the BIOS-reserved
area of the EBDA, while the option ROMs place their data below that
segment.
For this reason, 0x413 is actually a better source than 0x40e to get
the location of the real-mode trampoline. Xen was already using it
as a second source, and this patch keeps that working. However, just
in case, let's also fetch the information from the multiboot structure,
where the boot loader should have placed it. This way we don't
necessarily trust one of the BIOS or the multiboot loader more than
the other.
Signed-off-by: Paolo Bonzini
Retain the previous code, thus using the multiboot value only if it's
sane but lower than the BDA computed one. Also use the full 32-bit
mem_lower value and prefer MBI_MEMLIMITS over open coding it (requiring
a slight adjustment to multiboot.h to make its constants actually
usable in assembly code, which previously they were only meant to be).
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Committed-by: Jan Beulich
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -88,6 +88,20 @@ __start:
movzwl 0x413,%eax /* use base memory size on failure */
shl $10-4,%eax
1:
+ /*
+ * Compare the value in the BDA with the information from the
+ * multiboot structure (if available) and use the smallest.
+ */
+ testb $MBI_MEMLIMITS,(%ebx)
+ jz 2f /* not available? BDA value will be fine */
+ mov 4(%ebx),%edx
+ cmp $0x100,%edx /* is the multiboot value too small? */
+ jb 2f /* if so, do not use it */
+ shl $10-4,%edx
+ cmp %eax,%edx /* compare with BDA value */
+ cmovb %edx,%eax /* and use the smaller */
+
+2: /* Reserve 64kb for the trampoline */
sub $0x1000,%eax
/* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
--- a/xen/include/xen/multiboot.h
+++ b/xen/include/xen/multiboot.h
@@ -18,6 +18,7 @@
#ifndef __MULTIBOOT_H__
#define __MULTIBOOT_H__
+#include "const.h"
/*
* Multiboot header structure.
@@ -31,17 +32,17 @@
/* The magic number passed by a Multiboot-compliant boot loader. */
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
-#define MBI_MEMLIMITS (1u<< 0)
-#define MBI_BOOTDEV (1u<< 1)
-#define MBI_CMDLINE (1u<< 2)
-#define MBI_MODULES (1u<< 3)
-#define MBI_AOUT_SYMS (1u<< 4)
-#define MBI_ELF_SYMS (1u<< 5)
-#define MBI_MEMMAP (1u<< 6)
-#define MBI_DRIVES (1u<< 7)
-#define MBI_BIOSCONFIG (1u<< 8)
-#define MBI_LOADERNAME (1u<< 9)
-#define MBI_APM (1u<<10)
+#define MBI_MEMLIMITS (_AC(1,u) << 0)
+#define MBI_BOOTDEV (_AC(1,u) << 1)
+#define MBI_CMDLINE (_AC(1,u) << 2)
+#define MBI_MODULES (_AC(1,u) << 3)
+#define MBI_AOUT_SYMS (_AC(1,u) << 4)
+#define MBI_ELF_SYMS (_AC(1,u) << 5)
+#define MBI_MEMMAP (_AC(1,u) << 6)
+#define MBI_DRIVES (_AC(1,u) << 7)
+#define MBI_BIOSCONFIG (_AC(1,u) << 8)
+#define MBI_LOADERNAME (_AC(1,u) << 9)
+#define MBI_APM (_AC(1,u) << 10)
#ifndef __ASSEMBLY__
++++++ 26532-AMD-IOMMU-phantom-MSI.patch ++++++
References: bnc#787169
# HG changeset patch
# User Jan Beulich
# Date 1360831377 -3600
# Node ID 788f4551580d476e13ea907e373e58806a32179e
# Parent e68f14b9e73925e9d404e517ba510f73fe472e4e
AMD IOMMU: handle MSI for phantom functions
With ordinary requests allowed to come from phantom functions, the
remapping tables ought to be set up to also allow for MSI triggers to
come from other than the "real" device too.
It is not clear to me whether the alias-ID handling also needs
adjustment for this to work properly, or whether firmware can be
expected to properly express this through a device alias range
descriptor (or multiple device alias ones).
Signed-off-by: Jan Beulich
Acked-by: Ian Campbell
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -284,33 +284,32 @@ void amd_iommu_ioapic_update_ire(
}
static void update_intremap_entry_from_msi_msg(
- struct amd_iommu *iommu, struct pci_dev *pdev,
- struct msi_desc *msi_desc, struct msi_msg *msg)
+ struct amd_iommu *iommu, u16 bdf,
+ int *remap_index, const struct msi_msg *msg)
{
unsigned long flags;
u32* entry;
- u16 bdf, req_id, alias_id;
+ u16 req_id, alias_id;
u8 delivery_mode, dest, vector, dest_mode;
spinlock_t *lock;
int offset;
- bdf = (pdev->bus << 8) | pdev->devfn;
- req_id = get_dma_requestor_id(pdev->seg, bdf);
- alias_id = get_intremap_requestor_id(pdev->seg, bdf);
+ req_id = get_dma_requestor_id(iommu->seg, bdf);
+ alias_id = get_intremap_requestor_id(iommu->seg, bdf);
if ( msg == NULL )
{
lock = get_intremap_lock(iommu->seg, req_id);
spin_lock_irqsave(lock, flags);
- free_intremap_entry(iommu->seg, req_id, msi_desc->remap_index);
+ free_intremap_entry(iommu->seg, req_id, *remap_index);
spin_unlock_irqrestore(lock, flags);
if ( ( req_id != alias_id ) &&
- get_ivrs_mappings(pdev->seg)[alias_id].intremap_table != NULL )
+ get_ivrs_mappings(iommu->seg)[alias_id].intremap_table != NULL )
{
lock = get_intremap_lock(iommu->seg, alias_id);
spin_lock_irqsave(lock, flags);
- free_intremap_entry(iommu->seg, alias_id, msi_desc->remap_index);
+ free_intremap_entry(iommu->seg, alias_id, *remap_index);
spin_unlock_irqrestore(lock, flags);
}
goto done;
@@ -324,7 +323,10 @@ static void update_intremap_entry_from_m
vector = (msg->data >> MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK;
dest = (msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff;
offset = get_intremap_offset(vector, delivery_mode);
- msi_desc->remap_index = offset;
+ if ( *remap_index < 0)
+ *remap_index = offset;
+ else
+ BUG_ON(*remap_index != offset);
entry = (u32*)get_intremap_entry(iommu->seg, req_id, offset);
update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
@@ -339,7 +341,7 @@ static void update_intremap_entry_from_m
lock = get_intremap_lock(iommu->seg, alias_id);
if ( ( req_id != alias_id ) &&
- get_ivrs_mappings(pdev->seg)[alias_id].intremap_table != NULL )
+ get_ivrs_mappings(iommu->seg)[alias_id].intremap_table != NULL )
{
spin_lock_irqsave(lock, flags);
entry = (u32*)get_intremap_entry(iommu->seg, alias_id, offset);
@@ -362,27 +364,44 @@ void amd_iommu_msi_msg_update_ire(
struct msi_desc *msi_desc, struct msi_msg *msg)
{
struct pci_dev *pdev = msi_desc->dev;
+ int bdf = PCI_BDF2(pdev->bus, pdev->devfn);
struct amd_iommu *iommu = NULL;
if ( !iommu_intremap )
return;
- iommu = find_iommu_for_device(pdev->seg, (pdev->bus << 8) | pdev->devfn);
-
+ iommu = find_iommu_for_device(pdev->seg, bdf);
if ( !iommu )
{
- AMD_IOMMU_DEBUG("Fail to find iommu for MSI device id = 0x%x\n",
- (pdev->bus << 8) | pdev->devfn);
+ AMD_IOMMU_DEBUG("Fail to find iommu for MSI device id = 0x%x\n", bdf);
return;
}
if ( msi_desc->remap_index >= 0 )
- update_intremap_entry_from_msi_msg(iommu, pdev, msi_desc, NULL);
+ {
+ do {
+ update_intremap_entry_from_msi_msg(iommu, bdf,
+ &msi_desc->remap_index, NULL);
+ if ( !pdev || !pdev->phantom_stride )
+ break;
+ bdf += pdev->phantom_stride;
+ } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
+
+ msi_desc->remap_index = -1;
+ if ( pdev )
+ bdf = PCI_BDF2(pdev->bus, pdev->devfn);
+ }
if ( !msg )
return;
- update_intremap_entry_from_msi_msg(iommu, pdev, msi_desc, msg);
+ do {
+ update_intremap_entry_from_msi_msg(iommu, bdf, &msi_desc->remap_index,
+ msg);
+ if ( !pdev || !pdev->phantom_stride )
+ break;
+ bdf += pdev->phantom_stride;
+ } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
}
void amd_iommu_read_msi_from_ire(
++++++ 26547-tools-xc_fix_logic_error_in_stdiostream_progress.patch ++++++
changeset: 26547:8285d20a6f5b
user: Olaf Hering
date: Fri Feb 15 13:32:11 2013 +0000
files: tools/libxc/xtl_logger_stdio.c
description:
tools/xc: fix logic error in stdiostream_progress
Setting XTL_STDIOSTREAM_HIDE_PROGRESS should disable progress reporting.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r 0141aeb86b79 -r 8285d20a6f5b tools/libxc/xtl_logger_stdio.c
--- a/tools/libxc/xtl_logger_stdio.c Fri Feb 15 13:32:10 2013 +0000
+++ b/tools/libxc/xtl_logger_stdio.c Fri Feb 15 13:32:11 2013 +0000
@@ -89,7 +89,7 @@ static void stdiostream_progress(struct
int newpel, extra_erase;
xentoollog_level this_level;
- if (!(lg->flags & XTL_STDIOSTREAM_HIDE_PROGRESS))
+ if (lg->flags & XTL_STDIOSTREAM_HIDE_PROGRESS)
return;
if (percent < lg->progress_last_percent) {
++++++ 26548-tools-xc_handle_tty_output_differently_in_stdiostream_progress.patch ++++++
changeset: 26548:e7d9bac5c11d
user: Olaf Hering
date: Fri Feb 15 13:32:11 2013 +0000
files: tools/libxc/xtl_logger_stdio.c
description:
tools/xc: handle tty output differently in stdiostream_progress
If the output goes to a tty, rewind the cursor and print everything in a
single line as it was done up to now. If the output goes to a file or
pipe print a newline after each progress output. This will fix logging
of progress messages from xc_save to xend.log.
To support XTL_STDIOSTREAM_SHOW_PID or XTL_STDIOSTREAM_SHOW_DATE print
the output via vmessage if the output is not a tty.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r 8285d20a6f5b -r e7d9bac5c11d tools/libxc/xtl_logger_stdio.c
--- a/tools/libxc/xtl_logger_stdio.c Fri Feb 15 13:32:11 2013 +0000
+++ b/tools/libxc/xtl_logger_stdio.c Fri Feb 15 13:32:11 2013 +0000
@@ -81,6 +81,17 @@ static void stdiostream_vmessage(xentool
fflush(lg->f);
}
+static void stdiostream_message(struct xentoollog_logger *logger_in,
+ xentoollog_level level,
+ const char *context,
+ const char *format, ...)
+{
+ va_list al;
+ va_start(al,format);
+ stdiostream_vmessage(logger_in, level, -1, context, format, al);
+ va_end(al);
+}
+
static void stdiostream_progress(struct xentoollog_logger *logger_in,
const char *context,
const char *doing_what, int percent,
@@ -105,11 +116,18 @@ static void stdiostream_progress(struct
if (this_level < lg->min_level)
return;
+ lg->progress_last_percent = percent;
+
+ if (isatty(fileno(lg->f)) <= 0) {
+ stdiostream_message(logger_in, this_level, context,
+ "%s: %lu/%lu %3d%%",
+ doing_what, done, total, percent);
+ return;
+ }
+
if (lg->progress_erase_len)
putc('\r', lg->f);
- lg->progress_last_percent = percent;
-
newpel = fprintf(lg->f, "%s%s" "%s: %lu/%lu %3d%%%s",
context?context:"", context?": ":"",
doing_what, done, total, percent,
++++++ 26549-tools-xc_turn_XCFLAGS__into_shifts.patch ++++++
changeset: 26549:d2991367ecd2
user: Olaf Hering
date: Fri Feb 15 13:32:12 2013 +0000
files: tools/libxc/xenguest.h
description:
tools/xc: turn XCFLAGS_* into shifts
to make it clear that these are bits and to make it easier to use in
xend code.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r e7d9bac5c11d -r d2991367ecd2 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h Fri Feb 15 13:32:11 2013 +0000
+++ b/tools/libxc/xenguest.h Fri Feb 15 13:32:12 2013 +0000
@@ -23,11 +23,12 @@
#ifndef XENGUEST_H
#define XENGUEST_H
-#define XCFLAGS_LIVE 1
-#define XCFLAGS_DEBUG 2
-#define XCFLAGS_HVM 4
-#define XCFLAGS_STDVGA 8
-#define XCFLAGS_CHECKPOINT_COMPRESS 16
+#define XCFLAGS_LIVE (1 << 0)
+#define XCFLAGS_DEBUG (1 << 1)
+#define XCFLAGS_HVM (1 << 2)
+#define XCFLAGS_STDVGA (1 << 3)
+#define XCFLAGS_CHECKPOINT_COMPRESS (1 << 4)
+
#define X86_64_B_SIZE 64
#define X86_32_B_SIZE 32
++++++ 26550-tools-xc_restore_logging_in_xc_save.patch ++++++
changeset: 26550:e6c373fcb73e
user: Olaf Hering
date: Fri Feb 15 13:32:13 2013 +0000
files: tools/xcutils/xc_save.c
description:
tools/xc: restore logging in xc_save
Prior to xen-4.1 the helper xc_save would print some progress during
migration. With the new xc_interface_open API no more messages were
printed because no logger was configured.
Restore previous behaviour by providing a logger. The progress in
xc_domain_save will be disabled because it generates alot of output and
fills up xend.log quickly.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
diff -r d2991367ecd2 -r e6c373fcb73e tools/xcutils/xc_save.c
--- a/tools/xcutils/xc_save.c Fri Feb 15 13:32:12 2013 +0000
+++ b/tools/xcutils/xc_save.c Fri Feb 15 13:32:13 2013 +0000
@@ -166,17 +166,15 @@ static int switch_qemu_logdirty(int domi
int
main(int argc, char **argv)
{
- unsigned int maxit, max_f;
+ unsigned int maxit, max_f, lflags;
int io_fd, ret, port;
struct save_callbacks callbacks;
+ xentoollog_level lvl;
+ xentoollog_logger *l;
if (argc != 6)
errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]);
- si.xch = xc_interface_open(0,0,0);
- if (!si.xch)
- errx(1, "failed to open control interface");
-
io_fd = atoi(argv[1]);
si.domid = atoi(argv[2]);
maxit = atoi(argv[3]);
@@ -185,6 +183,13 @@ main(int argc, char **argv)
si.suspend_evtchn = -1;
+ lvl = si.flags & XCFLAGS_DEBUG ? XTL_DEBUG: XTL_DETAIL;
+ lflags = XTL_STDIOSTREAM_HIDE_PROGRESS;
+ l = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, lvl, lflags);
+ si.xch = xc_interface_open(l, 0, 0);
+ if (!si.xch)
+ errx(1, "failed to open control interface");
+
si.xce = xc_evtchn_open(NULL, 0);
if (si.xce == NULL)
warnx("failed to open event channel handle");
++++++ 26551-tools-xc_log_pid_in_xc_save-xc_restore_output.patch ++++++
changeset: 26551:48f9436959dd
user: Olaf Hering
date: Fri Feb 15 13:32:13 2013 +0000
files: tools/libxc/xc_domain_restore.c tools/libxc/xc_domain_save.c tools/xcutils/xc_restore.c tools/xcutils/xc_save.c
description:
tools/xc: log pid in xc_save/xc_restore output
If several migrations log their output to xend.log its not clear which
line belongs to a which guest. Print entry/exit of xc_save and
xc_restore and also request to print pid with each log call.
Signed-off-by: Olaf Hering
Acked-by: Ian Campbell
Committed-by: Ian Campbell
Index: xen-4.2.4-testing/tools/libxc/xc_domain_restore.c
===================================================================
--- xen-4.2.4-testing.orig/tools/libxc/xc_domain_restore.c
+++ xen-4.2.4-testing/tools/libxc/xc_domain_restore.c
@@ -1387,6 +1387,8 @@ int xc_domain_restore(xc_interface *xch,
struct restore_ctx *ctx = &_ctx;
struct domain_info_context *dinfo = &ctx->dinfo;
+ DPRINTF("%s: starting restore of new domid %u", __func__, dom);
+
pagebuf_init(&pagebuf);
memset(&tailbuf, 0, sizeof(tailbuf));
tailbuf.ishvm = hvm;
@@ -1413,7 +1415,7 @@ int xc_domain_restore(xc_interface *xch,
PERROR("read: p2m_size");
goto out;
}
- DPRINTF("xc_domain_restore start: p2m_size = %lx\n", dinfo->p2m_size);
+ DPRINTF("%s: p2m_size = %lx\n", __func__, dinfo->p2m_size);
if ( !get_platform_info(xch, dom,
&ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, &dinfo->guest_width) )
@@ -2247,7 +2249,7 @@ int xc_domain_restore(xc_interface *xch,
fcntl(io_fd, F_SETFL, orig_io_fd_flags);
- DPRINTF("Restore exit with rc=%d\n", rc);
+ DPRINTF("Restore exit of domid %u with rc=%d\n", dom, rc);
return rc;
}
Index: xen-4.2.4-testing/tools/libxc/xc_domain_save.c
===================================================================
--- xen-4.2.4-testing.orig/tools/libxc/xc_domain_save.c
+++ xen-4.2.4-testing/tools/libxc/xc_domain_save.c
@@ -897,6 +897,8 @@ int xc_domain_save(xc_interface *xch, in
int completed = 0;
+ DPRINTF("%s: starting save of domid %u", __func__, dom);
+
if ( hvm && !callbacks->switch_qemu_logdirty )
{
ERROR("No switch_qemu_logdirty callback provided.");
@@ -2112,7 +2114,7 @@ int xc_domain_save(xc_interface *xch, in
free(pfn_err);
free(to_fix);
- DPRINTF("Save exit rc=%d\n",rc);
+ DPRINTF("Save exit of domid %u with rc=%d\n", dom, rc);
return !!rc;
}
Index: xen-4.2.4-testing/tools/xcutils/xc_restore.c
===================================================================
--- xen-4.2.4-testing.orig/tools/xcutils/xc_restore.c
+++ xen-4.2.4-testing/tools/xcutils/xc_restore.c
@@ -19,17 +19,22 @@ int
main(int argc, char **argv)
{
unsigned int domid, store_evtchn, console_evtchn;
- unsigned int hvm, pae, apic;
+ unsigned int hvm, pae, apic, lflags;
xc_interface *xch;
int io_fd, ret;
int superpages;
unsigned long store_mfn = 0, console_mfn = 0;
+ xentoollog_level lvl;
+ xentoollog_logger *l;
if ( (argc != 8) && (argc != 9) )
errx(1, "usage: %s iofd domid store_evtchn "
"console_evtchn hvm pae apic [superpages]", argv[0]);
- xch = xc_interface_open(0,0,0);
+ lvl = XTL_DETAIL;
+ lflags = XTL_STDIOSTREAM_SHOW_PID | XTL_STDIOSTREAM_HIDE_PROGRESS;
+ l = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, lvl, lflags);
+ xch = xc_interface_open(l, 0, 0);
if ( !xch )
errx(1, "failed to open control interface");
Index: xen-4.2.4-testing/tools/xcutils/xc_save.c
===================================================================
--- xen-4.2.4-testing.orig/tools/xcutils/xc_save.c
+++ xen-4.2.4-testing/tools/xcutils/xc_save.c
@@ -184,7 +184,7 @@ main(int argc, char **argv)
si.suspend_evtchn = -1;
lvl = si.flags & XCFLAGS_DEBUG ? XTL_DEBUG: XTL_DETAIL;
- lflags = XTL_STDIOSTREAM_HIDE_PROGRESS;
+ lflags = XTL_STDIOSTREAM_SHOW_PID | XTL_STDIOSTREAM_HIDE_PROGRESS;
l = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, lvl, lflags);
si.xch = xc_interface_open(l, 0, 0);
if (!si.xch)
++++++ 26554-hvm-firmware-passthrough.patch ++++++
# HG changeset patch
# User Ross Philipson
# Date 1360935136 0
# Node ID 3124ab7855fd7d4e0f3ea125cb21b60d693e8800
# Parent 71c15ae0998378b5c117bbd27a48015757685706
libxl: switch to using the new xc_hvm_build() libxc API.
Signed-off-by: Ross Philipson
Acked-by: Ian Campbell
Committed-by: Ian Campbell
Index: xen-4.2.2-testing/tools/libxl/libxl_dom.c
===================================================================
--- xen-4.2.2-testing.orig/tools/libxl/libxl_dom.c
+++ xen-4.2.2-testing/tools/libxl/libxl_dom.c
@@ -546,17 +546,24 @@ int libxl__build_hvm(libxl__gc *gc, uint
libxl__domain_build_state *state)
{
libxl_ctx *ctx = libxl__gc_owner(gc);
+ struct xc_hvm_build_args args = {};
int ret, rc = ERROR_FAIL;
const char *firmware = libxl__domain_firmware(gc, info);
if (!firmware)
goto out;
- ret = xc_hvm_build_target_mem(
- ctx->xch,
- domid,
- (info->max_memkb - info->video_memkb) / 1024,
- (info->target_memkb - info->video_memkb) / 1024,
- firmware);
+
+ memset(&args, 0, sizeof(struct xc_hvm_build_args));
+ /* The params from the configuration file are in Mb, which are then
+ * multiplied by 1 Kb. This was then divided off when calling
+ * the old xc_hvm_build_target_mem() which then turned them to bytes.
+ * Do all this in one step here...
+ */
+ args.mem_size = (uint64_t)(info->max_memkb - info->video_memkb) << 10;
+ args.mem_target = (uint64_t)(info->target_memkb - info->video_memkb) << 10;
+ args.image_file_name = firmware;
+
+ ret = xc_hvm_build(ctx->xch, domid, &args);
if (ret) {
LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "hvm building failed");
goto out;
++++++ 26555-hvm-firmware-passthrough.patch ++++++
# HG changeset patch
# User Ross Philipson
# Date 1360935136 0
# Node ID 17a228e37ec0913ff86b8b5f2d88f1b8e92146f1
# Parent 3124ab7855fd7d4e0f3ea125cb21b60d693e8800
libxl: HVM firmware passthrough support
This patch introduces support for two new parameters in libxl:
smbios_firmware=
acpi_firmware=
The changes are primarily in the domain building code where the firmware files
are read and passed to libxc for loading into the new guest. After the domain
building call to libxc, the addresses for the loaded blobs are returned and
written to xenstore.
LIBXL_HAVE_FIRMWARE_PASSTHROUGH is defined in libxl.h to allow users to
determine if the feature is present.
This patch also updates the xl.cfg man page with descriptions of the two new
parameters for firmware passthrough.
Signed-off-by: Ross Philipson
Acked-by: Ian Campbell
Committed-by: Ian Campbell
Index: xen-4.2.2-testing/docs/man/xl.cfg.pod.5
===================================================================
--- xen-4.2.2-testing.orig/docs/man/xl.cfg.pod.5
+++ xen-4.2.2-testing/docs/man/xl.cfg.pod.5
@@ -637,6 +637,25 @@ of Xen) within a Xen guest or to support
which uses hardware virtualisation extensions (e.g. Windows XP
compatibility mode on more modern Windows OS).
+=item B
+
+Specify a path to a file that contains extra ACPI firmware tables to pass in to
+a guest. The file can contain several tables in their binary AML form
+concatenated together. Each table self describes its length so no additional
+information is needed. These tables will be added to the ACPI table set in the
+guest. Note that existing tables cannot be overridden by this feature. For
+example this cannot be used to override tables like DSDT, FADT, etc.
+
+=item B
+
+Specify a path to a file that contains extra SMBIOS firmware structures to pass
+in to a guest. The file can contain a set DMTF predefined structures which will
+override the internal defaults. Not all predefined structures can be overridden,
+only the following types: 0, 1, 2, 3, 11, 22, 39. The file can also contain any
+number of vendor defined SMBIOS structures (type 128 - 255). Since SMBIOS
+structures do not present their overall size, each entry in the file must be
+preceded by a 32b integer indicating the size of the next structure.
+
=back
=head3 Guest Virtual Time Controls
Index: xen-4.2.2-testing/tools/libxl/libxl.h
===================================================================
--- xen-4.2.2-testing.orig/tools/libxl/libxl.h
+++ xen-4.2.2-testing/tools/libxl/libxl.h
@@ -68,6 +68,13 @@
*/
/*
+ * LIBXL_HAVE_FIRMWARE_PASSTHROUGH indicates the feature for
+ * passing in SMBIOS and ACPI firmware to HVM guests is present
+ * in the library.
+ */
+#define LIBXL_HAVE_FIRMWARE_PASSTHROUGH 1
+
+/*
* libxl ABI compatibility
*
* The only guarantee which libxl makes regarding ABI compatibility
Index: xen-4.2.2-testing/tools/libxl/libxl_dom.c
===================================================================
--- xen-4.2.2-testing.orig/tools/libxl/libxl_dom.c
+++ xen-4.2.2-testing/tools/libxl/libxl_dom.c
@@ -22,6 +22,7 @@
#include
#include
+#include
libxl_domain_type libxl__domain_type(libxl__gc *gc, uint32_t domid)
{
@@ -514,11 +515,61 @@ static int hvm_build_set_params(xc_inter
return 0;
}
-static const char *libxl__domain_firmware(libxl__gc *gc,
- libxl_domain_build_info *info)
+static int hvm_build_set_xs_values(libxl__gc *gc,
+ uint32_t domid,
+ struct xc_hvm_build_args *args)
+{
+ char *path = NULL;
+ int ret = 0;
+
+ if (args->smbios_module.guest_addr_out) {
+ path = GCSPRINTF("/local/domain/%d/"HVM_XS_SMBIOS_PT_ADDRESS, domid);
+
+ ret = libxl__xs_write(gc, XBT_NULL, path, "0x%"PRIx64,
+ args->smbios_module.guest_addr_out);
+ if (ret)
+ goto err;
+
+ path = GCSPRINTF("/local/domain/%d/"HVM_XS_SMBIOS_PT_LENGTH, domid);
+
+ ret = libxl__xs_write(gc, XBT_NULL, path, "0x%x",
+ args->smbios_module.length);
+ if (ret)
+ goto err;
+ }
+
+ if (args->acpi_module.guest_addr_out) {
+ path = GCSPRINTF("/local/domain/%d/"HVM_XS_ACPI_PT_ADDRESS, domid);
+
+ ret = libxl__xs_write(gc, XBT_NULL, path, "0x%"PRIx64,
+ args->acpi_module.guest_addr_out);
+ if (ret)
+ goto err;
+
+ path = GCSPRINTF("/local/domain/%d/"HVM_XS_ACPI_PT_LENGTH, domid);
+
+ ret = libxl__xs_write(gc, XBT_NULL, path, "0x%x",
+ args->acpi_module.length);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ LOG(ERROR, "failed to write firmware xenstore value, err: %d", ret);
+ return ret;
+}
+
+static int libxl__domain_firmware(libxl__gc *gc,
+ libxl_domain_build_info *info,
+ struct xc_hvm_build_args *args)
{
libxl_ctx *ctx = libxl__gc_owner(gc);
const char *firmware;
+ int e, rc = ERROR_FAIL;
+ int datalen = 0;
+ void *data;
if (info->u.hvm.firmware)
firmware = info->u.hvm.firmware;
@@ -532,13 +583,52 @@ static const char *libxl__domain_firmwar
firmware = "hvmloader";
break;
default:
- LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "invalid device model version %d",
- info->device_model_version);
- return NULL;
+ LOG(ERROR, "invalid device model version %d",
+ info->device_model_version);
+ return ERROR_FAIL;
break;
}
}
- return libxl__abs_path(gc, firmware, libxl__xenfirmwaredir_path());
+ args->image_file_name = libxl__abs_path(gc, firmware,
+ libxl__xenfirmwaredir_path());
+
+ if (info->u.hvm.smbios_firmware) {
+ data = NULL;
+ e = libxl_read_file_contents(ctx, info->u.hvm.smbios_firmware,
+ &data, &datalen);
+ if (e) {
+ LOGEV(ERROR, e, "failed to read SMBIOS firmware file %s",
+ info->u.hvm.smbios_firmware);
+ goto out;
+ }
+ libxl__ptr_add(gc, data);
+ if (datalen) {
+ /* Only accept non-empty files */
+ args->smbios_module.data = data;
+ args->smbios_module.length = (uint32_t)datalen;
+ }
+ }
+
+ if (info->u.hvm.acpi_firmware) {
+ data = NULL;
+ e = libxl_read_file_contents(ctx, info->u.hvm.acpi_firmware,
+ &data, &datalen);
+ if (e) {
+ LOGEV(ERROR, e, "failed to read ACPI firmware file %s",
+ info->u.hvm.acpi_firmware);
+ goto out;
+ }
+ libxl__ptr_add(gc, data);
+ if (datalen) {
+ /* Only accept non-empty files */
+ args->acpi_module.data = data;
+ args->acpi_module.length = (uint32_t)datalen;
+ }
+ }
+
+ return 0;
+out:
+ return rc;
}
int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
@@ -548,10 +638,6 @@ int libxl__build_hvm(libxl__gc *gc, uint
libxl_ctx *ctx = libxl__gc_owner(gc);
struct xc_hvm_build_args args = {};
int ret, rc = ERROR_FAIL;
- const char *firmware = libxl__domain_firmware(gc, info);
-
- if (!firmware)
- goto out;
memset(&args, 0, sizeof(struct xc_hvm_build_args));
/* The params from the configuration file are in Mb, which are then
@@ -561,22 +647,34 @@ int libxl__build_hvm(libxl__gc *gc, uint
*/
args.mem_size = (uint64_t)(info->max_memkb - info->video_memkb) << 10;
args.mem_target = (uint64_t)(info->target_memkb - info->video_memkb) << 10;
- args.image_file_name = firmware;
+
+ if (libxl__domain_firmware(gc, info, &args)) {
+ LOG(ERROR, "initializing domain firmware failed");
+ goto out;
+ }
ret = xc_hvm_build(ctx->xch, domid, &args);
if (ret) {
- LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "hvm building failed");
+ LOGEV(ERROR, ret, "hvm building failed");
goto out;
}
+
ret = hvm_build_set_params(ctx->xch, domid, info, state->store_port,
&state->store_mfn, state->console_port,
&state->console_mfn, state->store_domid,
state->console_domid);
if (ret) {
- LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "hvm build set params failed");
+ LOGEV(ERROR, ret, "hvm build set params failed");
goto out;
}
- rc = 0;
+
+ ret = hvm_build_set_xs_values(gc, domid, &args);
+ if (ret) {
+ LOG(ERROR, "hvm build set xenstore values failed (ret=%d)", ret);
+ goto out;
+ }
+
+ return 0;
out:
return rc;
}
@@ -638,7 +736,7 @@ int libxl__toolstack_restore(uint32_t do
memcpy(&count, ptr, sizeof(count));
ptr += sizeof(count);
-
+
if (size < sizeof(version) + sizeof(count) +
count * (sizeof(struct libxl__physmap_info))) {
LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "wrong size");
@@ -852,7 +950,7 @@ static void switch_logdirty_xswatch(libx
rc = libxl__xs_rm_checked(gc, t, lds->ret_path);
if (rc) goto out;
- rc = libxl__xs_transaction_commit(gc, &t);
+ rc = libxl__xs_transaction_commit(gc, &t);
if (!rc) break;
if (rc<0) goto out;
}
@@ -1324,7 +1422,7 @@ void libxl__xc_domain_save_done(libxl__e
if (type == LIBXL_DOMAIN_TYPE_HVM) {
rc = libxl__domain_suspend_device_model(gc, dss);
if (rc) goto out;
-
+
libxl__domain_save_device_model(egc, dss, domain_suspend_done);
return;
}
Index: xen-4.2.2-testing/tools/libxl/libxl_types.idl
===================================================================
--- xen-4.2.2-testing.orig/tools/libxl/libxl_types.idl
+++ xen-4.2.2-testing/tools/libxl/libxl_types.idl
@@ -301,6 +301,8 @@ libxl_domain_build_info = Struct("domain
("vpt_align", libxl_defbool),
("timer_mode", libxl_timer_mode),
("nested_hvm", libxl_defbool),
+ ("smbios_firmware", string),
+ ("acpi_firmware", string),
("nographic", libxl_defbool),
("vga", libxl_vga_interface_info),
("vnc", libxl_vnc_info),
Index: xen-4.2.2-testing/tools/libxl/xl_cmdimpl.c
===================================================================
--- xen-4.2.2-testing.orig/tools/libxl/xl_cmdimpl.c
+++ xen-4.2.2-testing/tools/libxl/xl_cmdimpl.c
@@ -863,6 +863,11 @@ static void parse_config_data(const char
}
xlu_cfg_get_defbool(config, "nestedhvm", &b_info->u.hvm.nested_hvm, 0);
+
+ xlu_cfg_replace_string(config, "smbios_firmware",
+ &b_info->u.hvm.smbios_firmware, 0);
+ xlu_cfg_replace_string(config, "acpi_firmware",
+ &b_info->u.hvm.acpi_firmware, 0);
break;
case LIBXL_DOMAIN_TYPE_PV:
{
++++++ 26556-hvm-firmware-passthrough.patch ++++++
# HG changeset patch
# User Ross Philipson
# Date 1360935137 0
# Node ID 6a9549a15108669408123e5e39f52ad09dea1c10
# Parent 17a228e37ec0913ff86b8b5f2d88f1b8e92146f1
libxl: Cleanup, use LOG* and GCSPRINTF macro in libxl_dom.c
Signed-off-by: Ross Philipson
Acked-by: Ian Campbell
Committed-by: Ian Campbell
Index: xen-4.2.2-testing/tools/libxl/libxl_dom.c
===================================================================
--- xen-4.2.2-testing.orig/tools/libxl/libxl_dom.c
+++ xen-4.2.2-testing/tools/libxl/libxl_dom.c
@@ -32,8 +32,7 @@ libxl_domain_type libxl__domain_type(lib
ret = xc_domain_getinfolist(ctx->xch, domid, 1, &info);
if (ret != 1 || info.domain != domid) {
- LIBXL__LOG(CTX, LIBXL__LOG_ERROR,
- "unable to get domain type for domid=%"PRIu32, domid);
+ LOG(ERROR, "unable to get domain type for domid=%"PRIu32, domid);
return LIBXL_DOMAIN_TYPE_INVALID;
}
if (info.flags & XEN_DOMINF_hvm_guest)
@@ -317,20 +316,19 @@ int libxl__build_post(libxl__gc *gc, uin
ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
ents[0] = "memory/static-max";
- ents[1] = libxl__sprintf(gc, "%"PRId64, info->max_memkb);
+ ents[1] = GCSPRINTF("%"PRId64, info->max_memkb);
ents[2] = "memory/target";
- ents[3] = libxl__sprintf(gc, "%"PRId64,
- info->target_memkb - info->video_memkb);
+ ents[3] = GCSPRINTF("%"PRId64, info->target_memkb - info->video_memkb);
ents[4] = "memory/videoram";
- ents[5] = libxl__sprintf(gc, "%"PRId64, info->video_memkb);
+ ents[5] = GCSPRINTF("%"PRId64, info->video_memkb);
ents[6] = "domid";
- ents[7] = libxl__sprintf(gc, "%d", domid);
+ ents[7] = GCSPRINTF("%d", domid);
ents[8] = "store/port";
- ents[9] = libxl__sprintf(gc, "%"PRIu32, state->store_port);
+ ents[9] = GCSPRINTF("%"PRIu32, state->store_port);
ents[10] = "store/ring-ref";
- ents[11] = libxl__sprintf(gc, "%lu", state->store_mfn);
+ ents[11] = GCSPRINTF("%lu", state->store_mfn);
for (i = 0; i < info->max_vcpus; i++) {
- ents[12+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i);
+ ents[12+(i*2)] = GCSPRINTF("cpu/%d/availability", i);
ents[12+(i*2)+1] = libxl_bitmap_test(&info->avail_vcpus, i)
? "online" : "offline";
}
@@ -339,7 +337,7 @@ int libxl__build_post(libxl__gc *gc, uin
if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
hvm_ents = libxl__calloc(gc, 3, sizeof(char *));
hvm_ents[0] = "hvmloader/generation-id-address";
- hvm_ents[1] = libxl__sprintf(gc, "0x%lx", state->vm_generationid_addr);
+ hvm_ents[1] = GCSPRINTF("0x%lx", state->vm_generationid_addr);
}
dom_path = libxl__xs_get_dompath(gc, domid);
@@ -347,7 +345,7 @@ int libxl__build_post(libxl__gc *gc, uin
return ERROR_FAIL;
}
- vm_path = xs_read(ctx->xsh, XBT_NULL, libxl__sprintf(gc, "%s/vm", dom_path), NULL);
+ vm_path = xs_read(ctx->xsh, XBT_NULL, GCSPRINTF("%s/vm", dom_path), NULL);
retry_transaction:
t = xs_transaction_start(ctx->xsh);
@@ -378,7 +376,7 @@ int libxl__build_pv(libxl__gc *gc, uint3
dom = xc_dom_allocate(ctx->xch, state->pv_cmdline, info->u.pv.features);
if (!dom) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_allocate failed");
+ LOGE(ERROR, "xc_dom_allocate failed");
return ERROR_FAIL;
}
@@ -388,13 +386,13 @@ int libxl__build_pv(libxl__gc *gc, uint3
state->pv_kernel.data,
state->pv_kernel.size);
if ( ret != 0) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_kernel_mem failed");
+ LOGE(ERROR, "xc_dom_kernel_mem failed");
goto out;
}
} else {
ret = xc_dom_kernel_file(dom, state->pv_kernel.path);
if ( ret != 0) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_kernel_file failed");
+ LOGE(ERROR, "xc_dom_kernel_file failed");
goto out;
}
}
@@ -402,12 +400,12 @@ int libxl__build_pv(libxl__gc *gc, uint3
if ( state->pv_ramdisk.path && strlen(state->pv_ramdisk.path) ) {
if (state->pv_ramdisk.mapped) {
if ( (ret = xc_dom_ramdisk_mem(dom, state->pv_ramdisk.data, state->pv_ramdisk.size)) != 0 ) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_ramdisk_mem failed");
+ LOGE(ERROR, "xc_dom_ramdisk_mem failed");
goto out;
}
} else {
if ( (ret = xc_dom_ramdisk_file(dom, state->pv_ramdisk.path)) != 0 ) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_ramdisk_file failed");
+ LOGE(ERROR, "xc_dom_ramdisk_file failed");
goto out;
}
}
@@ -420,31 +418,31 @@ int libxl__build_pv(libxl__gc *gc, uint3
dom->xenstore_domid = state->store_domid;
if ( (ret = xc_dom_boot_xen_init(dom, ctx->xch, domid)) != 0 ) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_boot_xen_init failed");
+ LOGE(ERROR, "xc_dom_boot_xen_init failed");
goto out;
}
if ( (ret = xc_dom_parse_image(dom)) != 0 ) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_parse_image failed");
+ LOGE(ERROR, "xc_dom_parse_image failed");
goto out;
}
if ( (ret = xc_dom_mem_init(dom, info->target_memkb / 1024)) != 0 ) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_mem_init failed");
+ LOGE(ERROR, "xc_dom_mem_init failed");
goto out;
}
if ( (ret = xc_dom_boot_mem_init(dom)) != 0 ) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_boot_mem_init failed");
+ LOGE(ERROR, "xc_dom_boot_mem_init failed");
goto out;
}
if ( (ret = xc_dom_build_image(dom)) != 0 ) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_build_image failed");
+ LOGE(ERROR, "xc_dom_build_image failed");
goto out;
}
if ( (ret = xc_dom_boot_image(dom)) != 0 ) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_boot_image failed");
+ LOGE(ERROR, "xc_dom_boot_image failed");
goto out;
}
if ( (ret = xc_dom_gnttab_init(dom)) != 0 ) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_gnttab_init failed");
+ LOGE(ERROR, "xc_dom_gnttab_init failed");
goto out;
}
@@ -683,8 +681,7 @@ int libxl__qemu_traditional_cmd(libxl__g
const char *cmd)
{
char *path = NULL;
- path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/command",
- domid);
+ path = GCSPRINTF("/local/domain/0/device-model/%d/command", domid);
return libxl__xs_write(gc, XBT_NULL, path, "%s", cmd);
}
@@ -701,8 +698,7 @@ struct libxl__physmap_info {
static inline char *restore_helper(libxl__gc *gc, uint32_t domid,
uint64_t phys_offset, char *node)
{
- return libxl__sprintf(gc,
- "/local/domain/0/device-model/%d/physmap/%"PRIx64"/%s",
+ return GCSPRINTF("/local/domain/0/device-model/%d/physmap/%"PRIx64"/%s",
domid, phys_offset, node);
}
@@ -712,7 +708,6 @@ int libxl__toolstack_restore(uint32_t do
libxl__save_helper_state *shs = user;
libxl__domain_create_state *dcs = CONTAINER_OF(shs, *dcs, shs);
STATE_AO_GC(dcs->ao);
- libxl_ctx *ctx = CTX;
int i, ret;
const uint8_t *ptr = buf;
uint32_t count = 0, version = 0;
@@ -722,7 +717,7 @@ int libxl__toolstack_restore(uint32_t do
LOG(DEBUG,"domain=%"PRIu32" toolstack data size=%"PRIu32, domid, size);
if (size < sizeof(version) + sizeof(count)) {
- LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "wrong size");
+ LOG(ERROR, "wrong size");
return -1;
}
@@ -730,7 +725,7 @@ int libxl__toolstack_restore(uint32_t do
ptr += sizeof(version);
if (version != TOOLSTACK_SAVE_VERSION) {
- LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "wrong version");
+ LOG(ERROR, "wrong version");
return -1;
}
@@ -739,7 +734,7 @@ int libxl__toolstack_restore(uint32_t do
if (size < sizeof(version) + sizeof(count) +
count * (sizeof(struct libxl__physmap_info))) {
- LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "wrong size");
+ LOG(ERROR, "wrong size");
return -1;
}
@@ -988,15 +983,13 @@ static void switch_logdirty_done(libxl__
int libxl__domain_suspend_device_model(libxl__gc *gc,
libxl__domain_suspend_state *dss)
{
- libxl_ctx *ctx = libxl__gc_owner(gc);
int ret = 0;
uint32_t const domid = dss->domid;
const char *const filename = dss->dm_savefile;
switch (libxl__device_model_version_running(gc, domid)) {
case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: {
- LIBXL__LOG(ctx, LIBXL__LOG_DEBUG,
- "Saving device model state to %s", filename);
+ LOG(DEBUG, "Saving device model state to %s", filename);
libxl__qemu_traditional_cmd(gc, domid, "save");
libxl__wait_for_device_model(gc, domid, "paused", NULL, NULL, NULL);
break;
@@ -1172,8 +1165,7 @@ int libxl__domain_suspend_common_callbac
static inline char *physmap_path(libxl__gc *gc, uint32_t domid,
char *phys_offset, char *node)
{
- return libxl__sprintf(gc,
- "/local/domain/0/device-model/%d/physmap/%s/%s",
+ return GCSPRINTF("/local/domain/0/device-model/%d/physmap/%s/%s",
domid, phys_offset, node);
}
@@ -1190,7 +1182,7 @@ int libxl__toolstack_save(uint32_t domid
char **entries = NULL;
struct libxl__physmap_info *pi;
- entries = libxl__xs_directory(gc, 0, libxl__sprintf(gc,
+ entries = libxl__xs_directory(gc, 0, GCSPRINTF(
"/local/domain/0/device-model/%d/physmap", domid), &num);
count = num;
@@ -1331,7 +1323,7 @@ void libxl__domain_suspend(libxl__egc *e
char *path;
char *addr;
- path = libxl__sprintf(gc, "%s/hvmloader/generation-id-address",
+ path = GCSPRINTF("%s/hvmloader/generation-id-address",
libxl__xs_get_dompath(gc, domid));
addr = libxl__xs_read(gc, XBT_NULL, path);
@@ -1545,10 +1537,7 @@ static void domain_suspend_done(libxl__e
char *libxl__uuid2string(libxl__gc *gc, const libxl_uuid uuid)
{
- char *s = libxl__sprintf(gc, LIBXL_UUID_FMT, LIBXL_UUID_BYTES(uuid));
- if (!s)
- LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR, "cannot allocate for uuid");
- return s;
+ return GCSPRINTF(LIBXL_UUID_FMT, LIBXL_UUID_BYTES(uuid));
}
static const char *userdata_path(libxl__gc *gc, uint32_t domid,
@@ -1556,34 +1545,27 @@ static const char *userdata_path(libxl__
const char *wh)
{
libxl_ctx *ctx = libxl__gc_owner(gc);
- char *path, *uuid_string;
+ char *uuid_string;
libxl_dominfo info;
int rc;
rc = libxl_domain_info(ctx, &info, domid);
if (rc) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to find domain info"
- " for domain %"PRIu32, domid);
+ LOGE(ERROR, "unable to find domain info for domain %"PRIu32, domid);
return NULL;
}
- uuid_string = libxl__sprintf(gc, LIBXL_UUID_FMT, LIBXL_UUID_BYTES(info.uuid));
+ uuid_string = GCSPRINTF(LIBXL_UUID_FMT, LIBXL_UUID_BYTES(info.uuid));
- path = libxl__sprintf(gc, "/var/lib/xen/"
- "userdata-%s.%u.%s.%s",
- wh, domid, uuid_string, userdata_userid);
- if (!path)
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to allocate for"
- " userdata path");
- return path;
+ return GCSPRINTF("/var/lib/xen/userdata-%s.%u.%s.%s",
+ wh, domid, uuid_string, userdata_userid);
}
static int userdata_delete(libxl__gc *gc, const char *path)
{
- libxl_ctx *ctx = libxl__gc_owner(gc);
int r;
r = unlink(path);
if (r) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "remove failed for %s", path);
+ LOGE(ERROR, "remove failed for %s", path);
return errno;
}
return 0;
@@ -1591,7 +1573,6 @@ static int userdata_delete(libxl__gc *gc
void libxl__userdata_destroyall(libxl__gc *gc, uint32_t domid)
{
- libxl_ctx *ctx = libxl__gc_owner(gc);
const char *pattern;
glob_t gl;
int r, i;
@@ -1607,7 +1588,7 @@ void libxl__userdata_destroyall(libxl__g
if (r == GLOB_NOMATCH)
goto out;
if (r)
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "glob failed for %s", pattern);
+ LOGE(ERROR, "glob failed for %s", pattern);
for (i=0; i
# Date 1361176078 -3600
# Node ID 4c3355d776e115f979fd2abc135bb77ba710f0d4
# Parent 217a4fc4cd46e8de06f2f43eed727838891e9398
x86/VMX: fix live migration while enabling APICV
SVI should be restored in case guest is processing virtual interrupt
while saveing a domain state. Otherwise SVI would be missed when
virtual interrupt delivery is enabled.
Signed-off-by: Jiongxi Li
Acked-by: Eddie Dong
Acked-by: Jun Nakajima
Committed-by: Jan Beulich
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vlapic.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
@@ -1215,6 +1215,9 @@ static int lapic_load_regs(struct domain
if ( hvm_load_entry(LAPIC_REGS, h, s->regs) != 0 )
return -EINVAL;
+ if ( hvm_funcs.process_isr )
+ hvm_funcs.process_isr(vlapic_find_highest_isr(s), v);
+
vlapic_adjust_i8259_target(d);
lapic_rearm(s);
return 0;
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/intr.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/intr.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/intr.c
@@ -290,8 +290,8 @@ void vmx_intr_assist(void)
vmx_set_eoi_exit_bitmap(v, pt_vector);
/* we need update the RVI field */
- status &= ~(unsigned long)0x0FF;
- status |= (unsigned long)0x0FF &
+ status &= ~VMX_GUEST_INTR_STATUS_SUBFIELD_BITMASK;
+ status |= VMX_GUEST_INTR_STATUS_SUBFIELD_BITMASK &
intack.vector;
__vmwrite(GUEST_INTR_STATUS, status);
if (v->arch.hvm_vmx.eoi_exitmap_changed) {
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
@@ -1588,6 +1588,29 @@ static int vmx_virtual_intr_delivery_ena
return cpu_has_vmx_virtual_intr_delivery;
}
+static void vmx_process_isr(int isr, struct vcpu *v)
+{
+ unsigned long status;
+ u8 old;
+
+ if ( !cpu_has_vmx_virtual_intr_delivery )
+ return;
+
+ if ( isr < 0 )
+ isr = 0;
+
+ vmx_vmcs_enter(v);
+ status = __vmread(GUEST_INTR_STATUS);
+ old = status >> VMX_GUEST_INTR_STATUS_SVI_OFFSET;
+ if ( isr != old )
+ {
+ status &= VMX_GUEST_INTR_STATUS_SUBFIELD_BITMASK;
+ status |= isr << VMX_GUEST_INTR_STATUS_SVI_OFFSET;
+ __vmwrite(GUEST_INTR_STATUS, status);
+ }
+ vmx_vmcs_exit(v);
+}
+
static struct hvm_function_table __read_mostly vmx_function_table = {
.name = "VMX",
.cpu_up_prepare = vmx_cpu_up_prepare,
@@ -1636,7 +1659,8 @@ static struct hvm_function_table __read_
.nhvm_intr_blocked = nvmx_intr_blocked,
.nhvm_domain_relinquish_resources = nvmx_domain_relinquish_resources,
.update_eoi_exit_bitmap = vmx_update_eoi_exit_bitmap,
- .virtual_intr_delivery_enabled = vmx_virtual_intr_delivery_enabled
+ .virtual_intr_delivery_enabled = vmx_virtual_intr_delivery_enabled,
+ .process_isr = vmx_process_isr,
};
struct hvm_function_table * __init start_vmx(void)
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/hvm.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/hvm.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/hvm.h
@@ -184,6 +184,7 @@ struct hvm_function_table {
/* Virtual interrupt delivery */
void (*update_eoi_exit_bitmap)(struct vcpu *v, u8 vector, u8 trig);
int (*virtual_intr_delivery_enabled)(void);
+ void (*process_isr)(int isr, struct vcpu *v);
};
extern struct hvm_function_table hvm_funcs;
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -247,6 +247,10 @@ extern bool_t cpu_has_vmx_ins_outs_instr
#define VMX_INTR_SHADOW_SMI 0x00000004
#define VMX_INTR_SHADOW_NMI 0x00000008
+/* Guest interrupt status */
+#define VMX_GUEST_INTR_STATUS_SUBFIELD_BITMASK 0x0FF
+#define VMX_GUEST_INTR_STATUS_SVI_OFFSET 8
+
/* VMCS field encodings. */
enum vmcs_field {
VIRTUAL_PROCESSOR_ID = 0x00000000,
++++++ 26577-x86-APICV-x2APIC.patch ++++++
References: FATE#313605
# HG changeset patch
# User Jiongxi Li
# Date 1361176458 -3600
# Node ID 45d59b822ed187c535b127679e32853b148ed411
# Parent 4c3355d776e115f979fd2abc135bb77ba710f0d4
x86/VMX: fix VMCS setting for x2APIC mode guest while enabling APICV
The "APIC-register virtualization" and "virtual-interrupt deliver"
VM-execution control has no effect on the behavior of RDMSR/WRMSR if
the "virtualize x2APIC mode" VM-execution control is 0.
When guest uses x2APIC mode, we should enable "virtualize x2APIC mode"
for APICV first.
Signed-off-by: Jiongxi Li
Acked-by: Eddie Dong
Acked-by: Jun Nakajima
Committed-by: Jan Beulich
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -194,7 +194,8 @@ static int vmx_init_vmcs_config(void)
*/
if ( _vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW )
opt |= SECONDARY_EXEC_APIC_REGISTER_VIRT |
- SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY;
+ SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
+ SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
_vmx_secondary_exec_control = adjust_vmx_controls(
@@ -682,19 +683,59 @@ void vmx_disable_intercept_for_msr(struc
*/
if ( msr <= 0x1fff )
{
- if (type & MSR_TYPE_R)
- __clear_bit(msr, msr_bitmap + 0x000/BYTES_PER_LONG); /* read-low */
- if (type & MSR_TYPE_W)
- __clear_bit(msr, msr_bitmap + 0x800/BYTES_PER_LONG); /* write-low */
+ if ( type & MSR_TYPE_R )
+ clear_bit(msr, msr_bitmap + 0x000/BYTES_PER_LONG); /* read-low */
+ if ( type & MSR_TYPE_W )
+ clear_bit(msr, msr_bitmap + 0x800/BYTES_PER_LONG); /* write-low */
}
else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
{
msr &= 0x1fff;
- if (type & MSR_TYPE_R)
- __clear_bit(msr, msr_bitmap + 0x400/BYTES_PER_LONG); /* read-high */
- if (type & MSR_TYPE_W)
- __clear_bit(msr, msr_bitmap + 0xc00/BYTES_PER_LONG); /* write-high */
+ if ( type & MSR_TYPE_R )
+ clear_bit(msr, msr_bitmap + 0x400/BYTES_PER_LONG); /* read-high */
+ if ( type & MSR_TYPE_W )
+ clear_bit(msr, msr_bitmap + 0xc00/BYTES_PER_LONG); /* write-high */
}
+ else
+ HVM_DBG_LOG(DBG_LEVEL_0,
+ "msr %x is out of the control range"
+ "0x00000000-0x00001fff and 0xc0000000-0xc0001fff"
+ "RDMSR or WRMSR will cause a VM exit", msr);
+}
+
+void vmx_enable_intercept_for_msr(struct vcpu *v, u32 msr, int type)
+{
+ unsigned long *msr_bitmap = v->arch.hvm_vmx.msr_bitmap;
+
+ /* VMX MSR bitmap supported? */
+ if ( msr_bitmap == NULL )
+ return;
+
+ /*
+ * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals
+ * have the write-low and read-high bitmap offsets the wrong way round.
+ * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
+ */
+ if ( msr <= 0x1fff )
+ {
+ if ( type & MSR_TYPE_R )
+ set_bit(msr, msr_bitmap + 0x000/BYTES_PER_LONG); /* read-low */
+ if ( type & MSR_TYPE_W )
+ set_bit(msr, msr_bitmap + 0x800/BYTES_PER_LONG); /* write-low */
+ }
+ else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
+ {
+ msr &= 0x1fff;
+ if ( type & MSR_TYPE_R )
+ set_bit(msr, msr_bitmap + 0x400/BYTES_PER_LONG); /* read-high */
+ if ( type & MSR_TYPE_W )
+ set_bit(msr, msr_bitmap + 0xc00/BYTES_PER_LONG); /* write-high */
+ }
+ else
+ HVM_DBG_LOG(DBG_LEVEL_0,
+ "msr %x is out of the control range"
+ "0x00000000-0x00001fff and 0xc0000000-0xc0001fff"
+ "RDMSR or WRMSR will cause a VM exit", msr);
}
/*
@@ -760,6 +801,10 @@ static int construct_vmcs(struct vcpu *v
vmentry_ctl &= ~VM_ENTRY_LOAD_GUEST_PAT;
}
+ /* Disable Virtualize x2APIC mode by default. */
+ v->arch.hvm_vmx.secondary_exec_control &=
+ ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
+
/* Do not enable Monitor Trap Flag unless start single step debug */
v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG;
@@ -797,18 +842,6 @@ static int construct_vmcs(struct vcpu *v
vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_EIP, MSR_TYPE_R | MSR_TYPE_W);
if ( paging_mode_hap(d) && (!iommu_enabled || iommu_snoop) )
vmx_disable_intercept_for_msr(v, MSR_IA32_CR_PAT, MSR_TYPE_R | MSR_TYPE_W);
- if ( cpu_has_vmx_apic_reg_virt )
- {
- int msr;
- for (msr = MSR_IA32_APICBASE_MSR; msr <= MSR_IA32_APICBASE_MSR + 0xff; msr++)
- vmx_disable_intercept_for_msr(v, msr, MSR_TYPE_R);
- }
- if ( cpu_has_vmx_virtual_intr_delivery )
- {
- vmx_disable_intercept_for_msr(v, MSR_IA32_APICTPR_MSR, MSR_TYPE_W);
- vmx_disable_intercept_for_msr(v, MSR_IA32_APICEOI_MSR, MSR_TYPE_W);
- vmx_disable_intercept_for_msr(v, MSR_IA32_APICSELF_MSR, MSR_TYPE_W);
- }
}
/* I/O access bitmap. */
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2081,18 +2081,63 @@ static void vmx_install_vlapic_mapping(s
void vmx_vlapic_msr_changed(struct vcpu *v)
{
+ int virtualize_x2apic_mode;
struct vlapic *vlapic = vcpu_vlapic(v);
- if ( !cpu_has_vmx_virtualize_apic_accesses )
+ virtualize_x2apic_mode = ( (cpu_has_vmx_apic_reg_virt ||
+ cpu_has_vmx_virtual_intr_delivery) &&
+ cpu_has_vmx_virtualize_x2apic_mode );
+
+ if ( !cpu_has_vmx_virtualize_apic_accesses &&
+ !virtualize_x2apic_mode )
return;
vmx_vmcs_enter(v);
v->arch.hvm_vmx.secondary_exec_control &=
- ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+ ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
+ SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE);
if ( !vlapic_hw_disabled(vlapic) &&
(vlapic_base_address(vlapic) == APIC_DEFAULT_PHYS_BASE) )
- v->arch.hvm_vmx.secondary_exec_control |=
- SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+ {
+ unsigned int msr;
+
+ if ( virtualize_x2apic_mode && vlapic_x2apic_mode(vlapic) )
+ {
+ v->arch.hvm_vmx.secondary_exec_control |=
+ SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
+ if ( cpu_has_vmx_apic_reg_virt )
+ {
+ for ( msr = MSR_IA32_APICBASE_MSR;
+ msr <= MSR_IA32_APICBASE_MSR + 0xff; msr++ )
+ vmx_disable_intercept_for_msr(v, msr, MSR_TYPE_R);
+
+ vmx_enable_intercept_for_msr(v, MSR_IA32_APICPPR_MSR,
+ MSR_TYPE_R);
+ vmx_enable_intercept_for_msr(v, MSR_IA32_APICTMICT_MSR,
+ MSR_TYPE_R);
+ vmx_enable_intercept_for_msr(v, MSR_IA32_APICTMCCT_MSR,
+ MSR_TYPE_R);
+ }
+ if ( cpu_has_vmx_virtual_intr_delivery )
+ {
+ vmx_disable_intercept_for_msr(v, MSR_IA32_APICTPR_MSR,
+ MSR_TYPE_W);
+ vmx_disable_intercept_for_msr(v, MSR_IA32_APICEOI_MSR,
+ MSR_TYPE_W);
+ vmx_disable_intercept_for_msr(v, MSR_IA32_APICSELF_MSR,
+ MSR_TYPE_W);
+ }
+ }
+ else
+ {
+ v->arch.hvm_vmx.secondary_exec_control |=
+ SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+ for ( msr = MSR_IA32_APICBASE_MSR;
+ msr <= MSR_IA32_APICBASE_MSR + 0xff; msr++ )
+ vmx_enable_intercept_for_msr(v, msr,
+ MSR_TYPE_R | MSR_TYPE_W);
+ }
+ }
vmx_update_secondary_exec_control(v);
vmx_vmcs_exit(v);
}
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -183,6 +183,7 @@ extern u32 vmx_vmentry_control;
#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
#define SECONDARY_EXEC_ENABLE_EPT 0x00000002
#define SECONDARY_EXEC_ENABLE_RDTSCP 0x00000008
+#define SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE 0x00000010
#define SECONDARY_EXEC_ENABLE_VPID 0x00000020
#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
#define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080
@@ -240,6 +241,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
(vmx_secondary_exec_control & SECONDARY_EXEC_APIC_REGISTER_VIRT)
#define cpu_has_vmx_virtual_intr_delivery \
(vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY)
+#define cpu_has_vmx_virtualize_x2apic_mode \
+ (vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE)
/* GUEST_INTERRUPTIBILITY_INFO flags. */
#define VMX_INTR_SHADOW_STI 0x00000001
@@ -415,6 +418,7 @@ enum vmcs_field {
#define MSR_TYPE_R 1
#define MSR_TYPE_W 2
void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr, int type);
+void vmx_enable_intercept_for_msr(struct vcpu *v, u32 msr, int type);
int vmx_read_guest_msr(u32 msr, u64 *val);
int vmx_write_guest_msr(u32 msr, u64 val);
int vmx_add_guest_msr(u32 msr);
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -296,7 +296,10 @@
#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
#define MSR_IA32_APICBASE_MSR 0x800
#define MSR_IA32_APICTPR_MSR 0x808
+#define MSR_IA32_APICPPR_MSR 0x80a
#define MSR_IA32_APICEOI_MSR 0x80b
+#define MSR_IA32_APICTMICT_MSR 0x838
+#define MSR_IA32_APICTMCCT_MSR 0x839
#define MSR_IA32_APICSELF_MSR 0x83f
#define MSR_IA32_UCODE_WRITE 0x00000079
++++++ 26675-tools-xentoollog_update_tty_detection_in_stdiostream_progress.patch ++++++
changeset: 26675:3eb62c576a1a
user: Olaf Hering
date: Wed Feb 27 14:16:36 2013 +0000
files: tools/libxc/xtl_logger_stdio.c
description:
tools/xentoollog: update tty detection in stdiostream_progress
As suggested by IanJ:
Check isatty only once to preserve the errno of ->progress users, and to
reduce the noice in strace output.
Signed-off-by: Olaf Hering
Acked-by: Ian Jackson
diff -r 4b25c1e6cfbb -r 3eb62c576a1a tools/libxc/xtl_logger_stdio.c
--- a/tools/libxc/xtl_logger_stdio.c Wed Feb 27 11:16:47 2013 +0000
+++ b/tools/libxc/xtl_logger_stdio.c Wed Feb 27 14:16:36 2013 +0000
@@ -35,6 +35,7 @@ struct xentoollog_logger_stdiostream {
xentoollog_level min_level;
unsigned flags;
int progress_erase_len, progress_last_percent;
+ int tty;
};
static void progress_erase(xentoollog_logger_stdiostream *lg) {
@@ -118,7 +119,7 @@ static void stdiostream_progress(struct
lg->progress_last_percent = percent;
- if (isatty(fileno(lg->f)) <= 0) {
+ if (!lg->tty) {
stdiostream_message(logger_in, this_level, context,
"%s: %lu/%lu %3d%%",
doing_what, done, total, percent);
@@ -166,6 +167,7 @@ xentoollog_logger_stdiostream *xtl_creat
newlogger.f = f;
newlogger.min_level = min_level;
newlogger.flags = flags;
+ newlogger.tty = isatty(fileno(newlogger.f)) > 0;
if (newlogger.flags & XTL_STDIOSTREAM_SHOW_DATE) tzset();
++++++ 26754-hvm-Improve-APIC-INIT-SIPI-emulation.patch ++++++
References: FATE#313605
# Commit 7242e0dc2c6c083ded570de159007d112ee34e88
# Date 2013-03-28 11:44:11 +0000
# Author Keir Fraser
# Committer Keir Fraser
hvm: Improve APIC INIT/SIPI emulation, fixing it for call paths other than x86_emulate().
In particular, on broadcast/multicast INIT/SIPI, we handle all target
APICs at once in a single invocation of the init/sipi tasklet. This
avoids needing to return an X86EMUL_RETRY error code to the caller,
which was being ignored by all except x86_emulate().
The original bug, and the general approach in this fix, pointed out by
Intel (yang.z.zhang@intel.com).
Signed-off-by: Keir Fraser
Index: xen-4.2.4-testing/xen/arch/x86/hvm/hvm.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/hvm.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/hvm.c
@@ -3530,8 +3530,6 @@ void hvm_vcpu_reset_state(struct vcpu *v
struct domain *d = v->domain;
struct segment_register reg;
- BUG_ON(vcpu_runnable(v));
-
domain_lock(d);
if ( v->is_initialised )
Index: xen-4.2.4-testing/xen/arch/x86/hvm/viridian.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/viridian.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/viridian.c
@@ -241,8 +241,8 @@ int wrmsr_viridian_regs(uint32_t idx, ui
eax &= ~(1 << 12);
edx &= 0xff000000;
vlapic_set_reg(vlapic, APIC_ICR2, edx);
- if ( vlapic_ipi(vlapic, eax, edx) == X86EMUL_OKAY )
- vlapic_set_reg(vlapic, APIC_ICR, eax);
+ vlapic_ipi(vlapic, eax, edx);
+ vlapic_set_reg(vlapic, APIC_ICR, eax);
break;
}
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vlapic.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
@@ -243,12 +243,8 @@ bool_t vlapic_match_dest(
return 0;
}
-static void vlapic_init_sipi_action(unsigned long _vcpu)
+static void vlapic_init_sipi_one(struct vcpu *target, uint32_t icr)
{
- struct vcpu *origin = (struct vcpu *)_vcpu;
- struct vcpu *target = vcpu_vlapic(origin)->init_sipi.target;
- uint32_t icr = vcpu_vlapic(origin)->init_sipi.icr;
-
vcpu_pause(target);
switch ( icr & APIC_MODE_MASK )
@@ -257,6 +253,14 @@ static void vlapic_init_sipi_action(unsi
bool_t fpu_initialised;
int rc;
+ /* No work on INIT de-assert for P4-type APIC. */
+ if ( (icr & (APIC_INT_LEVELTRIG | APIC_INT_ASSERT)) ==
+ APIC_INT_LEVELTRIG )
+ break;
+ /* Nothing to do if the VCPU is already reset. */
+ if ( !target->is_initialised )
+ break;
+ hvm_vcpu_down(target);
domain_lock(target->domain);
/* Reset necessary VCPU state. This does not include FPU state. */
fpu_initialised = target->fpu_initialised;
@@ -279,36 +283,36 @@ static void vlapic_init_sipi_action(unsi
}
vcpu_unpause(target);
-
- vcpu_vlapic(origin)->init_sipi.target = NULL;
- vcpu_unpause(origin);
}
-static int vlapic_schedule_init_sipi_tasklet(struct vcpu *target, uint32_t icr)
+static void vlapic_init_sipi_action(unsigned long _vcpu)
{
- struct vcpu *origin = current;
+ struct vcpu *origin = (struct vcpu *)_vcpu;
+ uint32_t icr = vcpu_vlapic(origin)->init_sipi.icr;
+ uint32_t dest = vcpu_vlapic(origin)->init_sipi.dest;
+ uint32_t short_hand = icr & APIC_SHORT_MASK;
+ uint32_t dest_mode = !!(icr & APIC_DEST_MASK);
+ struct vcpu *v;
+
+ if ( icr == 0 )
+ return;
- if ( vcpu_vlapic(origin)->init_sipi.target != NULL )
+ for_each_vcpu ( origin->domain, v )
{
- WARN(); /* should be impossible but don't BUG, just in case */
- return X86EMUL_UNHANDLEABLE;
+ if ( vlapic_match_dest(vcpu_vlapic(v), vcpu_vlapic(origin),
+ short_hand, dest, dest_mode) )
+ vlapic_init_sipi_one(v, icr);
}
- vcpu_pause_nosync(origin);
-
- vcpu_vlapic(origin)->init_sipi.target = target;
- vcpu_vlapic(origin)->init_sipi.icr = icr;
- tasklet_schedule(&vcpu_vlapic(origin)->init_sipi.tasklet);
-
- return X86EMUL_RETRY;
+ vcpu_vlapic(origin)->init_sipi.icr = 0;
+ vcpu_unpause(origin);
}
/* Add a pending IRQ into lapic. */
-static int vlapic_accept_irq(struct vcpu *v, uint32_t icr_low)
+static void vlapic_accept_irq(struct vcpu *v, uint32_t icr_low)
{
struct vlapic *vlapic = vcpu_vlapic(v);
uint8_t vector = (uint8_t)icr_low;
- int rc = X86EMUL_OKAY;
switch ( icr_low & APIC_MODE_MASK )
{
@@ -342,31 +346,15 @@ static int vlapic_accept_irq(struct vcpu
break;
case APIC_DM_INIT:
- /* No work on INIT de-assert for P4-type APIC. */
- if ( (icr_low & (APIC_INT_LEVELTRIG | APIC_INT_ASSERT)) ==
- APIC_INT_LEVELTRIG )
- break;
- /* Nothing to do if the VCPU is already reset. */
- if ( !v->is_initialised )
- break;
- hvm_vcpu_down(v);
- rc = vlapic_schedule_init_sipi_tasklet(v, icr_low);
- break;
-
case APIC_DM_STARTUP:
- /* Nothing to do if the VCPU is already initialised. */
- if ( v->is_initialised )
- break;
- rc = vlapic_schedule_init_sipi_tasklet(v, icr_low);
- break;
+ /* Handled in vlapic_ipi(). */
+ BUG();
default:
gdprintk(XENLOG_ERR, "TODO: unsupported delivery mode in ICR %x\n",
icr_low);
domain_crash(v->domain);
}
-
- return rc;
}
struct vlapic *vlapic_lowest_prio(
@@ -424,15 +412,12 @@ void vlapic_handle_EOI_induced_exit(stru
hvm_dpci_msi_eoi(current->domain, vector);
}
-int vlapic_ipi(
+void vlapic_ipi(
struct vlapic *vlapic, uint32_t icr_low, uint32_t icr_high)
{
unsigned int dest;
unsigned int short_hand = icr_low & APIC_SHORT_MASK;
unsigned int dest_mode = !!(icr_low & APIC_DEST_MASK);
- struct vlapic *target;
- struct vcpu *v;
- int rc = X86EMUL_OKAY;
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "icr = 0x%08x:%08x", icr_high, icr_low);
@@ -440,25 +425,40 @@ int vlapic_ipi(
? icr_high
: GET_xAPIC_DEST_FIELD(icr_high));
- if ( (icr_low & APIC_MODE_MASK) == APIC_DM_LOWEST )
+ switch ( icr_low & APIC_MODE_MASK )
{
- target = vlapic_lowest_prio(vlapic_domain(vlapic), vlapic,
- short_hand, dest, dest_mode);
+ case APIC_DM_INIT:
+ case APIC_DM_STARTUP:
+ if ( vlapic->init_sipi.icr != 0 )
+ {
+ WARN(); /* should be impossible but don't BUG, just in case */
+ break;
+ }
+ vcpu_pause_nosync(vlapic_vcpu(vlapic));
+ vlapic->init_sipi.icr = icr_low;
+ vlapic->init_sipi.dest = dest;
+ tasklet_schedule(&vlapic->init_sipi.tasklet);
+ break;
+
+ case APIC_DM_LOWEST: {
+ struct vlapic *target = vlapic_lowest_prio(
+ vlapic_domain(vlapic), vlapic, short_hand, dest, dest_mode);
if ( target != NULL )
- rc = vlapic_accept_irq(vlapic_vcpu(target), icr_low);
- return rc;
+ vlapic_accept_irq(vlapic_vcpu(target), icr_low);
+ break;
}
- for_each_vcpu ( vlapic_domain(vlapic), v )
- {
- if ( vlapic_match_dest(vcpu_vlapic(v), vlapic,
- short_hand, dest, dest_mode) )
- rc = vlapic_accept_irq(v, icr_low);
- if ( rc != X86EMUL_OKAY )
- break;
+ default: {
+ struct vcpu *v;
+ for_each_vcpu ( vlapic_domain(vlapic), v )
+ {
+ if ( vlapic_match_dest(vcpu_vlapic(v), vlapic,
+ short_hand, dest, dest_mode) )
+ vlapic_accept_irq(v, icr_low);
+ }
+ break;
+ }
}
-
- return rc;
}
static uint32_t vlapic_get_tmcct(struct vlapic *vlapic)
@@ -701,9 +701,8 @@ static int vlapic_reg_write(struct vcpu
case APIC_ICR:
val &= ~(1 << 12); /* always clear the pending bit */
- rc = vlapic_ipi(vlapic, val, vlapic_get_reg(vlapic, APIC_ICR2));
- if ( rc == X86EMUL_OKAY )
- vlapic_set_reg(vlapic, APIC_ICR, val);
+ vlapic_ipi(vlapic, val, vlapic_get_reg(vlapic, APIC_ICR2));
+ vlapic_set_reg(vlapic, APIC_ICR, val);
break;
case APIC_ICR2:
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vlapic.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vlapic.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vlapic.h
@@ -62,8 +62,7 @@ struct vlapic {
struct page_info *regs_page;
/* INIT-SIPI-SIPI work gets deferred to a tasklet. */
struct {
- struct vcpu *target;
- uint32_t icr;
+ uint32_t icr, dest;
struct tasklet tasklet;
} init_sipi;
};
@@ -102,7 +101,7 @@ void vlapic_adjust_i8259_target(struct d
void vlapic_EOI_set(struct vlapic *vlapic);
void vlapic_handle_EOI_induced_exit(struct vlapic *vlapic, int vector);
-int vlapic_ipi(struct vlapic *vlapic, uint32_t icr_low, uint32_t icr_high);
+void vlapic_ipi(struct vlapic *vlapic, uint32_t icr_low, uint32_t icr_high);
int vlapic_apicv_write(struct vcpu *v, unsigned int offset);
++++++ 26878-VMX-Detect-posted-interrupt-capability.patch ++++++
References: bnc#808269 FATE#313605
# Commit b266924990af96ee47ee299e1b6bb87fac2e2548
# Date 2013-04-18 11:32:02 +0200
# Author Yang Zhang
# Committer Jan Beulich
VMX: Detect posted interrupt capability
Check whether the Hardware supports posted interrupt capability.
Signed-off-by: Yang Zhang
Reviewed-by: Jun Nakajima
Acked-by: Keir Fraser
Acked-by: George Dunlap (from a release perspective)
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
@@ -91,6 +91,7 @@ static void __init vmx_display_features(
P(cpu_has_vmx_unrestricted_guest, "Unrestricted Guest");
P(cpu_has_vmx_apic_reg_virt, "APIC Register Virtualization");
P(cpu_has_vmx_virtual_intr_delivery, "Virtual Interrupt Delivery");
+ P(cpu_has_vmx_posted_intr_processing, "Posted Interrupt Processing");
#undef P
if ( !printed )
@@ -140,7 +141,8 @@ static int vmx_init_vmcs_config(void)
min = (PIN_BASED_EXT_INTR_MASK |
PIN_BASED_NMI_EXITING);
- opt = PIN_BASED_VIRTUAL_NMIS;
+ opt = (PIN_BASED_VIRTUAL_NMIS |
+ PIN_BASED_POSTED_INTERRUPT);
_vmx_pin_based_exec_control = adjust_vmx_controls(
"Pin-Based Exec Control", min, opt,
MSR_IA32_VMX_PINBASED_CTLS, &mismatch);
@@ -276,6 +278,14 @@ static int vmx_init_vmcs_config(void)
_vmx_vmexit_control = adjust_vmx_controls(
"VMExit Control", min, opt, MSR_IA32_VMX_EXIT_CTLS, &mismatch);
+ /*
+ * "Process posted interrupt" can be set only when "virtual-interrupt
+ * delivery" and "acknowledge interrupt on exit" is set
+ */
+ if ( !(_vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY)
+ || !(_vmx_vmexit_control & VM_EXIT_ACK_INTR_ON_EXIT) )
+ _vmx_pin_based_exec_control &= ~ PIN_BASED_POSTED_INTERRUPT;
+
min = 0;
opt = VM_ENTRY_LOAD_GUEST_PAT;
_vmx_vmentry_control = adjust_vmx_controls(
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -161,6 +161,7 @@ extern u32 vmx_cpu_based_exec_control;
#define PIN_BASED_NMI_EXITING 0x00000008
#define PIN_BASED_VIRTUAL_NMIS 0x00000020
#define PIN_BASED_PREEMPT_TIMER 0x00000040
+#define PIN_BASED_POSTED_INTERRUPT 0x00000080
extern u32 vmx_pin_based_exec_control;
#define VM_EXIT_SAVE_DEBUG_CNTRLS 0x00000004
@@ -243,6 +244,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
(vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY)
#define cpu_has_vmx_virtualize_x2apic_mode \
(vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE)
+#define cpu_has_vmx_posted_intr_processing \
+ (vmx_pin_based_exec_control & PIN_BASED_POSTED_INTERRUPT)
/* GUEST_INTERRUPTIBILITY_INFO flags. */
#define VMX_INTR_SHADOW_STI 0x00000001
@@ -257,6 +260,7 @@ extern bool_t cpu_has_vmx_ins_outs_instr
/* VMCS field encodings. */
enum vmcs_field {
VIRTUAL_PROCESSOR_ID = 0x00000000,
+ POSTED_INTR_NOTIFICATION_VECTOR = 0x00000002,
GUEST_ES_SELECTOR = 0x00000800,
GUEST_CS_SELECTOR = 0x00000802,
GUEST_SS_SELECTOR = 0x00000804,
@@ -291,6 +295,8 @@ enum vmcs_field {
VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013,
APIC_ACCESS_ADDR = 0x00002014,
APIC_ACCESS_ADDR_HIGH = 0x00002015,
+ PI_DESC_ADDR = 0x00002016,
+ PI_DESC_ADDR_HIGH = 0x00002017,
EPT_POINTER = 0x0000201a,
EPT_POINTER_HIGH = 0x0000201b,
EOI_EXIT_BITMAP0 = 0x0000201c,
++++++ 26879-VMX-Turn-on-posted-interrupt-bit-in-vmcs.patch ++++++
References: bnc#808269 FATE#313605
# Commit 1c0ac49b1d6c3d54fc1f75661742a988ca7cf255
# Date 2013-04-18 11:34:04 +0200
# Author Yang Zhang
# Committer Jan Beulich
VMX: Turn on posted interrupt bit in vmcs
Turn on posted interrupt for vcpu if posted interrupt is avaliable.
Signed-off-by: Yang Zhang
Reviewed-by: Jun Nakajima
Acked-by: Keir Fraser
Acked-by: George Dunlap (from a release perspective)
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
@@ -874,6 +874,12 @@ static int construct_vmcs(struct vcpu *v
__vmwrite(GUEST_INTR_STATUS, 0);
}
+ if ( cpu_has_vmx_posted_intr_processing )
+ {
+ __vmwrite(PI_DESC_ADDR, virt_to_maddr(&v->arch.hvm_vmx.pi_desc));
+ __vmwrite(POSTED_INTR_NOTIFICATION_VECTOR, posted_intr_vector);
+ }
+
/* Host data selectors. */
__vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS);
__vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS);
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
@@ -77,6 +77,8 @@ static int vmx_msr_write_intercept(unsig
static void vmx_invlpg_intercept(unsigned long vaddr);
static void __ept_sync_domain(void *info);
+uint8_t __read_mostly posted_intr_vector;
+
static int vmx_domain_initialise(struct domain *d)
{
int rc;
@@ -1694,6 +1696,9 @@ struct hvm_function_table * __init start
setup_ept_dump();
}
+ if ( cpu_has_vmx_posted_intr_processing )
+ alloc_direct_apic_vector(&posted_intr_vector, event_check_interrupt);
+
setup_vmcs_dump();
return &vmx_function_table;
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -21,6 +21,7 @@
#include
#include
+#include
extern void vmcs_dump_vcpu(struct vcpu *v);
extern void setup_vmcs_dump(void);
@@ -70,6 +71,12 @@ struct vmx_domain {
cpumask_var_t ept_synced;
};
+struct pi_desc {
+ DECLARE_BITMAP(pir, NR_VECTORS);
+ u32 control;
+ u32 rsvd[7];
+} __attribute__ ((aligned (64)));
+
#define ept_get_wl(d) \
((d)->arch.hvm_domain.vmx.ept_control.ept_wl)
#define ept_get_asr(d) \
@@ -112,6 +119,7 @@ struct arch_vmx_struct {
uint32_t eoi_exitmap_changed;
uint64_t eoi_exit_bitmap[4];
+ struct pi_desc pi_desc;
unsigned long host_cr0;
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmx.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmx.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -189,6 +189,7 @@ void vmx_update_cpu_exec_control(struct
#define MODRM_EAX_ECX ".byte 0xc1\n" /* EAX, ECX */
extern u64 vmx_ept_vpid_cap;
+extern uint8_t posted_intr_vector;
#define cpu_has_vmx_ept_wl4_supported \
(vmx_ept_vpid_cap & VMX_EPT_WALK_LENGTH_4_SUPPORTED)
++++++ 26880-VMX-Add-posted-interrupt-supporting.patch ++++++
References: bnc#808269 FATE#313605
# Commit d7dafa375bc13772e2e3274d975d544af4208939
# Date 2013-04-18 11:34:49 +0200
# Author Yang Zhang
# Committer Jan Beulich
VMX: Add posted interrupt supporting
Add the supporting of using posted interrupt to deliver interrupt.
Signed-off-by: Yang Zhang
Reviewed-by: Jun Nakajima
Acked-by: Keir Fraser
Acked-by: George Dunlap (from a release perspective)
# Commit e4e1e0ecc023caf4cf3b87a4aa4d5e210760f4e8
# Date 2013-04-19 12:31:18 +0200
# Author Jan Beulich
# Committer Jan Beulich
VMX: adjust correct table when there's no posted interrupt support
The caller of start_vmx() will overwrite hvm_funcs, so there's no point
in adjusting that table in start_vmx().
Signed-off-by: Jan Beulich
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vlapic.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
@@ -90,24 +90,6 @@ static unsigned int vlapic_lvt_mask[VLAP
((vlapic_get_reg(vlapic, APIC_LVTT) & APIC_TIMER_MODE_MASK) \
== APIC_TIMER_MODE_TSC_DEADLINE)
-
-/*
- * Generic APIC bitmap vector update & search routines.
- */
-
-#define VEC_POS(v) ((v)%32)
-#define REG_POS(v) (((v)/32) * 0x10)
-#define vlapic_test_and_set_vector(vec, bitmap) \
- test_and_set_bit(VEC_POS(vec), \
- (unsigned long *)((bitmap) + REG_POS(vec)))
-#define vlapic_test_and_clear_vector(vec, bitmap) \
- test_and_clear_bit(VEC_POS(vec), \
- (unsigned long *)((bitmap) + REG_POS(vec)))
-#define vlapic_set_vector(vec, bitmap) \
- set_bit(VEC_POS(vec), (unsigned long *)((bitmap) + REG_POS(vec)))
-#define vlapic_clear_vector(vec, bitmap) \
- clear_bit(VEC_POS(vec), (unsigned long *)((bitmap) + REG_POS(vec)))
-
static int vlapic_find_highest_vector(void *bitmap)
{
uint32_t *word = bitmap;
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
@@ -56,6 +56,7 @@
#include
#include
#include
+#include
enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised };
@@ -1613,6 +1614,60 @@ static void vmx_process_isr(int isr, str
vmx_vmcs_exit(v);
}
+static void __vmx_deliver_posted_interrupt(struct vcpu *v)
+{
+ bool_t running = v->is_running;
+
+ vcpu_unblock(v);
+ if ( running && (in_irq() || (v != current)) )
+ {
+ unsigned int cpu = v->processor;
+
+ if ( !test_and_set_bit(VCPU_KICK_SOFTIRQ, &softirq_pending(cpu))
+ && (cpu != smp_processor_id()) )
+ send_IPI_mask(cpumask_of(cpu), posted_intr_vector);
+ }
+}
+
+static void vmx_deliver_posted_intr(struct vcpu *v, u8 vector)
+{
+ if ( pi_test_and_set_pir(vector, &v->arch.hvm_vmx.pi_desc) )
+ return;
+
+ if ( unlikely(v->arch.hvm_vmx.eoi_exitmap_changed) )
+ {
+ /*
+ * If EOI exitbitmap needs to changed or notification vector
+ * can't be allocated, interrupt will not be injected till
+ * VMEntry as it used to be.
+ */
+ pi_set_on(&v->arch.hvm_vmx.pi_desc);
+ }
+ else if ( !pi_test_and_set_on(&v->arch.hvm_vmx.pi_desc) )
+ {
+ __vmx_deliver_posted_interrupt(v);
+ return;
+ }
+
+ vcpu_kick(v);
+}
+
+static void vmx_sync_pir_to_irr(struct vcpu *v)
+{
+ struct vlapic *vlapic = vcpu_vlapic(v);
+ unsigned int group, i;
+ DECLARE_BITMAP(pending_intr, NR_VECTORS);
+
+ if ( !pi_test_and_clear_on(&v->arch.hvm_vmx.pi_desc) )
+ return;
+
+ for ( group = 0; group < ARRAY_SIZE(pending_intr); group++ )
+ pending_intr[group] = pi_get_pir(&v->arch.hvm_vmx.pi_desc, group);
+
+ for_each_set_bit(i, pending_intr, NR_VECTORS)
+ vlapic_set_vector(i, &vlapic->regs->data[APIC_IRR]);
+}
+
static struct hvm_function_table __read_mostly vmx_function_table = {
.name = "VMX",
.cpu_up_prepare = vmx_cpu_up_prepare,
@@ -1663,6 +1718,8 @@ static struct hvm_function_table __read_
.update_eoi_exit_bitmap = vmx_update_eoi_exit_bitmap,
.virtual_intr_delivery_enabled = vmx_virtual_intr_delivery_enabled,
.process_isr = vmx_process_isr,
+ .deliver_posted_intr = vmx_deliver_posted_intr,
+ .sync_pir_to_irr = vmx_sync_pir_to_irr,
};
struct hvm_function_table * __init start_vmx(void)
@@ -1698,6 +1755,11 @@ struct hvm_function_table * __init start
if ( cpu_has_vmx_posted_intr_processing )
alloc_direct_apic_vector(&posted_intr_vector, event_check_interrupt);
+ else
+ {
+ vmx_function_table.deliver_posted_intr = NULL;
+ vmx_function_table.sync_pir_to_irr = NULL;
+ }
setup_vmcs_dump();
Index: xen-4.2.4-testing/xen/include/asm-x86/bitops.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/bitops.h
+++ xen-4.2.4-testing/xen/include/asm-x86/bitops.h
@@ -367,6 +367,16 @@ static inline unsigned int __scanbit(uns
((off)+(__scanbit(~(((*(const unsigned long *)addr)) >> (off)), size))) : \
__find_next_zero_bit(addr,size,off)))
+/**
+ * for_each_set_bit - iterate over every set bit in a memory region
+ * @bit: The integer iterator
+ * @addr: The address to base the search on
+ * @size: The maximum size to search
+ */
+#define for_each_set_bit(bit, addr, size) \
+ for ( (bit) = find_first_bit(addr, size); \
+ (bit) < (size); \
+ (bit) = find_next_bit(addr, size, (bit) + 1) )
/**
* find_first_set_bit - find the first set bit in @word
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/hvm.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/hvm.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/hvm.h
@@ -185,6 +185,8 @@ struct hvm_function_table {
void (*update_eoi_exit_bitmap)(struct vcpu *v, u8 vector, u8 trig);
int (*virtual_intr_delivery_enabled)(void);
void (*process_isr)(int isr, struct vcpu *v);
+ void (*deliver_posted_intr)(struct vcpu *v, u8 vector);
+ void (*sync_pir_to_irr)(struct vcpu *v);
};
extern struct hvm_function_table hvm_funcs;
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vlapic.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vlapic.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vlapic.h
@@ -54,6 +54,21 @@
#define vlapic_x2apic_mode(vlapic) \
((vlapic)->hw.apic_base_msr & MSR_IA32_APICBASE_EXTD)
+/*
+ * Generic APIC bitmap vector update & search routines.
+ */
+
+#define VEC_POS(v) ((v) % 32)
+#define REG_POS(v) (((v) / 32) * 0x10)
+#define vlapic_test_and_set_vector(vec, bitmap) \
+ test_and_set_bit(VEC_POS(vec), (uint32_t *)((bitmap) + REG_POS(vec)))
+#define vlapic_test_and_clear_vector(vec, bitmap) \
+ test_and_clear_bit(VEC_POS(vec), (uint32_t *)((bitmap) + REG_POS(vec)))
+#define vlapic_set_vector(vec, bitmap) \
+ set_bit(VEC_POS(vec), (uint32_t *)((bitmap) + REG_POS(vec)))
+#define vlapic_clear_vector(vec, bitmap) \
+ clear_bit(VEC_POS(vec), (uint32_t *)((bitmap) + REG_POS(vec)))
+
struct vlapic {
struct hvm_hw_lapic hw;
struct hvm_hw_lapic_regs *regs;
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmx.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmx.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -71,6 +71,31 @@ void vmx_update_debug_state(struct vcpu
void vmx_update_exception_bitmap(struct vcpu *v);
void vmx_update_cpu_exec_control(struct vcpu *v);
+#define POSTED_INTR_ON 0
+static inline int pi_test_and_set_pir(int vector, struct pi_desc *pi_desc)
+{
+ return test_and_set_bit(vector, pi_desc->pir);
+}
+
+static inline int pi_test_and_set_on(struct pi_desc *pi_desc)
+{
+ return test_and_set_bit(POSTED_INTR_ON, &pi_desc->control);
+}
+
+static inline void pi_set_on(struct pi_desc *pi_desc)
+{
+ set_bit(POSTED_INTR_ON, &pi_desc->control);
+}
+
+static inline int pi_test_and_clear_on(struct pi_desc *pi_desc)
+{
+ return test_and_clear_bit(POSTED_INTR_ON, &pi_desc->control);
+}
+
+static inline unsigned long pi_get_pir(struct pi_desc *pi_desc, int group)
+{
+ return xchg(&pi_desc->pir[group], 0);
+}
/*
* Exit Reasons
++++++ 26881-x86-HVM-Call-vlapic_set_irq-to-delivery-virtual-interrupt.patch ++++++
References: bnc#808269 FATE#313605
# Commit 04015d6326f17e4aafb32593b94dac44b72ef4c1
# Date 2013-04-18 11:35:43 +0200
# Author Yang Zhang
# Committer Jan Beulich
x86/HVM: Call vlapic_set_irq() to delivery virtual interrupt
Move kick_vcpu into vlapic_set_irq. And call it to deliver virtual interrupt
instead set vIRR directly.
Signed-off-by: Yang Zhang
Acked-by: Keir Fraser
Acked-by: George Dunlap (from a release perspective)
Index: xen-4.2.3-testing/xen/arch/x86/hvm/vioapic.c
===================================================================
--- xen-4.2.3-testing.orig/xen/arch/x86/hvm/vioapic.c
+++ xen-4.2.3-testing/xen/arch/x86/hvm/vioapic.c
@@ -263,8 +263,7 @@ static void ioapic_inj_irq(
ASSERT((delivery_mode == dest_Fixed) ||
(delivery_mode == dest_LowestPrio));
- if ( vlapic_set_irq(target, vector, trig_mode) )
- vcpu_kick(vlapic_vcpu(target));
+ vlapic_set_irq(target, vector, trig_mode);
}
static inline int pit_channel0_enabled(void)
Index: xen-4.2.3-testing/xen/arch/x86/hvm/vlapic.c
===================================================================
--- xen-4.2.3-testing.orig/xen/arch/x86/hvm/vlapic.c
+++ xen-4.2.3-testing/xen/arch/x86/hvm/vlapic.c
@@ -122,16 +122,19 @@ static int vlapic_find_highest_irr(struc
return vlapic_find_highest_vector(&vlapic->regs->data[APIC_IRR]);
}
-int vlapic_set_irq(struct vlapic *vlapic, uint8_t vec, uint8_t trig)
+void vlapic_set_irq(struct vlapic *vlapic, uint8_t vec, uint8_t trig)
{
+ struct vcpu *target = vlapic_vcpu(vlapic);
+
if ( trig )
vlapic_set_vector(vec, &vlapic->regs->data[APIC_TMR]);
if ( hvm_funcs.update_eoi_exit_bitmap )
- hvm_funcs.update_eoi_exit_bitmap(vlapic_vcpu(vlapic), vec ,trig);
+ hvm_funcs.update_eoi_exit_bitmap(target, vec, trig);
/* We may need to wake up target vcpu, besides set pending bit here */
- return !vlapic_test_and_set_irr(vec, vlapic);
+ if ( !vlapic_test_and_set_irr(vec, vlapic) )
+ vcpu_kick(target);
}
static int vlapic_find_highest_isr(struct vlapic *vlapic)
@@ -300,9 +303,8 @@ static void vlapic_accept_irq(struct vcp
{
case APIC_DM_FIXED:
case APIC_DM_LOWEST:
- if ( vlapic_enabled(vlapic) &&
- !vlapic_test_and_set_irr(vector, vlapic) )
- vcpu_kick(v);
+ if ( vlapic_enabled(vlapic) )
+ vlapic_set_irq(vlapic, vector, 0);
break;
case APIC_DM_REMRD:
Index: xen-4.2.3-testing/xen/arch/x86/hvm/vmsi.c
===================================================================
--- xen-4.2.3-testing.orig/xen/arch/x86/hvm/vmsi.c
+++ xen-4.2.3-testing/xen/arch/x86/hvm/vmsi.c
@@ -57,8 +57,7 @@ static void vmsi_inj_irq(
{
case dest_Fixed:
case dest_LowestPrio:
- if ( vlapic_set_irq(target, vector, trig_mode) )
- vcpu_kick(vlapic_vcpu(target));
+ vlapic_set_irq(target, vector, trig_mode);
break;
default:
gdprintk(XENLOG_WARNING, "error delivery mode %d\n", delivery_mode);
Index: xen-4.2.3-testing/xen/include/asm-x86/hvm/vlapic.h
===================================================================
--- xen-4.2.3-testing.orig/xen/include/asm-x86/hvm/vlapic.h
+++ xen-4.2.3-testing/xen/include/asm-x86/hvm/vlapic.h
@@ -95,7 +95,7 @@ static inline void vlapic_set_reg(
bool_t is_vlapic_lvtpc_enabled(struct vlapic *vlapic);
-int vlapic_set_irq(struct vlapic *vlapic, uint8_t vec, uint8_t trig);
+void vlapic_set_irq(struct vlapic *vlapic, uint8_t vec, uint8_t trig);
int vlapic_has_pending_irq(struct vcpu *v);
int vlapic_ack_pending_irq(struct vcpu *v, int vector);
++++++ 26882-VMX-Use-posted-interrupt-to-deliver-virtual-interrupt.patch ++++++
References: bnc#808269 FATE#313605
# Commit 8d266f6b2c5c3d2d0da42f1e40ba1fb2ac8fdf1a
# Date 2013-04-18 11:36:28 +0200
# Author Yang Zhang
# Committer Jan Beulich
VMX: Use posted interrupt to deliver virutal interrupt
Deliver virtual interrupt through posted way if posted interrupt
is enabled.
Signed-off-by: Yang Zhang
Reviewed-by: Jun Nakajima
Acked-by: Keir Fraser
Acked-by: George Dunlap (from a release perspective)
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -119,6 +119,9 @@ static void vlapic_clear_irr(int vector,
static int vlapic_find_highest_irr(struct vlapic *vlapic)
{
+ if ( hvm_funcs.sync_pir_to_irr )
+ hvm_funcs.sync_pir_to_irr(vlapic_vcpu(vlapic));
+
return vlapic_find_highest_vector(&vlapic->regs->data[APIC_IRR]);
}
@@ -132,8 +135,9 @@ void vlapic_set_irq(struct vlapic *vlapi
if ( hvm_funcs.update_eoi_exit_bitmap )
hvm_funcs.update_eoi_exit_bitmap(target, vec, trig);
- /* We may need to wake up target vcpu, besides set pending bit here */
- if ( !vlapic_test_and_set_irr(vec, vlapic) )
+ if ( hvm_funcs.deliver_posted_intr )
+ hvm_funcs.deliver_posted_intr(target, vec);
+ else if ( !vlapic_test_and_set_irr(vec, vlapic) )
vcpu_kick(target);
}
++++++ 26902-x86-EFI-pass-boot-services-variable-info-to-runtime-code.patch ++++++
References: FATE#314499, FATE#314509
# Commit 9be8a4447103d92843fcfeaad8be42408c90e9a9
# Date 2013-04-22 13:58:01 +0200
# Author Jan Beulich
# Committer Jan Beulich
x86/EFI: pass boot services variable info to runtime code
EFI variables can be flagged as being accessible only within boot services.
This makes it awkward for us to figure out how much space they use at
runtime. In theory we could figure this out by simply comparing the results
from QueryVariableInfo() to the space used by all of our variables, but
that fails if the platform doesn't garbage collect on every boot. Thankfully,
calling QueryVariableInfo() while still inside boot services gives a more
reliable answer. This patch passes that information from the EFI boot stub
up to the efi platform code.
Based on a similarly named Linux patch by Matthew Garrett .
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Acked-by: George Dunlap
# Commit 47f71a8ccb0c881cf3d9e0b917ef5f0dc084b062
# Date 2013-05-23 13:08:51 +0200
# Author Eric Shelton
# Committer Jan Beulich
x86/EFI: fix boot for pre-UEFI systems
efi/boot.c makes a call to QueryVariableInfo on all systems. However,
as it is only promised for UEFI 2.0+ systems, pre-UEFI systems can
hang or crash on this call. The below patch adds a version check, a
technique used in other parts of the Xen EFI codebase.
Signed-off-by: Eric Shelton
Check runtime services version instead of EFI version (while generally
they would be in sync, nothing requires them to be).
Signed-off-by: Jan Beulich
Index: xen-4.2.4-testing/xen/arch/x86/efi/boot.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/efi/boot.c
+++ xen-4.2.4-testing/xen/arch/x86/efi/boot.c
@@ -1146,6 +1146,25 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
if (efi.smbios != EFI_INVALID_TABLE_ADDR)
dmi_efi_get_table((void *)(long)efi.smbios);
+ /* Get snapshot of variable store parameters. */
+ status = (efi_rs->Hdr.Revision >> 16) >= 2 ?
+ efi_rs->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ &efi_boot_max_var_store_size,
+ &efi_boot_remain_var_store_size,
+ &efi_boot_max_var_size) :
+ EFI_INCOMPATIBLE_VERSION;
+ if ( EFI_ERROR(status) )
+ {
+ efi_boot_max_var_store_size = 0;
+ efi_boot_remain_var_store_size = 0;
+ efi_boot_max_var_size = status;
+ PrintStr(L"Warning: Could not query variable store: ");
+ DisplayUint(status, 0);
+ PrintStr(newline);
+ }
+
/* Allocate space for trampoline (in first Mb). */
cfg.addr = 0x100000;
cfg.size = trampoline_end - trampoline_start;
Index: xen-4.2.4-testing/xen/arch/x86/efi/efi.h
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/efi/efi.h
+++ xen-4.2.4-testing/xen/arch/x86/efi/efi.h
@@ -22,5 +22,8 @@ extern void *efi_memmap;
extern l4_pgentry_t *efi_l4_pgtable;
+extern UINT64 efi_boot_max_var_store_size, efi_boot_remain_var_store_size,
+ efi_boot_max_var_size;
+
unsigned long efi_rs_enter(void);
void efi_rs_leave(unsigned long);
Index: xen-4.2.4-testing/xen/arch/x86/efi/runtime.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/efi/runtime.c
+++ xen-4.2.4-testing/xen/arch/x86/efi/runtime.c
@@ -28,6 +28,10 @@ UINTN __read_mostly efi_memmap_size;
UINTN __read_mostly efi_mdesc_size;
void *__read_mostly efi_memmap;
+UINT64 __read_mostly efi_boot_max_var_store_size;
+UINT64 __read_mostly efi_boot_remain_var_store_size;
+UINT64 __read_mostly efi_boot_max_var_size;
+
struct efi __read_mostly efi = {
.acpi = EFI_INVALID_TABLE_ADDR,
.acpi20 = EFI_INVALID_TABLE_ADDR,
@@ -446,6 +450,35 @@ int efi_runtime_call(struct xenpf_efi_ru
break;
case XEN_EFI_query_variable_info:
+ if ( op->misc & ~XEN_EFI_VARINFO_BOOT_SNAPSHOT )
+ return -EINVAL;
+
+ if ( op->misc & XEN_EFI_VARINFO_BOOT_SNAPSHOT )
+ {
+ if ( (op->u.query_variable_info.attr
+ & ~EFI_VARIABLE_APPEND_WRITE) !=
+ (EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS) )
+ return -EINVAL;
+
+ op->u.query_variable_info.max_store_size =
+ efi_boot_max_var_store_size;
+ op->u.query_variable_info.remain_store_size =
+ efi_boot_remain_var_store_size;
+ if ( efi_boot_max_var_store_size )
+ {
+ op->u.query_variable_info.max_size = efi_boot_max_var_size;
+ status = EFI_SUCCESS;
+ }
+ else
+ {
+ op->u.query_variable_info.max_size = 0;
+ status = efi_boot_max_var_size;
+ }
+ break;
+ }
+
cr3 = efi_rs_enter();
if ( (efi_rs->Hdr.Revision >> 16) < 2 )
{
@@ -462,6 +495,9 @@ int efi_runtime_call(struct xenpf_efi_ru
case XEN_EFI_query_capsule_capabilities:
case XEN_EFI_update_capsule:
+ if ( op->misc )
+ return -EINVAL;
+
cr3 = efi_rs_enter();
if ( (efi_rs->Hdr.Revision >> 16) < 2 )
{
Index: xen-4.2.4-testing/xen/include/efi/efiapi.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/efi/efiapi.h
+++ xen-4.2.4-testing/xen/include/efi/efiapi.h
@@ -213,6 +213,10 @@ VOID
#define EFI_VARIABLE_NON_VOLATILE 0x00000001
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
+#define EFI_VARIABLE_APPEND_WRITE 0x00000040
// Variable size limitation
#define EFI_MAXIMUM_VARIABLE_SIZE 1024
Index: xen-4.2.4-testing/xen/include/efi/efierr.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/efi/efierr.h
+++ xen-4.2.4-testing/xen/include/efi/efierr.h
@@ -50,6 +50,7 @@ Revision History
#define EFI_ICMP_ERROR EFIERR(22)
#define EFI_TFTP_ERROR EFIERR(23)
#define EFI_PROTOCOL_ERROR EFIERR(24)
+#define EFI_INCOMPATIBLE_VERSION EFIERR(25)
#define EFI_WARN_UNKOWN_GLYPH EFIWARN(1)
#define EFI_WARN_DELETE_FAILURE EFIWARN(2)
Index: xen-4.2.4-testing/xen/include/public/platform.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/public/platform.h
+++ xen-4.2.4-testing/xen/include/public/platform.h
@@ -184,6 +184,7 @@ struct xenpf_efi_runtime_call {
struct xenpf_efi_guid vendor_guid;
} get_next_variable_name;
+#define XEN_EFI_VARINFO_BOOT_SNAPSHOT 0x00000001
struct {
uint32_t attr;
uint64_t max_store_size;
++++++ 26953-x86-allow-Dom0-read-only-access-to-IO-APICs.patch ++++++
References: bnc#808085
# Commit d1222afda4d27916580c28533762e362d64ace22
# Date 2013-05-02 16:46:02 +0200
# Author Jan Beulich
# Committer Jan Beulich
x86: allow Dom0 read-only access to IO-APICs
There are BIOSes that want to map the IO-APIC MMIO region from some
ACPI method(s), and there is at least one BIOS flavor that wants to
use this mapping to clear an RTE's mask bit. While we can't allow the
latter, we can permit reads and simply drop write attempts, leveraging
the already existing infrastructure introduced for dealing with AMD
IOMMUs' representation as PCI devices.
This fixes an interrupt setup problem on a system where _CRS evaluation
involved the above described BIOS/ACPI behavior, and is expected to
also deal with a boot time crash of pv-ops Linux upon encountering the
same kind of system.
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Index: xen-4.2.4-testing/xen/arch/x86/domain_build.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/domain_build.c
+++ xen-4.2.4-testing/xen/arch/x86/domain_build.c
@@ -1258,7 +1258,7 @@ int __init construct_dom0(
for ( i = 0; i < nr_ioapics; i++ )
{
mfn = paddr_to_pfn(mp_ioapics[i].mpc_apicaddr);
- if ( smp_found_config )
+ if ( !rangeset_contains_singleton(mmio_ro_ranges, mfn) )
rc |= iomem_deny_access(dom0, mfn, mfn);
}
/* MSI range. */
Index: xen-4.2.4-testing/xen/arch/x86/io_apic.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/io_apic.c
+++ xen-4.2.4-testing/xen/arch/x86/io_apic.c
@@ -2567,6 +2567,11 @@ void __init init_ioapic_mappings(void)
reg_01.raw = io_apic_read(i, 1);
nr_ioapic_entries[i] = reg_01.bits.entries + 1;
nr_irqs_gsi += nr_ioapic_entries[i];
+
+ if ( rangeset_add_singleton(mmio_ro_ranges,
+ ioapic_phys >> PAGE_SHIFT) )
+ printk(KERN_ERR "Failed to mark IO-APIC page %lx read-only\n",
+ ioapic_phys);
}
}
Index: xen-4.2.4-testing/xen/arch/x86/mm.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/mm.c
+++ xen-4.2.4-testing/xen/arch/x86/mm.c
@@ -161,6 +161,8 @@ unsigned long __read_mostly pdx_group_va
bool_t __read_mostly machine_to_phys_mapping_valid = 0;
+struct rangeset *__read_mostly mmio_ro_ranges;
+
#define PAGE_CACHE_ATTRS (_PAGE_PAT|_PAGE_PCD|_PAGE_PWT)
bool_t __read_mostly opt_allow_superpage;
Index: xen-4.2.4-testing/xen/arch/x86/setup.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/setup.c
+++ xen-4.2.4-testing/xen/arch/x86/setup.c
@@ -1226,6 +1226,9 @@ void __init __start_xen(unsigned long mb
zap_low_mappings();
#endif
+ mmio_ro_ranges = rangeset_new(NULL, "r/o mmio ranges",
+ RANGESETF_prettyprint_hex);
+
init_apic_mappings();
normalise_cpu_order();
Index: xen-4.2.4-testing/xen/drivers/passthrough/io.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/io.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/io.c
@@ -27,8 +27,6 @@
#include
#include
-struct rangeset *__read_mostly mmio_ro_ranges;
-
static void hvm_dirq_assist(unsigned long _d);
bool_t pt_irq_need_timer(uint32_t flags)
Index: xen-4.2.4-testing/xen/drivers/passthrough/pci.c
===================================================================
--- xen-4.2.4-testing.orig/xen/drivers/passthrough/pci.c
+++ xen-4.2.4-testing/xen/drivers/passthrough/pci.c
@@ -107,8 +107,6 @@ void __init pt_pci_init(void)
radix_tree_init(&pci_segments);
if ( !alloc_pseg(0) )
panic("Could not initialize PCI segment 0\n");
- mmio_ro_ranges = rangeset_new(NULL, "r/o mmio ranges",
- RANGESETF_prettyprint_hex);
}
int __init pci_add_segment(u16 seg)
Index: xen-4.2.4-testing/xen/include/asm-x86/mm.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/mm.h
+++ xen-4.2.4-testing/xen/include/asm-x86/mm.h
@@ -531,6 +531,8 @@ extern bool_t machine_to_phys_mapping_va
_set_gpfn_from_mfn(mfn, pfn); \
} while (0)
+extern struct rangeset *mmio_ro_ranges;
+
#define get_gpfn_from_mfn(mfn) (machine_to_phys_mapping[(mfn)])
#define mfn_to_gmfn(_d, mfn) \
Index: xen-4.2.4-testing/xen/include/xen/iommu.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/xen/iommu.h
+++ xen-4.2.4-testing/xen/include/xen/iommu.h
@@ -37,8 +37,6 @@ extern bool_t amd_iommu_perdev_intremap;
/* Does this domain have a P2M table we can use as its IOMMU pagetable? */
#define iommu_use_hap_pt(d) (hap_enabled(d) && iommu_hap_pt_share)
-extern struct rangeset *mmio_ro_ranges;
-
#define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu)
#define MAX_IOMMUS 32
++++++ 27179-VMX-Viridian-suppress-MSR-based-APIC-suggestion-when-having-APIC-V.patch ++++++
References: bnc#808269
# Commit 7f2e992b824ec62a2818e64390ac2ccfbd74e6b7
# Date 2013-06-25 15:57:44 +0200
# Author Jan Beulich
# Committer Jan Beulich
VMX/Viridian: suppress MSR-based APIC suggestion when having APIC-V
When the CPU has the necessary capabilities, having Windows use
synthetic MSR reads/writes is bogus, as this still requires emulation
(which is pretty much guaranteed to be slower than having the hardware
carry out the operation).
Signed-off-by: Jan Beulich
Acked-by: Paul Durrant
Acked-by: George Dunlap
--- a/xen/arch/x86/hvm/viridian.c
+++ b/xen/arch/x86/hvm/viridian.c
@@ -87,8 +87,9 @@ int cpuid_viridian_leaves(unsigned int l
if ( (d->arch.hvm_domain.viridian.guest_os_id.raw == 0) ||
(d->arch.hvm_domain.viridian.guest_os_id.fields.os < 4) )
break;
- *eax = (CPUID4A_MSR_BASED_APIC |
- CPUID4A_RELAX_TIMER_INT);
+ *eax = CPUID4A_RELAX_TIMER_INT;
+ if ( !cpu_has_vmx_apic_reg_virt )
+ *eax |= CPUID4A_MSR_BASED_APIC;
*ebx = 2047; /* long spin count */
break;
}
++++++ 27184-libxl-devid-fix.patch ++++++
commit dfeccbeaa6536ceb3303380361b7ac18e1013292
Author: Jim Fehlig
Date: Tue Jun 25 16:02:15 2013 -0600
libxl: Fix assignment of devid value returned from libxl__device_nextid
Commit 5420f265 has some misplaced parenthesis that caused devid
to be assigned 1 or 0 based on checking return value of
libxl__device_nextid < 0, e.g.
devid = libxl__device_nextid(...) < 0
This works when only one instance of a given device type exists, but
subsequent devices of the same type will also have a devid = 1 if
libxl__device_nextid succeeds. Fix by checking the value assigned to
devid, e.g.
(devid = libxl__device_nextid(...)) < 0
Signed-off-by: Jim Fehlig
Acked-by: George Dunlap
Acked-by: Ian Campbell
Index: xen-4.2.4-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.2.4-testing.orig/tools/libxl/libxl.c
+++ xen-4.2.4-testing/tools/libxl/libxl.c
@@ -2606,7 +2606,7 @@ void libxl__device_nic_add(libxl__egc *e
}
if (nic->devid == -1) {
- if ((nic->devid = libxl__device_nextid(gc, domid, "vif") < 0)) {
+ if ((nic->devid = libxl__device_nextid(gc, domid, "vif")) < 0) {
rc = ERROR_FAIL;
goto out_free;
}
@@ -3008,7 +3008,7 @@ int libxl__device_vkb_add(libxl__gc *gc,
}
if (vkb->devid == -1) {
- if ((vkb->devid = libxl__device_nextid(gc, domid, "vkb") < 0)) {
+ if ((vkb->devid = libxl__device_nextid(gc, domid, "vkb")) < 0) {
rc = ERROR_FAIL;
goto out_free;
}
@@ -3117,7 +3117,7 @@ int libxl__device_vfb_add(libxl__gc *gc,
}
if (vfb->devid == -1) {
- if ((vfb->devid = libxl__device_nextid(gc, domid, "vfb") < 0)) {
+ if ((vfb->devid = libxl__device_nextid(gc, domid, "vfb")) < 0) {
rc = ERROR_FAIL;
goto out_free;
}
++++++ 27249-VMX-fix-interaction-of-APIC-V-and-Viridian-emulation.patch ++++++
References: bnc#808269
# Commit 303066fdb1e4fe816e48acd665453f58b8399e81
# Date 2013-07-17 08:47:18 +0200
# Author Jan Beulich
# Committer Jan Beulich
VMX: fix interaction of APIC-V and Viridian emulation
Viridian using a synthetic MSR for issuing EOI notifications bypasses
the normal in-processor handling, which would clear
GUEST_INTR_STATUS.SVI. Hence we need to do this in software in order
for future interrupts to get delivered.
Based on analysis by Yang Z Zhang .
Signed-off-by: Jan Beulich
Reviewed-by: Andrew Cooper
Reviewed-by: Yang Zhang
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vlapic.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
@@ -386,6 +386,9 @@ void vlapic_EOI_set(struct vlapic *vlapi
vlapic_clear_vector(vector, &vlapic->regs->data[APIC_ISR]);
+ if ( hvm_funcs.handle_eoi )
+ hvm_funcs.handle_eoi(vector);
+
if ( vlapic_test_and_clear_vector(vector, &vlapic->regs->data[APIC_TMR]) )
vioapic_update_EOI(vlapic_domain(vlapic), vector);
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
@@ -1668,6 +1668,15 @@ static void vmx_sync_pir_to_irr(struct v
vlapic_set_vector(i, &vlapic->regs->data[APIC_IRR]);
}
+static void vmx_handle_eoi(u8 vector)
+{
+ unsigned long status = __vmread(GUEST_INTR_STATUS);
+
+ /* We need to clear the SVI field. */
+ status &= VMX_GUEST_INTR_STATUS_SUBFIELD_BITMASK;
+ __vmwrite(GUEST_INTR_STATUS, status);
+}
+
static struct hvm_function_table __read_mostly vmx_function_table = {
.name = "VMX",
.cpu_up_prepare = vmx_cpu_up_prepare,
@@ -1720,6 +1729,7 @@ static struct hvm_function_table __read_
.process_isr = vmx_process_isr,
.deliver_posted_intr = vmx_deliver_posted_intr,
.sync_pir_to_irr = vmx_sync_pir_to_irr,
+ .handle_eoi = vmx_handle_eoi,
};
struct hvm_function_table * __init start_vmx(void)
@@ -1753,6 +1763,9 @@ struct hvm_function_table * __init start
setup_ept_dump();
}
+ if ( !cpu_has_vmx_virtual_intr_delivery )
+ vmx_function_table.handle_eoi = NULL;
+
if ( cpu_has_vmx_posted_intr_processing )
alloc_direct_apic_vector(&posted_intr_vector, event_check_interrupt);
else
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/hvm.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/hvm.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/hvm.h
@@ -187,6 +187,7 @@ struct hvm_function_table {
void (*process_isr)(int isr, struct vcpu *v);
void (*deliver_posted_intr)(struct vcpu *v, u8 vector);
void (*sync_pir_to_irr)(struct vcpu *v);
+ void (*handle_eoi)(u8 vector);
};
extern struct hvm_function_table hvm_funcs;
++++++ 27353-VMX-add-boot-parameter-to-enable-disable-APIC-v-dynamically.patch ++++++
# Commit 0c006b41a283a0a569c863d44abde5aa5750ae01
# Date 2013-08-13 17:47:16 +0200
# Author Yang Zhang
# Committer Jan Beulich
VMX: add boot parameter to enable/disable APIC-v dynamically
Add a boot parameter to enable/disable the APIC-v dynamically. APIC-v is
enabled by default. User can use apicv=0 to disable it.
Signed-off-by: Yang Zhang
--- 2013-08-06.orig/xen/arch/x86/hvm/vmx/vmcs.c 2013-08-06 00:00:00.000000000 +0200
+++ 2013-08-06/xen/arch/x86/hvm/vmx/vmcs.c 2013-08-20 15:11:22.000000000 +0200
@@ -45,6 +45,9 @@ boolean_param("vpid", opt_vpid_enabled);
static bool_t __read_mostly opt_unrestricted_guest_enabled = 1;
boolean_param("unrestricted_guest", opt_unrestricted_guest_enabled);
+static bool_t __read_mostly opt_apicv_enabled = 1;
+boolean_param("apicv", opt_apicv_enabled);
+
/*
* These two parameters are used to config the controls for Pause-Loop Exiting:
* ple_gap: upper bound on the amount of time between two successive
@@ -194,12 +197,12 @@ static int vmx_init_vmcs_config(void)
* "APIC Register Virtualization" and "Virtual Interrupt Delivery"
* can be set only when "use TPR shadow" is set
*/
- if ( _vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW )
+ if ( (_vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW) &&
+ opt_apicv_enabled )
opt |= SECONDARY_EXEC_APIC_REGISTER_VIRT |
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
-
_vmx_secondary_exec_control = adjust_vmx_controls(
"Secondary Exec Control", min, opt,
MSR_IA32_VMX_PROCBASED_CTLS2, &mismatch);
++++++ 27405-Nested-VMX-Check-whether-interrupt-is-blocked-by-TPR.patch ++++++
# Commit 7fb5c6b9ef22915e3fcac95cd44857f4457ba783
# Date 2013-08-22 10:49:24 +0200
# Author Yang Zhang
# Committer Jan Beulich
Nested VMX: Check whether interrupt is blocked by TPR
If interrupt is blocked by L1's TPR, L2 should not see it and keep
running. Adding the check before L2 to retrive interrupt.
Signed-off-by: Yang Zhang
Acked-by: "Dong, Eddie"
--- a/xen/arch/x86/hvm/vmx/intr.c
+++ b/xen/arch/x86/hvm/vmx/intr.c
@@ -165,6 +165,11 @@ static int nvmx_intr_intercept(struct vc
{
u32 ctrl;
+ /* If blocked by L1's tpr, then nothing to do. */
+ if ( nestedhvm_vcpu_in_guestmode(v) &&
+ hvm_interrupt_blocked(v, intack) == hvm_intblk_tpr )
+ return 1;
+
if ( nvmx_intr_blocked(v) != hvm_intblk_none )
{
enable_intr_window(v, intack);
++++++ 27406-Nested-VMX-Force-check-ISR-when-L2-is-running.patch ++++++
# Commit b35d0a26983843c092bfa353fd6b9aa8c3bf4886
# Date 2013-08-22 10:50:13 +0200
# Author Yang Zhang
# Committer Jan Beulich
Nested VMX: Force check ISR when L2 is running
External interrupt is allowed to notify CPU only when it has higher
priority than current in servicing interrupt. With APIC-v, the priority
comparing is done by hardware and hardware will inject the interrupt to
VCPU when it recognizes an interrupt. Currently, there is no virtual
APIC-v feature available for L1 to use, so when L2 is running, we still need
to compare interrupt priority with ISR in hypervisor instead via hardware.
Signed-off-by: Yang Zhang
Acked-by: "Dong, Eddie"
Index: xen-4.2.3-testing/xen/arch/x86/hvm/vlapic.c
===================================================================
--- xen-4.2.3-testing.orig/xen/arch/x86/hvm/vlapic.c
+++ xen-4.2.3-testing/xen/arch/x86/hvm/vlapic.c
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include
#include
@@ -1038,7 +1039,8 @@ int vlapic_has_pending_irq(struct vcpu *
if ( irr == -1 )
return -1;
- if ( vlapic_virtual_intr_delivery_enabled() )
+ if ( vlapic_virtual_intr_delivery_enabled() &&
+ !nestedhvm_vcpu_in_guestmode(v) )
return irr;
isr = vlapic_find_highest_isr(vlapic);
++++++ 27407-Nested-VMX-Clear-APIC-v-control-bit-in-vmcs02.patch ++++++
# Commit 375a1035002fb257087756a86e6caeda649fc0f1
# Date 2013-08-22 10:52:05 +0200
# Author Yang Zhang
# Committer Jan Beulich
Nested VMX: Clear APIC-v control bit in vmcs02
There is no vAPIC-v support, so mask APIC-v control bit when
constructing vmcs02.
Signed-off-by: Yang Zhang
Acked-by: "Dong, Eddie"
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -529,6 +529,10 @@ void nvmx_update_exec_control(struct vcp
void nvmx_update_secondary_exec_control(struct vcpu *v,
unsigned long value)
{
+ u32 apicv_bit = SECONDARY_EXEC_APIC_REGISTER_VIRT |
+ SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY;
+
+ value &= ~apicv_bit;
set_shadow_control(v, SECONDARY_VM_EXEC_CONTROL, value);
}
@@ -537,7 +541,12 @@ static void nvmx_update_pin_control(stru
u32 shadow_cntrl;
struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
+ host_cntrl &= ~PIN_BASED_POSTED_INTERRUPT;
shadow_cntrl = __get_vvmcs(nvcpu->nv_vvmcx, PIN_BASED_VM_EXEC_CONTROL);
+
+ /* No vAPIC-v support, so it shouldn't be set in vmcs12. */
+ ASSERT(!(shadow_cntrl & PIN_BASED_POSTED_INTERRUPT));
+
shadow_cntrl &= ~PIN_BASED_PREEMPT_TIMER;
shadow_cntrl |= host_cntrl;
__vmwrite(PIN_BASED_VM_EXEC_CONTROL, shadow_cntrl);
++++++ 27408-Nested-VMX-Update-APIC-v-RVI-SVI-when-vmexit-to-L1.patch ++++++
# Commit 84e6af58707520baf59c1c86c29237419e439afb
# Date 2013-08-22 10:59:01 +0200
# Author Yang Zhang
# Committer Jan Beulich
Nested VMX: Update APIC-v(RVI/SVI) when vmexit to L1
If enabling APIC-v, all interrupts to L1 are delivered through APIC-v.
But when L2 is running, external interrupt will casue L1 vmexit with
reason external interrupt. Then L1 will pick up the interrupt through
vmcs12. when L1 ack the interrupt, since the APIC-v is enabled when
L1 is running, so APIC-v hardware still will do vEOI updating. The problem
is that the interrupt is delivered not through APIC-v hardware, this means
SVI/RVI/vPPR are not setting, but hardware required them when doing vEOI
updating. The solution is that, when L1 tried to pick up the interrupt
from vmcs12, then hypervisor will help to update the SVI/RVI/vPPR to make
sure the following vEOI updating and vPPR updating corrently.
Also, since interrupt is delivered through vmcs12, so APIC-v hardware will
not cleare vIRR and hypervisor need to clear it before L1 running.
Signed-off-by: Yang Zhang
Acked-by: "Dong, Eddie"
Index: xen-4.2.4-testing/xen/arch/x86/hvm/irq.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/irq.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/irq.c
@@ -437,7 +437,7 @@ struct hvm_intack hvm_vcpu_ack_pending_i
intack.vector = (uint8_t)vector;
break;
case hvm_intsrc_lapic:
- if ( !vlapic_ack_pending_irq(v, intack.vector) )
+ if ( !vlapic_ack_pending_irq(v, intack.vector, 0) )
intack = hvm_intack_none;
break;
case hvm_intsrc_vector:
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vlapic.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vlapic.c
@@ -168,6 +168,14 @@ static uint32_t vlapic_get_ppr(struct vl
return ppr;
}
+uint32_t vlapic_set_ppr(struct vlapic *vlapic)
+{
+ uint32_t ppr = vlapic_get_ppr(vlapic);
+
+ vlapic_set_reg(vlapic, APIC_PROCPRI, ppr);
+ return ppr;
+}
+
static int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda)
{
int result = 0;
@@ -1051,15 +1059,15 @@ int vlapic_has_pending_irq(struct vcpu *
return irr;
}
-int vlapic_ack_pending_irq(struct vcpu *v, int vector)
+int vlapic_ack_pending_irq(struct vcpu *v, int vector, bool_t force_ack)
{
struct vlapic *vlapic = vcpu_vlapic(v);
- if ( vlapic_virtual_intr_delivery_enabled() )
- return 1;
-
- vlapic_set_vector(vector, &vlapic->regs->data[APIC_ISR]);
- vlapic_clear_irr(vector, vlapic);
+ if ( force_ack || !vlapic_virtual_intr_delivery_enabled() )
+ {
+ vlapic_set_vector(vector, &vlapic->regs->data[APIC_ISR]);
+ vlapic_clear_irr(vector, vlapic);
+ }
return 1;
}
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/intr.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/intr.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/intr.c
@@ -185,7 +185,7 @@ static int nvmx_intr_intercept(struct vc
if ( !(ctrl & PIN_BASED_EXT_INTR_MASK) )
return 0;
- vmx_inject_extint(intack.vector);
+ vmx_inject_extint(intack.vector, intack.source);
ctrl = __get_vvmcs(vcpu_nestedhvm(v).nv_vvmcx, VM_EXIT_CONTROLS);
if ( ctrl & VM_EXIT_ACK_INTR_ON_EXIT )
@@ -321,7 +321,7 @@ void vmx_intr_assist(void)
else
{
HVMTRACE_2D(INJ_VIRQ, intack.vector, /*fake=*/ 0);
- vmx_inject_extint(intack.vector);
+ vmx_inject_extint(intack.vector, intack.source);
pt_intr_post(v, intack);
}
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmx.c
@@ -1374,7 +1374,7 @@ void ept_sync_domain(struct domain *d)
}
void nvmx_enqueue_n2_exceptions(struct vcpu *v,
- unsigned long intr_fields, int error_code)
+ unsigned long intr_fields, int error_code, uint8_t source)
{
struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
@@ -1382,6 +1382,7 @@ void nvmx_enqueue_n2_exceptions(struct v
/* enqueue the exception till the VMCS switch back to L1 */
nvmx->intr.intr_info = intr_fields;
nvmx->intr.error_code = error_code;
+ nvmx->intr.source = source;
vcpu_nestedhvm(v).nv_vmexit_pending = 1;
return;
}
@@ -1393,7 +1394,8 @@ void nvmx_enqueue_n2_exceptions(struct v
static int nvmx_vmexit_trap(struct vcpu *v, struct hvm_trap *trap)
{
- nvmx_enqueue_n2_exceptions(v, trap->vector, trap->error_code);
+ nvmx_enqueue_n2_exceptions(v, trap->vector, trap->error_code,
+ hvm_intsrc_none);
return NESTEDHVM_VMEXIT_DONE;
}
@@ -1424,7 +1426,7 @@ static void __vmx_inject_exception(int t
curr->arch.hvm_vmx.vmx_emulate = 1;
}
-void vmx_inject_extint(int trap)
+void vmx_inject_extint(int trap, uint8_t source)
{
struct vcpu *v = current;
u32 pin_based_cntrl;
@@ -1435,7 +1437,7 @@ void vmx_inject_extint(int trap)
if ( pin_based_cntrl & PIN_BASED_EXT_INTR_MASK ) {
nvmx_enqueue_n2_exceptions (v,
INTR_INFO_VALID_MASK | (X86_EVENTTYPE_EXT_INTR<<8) | trap,
- HVM_DELIVER_NO_ERROR_CODE);
+ HVM_DELIVER_NO_ERROR_CODE, source);
return;
}
}
@@ -1454,7 +1456,7 @@ void vmx_inject_nmi(void)
if ( pin_based_cntrl & PIN_BASED_NMI_EXITING ) {
nvmx_enqueue_n2_exceptions (v,
INTR_INFO_VALID_MASK | (X86_EVENTTYPE_NMI<<8) | TRAP_nmi,
- HVM_DELIVER_NO_ERROR_CODE);
+ HVM_DELIVER_NO_ERROR_CODE, hvm_intsrc_nmi);
return;
}
}
@@ -1522,7 +1524,7 @@ static void vmx_inject_trap(struct hvm_t
{
nvmx_enqueue_n2_exceptions (curr,
INTR_INFO_VALID_MASK | (_trap.type<<8) | _trap.vector,
- _trap.error_code);
+ _trap.error_code, hvm_intsrc_none);
return;
}
else
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vvmx.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vvmx.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vvmx.c
@@ -959,6 +959,36 @@ static void sync_exception_state(struct
}
}
+static void nvmx_update_apicv(struct vcpu *v)
+{
+ struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
+ struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
+ unsigned long reason = __get_vvmcs(nvcpu->nv_vvmcx, VM_EXIT_REASON);
+ uint32_t intr_info = __get_vvmcs(nvcpu->nv_vvmcx, VM_EXIT_INTR_INFO);
+
+ if ( reason == EXIT_REASON_EXTERNAL_INTERRUPT &&
+ nvmx->intr.source == hvm_intsrc_lapic &&
+ (intr_info & INTR_INFO_VALID_MASK) )
+ {
+ uint16_t status;
+ uint32_t rvi, ppr;
+ uint32_t vector = intr_info & 0xff;
+ struct vlapic *vlapic = vcpu_vlapic(v);
+
+ vlapic_ack_pending_irq(v, vector, 1);
+
+ ppr = vlapic_set_ppr(vlapic);
+ WARN_ON((ppr & 0xf0) != (vector & 0xf0));
+
+ status = vector << 8;
+ rvi = vlapic_has_pending_irq(v);
+ if ( rvi != -1 )
+ status |= rvi & 0xff;
+
+ __vmwrite(GUEST_INTR_STATUS, status);
+ }
+}
+
static void virtual_vmexit(struct cpu_user_regs *regs)
{
struct vcpu *v = current;
@@ -1005,6 +1035,9 @@ static void virtual_vmexit(struct cpu_us
/* updating host cr0 to sync TS bit */
__vmwrite(HOST_CR0, v->arch.hvm_vmx.host_cr0);
+ if ( cpu_has_vmx_virtual_intr_delivery )
+ nvmx_update_apicv(v);
+
vmreturn(regs, VMSUCCEED);
}
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vlapic.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vlapic.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vlapic.h
@@ -98,7 +98,7 @@ bool_t is_vlapic_lvtpc_enabled(struct vl
void vlapic_set_irq(struct vlapic *vlapic, uint8_t vec, uint8_t trig);
int vlapic_has_pending_irq(struct vcpu *v);
-int vlapic_ack_pending_irq(struct vcpu *v, int vector);
+int vlapic_ack_pending_irq(struct vcpu *v, int vector, bool_t force_ack);
int vlapic_init(struct vcpu *v);
void vlapic_destroy(struct vcpu *v);
@@ -110,6 +110,7 @@ void vlapic_tdt_msr_set(struct vlapic *v
uint64_t vlapic_tdt_msr_get(struct vlapic *vlapic);
int vlapic_accept_pic_intr(struct vcpu *v);
+uint32_t vlapic_set_ppr(struct vlapic *vlapic);
void vlapic_adjust_i8259_target(struct domain *d);
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmx.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmx.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -415,7 +415,7 @@ static inline int __vmxon(u64 addr)
return rc;
}
-void vmx_inject_extint(int trap);
+void vmx_inject_extint(int trap, uint8_t source);
void vmx_inject_nmi(void);
void ept_p2m_init(struct p2m_domain *p2m);
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vvmx.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vvmx.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vvmx.h
@@ -30,6 +30,7 @@ struct nestedvmx {
struct {
unsigned long intr_info;
u32 error_code;
+ u8 source;
} intr;
};
++++++ 27431-x86-don-t-allow-Dom0-access-to-the-HT-address-range.patch ++++++
# Commit d838ac2539cf1987bea6e15662fd6a80a58fe26d
# Date 2013-08-27 11:12:12 +0200
# Author Jan Beulich
# Committer Jan Beulich
x86: don't allow Dom0 access to the HT address range
In particular, MMIO assignments should not be done using this area.
Signed-off-by: Jan Beulich
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -1265,6 +1265,10 @@ int __init construct_dom0(
rc |= iomem_deny_access(dom0, paddr_to_pfn(MSI_ADDR_BASE_LO),
paddr_to_pfn(MSI_ADDR_BASE_LO +
MSI_ADDR_DEST_ID_MASK));
+ /* HyperTransport range. */
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+ rc |= iomem_deny_access(dom0, paddr_to_pfn(0xfdULL << 32),
+ paddr_to_pfn((1ULL << 40) - 1));
/* Remove access to E820_UNUSABLE I/O regions above 1MB. */
for ( i = 0; i < e820.nr_map; i++ )
++++++ 27511-x86-fix-memory-cut-off-when-using-PFN-compression.patch ++++++
References: bnc#839600
# Commit 8efce9d69998a3d3c720ac7dbdb9b7e240369957
# Date 2013-09-12 09:52:53 +0200
# Author Jan Beulich
# Committer Jan Beulich
x86: fix memory cut-off when using PFN compression
For one setup_max_pdx(), when invoked a second time (after SRAT got
parsed), needs to start from the original max_page value again (using
the already adjusted one from the first invocation would not allow the
cut-off boundary to be moved up).
Second, _if_ we need to cut off some part of memory, we must not allow
this to also propagate into the NUMA accounting. Otherwise
cutoff_node() results in nodes_cover_memory() to find some parts of
memory apparently not having a PXM association, causing all SRAT info
to be ignored.
The only possibly problematic consumer of node_spanned_pages (the
meaning of which gets altered here in that it now also includes memory
Xen can't actively make use of) is XEN_SYSCTL_numainfo: At a first
glance the potentially larger reported memory size shouldn't confuse
tool stacks.
And finally we must not put our boot time modules at addresses which
(at that time) can't be guaranteed to be accessible later. This applies
to both the EFI boot loader and the module relocation code.
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Acked-by: Dario Faggioli
Index: xen-4.2.4-testing/xen/arch/x86/efi/boot.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/efi/boot.c
+++ xen-4.2.4-testing/xen/arch/x86/efi/boot.c
@@ -448,7 +448,7 @@ static bool_t __init read_file(EFI_FILE_
what = what ?: L"Seek";
else
{
- file->addr = (EFI_PHYSICAL_ADDRESS)1 << (32 + PAGE_SHIFT);
+ file->addr = min(1UL << (32 + PAGE_SHIFT), DIRECTMAP_SIZE);
ret = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
PFN_UP(size), &file->addr);
}
Index: xen-4.2.4-testing/xen/arch/x86/setup.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/setup.c
+++ xen-4.2.4-testing/xen/arch/x86/setup.c
@@ -382,10 +382,10 @@ static uint64_t __init consider_modules(
return e;
}
-static void __init setup_max_pdx(void)
+static void __init setup_max_pdx(unsigned long top_page)
{
#ifdef __x86_64__
- max_pdx = pfn_to_pdx(max_page - 1) + 1;
+ max_pdx = pfn_to_pdx(top_page - 1) + 1;
if ( max_pdx > (DIRECTMAP_SIZE >> PAGE_SHIFT) )
max_pdx = DIRECTMAP_SIZE >> PAGE_SHIFT;
@@ -551,7 +551,7 @@ void __init __start_xen(unsigned long mb
unsigned int initrdidx;
multiboot_info_t *mbi = __va(mbi_p);
module_t *mod = (module_t *)__va(mbi->mods_addr);
- unsigned long nr_pages, modules_headroom, *module_map;
+ unsigned long nr_pages, raw_max_page, modules_headroom, *module_map;
int i, j, e820_warn = 0, bytes = 0;
bool_t acpi_boot_table_init_done = 0;
struct ns16550_defaults ns16550 = {
@@ -757,7 +757,7 @@ void __init __start_xen(unsigned long mb
}
/* Sanitise the raw E820 map to produce a final clean version. */
- max_page = init_e820(memmap_type, e820_raw, &e820_raw_nr);
+ max_page = raw_max_page = init_e820(memmap_type, e820_raw, &e820_raw_nr);
/* Create a temporary copy of the E820 map. */
memcpy(&boot_e820, &e820, sizeof(e820));
@@ -821,7 +821,8 @@ void __init __start_xen(unsigned long mb
}
#if defined(CONFIG_X86_64)
- e = min_t(uint64_t, e, 1ULL << (PAGE_SHIFT + 32));
+ if ( e > min(DIRECTMAP_SIZE, 1UL << (PAGE_SHIFT + 32)) )
+ e = min(DIRECTMAP_SIZE, 1UL << (PAGE_SHIFT + 32));
#define reloc_size ((__pa(&_end) + mask) & ~mask)
/* Is the region suitable for relocating Xen? */
if ( !xen_phys_start && e <= limit )
@@ -979,7 +980,7 @@ void __init __start_xen(unsigned long mb
/* Late kexec reservation (dynamic start address). */
kexec_reserve_area(&boot_e820);
- setup_max_pdx();
+ setup_max_pdx(raw_max_page);
/*
* Walk every RAM region and map it in its entirety (on x86/64, at least)
@@ -1010,7 +1011,7 @@ void __init __start_xen(unsigned long mb
{
acpi_boot_table_init_done = 1;
srat_parse_regions(s);
- setup_max_pdx();
+ setup_max_pdx(raw_max_page);
}
if ( pfn_to_pdx((e - 1) >> PAGE_SHIFT) >= max_pdx )
@@ -1153,7 +1154,7 @@ void __init __start_xen(unsigned long mb
acpi_numa_init();
- numa_initmem_init(0, max_page);
+ numa_initmem_init(0, raw_max_page);
#if defined(CONFIG_X86_32)
/* Initialise the Xen heap. */
++++++ 27512-libxc-x86-fix-page-table-creation-for-huge-guests.patch ++++++
# Commit 06d086832155fc7f5344e9d108b979de34674d11
# Date 2013-09-12 17:41:04 +0200
# Author Jan Beulich
# Committer Jan Beulich
libxc/x86: fix page table creation for huge guests
The switch-over logic from one page directory to the next was wrong;
it needs to be deferred until we actually reach the last page within
a given region, instead of being done when the last entry of a page
directory gets started with.
Signed-off-by: Jan Beulich
Tested-by: Konrad Rzeszutek Wilk
Acked-by: Ian Jackson
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -269,7 +269,7 @@ static int setup_pgtables_x86_32_pae(str
l3_pgentry_64_t *l3tab;
l2_pgentry_64_t *l2tab = NULL;
l1_pgentry_64_t *l1tab = NULL;
- unsigned long l3off, l2off, l1off;
+ unsigned long l3off, l2off = 0, l1off;
xen_vaddr_t addr;
xen_pfn_t pgpfn;
xen_pfn_t l3mfn = xc_dom_p2m_guest(dom, l3pfn);
@@ -317,8 +317,6 @@ static int setup_pgtables_x86_32_pae(str
l2off = l2_table_offset_pae(addr);
l2tab[l2off] =
pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
- if ( l2off == (L2_PAGETABLE_ENTRIES_PAE - 1) )
- l2tab = NULL;
l1pfn++;
}
@@ -330,8 +328,13 @@ static int setup_pgtables_x86_32_pae(str
if ( (addr >= dom->pgtables_seg.vstart) &&
(addr < dom->pgtables_seg.vend) )
l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */
+
if ( l1off == (L1_PAGETABLE_ENTRIES_PAE - 1) )
+ {
l1tab = NULL;
+ if ( l2off == (L2_PAGETABLE_ENTRIES_PAE - 1) )
+ l2tab = NULL;
+ }
}
if ( dom->virt_pgtab_end <= 0xc0000000 )
@@ -379,7 +382,7 @@ static int setup_pgtables_x86_64(struct
l3_pgentry_64_t *l3tab = NULL;
l2_pgentry_64_t *l2tab = NULL;
l1_pgentry_64_t *l1tab = NULL;
- uint64_t l4off, l3off, l2off, l1off;
+ uint64_t l4off, l3off = 0, l2off = 0, l1off;
uint64_t addr;
xen_pfn_t pgpfn;
@@ -410,8 +413,6 @@ static int setup_pgtables_x86_64(struct
l3off = l3_table_offset_x86_64(addr);
l3tab[l3off] =
pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
- if ( l3off == (L3_PAGETABLE_ENTRIES_X86_64 - 1) )
- l3tab = NULL;
l2pfn++;
}
@@ -424,8 +425,6 @@ static int setup_pgtables_x86_64(struct
l2off = l2_table_offset_x86_64(addr);
l2tab[l2off] =
pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
- if ( l2off == (L2_PAGETABLE_ENTRIES_X86_64 - 1) )
- l2tab = NULL;
l1pfn++;
}
@@ -437,8 +436,17 @@ static int setup_pgtables_x86_64(struct
if ( (addr >= dom->pgtables_seg.vstart) &&
(addr < dom->pgtables_seg.vend) )
l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */
+
if ( l1off == (L1_PAGETABLE_ENTRIES_X86_64 - 1) )
+ {
l1tab = NULL;
+ if ( l2off == (L2_PAGETABLE_ENTRIES_X86_64 - 1) )
+ {
+ l2tab = NULL;
+ if ( l3off == (L3_PAGETABLE_ENTRIES_X86_64 - 1) )
+ l3tab = NULL;
+ }
+ }
}
return 0;
++++++ 27515-cpufreq-missing-check-of-copy_from_guest.patch ++++++
# Commit 803f9a6cdfeda64beee908576de0ad02d6b0c480
# Date 2013-09-12 17:47:08 +0100
# Author Tim Deegan
# Committer Tim Deegan
cpufreq: missing check of copy_from_guest()
Coverity CID 1055131
Coverity CID 1055132
Signed-off-by: Tim Deegan
Reviewed-by: Andrew Cooper
Acked-by: Jan Beulich
--- a/xen/drivers/cpufreq/cpufreq.c
+++ b/xen/drivers/cpufreq/cpufreq.c
@@ -471,8 +471,12 @@ int set_px_pminfo(uint32_t acpi_id, stru
ret = -ENOMEM;
goto out;
}
- copy_from_guest(pxpt->states, dom0_px_info->states,
- dom0_px_info->state_count);
+ if ( copy_from_guest(pxpt->states, dom0_px_info->states,
+ dom0_px_info->state_count) )
+ {
+ ret = -EFAULT;
+ goto out;
+ }
pxpt->state_count = dom0_px_info->state_count;
if ( cpufreq_verbose )
++++++ 27519-x86-machine_restart-must-not-call-acpi_dmar_reinstate-twice.patch ++++++
# Commit a54dc5f4fe1eae6b1beb21326ef0338cd3969cd1
# Date 2013-09-13 14:27:34 +0200
# Author Jan Beulich
# Committer Jan Beulich
x86: machine_restart() must not call acpi_dmar_reinstate() twice
.. as that function is not idempotent (it always alters the table
checksum). The (generally) duplicate call was a result from it being
made before machine_restart() re-invoking itself on the boot CPU.
Considering that no problem arose so far from the table corruption I
doubt that we need to restore the correct table signature on the
reboot path in general. The only case I can see this as potentially
necessary is the tboot one, hence do the call just in that case.
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
--- a/xen/arch/x86/shutdown.c
+++ b/xen/arch/x86/shutdown.c
@@ -310,8 +310,6 @@ void machine_restart(unsigned int delay_
console_start_sync();
spin_debug_disable();
- acpi_dmar_reinstate();
-
local_irq_enable();
/* Ensure we are the boot CPU. */
@@ -336,7 +334,10 @@ void machine_restart(unsigned int delay_
mdelay(delay_millisecs);
if ( tboot_in_measured_env() )
+ {
+ acpi_dmar_reinstate();
tboot_shutdown(TB_SHUTDOWN_REBOOT);
+ }
efi_reset_system(reboot_mode != 0);
++++++ 27549-set-mtu-from-bridge-for-tap-interface.patch ++++++
# HG changeset patch
# User Charles Arnold
# Date 1379427987 -3600
# Node ID e6da6ffd6749237316d4440799f0a0272bbdae9c
# Parent 5597ce99ec7f2587a29f3b2dee0bde98d59bf327
tools/hotplug: set mtu from bridge for tap interface
With changeset 22885 support was added for setting the MTU in the vif-bridge
script for when a vif interface was set to 'online'. The was not done for the
'add' operation. The 'add' operation was added to the script for when tap
devices were specified (c/s 21944). With the setting of the MTU for the
'online' case was there a reason for omitting the 'add'?
This patch sets the MTU for both 'online' and 'add' in the vif-bridge script.
Signed-off-by: Charles Arnold
Acked-by: Ian Campbell
Index: xen-4.2.3-testing/tools/hotplug/Linux/vif-bridge
===================================================================
--- xen-4.2.3-testing.orig/tools/hotplug/Linux/vif-bridge
+++ xen-4.2.3-testing/tools/hotplug/Linux/vif-bridge
@@ -82,11 +82,7 @@ fi
case "$command" in
online)
setup_virtual_bridge_port "$dev"
- mtu="`ip link show $bridge | awk '/mtu/ { print $5 }'`"
- if [ -n "$mtu" ] && [ "$mtu" -gt 0 ]
- then
- ip link set $dev mtu $mtu || :
- fi
+ set_mtu "$bridge" "$dev"
add_to_bridge "$bridge" "$dev"
;;
@@ -97,6 +93,7 @@ case "$command" in
add)
setup_virtual_bridge_port "$dev"
+ set_mtu "$bridge" "$dev"
add_to_bridge "$bridge" "$dev"
;;
esac
Index: xen-4.2.3-testing/tools/hotplug/Linux/xen-network-common.sh
===================================================================
--- xen-4.2.3-testing.orig/tools/hotplug/Linux/xen-network-common.sh
+++ xen-4.2.3-testing/tools/hotplug/Linux/xen-network-common.sh
@@ -132,3 +132,13 @@ add_to_bridge () {
ip link set ${dev} up
}
+# Usage: set_mtu bridge dev
+set_mtu () {
+ local bridge=$1
+ local dev=$2
+ mtu="`ip link show ${bridge}| awk '/mtu/ { print $5 }'`"
+ if [ -n "$mtu" ] && [ "$mtu" -gt 0 ]
+ then
+ ip link set ${dev} mtu $mtu || :
+ fi
+}
++++++ 27582-x86-HVM-fix-failure-path-in-hvm_vcpu_initialise.patch ++++++
# Commit 925fbcb7fdd6238f26b1576dc1f3e297f1f24f1e
# Date 2013-09-18 14:45:24 +0200
# Author George Dunlap
# Committer Jan Beulich
x86/HVM: fix failure path in hvm_vcpu_initialise
It looks like one of the failure cases in hvm_vcpu_initialise jumps to
the wrong label; this could lead to slow leaks if something isn't
cleaned up properly.
I will probably change these labels in a future patch, but I figured
it was better to have this fix separately.
This is also a candidate for backport.
Signed-off-by: George Dunlap
Signed-off-by: Mukesh Rathor
Index: xen-4.2.4-testing/xen/arch/x86/hvm/hvm.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/hvm.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/hvm.c
@@ -1125,7 +1125,7 @@ int hvm_vcpu_initialise(struct vcpu *v)
/* Create bufioreq event channel. */
rc = alloc_unbound_xen_event_channel(v, 0, NULL);
if ( rc < 0 )
- goto fail2;
+ goto fail4;
v->domain->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_EVTCHN] = rc;
}
++++++ 27583-VMX-fix-failure-path-in-construct_vmcs.patch ++++++
# Commit dad7e45bf44c0569546a3ed7d0fa4182a4a73f0a
# Date 2013-09-18 14:45:42 +0200
# Author George Dunlap
# Committer Jan Beulich
VMX: fix failure path in construct_vmcs
If the allocation fails, make sure to call vmx_vmcs_exit().
This is a candidate for backport.
Signed-off-by: George Dunlap
Signed-off-by: Mukesh Rathor
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
@@ -841,7 +841,10 @@ static int construct_vmcs(struct vcpu *v
unsigned long *msr_bitmap = alloc_xenheap_page();
if ( msr_bitmap == NULL )
+ {
+ vmx_vmcs_exit(v);
return -ENOMEM;
+ }
memset(msr_bitmap, ~0, PAGE_SIZE);
v->arch.hvm_vmx.msr_bitmap = msr_bitmap;
++++++ 27586-x86-HVM-properly-handle-wide-MMIO.patch ++++++
# Commit 3b89f08a498ddac09d4002d9849e329018ceb107
# Date 2013-09-20 11:01:08 +0200
# Author Jan Beulich
# Committer Jan Beulich
x86/HVM: properly handle MMIO reads and writes wider than a machine word
Just like real hardware we ought to split such accesses transparently
to the caller. With little extra effort we can at once even handle page
crossing accesses correctly.
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -438,6 +438,7 @@ static int __hvmemul_read(
{
struct vcpu *curr = current;
unsigned long addr, reps = 1;
+ unsigned int off, chunk = min(bytes, 1U << LONG_BYTEORDER);
uint32_t pfec = PFEC_page_present;
struct hvm_vcpu_io *vio = &curr->arch.hvm_vcpu.hvm_io;
paddr_t gpa;
@@ -447,16 +448,38 @@ static int __hvmemul_read(
seg, offset, bytes, &reps, access_type, hvmemul_ctxt, &addr);
if ( rc != X86EMUL_OKAY )
return rc;
+ off = addr & (PAGE_SIZE - 1);
+ /*
+ * We only need to handle sizes actual instruction operands can have. All
+ * such sizes are either powers of 2 or the sum of two powers of 2. Thus
+ * picking as initial chunk size the largest power of 2 not greater than
+ * the total size will always result in only power-of-2 size requests
+ * issued to hvmemul_do_mmio() (hvmemul_do_io() rejects non-powers-of-2).
+ */
+ while ( chunk & (chunk - 1) )
+ chunk &= chunk - 1;
+ if ( off + bytes > PAGE_SIZE )
+ while ( off & (chunk - 1) )
+ chunk >>= 1;
if ( unlikely(vio->mmio_gva == (addr & PAGE_MASK)) && vio->mmio_gva )
{
- unsigned int off = addr & (PAGE_SIZE - 1);
if ( access_type == hvm_access_insn_fetch )
return X86EMUL_UNHANDLEABLE;
gpa = (((paddr_t)vio->mmio_gpfn << PAGE_SHIFT) | off);
- if ( (off + bytes) <= PAGE_SIZE )
- return hvmemul_do_mmio(gpa, &reps, bytes, 0,
- IOREQ_READ, 0, p_data);
+ while ( (off + chunk) <= PAGE_SIZE )
+ {
+ rc = hvmemul_do_mmio(gpa, &reps, chunk, 0, IOREQ_READ, 0, p_data);
+ if ( rc != X86EMUL_OKAY || bytes == chunk )
+ return rc;
+ addr += chunk;
+ off += chunk;
+ gpa += chunk;
+ p_data += chunk;
+ bytes -= chunk;
+ if ( bytes < chunk )
+ chunk = bytes;
+ }
}
if ( (seg != x86_seg_none) &&
@@ -473,14 +496,32 @@ static int __hvmemul_read(
return X86EMUL_EXCEPTION;
case HVMCOPY_unhandleable:
return X86EMUL_UNHANDLEABLE;
- case HVMCOPY_bad_gfn_to_mfn:
+ case HVMCOPY_bad_gfn_to_mfn:
if ( access_type == hvm_access_insn_fetch )
return X86EMUL_UNHANDLEABLE;
- rc = hvmemul_linear_to_phys(
- addr, &gpa, bytes, &reps, pfec, hvmemul_ctxt);
- if ( rc != X86EMUL_OKAY )
- return rc;
- return hvmemul_do_mmio(gpa, &reps, bytes, 0, IOREQ_READ, 0, p_data);
+ rc = hvmemul_linear_to_phys(addr, &gpa, chunk, &reps, pfec,
+ hvmemul_ctxt);
+ while ( rc == X86EMUL_OKAY )
+ {
+ rc = hvmemul_do_mmio(gpa, &reps, chunk, 0, IOREQ_READ, 0, p_data);
+ if ( rc != X86EMUL_OKAY || bytes == chunk )
+ break;
+ addr += chunk;
+ off += chunk;
+ p_data += chunk;
+ bytes -= chunk;
+ if ( bytes < chunk )
+ chunk = bytes;
+ if ( off < PAGE_SIZE )
+ gpa += chunk;
+ else
+ {
+ rc = hvmemul_linear_to_phys(addr, &gpa, chunk, &reps, pfec,
+ hvmemul_ctxt);
+ off = 0;
+ }
+ }
+ return rc;
case HVMCOPY_gfn_paged_out:
return X86EMUL_RETRY;
case HVMCOPY_gfn_shared:
@@ -537,6 +578,7 @@ static int hvmemul_write(
container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
struct vcpu *curr = current;
unsigned long addr, reps = 1;
+ unsigned int off, chunk = min(bytes, 1U << LONG_BYTEORDER);
uint32_t pfec = PFEC_page_present | PFEC_write_access;
struct hvm_vcpu_io *vio = &curr->arch.hvm_vcpu.hvm_io;
paddr_t gpa;
@@ -546,14 +588,30 @@ static int hvmemul_write(
seg, offset, bytes, &reps, hvm_access_write, hvmemul_ctxt, &addr);
if ( rc != X86EMUL_OKAY )
return rc;
+ off = addr & (PAGE_SIZE - 1);
+ /* See the respective comment in __hvmemul_read(). */
+ while ( chunk & (chunk - 1) )
+ chunk &= chunk - 1;
+ if ( off + bytes > PAGE_SIZE )
+ while ( off & (chunk - 1) )
+ chunk >>= 1;
if ( unlikely(vio->mmio_gva == (addr & PAGE_MASK)) && vio->mmio_gva )
{
- unsigned int off = addr & (PAGE_SIZE - 1);
gpa = (((paddr_t)vio->mmio_gpfn << PAGE_SHIFT) | off);
- if ( (off + bytes) <= PAGE_SIZE )
- return hvmemul_do_mmio(gpa, &reps, bytes, 0,
- IOREQ_WRITE, 0, p_data);
+ while ( (off + chunk) <= PAGE_SIZE )
+ {
+ rc = hvmemul_do_mmio(gpa, &reps, chunk, 0, IOREQ_WRITE, 0, p_data);
+ if ( rc != X86EMUL_OKAY || bytes == chunk )
+ return rc;
+ addr += chunk;
+ off += chunk;
+ gpa += chunk;
+ p_data += chunk;
+ bytes -= chunk;
+ if ( bytes < chunk )
+ chunk = bytes;
+ }
}
if ( (seg != x86_seg_none) &&
@@ -569,12 +627,29 @@ static int hvmemul_write(
case HVMCOPY_unhandleable:
return X86EMUL_UNHANDLEABLE;
case HVMCOPY_bad_gfn_to_mfn:
- rc = hvmemul_linear_to_phys(
- addr, &gpa, bytes, &reps, pfec, hvmemul_ctxt);
- if ( rc != X86EMUL_OKAY )
- return rc;
- return hvmemul_do_mmio(gpa, &reps, bytes, 0,
- IOREQ_WRITE, 0, p_data);
+ rc = hvmemul_linear_to_phys(addr, &gpa, chunk, &reps, pfec,
+ hvmemul_ctxt);
+ while ( rc == X86EMUL_OKAY )
+ {
+ rc = hvmemul_do_mmio(gpa, &reps, chunk, 0, IOREQ_WRITE, 0, p_data);
+ if ( rc != X86EMUL_OKAY || bytes == chunk )
+ break;
+ addr += chunk;
+ off += chunk;
+ p_data += chunk;
+ bytes -= chunk;
+ if ( bytes < chunk )
+ chunk = bytes;
+ if ( off < PAGE_SIZE )
+ gpa += chunk;
+ else
+ {
+ rc = hvmemul_linear_to_phys(addr, &gpa, chunk, &reps, pfec,
+ hvmemul_ctxt);
+ off = 0;
+ }
+ }
+ return rc;
case HVMCOPY_gfn_paged_out:
return X86EMUL_RETRY;
case HVMCOPY_gfn_shared:
++++++ 27611-x86-HVM-linear-address-must-be-canonical-for-the-whole-accessed-range.patch ++++++
# Commit 7f12732670b31b2fea899a4160d455574658474f
# Date 2013-09-23 09:53:55 +0200
# Author Jan Beulich
# Committer Jan Beulich
x86/HVM: linear address must be canonical for the whole accessed range
... rather than just for the first byte.
While at it, also
- make the real mode case at least dpo a wrap around check
- drop the mis-named "gpf" label (we're not generating faults here)
and use in-place returns instead
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
Index: xen-4.2.4-testing/xen/arch/x86/hvm/hvm.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/hvm.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/hvm.c
@@ -1960,8 +1960,7 @@ int hvm_virtual_to_linear_addr(
unsigned int addr_size,
unsigned long *linear_addr)
{
- unsigned long addr = offset;
- uint32_t last_byte;
+ unsigned long addr = offset, last_byte;
if ( !(current->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) )
{
@@ -1970,6 +1969,9 @@ int hvm_virtual_to_linear_addr(
* Certain of them are not done in native real mode anyway.
*/
addr = (uint32_t)(addr + reg->base);
+ last_byte = (uint32_t)addr + bytes - 1;
+ if ( last_byte < addr )
+ return 0;
}
else if ( addr_size != 64 )
{
@@ -1981,17 +1983,17 @@ int hvm_virtual_to_linear_addr(
{
case hvm_access_read:
if ( (reg->attr.fields.type & 0xa) == 0x8 )
- goto gpf; /* execute-only code segment */
+ return 0; /* execute-only code segment */
break;
case hvm_access_write:
if ( (reg->attr.fields.type & 0xa) != 0x2 )
- goto gpf; /* not a writable data segment */
+ return 0; /* not a writable data segment */
break;
default:
break;
}
- last_byte = offset + bytes - 1;
+ last_byte = (uint32_t)offset + bytes - 1;
/* Is this a grows-down data segment? Special limit check if so. */
if ( (reg->attr.fields.type & 0xc) == 0x4 )
@@ -2002,10 +2004,10 @@ int hvm_virtual_to_linear_addr(
/* Check first byte and last byte against respective bounds. */
if ( (offset <= reg->limit) || (last_byte < offset) )
- goto gpf;
+ return 0;
}
else if ( (last_byte > reg->limit) || (last_byte < offset) )
- goto gpf; /* last byte is beyond limit or wraps 0xFFFFFFFF */
+ return 0; /* last byte is beyond limit or wraps 0xFFFFFFFF */
/*
* Hardware truncates to 32 bits in compatibility mode.
@@ -2022,15 +2024,14 @@ int hvm_virtual_to_linear_addr(
if ( (seg == x86_seg_fs) || (seg == x86_seg_gs) )
addr += reg->base;
- if ( !is_canonical_address(addr) )
- goto gpf;
+ last_byte = addr + bytes - 1;
+ if ( !is_canonical_address(addr) || last_byte < addr ||
+ !is_canonical_address(last_byte) )
+ return 0;
}
*linear_addr = addr;
return 1;
-
- gpf:
- return 0;
}
/* On non-NULL return, we leave this function holding an additional
++++++ 27612-x86-HVM-refuse-doing-string-operations-in-certain-situations.patch ++++++
# Commit 14fcce2fa883405bab26b60821a6cc5f2c770833
# Date 2013-09-23 09:55:14 +0200
# Author Jan Beulich
# Committer Jan Beulich
x86/HVM: refuse doing string operations in certain situations
We shouldn't do any acceleration for
- "rep movs" when either side is passed through MMIO or when both sides
are handled by qemu
- "rep ins" and "rep outs" when the memory operand is any kind of MMIO
Signed-off-by: Jan Beulich
Acked-by: Keir Fraser
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -686,6 +686,7 @@ static int hvmemul_rep_ins(
unsigned long addr;
uint32_t pfec = PFEC_page_present | PFEC_write_access;
paddr_t gpa;
+ p2m_type_t p2mt;
int rc;
rc = hvmemul_virtual_to_linear(
@@ -702,6 +703,10 @@ static int hvmemul_rep_ins(
if ( rc != X86EMUL_OKAY )
return rc;
+ (void) get_gfn_query_unlocked(current->domain, gpa >> PAGE_SHIFT, &p2mt);
+ if ( p2mt == p2m_mmio_direct || p2mt == p2m_mmio_dm )
+ return X86EMUL_UNHANDLEABLE;
+
return hvmemul_do_pio(src_port, reps, bytes_per_rep, gpa, IOREQ_READ,
!!(ctxt->regs->eflags & X86_EFLAGS_DF), NULL);
}
@@ -719,6 +724,7 @@ static int hvmemul_rep_outs(
unsigned long addr;
uint32_t pfec = PFEC_page_present;
paddr_t gpa;
+ p2m_type_t p2mt;
int rc;
rc = hvmemul_virtual_to_linear(
@@ -735,6 +741,10 @@ static int hvmemul_rep_outs(
if ( rc != X86EMUL_OKAY )
return rc;
+ (void) get_gfn_query_unlocked(current->domain, gpa >> PAGE_SHIFT, &p2mt);
+ if ( p2mt == p2m_mmio_direct || p2mt == p2m_mmio_dm )
+ return X86EMUL_UNHANDLEABLE;
+
return hvmemul_do_pio(dst_port, reps, bytes_per_rep, gpa, IOREQ_WRITE,
!!(ctxt->regs->eflags & X86_EFLAGS_DF), NULL);
}
@@ -787,6 +797,10 @@ static int hvmemul_rep_movs(
(void) get_gfn_query_unlocked(current->domain, sgpa >> PAGE_SHIFT, &sp2mt);
(void) get_gfn_query_unlocked(current->domain, dgpa >> PAGE_SHIFT, &dp2mt);
+ if ( sp2mt == p2m_mmio_direct || dp2mt == p2m_mmio_direct ||
+ (sp2mt == p2m_mmio_dm && dp2mt == p2m_mmio_dm) )
+ return X86EMUL_UNHANDLEABLE;
+
if ( sp2mt == p2m_mmio_dm )
return hvmemul_do_mmio(
sgpa, reps, bytes_per_rep, dgpa, IOREQ_READ, df, NULL);
++++++ 27691-x86-percpu-Force-INVALID_PERCPU_AREA-into-the-non-canonical-address-region.patch ++++++
# Commit 7cfb0053629c4dd1a6f01dc43cca7c0c25b8b7bf
# Date 2013-10-04 12:24:34 +0200
# Author Andrew Cooper
# Committer Jan Beulich
x86-64/percpu: Force INVALID_PERCPU_AREA into the non-canonical address region
This causes accidental uses of per_cpu() on a pcpu with an INVALID_PERCPU_AREA
to result in a #GF for attempting to access the middle of the non-canonical
virtual address region.
This is preferable to the current behaviour, where incorrect use of per_cpu()
will result in an effective NULL structure dereference which has security
implication in the context of PV guests.
Signed-off-by: Andrew Cooper
Acked-by: Keir Fraser
--- a/xen/arch/x86/percpu.c
+++ b/xen/arch/x86/percpu.c
@@ -6,7 +6,17 @@
#include
unsigned long __per_cpu_offset[NR_CPUS];
+#ifdef __i386__
#define INVALID_PERCPU_AREA (-(long)__per_cpu_start)
+#else
+/*
+ * Force uses of per_cpu() with an invalid area to attempt to access the
+ * middle of the non-canonical address space resulting in a #GP, rather than a
+ * possible #PF at (NULL + a little) which has security implications in the
+ * context of PV guests.
+ */
+#define INVALID_PERCPU_AREA (0x8000000000000000L - (long)__per_cpu_start)
+#endif
#define PERCPU_ORDER (get_order_from_bytes(__per_cpu_data_end-__per_cpu_start))
void __init percpu_init_areas(void)
++++++ 27692-Nested-VMX-check-VMX-capability-before-read-VMX-related-MSRs.patch ++++++
# Commit 190b667ac20e8175758f4a3a0f13c4d990e6af7e
# Date 2013-10-04 12:28:14 +0200
# Author Yang Zhang
# Committer Jan Beulich
Nested VMX: check VMX capability before read VMX related MSRs
VMX MSRs only available when the CPU support the VMX feature. In addition,
VMX_TRUE* MSRs only available when bit 55 of VMX_BASIC MSR is set.
Signed-off-by: Yang Zhang
Cleanup.
Signed-off-by: Jan Beulich
Acked-by: Jun Nakajima
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vmcs.c
@@ -77,6 +77,7 @@ static DEFINE_PER_CPU(struct list_head,
static DEFINE_PER_CPU(bool_t, vmxon);
static u32 vmcs_revision_id __read_mostly;
+u64 __read_mostly vmx_basic_msr;
static void __init vmx_display_features(void)
{
@@ -308,6 +309,8 @@ static int vmx_init_vmcs_config(void)
vmx_vmexit_control = _vmx_vmexit_control;
vmx_vmentry_control = _vmx_vmentry_control;
cpu_has_vmx_ins_outs_instr_info = !!(vmx_basic_msr_high & (1U<<22));
+ vmx_basic_msr = ((u64)vmx_basic_msr_high << 32) |
+ vmx_basic_msr_low;
vmx_display_features();
}
else
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vvmx.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vvmx.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vvmx.c
@@ -1339,12 +1339,33 @@ int nvmx_handle_vmwrite(struct cpu_user_
*/
int nvmx_msr_read_intercept(unsigned int msr, u64 *msr_content)
{
+ unsigned int ecx, dummy;
u64 data = 0, tmp;
int r = 1;
if ( !nestedhvm_enabled(current->domain) )
return 0;
+ /* VMX capablity MSRs are available only when guest supports VMX. */
+ hvm_cpuid(0x1, &dummy, &dummy, &ecx, &dummy);
+ if ( !(ecx & cpufeat_mask(X86_FEATURE_VMXE)) )
+ return 0;
+
+ /*
+ * Those MSRs are available only when bit 55 of
+ * MSR_IA32_VMX_BASIC is set.
+ */
+ switch ( msr )
+ {
+ case MSR_IA32_VMX_TRUE_PINBASED_CTLS:
+ case MSR_IA32_VMX_TRUE_PROCBASED_CTLS:
+ case MSR_IA32_VMX_TRUE_EXIT_CTLS:
+ case MSR_IA32_VMX_TRUE_ENTRY_CTLS:
+ if ( !(vmx_basic_msr & VMX_BASIC_DEFAULT1_ZERO) )
+ return 0;
+ break;
+ }
+
/*
* Remove unsupport features from n1 guest capability MSR
*/
Index: xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ xen-4.2.4-testing/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -261,6 +261,14 @@ extern bool_t cpu_has_vmx_ins_outs_instr
#define VMX_INTR_SHADOW_SMI 0x00000004
#define VMX_INTR_SHADOW_NMI 0x00000008
+/*
+ * bit 55 of IA32_VMX_BASIC MSR, indicating whether any VMX controls that
+ * default to 1 may be cleared to 0.
+ */
+#define VMX_BASIC_DEFAULT1_ZERO (1ULL << 55)
+
+extern u64 vmx_basic_msr;
+
/* Guest interrupt status */
#define VMX_GUEST_INTR_STATUS_SUBFIELD_BITMASK 0x0FF
#define VMX_GUEST_INTR_STATUS_SVI_OFFSET 8
++++++ 27694-Nested-VMX-fix-IA32_VMX_CR4_FIXED1-msr-emulation.patch ++++++
# Commit c6f92aed0e209df823d2cb5780dbb1ea12fc6d4a
# Date 2013-10-04 12:30:09 +0200
# Author Yang Zhang
# Committer Jan Beulich
Nested VMX: fix IA32_VMX_CR4_FIXED1 msr emulation
Currently, it use hardcode value for IA32_VMX_CR4_FIXED1. This is wrong.
We should check guest's cpuid to know which bits are writeable in CR4 by guest
and allow the guest to set the corresponding bit only when guest has the feature.
Signed-off-by: Yang Zhang
Cleanup.
Signed-off-by: Jan Beulich
Acked-by: Jun Nakajima
Index: xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vvmx.c
===================================================================
--- xen-4.2.4-testing.orig/xen/arch/x86/hvm/vmx/vvmx.c
+++ xen-4.2.4-testing/xen/arch/x86/hvm/vmx/vvmx.c
@@ -1339,7 +1339,7 @@ int nvmx_handle_vmwrite(struct cpu_user_
*/
int nvmx_msr_read_intercept(unsigned int msr, u64 *msr_content)
{
- unsigned int ecx, dummy;
+ unsigned int eax, ebx, ecx, edx, dummy;
u64 data = 0, tmp;
int r = 1;
@@ -1347,7 +1347,7 @@ int nvmx_msr_read_intercept(unsigned int
return 0;
/* VMX capablity MSRs are available only when guest supports VMX. */
- hvm_cpuid(0x1, &dummy, &dummy, &ecx, &dummy);
+ hvm_cpuid(0x1, &dummy, &dummy, &ecx, &edx);
if ( !(ecx & cpufeat_mask(X86_FEATURE_VMXE)) )
return 0;
@@ -1440,8 +1440,55 @@ int nvmx_msr_read_intercept(unsigned int
data = X86_CR4_VMXE;
break;
case MSR_IA32_VMX_CR4_FIXED1:
- /* allow 0-settings except SMXE */
- data = 0x267ff & ~X86_CR4_SMXE;
+ if ( edx & cpufeat_mask(X86_FEATURE_VME) )
+ data |= X86_CR4_VME | X86_CR4_PVI;
+ if ( edx & cpufeat_mask(X86_FEATURE_TSC) )
+ data |= X86_CR4_TSD;
+ if ( edx & cpufeat_mask(X86_FEATURE_DE) )
+ data |= X86_CR4_DE;
+ if ( edx & cpufeat_mask(X86_FEATURE_PSE) )
+ data |= X86_CR4_PSE;
+ if ( edx & cpufeat_mask(X86_FEATURE_PAE) )
+ data |= X86_CR4_PAE;
+ if ( edx & cpufeat_mask(X86_FEATURE_MCE) )
+ data |= X86_CR4_MCE;
+ if ( edx & cpufeat_mask(X86_FEATURE_PGE) )
+ data |= X86_CR4_PGE;
+ if ( edx & cpufeat_mask(X86_FEATURE_FXSR) )
+ data |= X86_CR4_OSFXSR;
+ if ( edx & cpufeat_mask(X86_FEATURE_XMM) )
+ data |= X86_CR4_OSXMMEXCPT;
+ if ( ecx & cpufeat_mask(X86_FEATURE_VMXE) )
+ data |= X86_CR4_VMXE;
+ if ( ecx & cpufeat_mask(X86_FEATURE_SMXE) )
+ data |= X86_CR4_SMXE;
+ if ( ecx & cpufeat_mask(X86_FEATURE_PCID) )
+ data |= X86_CR4_PCIDE;
+ if ( ecx & cpufeat_mask(X86_FEATURE_XSAVE) )
+ data |= X86_CR4_OSXSAVE;
+
+ hvm_cpuid(0x0, &eax, &dummy, &dummy, &dummy);
+ switch ( eax )
+ {
+ default:
+ hvm_cpuid(0xa, &eax, &dummy, &dummy, &dummy);
+ /* Check whether guest has the perf monitor feature. */
+ if ( (eax & 0xff) && (eax & 0xff00) )
+ data |= X86_CR4_PCE;
+ /* fall through */
+ case 0x7 ... 0x9:
+ ecx = 0;
+ hvm_cpuid(0x7, &dummy, &ebx, &ecx, &dummy);
+ if ( ebx & cpufeat_mask(X86_FEATURE_FSGSBASE) )
+ data |= X86_CR4_FSGSBASE;
+ if ( ebx & cpufeat_mask(X86_FEATURE_SMEP) )
+ data |= X86_CR4_SMEP;
+ if ( ebx & cpufeat_mask(X86_FEATURE_SMAP) )
+ data |= X86_CR4_SMAP;
+ /* fall through */
+ case 0x0 ... 0x6:
+ break;
+ }
break;
case MSR_IA32_VMX_MISC:
gdprintk(XENLOG_WARNING, "VMX MSR %x not fully supported yet.\n", msr);
Index: xen-4.2.4-testing/xen/include/asm-x86/cpufeature.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/cpufeature.h
+++ xen-4.2.4-testing/xen/include/asm-x86/cpufeature.h
@@ -157,6 +157,7 @@
#define X86_FEATURE_INVPCID (7*32+10) /* Invalidate Process Context ID */
#define X86_FEATURE_RTM (7*32+11) /* Restricted Transactional Memory */
#define X86_FEATURE_NO_FPU_SEL (7*32+13) /* FPU CS/DS stored as zero */
+#define X86_FEATURE_SMAP (7*32+20) /* Supervisor Mode Access Prevention */
#define cpu_has(c, bit) test_bit(bit, (c)->x86_capability)
#define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability)
Index: xen-4.2.4-testing/xen/include/asm-x86/processor.h
===================================================================
--- xen-4.2.4-testing.orig/xen/include/asm-x86/processor.h
+++ xen-4.2.4-testing/xen/include/asm-x86/processor.h
@@ -87,6 +87,7 @@
#define X86_CR4_PCIDE 0x20000 /* enable PCID */
#define X86_CR4_OSXSAVE 0x40000 /* enable XSAVE/XRSTOR */
#define X86_CR4_SMEP 0x100000/* enable SMEP */
+#define X86_CR4_SMAP 0x200000/* enable SMAP */
/*
* Trap/fault mnemonics.
++++++ 27756-pygrub-xvda-style-disk.patch ++++++
# HG changeset patch
# User Ian Campbell
# Date 1381768836 -3600
# Node ID 2bddf95a879f3e75dff243a340493985f6502d5b
# Parent 522b00942ed31f8194d3c551b01bea824d5bda83
pygrub: Support (/dev/xvda) style disk specifications
You get these if you install Debian Wheezy as HVM and then try to convert to
PV.
This is Debian bug #603391.
Signed-off-by: Ian Campbell