Hello community,
here is the log from the commit of package xen for openSUSE:Factory checked in at 2015-07-05 17:50:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/xen (Old)
and /work/SRC/openSUSE:Factory/.xen.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "xen"
Changes:
--------
--- /work/SRC/openSUSE:Factory/xen/xen.changes 2015-05-16 07:12:47.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.xen.new/xen.changes 2015-07-05 17:50:50.000000000 +0200
@@ -1,0 +2,116 @@
+Tue Jun 30 08:25:35 MDT 2015 - carnold@suse.com
+
+- bnc#936516 - xen fails to build with kernel update(4.1.0 from
+ stable)
+ 556d973f-unmodified-drivers-tolerate-IRQF_DISABLED-being-undefined.patch
+
+-------------------------------------------------------------------
+Fri Jun 26 09:22:28 MDT 2015 - carnold@suse.com
+
+- Update to Xen Version 4.5.1 FCS (fate#315675)
+ xen-4.5.1-testing-src.tar.bz2
+- Dropped patches now contained in tarball
+ 556c2cf2-x86-don-t-crash-mapping-a-page-using-EFI-rt-page-tables.patch
+ 556d9718-efi-fix-allocation-problems-if-ExitBootServices-fails.patch
+ 556eabf7-x86-apic-Disable-the-LAPIC-later-in-smp_send_stop.patch
+ 556eac15-x86-crash-don-t-use-set_fixmap-in-the-crash-path.patch
+ 55780aaa-efi-avoid-calling-boot-services-after-ExitBootServices.patch
+ 55780aff-x86-EFI-fix-EFI_MEMORY_WP-handling.patch
+ 55780b43-EFI-early-add-mapbs-to-map-EfiBootServices-Code-Data.patch
+ 55780b97-EFI-support-default-attributes-to-map-Runtime-service-areas.patch
+ 5513b458-allow-reboot-overrides-when-running-under-EFI.patch
+ 5513b4d1-dont-apply-reboot-quirks-if-reboot-set-by-user.patch
+ 5576f178-kexec-add-more-pages-to-v1-environment.patch
+ 5535f633-dont-leak-hypervisor-stack-to-toolstacks.patch
+ CVE-2015-3456-xsa133-qemuu.patch
+ CVE-2015-3456-xsa133-qemut.patch
+
+-------------------------------------------------------------------
+Thu Jun 25 17:19:35 MDT 2015 - jfehlig@suse.com
+
+- Replace 5124efbe-add-qxl-support.patch with the variant that
+ finally made it upstream, 554cc211-libxl-add-qxl.patch
+
+-------------------------------------------------------------------
+Wed Jun 10 09:06:36 MDT 2015 - carnold@suse.com
+
+- bsc#931627 - VUL-0: CVE-2015-4105: XSA-130: xen: Guest triggerable
+ qemu MSI-X pass-through error messages
+ qemu-MSI-X-latch-writes.patch
+- bsc#907514 - Bus fatal error & sles12 sudden reboot has been observed
+- bsc#910258 - SLES12 Xen host crashes with FATAL NMI after shutdown
+ of guest with VT-d NIC
+- bsc#918984 - Bus fatal error & sles11-SP4 sudden reboot has been
+ observed
+- bsc#923967 - Partner-L3: Bus fatal error & sles11-SP3 sudden reboot
+ has been observed
+ x86-MSI-X-teardown.patch
+ x86-MSI-X-enable.patch
+ x86-MSI-X-guest-mask.patch
+ x86-MSI-X-maskall.patch
+ qemu-MSI-X-enable-maskall.patch
+- Upstream patches from Jan
+ 55780aaa-efi-avoid-calling-boot-services-after-ExitBootServices.patch
+ 55780aff-x86-EFI-fix-EFI_MEMORY_WP-handling.patch
+ 55780b43-EFI-early-add-mapbs-to-map-EfiBootServices-Code-Data.patch
+ 55780b97-EFI-support-default-attributes-to-map-Runtime-service-areas.patch
+ 55780be1-x86-EFI-adjust-EFI_MEMORY_WP-handling-for-spec-version-2.5.patch
+ 55103616-vm-assist-prepare-for-discontiguous-used-bit-numbers.patch
+ 5548e95d-x86-allow-to-suppress-M2P-user-mode-exposure.patch
+- Dropped the following patches now contained in the tarball
+ xen-no-array-bounds.patch CVE-2015-4103-xsa128.patch
+ CVE-2015-4104-xsa129.patch CVE-2015-4105-xsa130.patch
+ CVE-2015-4106-xsa131-1.patch CVE-2015-4106-xsa131-2.patch
+ CVE-2015-4106-xsa131-3.patch CVE-2015-4106-xsa131-4.patch
+ CVE-2015-4106-xsa131-5.patch CVE-2015-4106-xsa131-6.patch
+ CVE-2015-4106-xsa131-7.patch CVE-2015-4106-xsa131-8.patch
+
+-------------------------------------------------------------------
+Wed Jun 3 08:57:26 MDT 2015 - carnold@suse.com
+
+- Update to Xen 4.5.1 RC2
+- bsc#931628 - VUL-0: CVE-2015-4106: XSA-131: xen: Unmediated PCI
+ register access in qemu
+ CVE-2015-4106-xsa131-1.patch
+ CVE-2015-4106-xsa131-2.patch
+ CVE-2015-4106-xsa131-3.patch
+ CVE-2015-4106-xsa131-4.patch
+ CVE-2015-4106-xsa131-5.patch
+ CVE-2015-4106-xsa131-6.patch
+ CVE-2015-4106-xsa131-7.patch
+ CVE-2015-4106-xsa131-8.patch
+ CVE-2015-4106-xsa131-9.patch
+- bsc#931627 - VUL-0: CVE-2015-4105: XSA-130: xen: Guest triggerable
+ qemu MSI-X pass-through error messages
+ CVE-2015-4105-xsa130.patch
+- bsc#931626 - VUL-0: CVE-2015-4104: XSA-129: xen: PCI MSI mask
+ bits inadvertently exposed to guests
+ CVE-2015-4104-xsa129.patch
+- bsc#931625 - VUL-0: CVE-2015-4103: XSA-128: xen: Potential
+ unintended writes to host MSI message data field via qemu
+ CVE-2015-4103-xsa128.patch
+- Upstream patches from Jan
+ 5548e903-domctl-don-t-truncate-XEN_DOMCTL_max_mem-requests.patch
+ 556c2cf2-x86-don-t-crash-mapping-a-page-using-EFI-rt-page-tables.patch
+ 556d9718-efi-fix-allocation-problems-if-ExitBootServices-fails.patch
+ 556d973f-unmodified-drivers-tolerate-IRQF_DISABLED-being-undefined.patch
+ 556eabf7-x86-apic-Disable-the-LAPIC-later-in-smp_send_stop.patch
+ 556eac15-x86-crash-don-t-use-set_fixmap-in-the-crash-path.patch
+
+-------------------------------------------------------------------
+Wed May 20 12:13:25 UTC 2015 - ohering@suse.de
+
+- Add DefaultDependencies=no to xen-dom0-modules.service because
+ it has to run before proc-xen.mount
+
+-------------------------------------------------------------------
+Tue May 19 11:05:31 MDT 2015 - carnold@suse.com
+
+- Update to Xen 4.5.1 RC1
+
+-------------------------------------------------------------------
+Fri May 15 16:34:08 UTC 2015 - ohering@suse.de
+
+- Update blktap-no-uninit.patch to work with gcc-4.5
+
+-------------------------------------------------------------------
Old:
----
5124efbe-add-qxl-support.patch
5513b458-allow-reboot-overrides-when-running-under-EFI.patch
5513b4d1-dont-apply-reboot-quirks-if-reboot-set-by-user.patch
5535f633-dont-leak-hypervisor-stack-to-toolstacks.patch
CVE-2015-3456-xsa133-qemut.patch
CVE-2015-3456-xsa133-qemuu.patch
xen-4.5.0-testing-src.tar.bz2
xen-no-array-bounds.patch
New:
----
55103616-vm-assist-prepare-for-discontiguous-used-bit-numbers.patch
5548e903-domctl-don-t-truncate-XEN_DOMCTL_max_mem-requests.patch
5548e95d-x86-allow-to-suppress-M2P-user-mode-exposure.patch
554cc211-libxl-add-qxl.patch
556d973f-unmodified-drivers-tolerate-IRQF_DISABLED-being-undefined.patch
5576f178-kexec-add-more-pages-to-v1-environment.patch
55780be1-x86-EFI-adjust-EFI_MEMORY_WP-handling-for-spec-version-2.5.patch
CVE-2015-4106-xsa131-9.patch
qemu-MSI-X-enable-maskall.patch
qemu-MSI-X-latch-writes.patch
x86-MSI-X-enable.patch
x86-MSI-X-guest-mask.patch
x86-MSI-X-maskall.patch
x86-MSI-X-teardown.patch
xen-4.5.1-testing-src.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ xen.spec ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:50:54.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:50:54.000000000 +0200
@@ -20,8 +20,8 @@
Name: xen
ExclusiveArch: %ix86 x86_64 %arm aarch64
-%define changeset 30080
-%define xen_build_dir xen-4.5.0-testing
+%define changeset 30152
+%define xen_build_dir xen-4.5.1-testing
#
%define with_kmp 0
%define with_debug 0
@@ -158,12 +158,12 @@
%endif
%endif
-Version: 4.5.0_04
+Version: 4.5.1_02
Release: 0
Summary: Xen Virtualization: Hypervisor (aka VMM aka Microkernel)
License: GPL-2.0
Group: System/Kernel
-Source0: xen-4.5.0-testing-src.tar.bz2
+Source0: xen-4.5.1-testing-src.tar.bz2
Source1: stubdom.tar.bz2
Source2: qemu-xen-traditional-dir-remote.tar.bz2
Source3: qemu-xen-dir-remote.tar.bz2
@@ -201,11 +201,13 @@
# http://xenbits.xensource.com/ext/xenalyze
Source20000: xenalyze.hg.tar.bz2
# Upstream patches
-Patch1: 5124efbe-add-qxl-support.patch
-Patch2: 551ac326-xentop-add-support-for-qdisk.patch
-Patch3: 5513b458-allow-reboot-overrides-when-running-under-EFI.patch
-Patch4: 5513b4d1-dont-apply-reboot-quirks-if-reboot-set-by-user.patch
-Patch5: 5535f633-dont-leak-hypervisor-stack-to-toolstacks.patch
+Patch1: 551ac326-xentop-add-support-for-qdisk.patch
+Patch2: 5548e903-domctl-don-t-truncate-XEN_DOMCTL_max_mem-requests.patch
+Patch3: 554cc211-libxl-add-qxl.patch
+Patch4: 556d973f-unmodified-drivers-tolerate-IRQF_DISABLED-being-undefined.patch
+Patch5: 5576f178-kexec-add-more-pages-to-v1-environment.patch
+Patch6: 55780be1-x86-EFI-adjust-EFI_MEMORY_WP-handling-for-spec-version-2.5.patch
+Patch131: CVE-2015-4106-xsa131-9.patch
# Upstream qemu
Patch250: VNC-Support-for-ExtendedKeyEvent-client-message.patch
Patch251: 0001-net-move-the-tap-buffer-into-TAPState.patch
@@ -216,8 +218,15 @@
Patch256: 0006-e1000-clear-EOP-for-multi-buffer-descriptors.patch
Patch257: 0007-e1000-verify-we-have-buffers-upfront.patch
Patch258: 0008-e1000-check-buffer-availability.patch
-Patch260: CVE-2015-3456-xsa133-qemuu.patch
-Patch261: CVE-2015-3456-xsa133-qemut.patch
+# Extra patches pending review
+Patch150: 55103616-vm-assist-prepare-for-discontiguous-used-bit-numbers.patch
+Patch151: 5548e95d-x86-allow-to-suppress-M2P-user-mode-exposure.patch
+Patch156: x86-MSI-X-teardown.patch
+Patch157: x86-MSI-X-enable.patch
+Patch158: x86-MSI-X-guest-mask.patch
+Patch159: x86-MSI-X-maskall.patch
+Patch160: qemu-MSI-X-latch-writes.patch
+Patch161: qemu-MSI-X-enable-maskall.patch
# Our platform specific patches
Patch301: xen-destdir.patch
Patch302: vif-bridge-no-iptables.patch
@@ -303,7 +312,6 @@
# Build patches
Patch99996: xen.stubdom.newlib.patch
Patch99998: tmp_build.patch
-Patch99999: xen-no-array-bounds.patch
Url: http://www.cl.cam.ac.uk/Research/SRG/netos/xen/
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%define pyver %(python -c "import sys; print sys.version[:3]")
@@ -512,6 +520,8 @@
%patch3 -p1
%patch4 -p1
%patch5 -p1
+%patch6 -p1
+%patch131 -p1
# Upstream qemu patches
%patch250 -p1
%patch251 -p1
@@ -522,8 +532,15 @@
%patch256 -p1
%patch257 -p1
%patch258 -p1
-%patch260 -p1
-%patch261 -p1
+# Extra patches pending review
+%patch150 -p1
+%patch151 -p1
+%patch156 -p1
+%patch157 -p1
+%patch158 -p1
+%patch159 -p1
+%patch160 -p1
+%patch161 -p1
# Our platform specific patches
%patch301 -p1
%patch302 -p1
@@ -608,7 +625,6 @@
# Build patches
%patch99996 -p1
%patch99998 -p1
-%patch99999 -p1
%build
# we control the version info of this package
++++++ 55103616-vm-assist-prepare-for-discontiguous-used-bit-numbers.patch ++++++
# Commit 88a2372c6ba44dd42b915a95a823cf9d4d260e25
# Date 2015-03-23 16:49:42 +0100
# Author Jan Beulich
# Committer Jan Beulich
vm-assist: prepare for discontiguous used bit numbers
Since the a flag will get assigned a value discontiguous to the
existing ones (in order to preserve the low bits, as only those are
currently accessible to 32-bit guests), this requires a little bit of
rework of the VM assist code in general: An architecture specific
VM_ASSIST_VALID definition gets introduced (with an optional compat
mode counterpart), and compilation of the respective code becomes
conditional upon this being defined (ARM doesn't wire these up and
hence doesn't need that code).
Signed-off-by: Jan Beulich
Reviewed-by: Tim Deegan
--- a/xen/common/compat/kernel.c
+++ b/xen/common/compat/kernel.c
@@ -41,6 +41,11 @@ CHECK_TYPE(domain_handle);
#define xennmi_callback compat_nmi_callback
#define xennmi_callback_t compat_nmi_callback_t
+#ifdef COMPAT_VM_ASSIST_VALID
+#undef VM_ASSIST_VALID
+#define VM_ASSIST_VALID COMPAT_VM_ASSIST_VALID
+#endif
+
#define DO(fn) int compat_##fn
#define COMPAT
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -1325,9 +1325,11 @@ long do_vcpu_op(int cmd, int vcpuid, XEN
return rc;
}
-long vm_assist(struct domain *p, unsigned int cmd, unsigned int type)
+#ifdef VM_ASSIST_VALID
+long vm_assist(struct domain *p, unsigned int cmd, unsigned int type,
+ unsigned long valid)
{
- if ( type > MAX_VMASST_TYPE )
+ if ( type >= BITS_PER_LONG || !test_bit(type, &valid) )
return -EINVAL;
switch ( cmd )
@@ -1342,6 +1344,7 @@ long vm_assist(struct domain *p, unsigne
return -ENOSYS;
}
+#endif
struct pirq *pirq_get_info(struct domain *d, int pirq)
{
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -396,10 +396,12 @@ DO(nmi_op)(unsigned int cmd, XEN_GUEST_H
return rc;
}
+#ifdef VM_ASSIST_VALID
DO(vm_assist)(unsigned int cmd, unsigned int type)
{
- return vm_assist(current->domain, cmd, type);
+ return vm_assist(current->domain, cmd, type, VM_ASSIST_VALID);
}
+#endif
DO(ni_hypercall)(void)
{
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -327,6 +327,14 @@ extern unsigned long xen_phys_start;
#define ARG_XLAT_START(v) \
(ARG_XLAT_VIRT_START + ((v)->vcpu_id << ARG_XLAT_VA_SHIFT))
+#define NATIVE_VM_ASSIST_VALID ((1UL << VMASST_TYPE_4gb_segments) | \
+ (1UL << VMASST_TYPE_4gb_segments_notify) | \
+ (1UL << VMASST_TYPE_writable_pagetables) | \
+ (1UL << VMASST_TYPE_pae_extended_cr3))
+#define VM_ASSIST_VALID NATIVE_VM_ASSIST_VALID
+#define COMPAT_VM_ASSIST_VALID (NATIVE_VM_ASSIST_VALID & \
+ ((1UL << COMPAT_BITS_PER_LONG) - 1))
+
#define ELFSIZE 64
#define ARCH_CRASH_SAVE_VMCOREINFO
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -486,7 +486,9 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
/* x86/PAE guests: support PDPTs above 4GB. */
#define VMASST_TYPE_pae_extended_cr3 3
+#if __XEN_INTERFACE_VERSION__ < 0x00040600
#define MAX_VMASST_TYPE 3
+#endif
#ifndef __ASSEMBLY__
--- a/xen/include/xen/lib.h
+++ b/xen/include/xen/lib.h
@@ -92,7 +92,8 @@ extern void guest_printk(const struct do
__attribute__ ((format (printf, 2, 3)));
extern void noreturn panic(const char *format, ...)
__attribute__ ((format (printf, 1, 2)));
-extern long vm_assist(struct domain *, unsigned int, unsigned int);
+extern long vm_assist(struct domain *, unsigned int cmd, unsigned int type,
+ unsigned long valid);
extern int __printk_ratelimit(int ratelimit_ms, int ratelimit_burst);
extern int printk_ratelimit(void);
++++++ 551ac326-xentop-add-support-for-qdisk.patch ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:50:54.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:50:54.000000000 +0200
@@ -1,8 +1,8 @@
-Index: xen-4.5.0-testing/tools/libxl/libxl_dm.c
+Index: xen-4.5.1-testing/tools/libxl/libxl_dm.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_dm.c
-+++ xen-4.5.0-testing/tools/libxl/libxl_dm.c
-@@ -440,6 +440,15 @@ static char ** libxl__build_device_model
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_dm.c
++++ xen-4.5.1-testing/tools/libxl/libxl_dm.c
+@@ -445,6 +445,15 @@ static char ** libxl__build_device_model
flexarray_append(dm_args, "-mon");
flexarray_append(dm_args, "chardev=libxl-cmd,mode=control");
@@ -18,10 +18,10 @@
for (i = 0; i < guest_config->num_channels; i++) {
connection = guest_config->channels[i].connection;
devid = guest_config->channels[i].devid;
-Index: xen-4.5.0-testing/tools/libxl/libxl_qmp.c
+Index: xen-4.5.1-testing/tools/libxl/libxl_qmp.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_qmp.c
-+++ xen-4.5.0-testing/tools/libxl/libxl_qmp.c
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_qmp.c
++++ xen-4.5.1-testing/tools/libxl/libxl_qmp.c
@@ -723,6 +723,13 @@ void libxl__qmp_cleanup(libxl__gc *gc, u
LOGE(ERROR, "Failed to remove QMP socket file %s", qmp_socket);
}
@@ -36,10 +36,10 @@
}
int libxl__qmp_query_serial(libxl__qmp_handler *qmp)
-Index: xen-4.5.0-testing/tools/xenstat/libxenstat/Makefile
+Index: xen-4.5.1-testing/tools/xenstat/libxenstat/Makefile
===================================================================
---- xen-4.5.0-testing.orig/tools/xenstat/libxenstat/Makefile
-+++ xen-4.5.0-testing/tools/xenstat/libxenstat/Makefile
+--- xen-4.5.1-testing.orig/tools/xenstat/libxenstat/Makefile
++++ xen-4.5.1-testing/tools/xenstat/libxenstat/Makefile
@@ -24,7 +24,7 @@ MINOR=0
LIB=src/libxenstat.a
SHLIB=src/libxenstat.so.$(MAJOR).$(MINOR)
@@ -58,10 +58,10 @@
LDLIBS-y = $(LDLIBS_libxenstore) $(LDLIBS_libxenctrl)
LDLIBS-$(CONFIG_SunOS) += -lkstat
-Index: xen-4.5.0-testing/tools/xenstat/xentop/Makefile
+Index: xen-4.5.1-testing/tools/xenstat/xentop/Makefile
===================================================================
---- xen-4.5.0-testing.orig/tools/xenstat/xentop/Makefile
-+++ xen-4.5.0-testing/tools/xenstat/xentop/Makefile
+--- xen-4.5.1-testing.orig/tools/xenstat/xentop/Makefile
++++ xen-4.5.1-testing/tools/xenstat/xentop/Makefile
@@ -19,7 +19,7 @@ all install xentop:
else
@@ -71,10 +71,10 @@
CFLAGS += -DHOST_$(XEN_OS)
# Include configure output (config.h) to headers search path
-Index: xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_priv.h
+Index: xen-4.5.1-testing/tools/xenstat/libxenstat/src/xenstat_priv.h
===================================================================
---- xen-4.5.0-testing.orig/tools/xenstat/libxenstat/src/xenstat_priv.h
-+++ xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_priv.h
+--- xen-4.5.1-testing.orig/tools/xenstat/libxenstat/src/xenstat_priv.h
++++ xen-4.5.1-testing/tools/xenstat/libxenstat/src/xenstat_priv.h
@@ -109,5 +109,7 @@ extern int xenstat_collect_networks(xens
extern void xenstat_uninit_networks(xenstat_handle * handle);
extern int xenstat_collect_vbds(xenstat_node * node);
@@ -83,10 +83,10 @@
+extern xenstat_vbd *xenstat_save_vbd(xenstat_domain * domain, xenstat_vbd * vbd);
#endif /* XENSTAT_PRIV_H */
-Index: xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat.c
+Index: xen-4.5.1-testing/tools/xenstat/libxenstat/src/xenstat.c
===================================================================
---- xen-4.5.0-testing.orig/tools/xenstat/libxenstat/src/xenstat.c
-+++ xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat.c
+--- xen-4.5.1-testing.orig/tools/xenstat/libxenstat/src/xenstat.c
++++ xen-4.5.1-testing/tools/xenstat/libxenstat/src/xenstat.c
@@ -657,6 +657,27 @@ static void xenstat_uninit_xen_version(x
* VBD functions
*/
@@ -115,10 +115,10 @@
/* Free VBD information */
static void xenstat_free_vbds(xenstat_node * node)
{
-Index: xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_linux.c
+Index: xen-4.5.1-testing/tools/xenstat/libxenstat/src/xenstat_linux.c
===================================================================
---- xen-4.5.0-testing.orig/tools/xenstat/libxenstat/src/xenstat_linux.c
-+++ xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_linux.c
+--- xen-4.5.1-testing.orig/tools/xenstat/libxenstat/src/xenstat_linux.c
++++ xen-4.5.1-testing/tools/xenstat/libxenstat/src/xenstat_linux.c
@@ -417,6 +417,9 @@ int xenstat_collect_vbds(xenstat_node *
}
}
@@ -151,10 +151,10 @@
}
return 1;
-Index: xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_qmp.c
+Index: xen-4.5.1-testing/tools/xenstat/libxenstat/src/xenstat_qmp.c
===================================================================
--- /dev/null
-+++ xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_qmp.c
++++ xen-4.5.1-testing/tools/xenstat/libxenstat/src/xenstat_qmp.c
@@ -0,0 +1,451 @@
+/* libxenstat: statistics-collection library for Xen
+ *
++++++ 5548e903-domctl-don-t-truncate-XEN_DOMCTL_max_mem-requests.patch ++++++
# Commit 017e667c433a1040306db6265b05e104568c70c8
# Date 2015-05-05 18:00:03 +0200
# Author Jan Beulich
# Committer Jan Beulich
domctl: don't truncate XEN_DOMCTL_max_mem requests
Instead saturate the value if the input can't be represented in the
respective struct domain field.
Signed-off-by: Jan Beulich
Reviewed-by: Andrew Cooper
Acked-by: Tim Deegan
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -943,7 +943,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
case XEN_DOMCTL_max_mem:
{
- unsigned long new_max;
+ uint64_t new_max;
ret = -EINVAL;
new_max = op->u.max_mem.max_memkb >> (PAGE_SHIFT-10);
@@ -954,7 +954,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
* that the domain will now be allowed to "ratchet" down to new_max. In
* the meantime, while tot > max, all new allocations are disallowed.
*/
- d->max_pages = new_max;
+ d->max_pages = min(new_max, (uint64_t)(typeof(d->max_pages))-1);
ret = 0;
spin_unlock(&d->page_alloc_lock);
}
++++++ 5548e95d-x86-allow-to-suppress-M2P-user-mode-exposure.patch ++++++
# Commit d72a4605e18d3a61c4469ff092dbbbfa4ac919f7
# Date 2015-05-05 18:01:33 +0200
# Author Jan Beulich
# Committer Jan Beulich
x86: allow 64-bit PV guest kernels to suppress user mode exposure of M2P
Xen L4 entries being uniformly installed into any L4 table and 64-bit
PV kernels running in ring 3 means that user mode was able to see the
read-only M2P presented by Xen to the guests. While apparently not
really representing an exploitable information leak, this still very
certainly was never meant to be that way.
Building on the fact that these guests already have separate kernel and
user mode page tables we can allow guest kernels to tell Xen that they
don't want user mode to see this table. We can't, however, do this by
default: There is no ABI requirement that kernel and user mode page
tables be separate. Therefore introduce a new VM-assist flag allowing
the guest to control respective hypervisor behavior:
- when not set, L4 tables get created with the respective slot blank,
and whenever the L4 table gets used as a kernel one the missing
mapping gets inserted,
- when set, L4 tables get created with the respective slot initialized
as before, and whenever the L4 table gets used as a user one the
mapping gets zapped.
Signed-off-by: Jan Beulich
Reviewed-by: Andrew Cooper
Reviewed-by: Tim Deegan
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -338,7 +338,7 @@ static int setup_compat_l4(struct vcpu *
l4tab = __map_domain_page(pg);
clear_page(l4tab);
- init_guest_l4_table(l4tab, v->domain);
+ init_guest_l4_table(l4tab, v->domain, 1);
unmap_domain_page(l4tab);
v->arch.guest_table = pagetable_from_page(pg);
@@ -977,7 +977,11 @@ int arch_set_info_guest(
case -EINTR:
rc = -ERESTART;
case -ERESTART:
+ break;
case 0:
+ if ( !compat && !VM_ASSIST(d, VMASST_TYPE_m2p_strict) &&
+ !paging_mode_refcounts(d) )
+ fill_ro_mpt(cr3_gfn);
break;
default:
if ( cr3_page == current->arch.old_guest_table )
@@ -1012,7 +1016,10 @@ int arch_set_info_guest(
default:
if ( cr3_page == current->arch.old_guest_table )
cr3_page = NULL;
+ break;
case 0:
+ if ( VM_ASSIST(d, VMASST_TYPE_m2p_strict) )
+ zap_ro_mpt(cr3_gfn);
break;
}
}
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -1092,7 +1092,7 @@ int __init construct_dom0(
l3start = __va(mpt_alloc); mpt_alloc += PAGE_SIZE;
}
clear_page(l4tab);
- init_guest_l4_table(l4tab, d);
+ init_guest_l4_table(l4tab, d, 0);
v->arch.guest_table = pagetable_from_paddr(__pa(l4start));
if ( is_pv_32on64_domain(d) )
v->arch.guest_table_user = v->arch.guest_table;
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -1380,7 +1380,8 @@ static int alloc_l3_table(struct page_in
return rc > 0 ? 0 : rc;
}
-void init_guest_l4_table(l4_pgentry_t l4tab[], const struct domain *d)
+void init_guest_l4_table(l4_pgentry_t l4tab[], const struct domain *d,
+ bool_t zap_ro_mpt)
{
/* Xen private mappings. */
memcpy(&l4tab[ROOT_PAGETABLE_FIRST_XEN_SLOT],
@@ -1395,6 +1396,25 @@ void init_guest_l4_table(l4_pgentry_t l4
l4e_from_pfn(domain_page_map_to_mfn(l4tab), __PAGE_HYPERVISOR);
l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] =
l4e_from_page(d->arch.perdomain_l3_pg, __PAGE_HYPERVISOR);
+ if ( zap_ro_mpt || is_pv_32on64_domain(d) || paging_mode_refcounts(d) )
+ l4tab[l4_table_offset(RO_MPT_VIRT_START)] = l4e_empty();
+}
+
+void fill_ro_mpt(unsigned long mfn)
+{
+ l4_pgentry_t *l4tab = map_domain_page(mfn);
+
+ l4tab[l4_table_offset(RO_MPT_VIRT_START)] =
+ idle_pg_table[l4_table_offset(RO_MPT_VIRT_START)];
+ unmap_domain_page(l4tab);
+}
+
+void zap_ro_mpt(unsigned long mfn)
+{
+ l4_pgentry_t *l4tab = map_domain_page(mfn);
+
+ l4tab[l4_table_offset(RO_MPT_VIRT_START)] = l4e_empty();
+ unmap_domain_page(l4tab);
}
static int alloc_l4_table(struct page_info *page)
@@ -1444,7 +1464,7 @@ static int alloc_l4_table(struct page_in
adjust_guest_l4e(pl4e[i], d);
}
- init_guest_l4_table(pl4e, d);
+ init_guest_l4_table(pl4e, d, !VM_ASSIST(d, VMASST_TYPE_m2p_strict));
unmap_domain_page(pl4e);
return rc > 0 ? 0 : rc;
@@ -2755,6 +2775,8 @@ int new_guest_cr3(unsigned long mfn)
invalidate_shadow_ldt(curr, 0);
+ if ( !VM_ASSIST(d, VMASST_TYPE_m2p_strict) && !paging_mode_refcounts(d) )
+ fill_ro_mpt(mfn);
curr->arch.guest_table = pagetable_from_pfn(mfn);
update_cr3(curr);
@@ -3111,6 +3133,9 @@ long do_mmuext_op(
op.arg1.mfn);
break;
}
+ if ( VM_ASSIST(d, VMASST_TYPE_m2p_strict) &&
+ !paging_mode_refcounts(d) )
+ zap_ro_mpt(op.arg1.mfn);
}
curr->arch.guest_table_user = pagetable_from_pfn(op.arg1.mfn);
--- a/xen/arch/x86/mm/shadow/multi.c
+++ b/xen/arch/x86/mm/shadow/multi.c
@@ -1438,6 +1438,13 @@ void sh_install_xen_entries_in_l4(struct
shadow_l4e_from_mfn(page_to_mfn(d->arch.perdomain_l3_pg),
__PAGE_HYPERVISOR);
+ if ( !shadow_mode_external(d) && !is_pv_32on64_domain(d) &&
+ !VM_ASSIST(d, VMASST_TYPE_m2p_strict) )
+ {
+ /* open coded zap_ro_mpt(mfn_x(sl4mfn)): */
+ sl4e[shadow_l4_table_offset(RO_MPT_VIRT_START)] = shadow_l4e_empty();
+ }
+
/* Shadow linear mapping for 4-level shadows. N.B. for 3-level
* shadows on 64-bit xen, this linear mapping is later replaced by the
* monitor pagetable structure, which is built in make_monitor_table
@@ -4062,6 +4069,17 @@ sh_update_cr3(struct vcpu *v, int do_loc
if ( sh_remove_write_access(v, gmfn, 4, 0) != 0 )
flush_tlb_mask(d->domain_dirty_cpumask);
sh_set_toplevel_shadow(v, 0, gmfn, SH_type_l4_shadow);
+ if ( !shadow_mode_external(d) && !is_pv_32on64_domain(d) )
+ {
+ mfn_t smfn = pagetable_get_mfn(v->arch.shadow_table[0]);
+
+ if ( !(v->arch.flags & TF_kernel_mode) &&
+ VM_ASSIST(d, VMASST_TYPE_m2p_strict) )
+ zap_ro_mpt(mfn_x(smfn));
+ else if ( (v->arch.flags & TF_kernel_mode) &&
+ !VM_ASSIST(d, VMASST_TYPE_m2p_strict) )
+ fill_ro_mpt(mfn_x(smfn));
+ }
#else
#error This should never happen
#endif
--- a/xen/arch/x86/x86_64/mm.c
+++ b/xen/arch/x86/x86_64/mm.c
@@ -480,7 +480,7 @@ static int setup_m2p_table(struct mem_ho
l2_ro_mpt += l2_table_offset(va);
}
- /* NB. Cannot be GLOBAL as shadow_mode_translate reuses this area. */
+ /* NB. Cannot be GLOBAL: guest user mode should not see it. */
l2e_write(l2_ro_mpt, l2e_from_pfn(mfn,
/*_PAGE_GLOBAL|*/_PAGE_PSE|_PAGE_USER|_PAGE_PRESENT));
}
@@ -583,7 +583,7 @@ void __init paging_init(void)
0x77, 1UL << L3_PAGETABLE_SHIFT);
ASSERT(!l2_table_offset(va));
- /* NB. Cannot be GLOBAL as shadow_mode_translate reuses this area. */
+ /* NB. Cannot be GLOBAL: guest user mode should not see it. */
l3e_write(&l3_ro_mpt[l3_table_offset(va)],
l3e_from_page(l1_pg,
/*_PAGE_GLOBAL|*/_PAGE_PSE|_PAGE_USER|_PAGE_PRESENT));
@@ -621,7 +621,7 @@ void __init paging_init(void)
l3e_from_page(l2_pg, __PAGE_HYPERVISOR | _PAGE_USER));
ASSERT(!l2_table_offset(va));
}
- /* NB. Cannot be GLOBAL as shadow_mode_translate reuses this area. */
+ /* NB. Cannot be GLOBAL: guest user mode should not see it. */
if ( l1_pg )
l2e_write(l2_ro_mpt, l2e_from_page(
l1_pg, /*_PAGE_GLOBAL|*/_PAGE_PSE|_PAGE_USER|_PAGE_PRESENT));
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -330,7 +330,8 @@ extern unsigned long xen_phys_start;
#define NATIVE_VM_ASSIST_VALID ((1UL << VMASST_TYPE_4gb_segments) | \
(1UL << VMASST_TYPE_4gb_segments_notify) | \
(1UL << VMASST_TYPE_writable_pagetables) | \
- (1UL << VMASST_TYPE_pae_extended_cr3))
+ (1UL << VMASST_TYPE_pae_extended_cr3) | \
+ (1UL << VMASST_TYPE_m2p_strict))
#define VM_ASSIST_VALID NATIVE_VM_ASSIST_VALID
#define COMPAT_VM_ASSIST_VALID (NATIVE_VM_ASSIST_VALID & \
((1UL << COMPAT_BITS_PER_LONG) - 1))
--- a/xen/include/asm-x86/mm.h
+++ b/xen/include/asm-x86/mm.h
@@ -314,7 +314,10 @@ static inline void *__page_to_virt(const
int free_page_type(struct page_info *page, unsigned long type,
int preemptible);
-void init_guest_l4_table(l4_pgentry_t[], const struct domain *);
+void init_guest_l4_table(l4_pgentry_t[], const struct domain *,
+ bool_t zap_ro_mpt);
+void fill_ro_mpt(unsigned long mfn);
+void zap_ro_mpt(unsigned long mfn);
int is_iomem_page(unsigned long mfn);
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -486,6 +486,18 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
/* x86/PAE guests: support PDPTs above 4GB. */
#define VMASST_TYPE_pae_extended_cr3 3
+/*
+ * x86/64 guests: strictly hide M2P from user mode.
+ * This allows the guest to control respective hypervisor behavior:
+ * - when not set, L4 tables get created with the respective slot blank,
+ * and whenever the L4 table gets used as a kernel one the missing
+ * mapping gets inserted,
+ * - when set, L4 tables get created with the respective slot initialized
+ * as before, and whenever the L4 table gets used as a user one the
+ * mapping gets zapped.
+ */
+#define VMASST_TYPE_m2p_strict 32
+
#if __XEN_INTERFACE_VERSION__ < 0x00040600
#define MAX_VMASST_TYPE 3
#endif
++++++ 554cc211-libxl-add-qxl.patch ++++++
commit 161212ef02312c0681d2d809c8ff1e1f0ea6f6f9
Author: Fabio Fantoni
Date: Wed Apr 29 11:20:28 2015 +0200
libxl: Add qxl vga interface support for upstream qemu
Usage:
vga="qxl"
Qxl vga support many resolutions that not supported by stdvga,
mainly the 16:9 ones and other high up to 2560x1600.
With QXL you can get improved performance and smooth video also
with high resolutions and high quality.
Require their drivers installed in the domU and spice used
otherwise act as a simple stdvga.
Signed-off-by: Fabio Fantoni
Signed-off-by: Zhou Peng
Acked-by: Stefano Stabellini
Acked-by: Ian Jackson
Acked-by: George Dunlap
Index: xen-4.5.1-testing/docs/man/xl.cfg.pod.5
===================================================================
--- xen-4.5.1-testing.orig/docs/man/xl.cfg.pod.5
+++ xen-4.5.1-testing/docs/man/xl.cfg.pod.5
@@ -1292,6 +1292,9 @@ qemu-xen-traditional device-model, the a
which is sufficient for 1024x768 at 32 bpp. For the upstream qemu-xen
device-model, the default and minimum is 8 MB.
+For B<qxl> vga, the default is both default and minimal 128MB.
+If B<videoram> is set less than 128MB, an error will be triggered.
+
=item B
Select a standard VGA card with VBE (VESA BIOS Extensions) as the
@@ -1303,9 +1306,14 @@ This option is deprecated, use vga="stdv
=item B
-Selects the emulated video card (none|stdvga|cirrus).
+Selects the emulated video card (none|stdvga|cirrus|qxl).
The default is cirrus.
+In general, QXL should work with the Spice remote display protocol
+for acceleration, and QXL driver is necessary in guest in this case.
+QXL can also work with the VNC protocol, but it will be like a standard
+VGA without acceleration.
+
=item B
Allow access to the display via the VNC protocol. This enables the
Index: xen-4.5.1-testing/tools/libxl/libxl.h
===================================================================
--- xen-4.5.1-testing.orig/tools/libxl/libxl.h
+++ xen-4.5.1-testing/tools/libxl/libxl.h
@@ -506,6 +506,16 @@ typedef struct libxl__ctx libxl_ctx;
#define LIBXL_HAVE_DOMINFO_OUTSTANDING_MEMKB 1
/*
+ * LIBXL_HAVE_QXL
+ *
+ * If defined, then the libxl_vga_interface_type will contain another value:
+ * "QXL". This value define if qxl vga is supported.
+ *
+ * If this is not defined, the qxl vga support is missed.
+ */
+#define LIBXL_HAVE_QXL 1
+
+/*
* LIBXL_HAVE_SPICE_VDAGENT
*
* If defined, then the libxl_spice_info structure will contain a boolean type:
Index: xen-4.5.1-testing/tools/libxl/libxl_create.c
===================================================================
--- xen-4.5.1-testing.orig/tools/libxl/libxl_create.c
+++ xen-4.5.1-testing/tools/libxl/libxl_create.c
@@ -240,6 +240,10 @@ int libxl__domain_build_info_setdefault(
if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT)
b_info->video_memkb = 0;
break;
+ case LIBXL_VGA_INTERFACE_TYPE_QXL:
+ LOG(ERROR,"qemu upstream required for qxl vga");
+ return ERROR_INVAL;
+ break;
case LIBXL_VGA_INTERFACE_TYPE_STD:
if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT)
b_info->video_memkb = 8 * 1024;
@@ -264,6 +268,15 @@ int libxl__domain_build_info_setdefault(
if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT)
b_info->video_memkb = 0;
break;
+ case LIBXL_VGA_INTERFACE_TYPE_QXL:
+ if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT) {
+ b_info->video_memkb = (128 * 1024);
+ } else if (b_info->video_memkb < (128 * 1024)) {
+ LOG(ERROR,
+ "128 Mib videoram is the minimum for qxl default");
+ return ERROR_INVAL;
+ }
+ break;
case LIBXL_VGA_INTERFACE_TYPE_STD:
if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT)
b_info->video_memkb = 16 * 1024;
Index: xen-4.5.1-testing/tools/libxl/libxl_dm.c
===================================================================
--- xen-4.5.1-testing.orig/tools/libxl/libxl_dm.c
+++ xen-4.5.1-testing/tools/libxl/libxl_dm.c
@@ -251,6 +251,8 @@ static char ** libxl__build_device_model
case LIBXL_VGA_INTERFACE_TYPE_NONE:
flexarray_append_pair(dm_args, "-vga", "none");
break;
+ case LIBXL_VGA_INTERFACE_TYPE_QXL:
+ break;
}
if (b_info->u.hvm.boot) {
@@ -616,6 +618,12 @@ static char ** libxl__build_device_model
break;
case LIBXL_VGA_INTERFACE_TYPE_NONE:
break;
+ case LIBXL_VGA_INTERFACE_TYPE_QXL:
+ /* QXL have 2 ram regions, ram and vram */
+ flexarray_append_pair(dm_args, "-device",
+ GCSPRINTF("qxl-vga,vram_size_mb=%"PRIu64",ram_size_mb=%"PRIu64,
+ (b_info->video_memkb/2/1024), (b_info->video_memkb/2/1024) ) );
+ break;
}
if (b_info->u.hvm.boot) {
Index: xen-4.5.1-testing/tools/libxl/libxl_types.idl
===================================================================
--- xen-4.5.1-testing.orig/tools/libxl/libxl_types.idl
+++ xen-4.5.1-testing/tools/libxl/libxl_types.idl
@@ -181,6 +181,7 @@ libxl_vga_interface_type = Enumeration("
(1, "CIRRUS"),
(2, "STD"),
(3, "NONE"),
+ (4, "QXL"),
], init_val = "LIBXL_VGA_INTERFACE_TYPE_CIRRUS")
libxl_vendor_device = Enumeration("vendor_device", [
Index: xen-4.5.1-testing/tools/libxl/xl_cmdimpl.c
===================================================================
--- xen-4.5.1-testing.orig/tools/libxl/xl_cmdimpl.c
+++ xen-4.5.1-testing/tools/libxl/xl_cmdimpl.c
@@ -1910,6 +1910,8 @@ skip_vfb:
b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_CIRRUS;
} else if (!strcmp(buf, "none")) {
b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_NONE;
+ } else if (!strcmp(buf, "qxl")) {
+ b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_QXL;
} else {
fprintf(stderr, "Unknown vga \"%s\" specified\n", buf);
exit(1);
++++++ 556d973f-unmodified-drivers-tolerate-IRQF_DISABLED-being-undefined.patch ++++++
# Commit fed56ba0e69b251d0222ef0785cd1c1838f9e51d
# Date 2015-06-02 13:45:03 +0200
# Author Jan Beulich
# Committer Jan Beulich
unmodified-drivers: tolerate IRQF_DISABLED being undefined
It's being removed in Linux 4.1.
Signed-off-by: Jan Beulich
Acked-by: Ian Campbell
--- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c
+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c
@@ -350,11 +350,13 @@ int xen_irq_init(struct pci_dev *pdev)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
SA_SHIRQ | SA_SAMPLE_RANDOM | SA_INTERRUPT,
#else
- IRQF_SHARED |
#ifdef IRQF_SAMPLE_RANDOM
IRQF_SAMPLE_RANDOM |
#endif
- IRQF_DISABLED,
+#ifdef IRQF_DISABLED
+ IRQF_DISABLED |
+#endif
+ IRQF_SHARED,
#endif
"xen-platform-pci", pdev);
}
++++++ 5576f178-kexec-add-more-pages-to-v1-environment.patch ++++++
References: bsc#925466
# Commit 5cb57f4bddee1f11079e69bf43c193a8b104c476
# Date 2015-06-09 16:00:24 +0200
# Author Jan Beulich
# Committer Jan Beulich
kexec: add more pages to v1 environment
Destination pages need mappings to be added to the page tables in the
v1 case (where nothing else calls machine_kexec_add_page() for them).
Further, without the tools mapping the low 1Mb (expected by at least
some Linux version), we need to do so in the hypervisor in the v1 case.
Suggested-by: David Vrabel
Signed-off-by: Jan Beulich
Tested-by: Alan Robinson
Reviewed-by: David Vrabel
Reviewed-by: Andrew Cooper
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -1003,6 +1003,24 @@ static int kexec_do_load_v1(xen_kexec_lo
if ( ret < 0 )
goto error;
+ if ( arch == EM_386 || arch == EM_X86_64 )
+ {
+ /*
+ * Ensure 0 - 1 MiB is mapped and accessible by the image.
+ *
+ * This allows access to VGA memory and the region purgatory copies
+ * in the crash case.
+ */
+ unsigned long addr;
+
+ for ( addr = 0; addr < MB(1); addr += PAGE_SIZE )
+ {
+ ret = machine_kexec_add_page(kimage, addr, addr);
+ if ( ret < 0 )
+ goto error;
+ }
+ }
+
ret = kexec_load_slot(kimage);
if ( ret < 0 )
goto error;
--- a/xen/common/kimage.c
+++ b/xen/common/kimage.c
@@ -923,6 +923,11 @@ int kimage_build_ind(struct kexec_image
ret = kimage_add_page(image, page_to_maddr(xen_page));
if ( ret < 0 )
goto done;
+
+ ret = machine_kexec_add_page(image, dest, dest);
+ if ( ret < 0 )
+ goto done;
+
dest += PAGE_SIZE;
break;
}
++++++ 55780be1-x86-EFI-adjust-EFI_MEMORY_WP-handling-for-spec-version-2.5.patch ++++++
# Commit 860313f0411d2dcc6b2fd78bfb834b39d05373a6
# Date 2015-06-10 12:05:21 +0200
# Author Jan Beulich
# Committer Jan Beulich
x86/EFI: adjust EFI_MEMORY_WP handling for spec version 2.5
That flag now means cachability rather than protection, and a new flag
EFI_MEMORY_RO got added in its place.
Along with EFI_MEMORY_RO also add the two other new EFI_MEMORY_*
definitions, even if we don't need them right away.
Signed-off-by: Jan Beulich
Reviewed-by: Andrew Cooper
Reviewed-by: Konrad Rzeszutek Wilk
Index: xen-4.5.1-testing/xen/common/efi/boot.c
===================================================================
--- xen-4.5.1-testing.orig/xen/common/efi/boot.c
+++ xen-4.5.1-testing/xen/common/efi/boot.c
@@ -32,6 +32,8 @@
/* Using SetVirtualAddressMap() is incompatible with kexec: */
#undef USE_SET_VIRTUAL_ADDRESS_MAP
+#define EFI_REVISION(major, minor) (((major) << 16) | (minor))
+
#define SHIM_LOCK_PROTOCOL_GUID \
{ 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
@@ -76,6 +78,7 @@ static int set_color(u32 mask, int bpp,
static bool_t match_guid(const EFI_GUID *guid1, const EFI_GUID *guid2);
static const EFI_BOOT_SERVICES *__initdata efi_bs;
+static UINT32 __initdata efi_bs_revision;
static EFI_HANDLE __initdata efi_ih;
static SIMPLE_TEXT_OUTPUT_INTERFACE *__initdata StdOut;
@@ -714,6 +717,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
efi_ih = ImageHandle;
efi_bs = SystemTable->BootServices;
+ efi_bs_revision = efi_bs->Hdr.Revision;
efi_rs = SystemTable->RuntimeServices;
efi_ct = SystemTable->ConfigurationTable;
efi_num_ct = SystemTable->NumberOfTableEntries;
@@ -1221,6 +1225,9 @@ void __init efi_init_memory(void)
prot |= _PAGE_PAT | MAP_SMALL_PAGES;
else if ( desc->Attribute & (EFI_MEMORY_UC | EFI_MEMORY_UCE) )
prot |= _PAGE_PWT | _PAGE_PCD | MAP_SMALL_PAGES;
+ else if ( efi_bs_revision >= EFI_REVISION(2, 5) &&
+ (desc->Attribute & EFI_MEMORY_WP) )
+ prot |= _PAGE_PAT | _PAGE_PWT | MAP_SMALL_PAGES;
else
{
printk(XENLOG_ERR "Unknown cachability for MFNs %#lx-%#lx%s\n",
@@ -1230,7 +1237,8 @@ void __init efi_init_memory(void)
prot |= _PAGE_PWT | _PAGE_PCD | MAP_SMALL_PAGES;
}
- if ( desc->Attribute & EFI_MEMORY_WP )
+ if ( desc->Attribute & (efi_bs_revision < EFI_REVISION(2, 5)
+ ? EFI_MEMORY_WP : EFI_MEMORY_RO) )
prot &= ~_PAGE_RW;
if ( (desc->Attribute & EFI_MEMORY_XP) && cpu_has_nx )
prot |= _PAGE_NX_BIT;
Index: xen-4.5.1-testing/xen/include/efi/efidef.h
===================================================================
--- xen-4.5.1-testing.orig/xen/include/efi/efidef.h
+++ xen-4.5.1-testing/xen/include/efi/efidef.h
@@ -156,11 +156,15 @@ typedef enum {
#define EFI_MEMORY_WT 0x0000000000000004
#define EFI_MEMORY_WB 0x0000000000000008
#define EFI_MEMORY_UCE 0x0000000000000010
+#define EFI_MEMORY_WP 0x0000000000001000
// physical memory protection on range
-#define EFI_MEMORY_WP 0x0000000000001000
#define EFI_MEMORY_RP 0x0000000000002000
#define EFI_MEMORY_XP 0x0000000000004000
+#define EFI_MEMORY_RO 0x0000000000020000
+
+#define EFI_MEMORY_NV 0x0000000000008000
+#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000
// range requires a runtime mapping
#define EFI_MEMORY_RUNTIME 0x8000000000000000
++++++ CVE-2015-3456-xsa133-qemut.patch -> CVE-2015-4106-xsa131-9.patch ++++++
--- /work/SRC/openSUSE:Factory/xen/CVE-2015-3456-xsa133-qemut.patch 2015-05-16 07:12:47.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.xen.new/CVE-2015-4106-xsa131-9.patch 2015-07-05 17:50:49.000000000 +0200
@@ -1,80 +1,37 @@
-From ac7ddbe342d7aa2303c39ca731cc6229dbbd739b Mon Sep 17 00:00:00 2001
-From: Petr Matousek
-Date: Wed, 6 May 2015 09:48:59 +0200
-Subject: [PATCH] fdc: force the fifo access to be in bounds of the allocated buffer
+tools: libxl: allow permissive qemu-upstream pci passthrough
-During processing of certain commands such as FD_CMD_READ_ID and
-FD_CMD_DRIVE_SPECIFICATION_COMMAND the fifo memory access could
-get out of bounds leading to memory corruption with values coming
-from the guest.
+Since XSA-131 qemu-xen now restricts access to PCI cfg by default. In
+order to allow local configuration of the existing libxl_device_pci
+"permissive" flag needs to be plumbed through via the new QMP property
+added by the XSA-131 patches.
-Fix this by making sure that the index is always bounded by the
-allocated memory.
+Versions of QEMU prior to XSA-131 did not support this permissive
+property, so we only pass it if it is true. Older versions only
+supported permissive mode.
-This is CVE-2015-3456.
+qemu-xen-traditional already supports the permissive mode setting via
+xenstore.
-Signed-off-by: Petr Matousek
-Reviewed-by: John Snow
----
- hw/block/fdc.c | 17 +++++++++++------
- 1 file changed, 11 insertions(+), 6 deletions(-)
+Signed-off-by: Ian Campbell
-Index: xen-4.2.5-testing/tools/qemu-xen-traditional-dir-remote/hw/fdc.c
-===================================================================
---- xen-4.2.5-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/fdc.c
-+++ xen-4.2.5-testing/tools/qemu-xen-traditional-dir-remote/hw/fdc.c
-@@ -1318,7 +1318,7 @@ static uint32_t fdctrl_read_data (fdctrl
- {
- fdrive_t *cur_drv;
- uint32_t retval = 0;
-- int pos;
-+ uint32_t pos;
-
- cur_drv = get_cur_drv(fdctrl);
- fdctrl->dsr &= ~FD_DSR_PWRDOWN;
-@@ -1327,8 +1327,8 @@ static uint32_t fdctrl_read_data (fdctrl
- return 0;
- }
- pos = fdctrl->data_pos;
-+ pos %= FD_SECTOR_LEN;
- if (fdctrl->msr & FD_MSR_NONDMA) {
-- pos %= FD_SECTOR_LEN;
- if (pos == 0) {
- if (fdctrl->data_pos != 0)
- if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
-@@ -1673,10 +1673,13 @@ static void fdctrl_handle_option (fdctrl
- static void fdctrl_handle_drive_specification_command (fdctrl_t *fdctrl, int direction)
- {
- fdrive_t *cur_drv = get_cur_drv(fdctrl);
-+ uint32_t pos;
-
-- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {
-+ pos = fdctrl->data_pos - 1;
-+ pos %= FD_SECTOR_LEN;
-+ if (fdctrl->fifo[pos] & 0x80) {
- /* Command parameters done */
-- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {
-+ if (fdctrl->fifo[pos] & 0x40) {
- fdctrl->fifo[0] = fdctrl->fifo[1];
- fdctrl->fifo[2] = 0;
- fdctrl->fifo[3] = 0;
-@@ -1771,7 +1774,7 @@ static uint8_t command_to_handler[256];
- static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value)
- {
- fdrive_t *cur_drv;
-- int pos;
-+ uint32_t pos;
-
- /* Reset mode */
- if (!(fdctrl->dor & FD_DOR_nRESET)) {
-@@ -1817,7 +1820,9 @@ static void fdctrl_write_data (fdctrl_t
+--- a/tools/libxl/libxl_qmp.c
++++ b/tools/libxl/libxl_qmp.c
+@@ -835,6 +835,18 @@ int libxl__qmp_pci_add(libxl__gc *gc, in
+ QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x",
+ PCI_SLOT(pcidev->vdevfn), PCI_FUNC(pcidev->vdevfn));
}
++ /*
++ * Version of QEMU prior to the XSA-131 fix did not support this
++ * property and were effectively always in permissive mode. The
++ * fix for XSA-131 switched the default to be restricted by
++ * default and added the permissive property.
++ *
++ * Therefore in order to support both old and new QEMU we only set
++ * the permissive flag if it is true. Users of older QEMU have no
++ * reason to set the flag so this is ok.
++ */
++ if (pcidev->permissive)
++ qmp_parameters_add_bool(gc, &args, "permissive", true);
- FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
-- fdctrl->fifo[fdctrl->data_pos++] = value;
-+ pos = fdctrl->data_pos++;
-+ pos %= FD_SECTOR_LEN;
-+ fdctrl->fifo[pos] = value;
- if (fdctrl->data_pos == fdctrl->data_len) {
- /* We now have all parameters
- * and will be able to treat the command
+ rc = qmp_synchronous_send(qmp, "device_add", args,
+ NULL, NULL, qmp->timeout);
++++++ blktap-no-uninit.patch ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:50:54.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:50:54.000000000 +0200
@@ -1,10 +1,12 @@
--- xen-4.5.0-testing/tools/blktap/drivers/Makefile.orig 2015-04-08 09:20:08.817373085 +0000
+++ xen-4.5.0-testing/tools/blktap/drivers/Makefile 2015-04-08 09:20:55.738897365 +0000
-@@ -6,6 +6,7 @@
+@@ -6,6 +6,9 @@
CFLAGS += -Werror
CFLAGS += -Wno-unused
-+CFLAGS += -Wno-error=maybe-uninitialized
++ifeq ($(call cc-ver,$(CC),0x040900),y)
++$(call cc-option-add,CFLAGS,CC,-Wno-error=maybe-uninitialized)
++endif
CFLAGS += -I../lib
CFLAGS += $(CFLAGS_libxenctrl)
CFLAGS += $(CFLAGS_libxenstore)
@@ -14,7 +16,7 @@
CFLAGS += -Werror
CFLAGS += -Wno-unused
-+CFLAGS += -Wno-error=array-bounds
++$(call cc-option-add,CFLAGS,CC,-Wno-error=array-bounds)
CFLAGS += -fno-strict-aliasing
CFLAGS += -I$(BLKTAP_ROOT)/include -I$(BLKTAP_ROOT)/drivers
CFLAGS += $(CFLAGS_libxenctrl)
++++++ blktap-pv-cdrom.patch ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:50:54.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:50:54.000000000 +0200
@@ -8,11 +8,11 @@
xen/include/public/io/cdromif.h | 122 ++++
7 files changed, 726 insertions(+), 3 deletions(-)
-Index: xen-4.5.0-testing/tools/blktap/drivers/Makefile
+Index: xen-4.5.1-testing/tools/blktap/drivers/Makefile
===================================================================
---- xen-4.5.0-testing.orig/tools/blktap/drivers/Makefile
-+++ xen-4.5.0-testing/tools/blktap/drivers/Makefile
-@@ -33,8 +33,9 @@ AIOLIBS := -laio
+--- xen-4.5.1-testing.orig/tools/blktap/drivers/Makefile
++++ xen-4.5.1-testing/tools/blktap/drivers/Makefile
+@@ -35,8 +35,9 @@ AIOLIBS := -laio
CFLAGS += $(PTHREAD_CFLAGS)
LDFLAGS += $(PTHREAD_LDFLAGS)
@@ -24,7 +24,7 @@
BLK-OBJS-y := block-aio.o
BLK-OBJS-y += block-sync.o
-@@ -42,6 +43,7 @@ BLK-OBJS-y += block-vmdk.o
+@@ -44,6 +45,7 @@ BLK-OBJS-y += block-vmdk.o
BLK-OBJS-y += block-ram.o
BLK-OBJS-y += block-qcow.o
BLK-OBJS-y += block-qcow2.o
@@ -32,10 +32,10 @@
BLK-OBJS-y += aes.o
BLK-OBJS-y += tapaio.o
BLK-OBJS-$(CONFIG_Linux) += blk_linux.o
-Index: xen-4.5.0-testing/tools/blktap/drivers/block-cdrom.c
+Index: xen-4.5.1-testing/tools/blktap/drivers/block-cdrom.c
===================================================================
--- /dev/null
-+++ xen-4.5.0-testing/tools/blktap/drivers/block-cdrom.c
++++ xen-4.5.1-testing/tools/blktap/drivers/block-cdrom.c
@@ -0,0 +1,568 @@
+/* block-cdrom.c
+ *
@@ -605,10 +605,10 @@
+ .td_get_parent_id = tdcdrom_get_parent_id,
+ .td_validate_parent = tdcdrom_validate_parent
+};
-Index: xen-4.5.0-testing/tools/blktap/drivers/tapdisk.c
+Index: xen-4.5.1-testing/tools/blktap/drivers/tapdisk.c
===================================================================
---- xen-4.5.0-testing.orig/tools/blktap/drivers/tapdisk.c
-+++ xen-4.5.0-testing/tools/blktap/drivers/tapdisk.c
+--- xen-4.5.1-testing.orig/tools/blktap/drivers/tapdisk.c
++++ xen-4.5.1-testing/tools/blktap/drivers/tapdisk.c
@@ -735,6 +735,22 @@ static void get_io_request(struct td_sta
goto out;
}
@@ -632,10 +632,10 @@
default:
DPRINTF("Unknown block operation\n");
break;
-Index: xen-4.5.0-testing/tools/blktap/drivers/tapdisk.h
+Index: xen-4.5.1-testing/tools/blktap/drivers/tapdisk.h
===================================================================
---- xen-4.5.0-testing.orig/tools/blktap/drivers/tapdisk.h
-+++ xen-4.5.0-testing/tools/blktap/drivers/tapdisk.h
+--- xen-4.5.1-testing.orig/tools/blktap/drivers/tapdisk.h
++++ xen-4.5.1-testing/tools/blktap/drivers/tapdisk.h
@@ -137,6 +137,9 @@ struct tap_disk {
int (*td_get_parent_id) (struct disk_driver *dd, struct disk_id *id);
int (*td_validate_parent)(struct disk_driver *dd,
@@ -680,10 +680,10 @@
};
typedef struct driver_list_entry {
-Index: xen-4.5.0-testing/tools/blktap/lib/blktaplib.h
+Index: xen-4.5.1-testing/tools/blktap/lib/blktaplib.h
===================================================================
---- xen-4.5.0-testing.orig/tools/blktap/lib/blktaplib.h
-+++ xen-4.5.0-testing/tools/blktap/lib/blktaplib.h
+--- xen-4.5.1-testing.orig/tools/blktap/lib/blktaplib.h
++++ xen-4.5.1-testing/tools/blktap/lib/blktaplib.h
@@ -219,6 +219,7 @@ typedef struct msg_pid {
#define DISK_TYPE_RAM 3
#define DISK_TYPE_QCOW 4
@@ -692,10 +692,10 @@
/* xenstore/xenbus: */
#define DOMNAME "Domain-0"
-Index: xen-4.5.0-testing/xen/include/public/io/blkif.h
+Index: xen-4.5.1-testing/xen/include/public/io/blkif.h
===================================================================
---- xen-4.5.0-testing.orig/xen/include/public/io/blkif.h
-+++ xen-4.5.0-testing/xen/include/public/io/blkif.h
+--- xen-4.5.1-testing.orig/xen/include/public/io/blkif.h
++++ xen-4.5.1-testing/xen/include/public/io/blkif.h
@@ -485,7 +485,7 @@
* Used in SLES sources for device specific command packet
* contained within the request. Reserved for that purpose.
@@ -705,10 +705,10 @@
/*
* Indicate to the backend device that a region of storage is no longer in
* use, and may be discarded at any time without impact to the client. If
-Index: xen-4.5.0-testing/xen/include/public/io/cdromif.h
+Index: xen-4.5.1-testing/xen/include/public/io/cdromif.h
===================================================================
--- /dev/null
-+++ xen-4.5.0-testing/xen/include/public/io/cdromif.h
++++ xen-4.5.1-testing/xen/include/public/io/cdromif.h
@@ -0,0 +1,122 @@
+/******************************************************************************
+ * cdromif.h
++++++ ipxe.tar.bz2 ++++++
Files old/tools/firmware/etherboot/_ipxe.tar.gz and new/tools/firmware/etherboot/_ipxe.tar.gz differ
Files old/tools/firmware/etherboot/ipxe.tar.gz and new/tools/firmware/etherboot/ipxe.tar.gz differ
++++++ libxl.add-option-to-disable-disk-cache-flushes-in-qdisk.patch ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:50:55.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:50:55.000000000 +0200
@@ -7,11 +7,11 @@
tools/libxl/libxlu_disk_l.l | 1 +
5 files changed, 18 insertions(+), 1 deletion(-)
-Index: xen-4.5.0-testing/tools/libxl/libxl.c
+Index: xen-4.5.1-testing/tools/libxl/libxl.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl.c
-+++ xen-4.5.0-testing/tools/libxl/libxl.c
-@@ -2771,6 +2771,8 @@ static void device_disk_add(libxl__egc *
+--- xen-4.5.1-testing.orig/tools/libxl/libxl.c
++++ xen-4.5.1-testing/tools/libxl/libxl.c
+@@ -2818,6 +2818,8 @@ static void device_disk_add(libxl__egc *
flexarray_append_pair(back, "discard-enable",
libxl_defbool_val(disk->discard_enable) ?
"1" : "0");
@@ -20,10 +20,10 @@
flexarray_append(front, "backend-id");
flexarray_append(front, libxl__sprintf(gc, "%d", disk->backend_domid));
-Index: xen-4.5.0-testing/tools/libxl/libxl.h
+Index: xen-4.5.1-testing/tools/libxl/libxl.h
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl.h
-+++ xen-4.5.0-testing/tools/libxl/libxl.h
+--- xen-4.5.1-testing.orig/tools/libxl/libxl.h
++++ xen-4.5.1-testing/tools/libxl/libxl.h
@@ -163,6 +163,18 @@
#define LIBXL_HAVE_BUILDINFO_HVM_MMIO_HOLE_MEMKB 1
@@ -43,10 +43,10 @@
* libxl ABI compatibility
*
* The only guarantee which libxl makes regarding ABI compatibility
-Index: xen-4.5.0-testing/tools/libxl/libxlu_disk.c
+Index: xen-4.5.1-testing/tools/libxl/libxlu_disk.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxlu_disk.c
-+++ xen-4.5.0-testing/tools/libxl/libxlu_disk.c
+--- xen-4.5.1-testing.orig/tools/libxl/libxlu_disk.c
++++ xen-4.5.1-testing/tools/libxl/libxlu_disk.c
@@ -79,6 +79,8 @@ int xlu_disk_parse(XLU_Config *cfg,
if (!disk->pdev_path || !strcmp(disk->pdev_path, ""))
disk->format = LIBXL_DISK_FORMAT_EMPTY;
@@ -56,10 +56,10 @@
if (!disk->vdev) {
xlu__disk_err(&dpc,0, "no vdev specified");
-Index: xen-4.5.0-testing/tools/libxl/libxlu_disk_i.h
+Index: xen-4.5.1-testing/tools/libxl/libxlu_disk_i.h
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxlu_disk_i.h
-+++ xen-4.5.0-testing/tools/libxl/libxlu_disk_i.h
+--- xen-4.5.1-testing.orig/tools/libxl/libxlu_disk_i.h
++++ xen-4.5.1-testing/tools/libxl/libxlu_disk_i.h
@@ -10,7 +10,7 @@ typedef struct {
void *scanner;
YY_BUFFER_STATE buf;
@@ -69,10 +69,10 @@
const char *spec;
} DiskParseContext;
-Index: xen-4.5.0-testing/tools/libxl/libxlu_disk_l.l
+Index: xen-4.5.1-testing/tools/libxl/libxlu_disk_l.l
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxlu_disk_l.l
-+++ xen-4.5.0-testing/tools/libxl/libxlu_disk_l.l
+--- xen-4.5.1-testing.orig/tools/libxl/libxlu_disk_l.l
++++ xen-4.5.1-testing/tools/libxl/libxlu_disk_l.l
@@ -176,6 +176,7 @@ script=[^,]*,? { STRIP(','); SAVESTRING(
direct-io-safe,? { DPC->disk->direct_io_safe = 1; }
discard,? { libxl_defbool_set(&DPC->disk->discard_enable, true); }
++++++ libxl.pvscsi.patch ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:50:55.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:50:55.000000000 +0200
@@ -31,10 +31,10 @@
7de6f49 support character devices too
c84381b allow /dev/sda as scsi devspec
f11e3a2 pvscsi
-Index: xen-4.5.0-testing/docs/man/xl.cfg.pod.5
+Index: xen-4.5.1-testing/docs/man/xl.cfg.pod.5
===================================================================
---- xen-4.5.0-testing.orig/docs/man/xl.cfg.pod.5
-+++ xen-4.5.0-testing/docs/man/xl.cfg.pod.5
+--- xen-4.5.1-testing.orig/docs/man/xl.cfg.pod.5
++++ xen-4.5.1-testing/docs/man/xl.cfg.pod.5
@@ -448,6 +448,36 @@ value is optional if this is a guest dom
=back
@@ -72,10 +72,10 @@
=item B
Specifies the paravirtual framebuffer devices which should be supplied
-Index: xen-4.5.0-testing/docs/man/xl.pod.1
+Index: xen-4.5.1-testing/docs/man/xl.pod.1
===================================================================
---- xen-4.5.0-testing.orig/docs/man/xl.pod.1
-+++ xen-4.5.0-testing/docs/man/xl.pod.1
+--- xen-4.5.1-testing.orig/docs/man/xl.pod.1
++++ xen-4.5.1-testing/docs/man/xl.pod.1
@@ -1323,6 +1323,26 @@ List virtual trusted platform modules fo
=back
@@ -103,11 +103,11 @@
=head1 PCI PASS-THROUGH
=over 4
-Index: xen-4.5.0-testing/tools/libxl/libxl.c
+Index: xen-4.5.1-testing/tools/libxl/libxl.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl.c
-+++ xen-4.5.0-testing/tools/libxl/libxl.c
-@@ -2263,6 +2263,273 @@ int libxl_devid_to_device_vtpm(libxl_ctx
+--- xen-4.5.1-testing.orig/tools/libxl/libxl.c
++++ xen-4.5.1-testing/tools/libxl/libxl.c
+@@ -2310,6 +2310,273 @@ int libxl_devid_to_device_vtpm(libxl_ctx
return rc;
}
@@ -381,7 +381,7 @@
/******************************************************************************/
-@@ -4138,6 +4405,8 @@ out:
+@@ -4185,6 +4452,8 @@ out:
* libxl_device_vkb_destroy
* libxl_device_vfb_remove
* libxl_device_vfb_destroy
@@ -390,7 +390,7 @@
*/
#define DEFINE_DEVICE_REMOVE(type, removedestroy, f) \
int libxl_device_##type##_##removedestroy(libxl_ctx *ctx, \
-@@ -4193,6 +4462,10 @@ DEFINE_DEVICE_REMOVE(vtpm, destroy, 1)
+@@ -4240,6 +4509,10 @@ DEFINE_DEVICE_REMOVE(vtpm, destroy, 1)
* 1. add support for secondary consoles to xenconsoled
* 2. dynamically add/remove qemu chardevs via qmp messages. */
@@ -401,7 +401,7 @@
#undef DEFINE_DEVICE_REMOVE
/******************************************************************************/
-@@ -4202,6 +4475,7 @@ DEFINE_DEVICE_REMOVE(vtpm, destroy, 1)
+@@ -4249,6 +4522,7 @@ DEFINE_DEVICE_REMOVE(vtpm, destroy, 1)
* libxl_device_disk_add
* libxl_device_nic_add
* libxl_device_vtpm_add
@@ -409,7 +409,7 @@
*/
#define DEFINE_DEVICE_ADD(type) \
-@@ -4233,6 +4507,9 @@ DEFINE_DEVICE_ADD(nic)
+@@ -4280,6 +4554,9 @@ DEFINE_DEVICE_ADD(nic)
/* vtpm */
DEFINE_DEVICE_ADD(vtpm)
@@ -419,7 +419,7 @@
#undef DEFINE_DEVICE_ADD
/******************************************************************************/
-@@ -6769,6 +7046,20 @@ out:
+@@ -6822,6 +7099,20 @@ out:
return rc;
}
@@ -440,11 +440,11 @@
/*
* Local variables:
* mode: C
-Index: xen-4.5.0-testing/tools/libxl/libxl.h
+Index: xen-4.5.1-testing/tools/libxl/libxl.h
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl.h
-+++ xen-4.5.0-testing/tools/libxl/libxl.h
-@@ -1228,6 +1228,26 @@ libxl_device_vtpm *libxl_device_vtpm_lis
+--- xen-4.5.1-testing.orig/tools/libxl/libxl.h
++++ xen-4.5.1-testing/tools/libxl/libxl.h
+@@ -1238,6 +1238,26 @@ libxl_device_vtpm *libxl_device_vtpm_lis
int libxl_device_vtpm_getinfo(libxl_ctx *ctx, uint32_t domid,
libxl_device_vtpm *vtpm, libxl_vtpminfo *vtpminfo);
@@ -471,7 +471,7 @@
/* Keyboard */
int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb,
const libxl_asyncop_how *ao_how)
-@@ -1485,6 +1505,27 @@ int libxl_fd_set_nonblock(libxl_ctx *ctx
+@@ -1495,6 +1515,27 @@ int libxl_fd_set_nonblock(libxl_ctx *ctx
#include
@@ -499,10 +499,10 @@
#endif /* LIBXL_H */
/*
-Index: xen-4.5.0-testing/tools/libxl/libxl_create.c
+Index: xen-4.5.1-testing/tools/libxl/libxl_create.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_create.c
-+++ xen-4.5.0-testing/tools/libxl/libxl_create.c
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_create.c
++++ xen-4.5.1-testing/tools/libxl/libxl_create.c
@@ -1141,6 +1141,7 @@ static void domcreate_rebuild_done(libxl
libxl__multidev_begin(ao, &dcs->multidev);
dcs->multidev.callback = domcreate_launch_dm;
@@ -511,10 +511,10 @@
libxl__multidev_prepared(egc, &dcs->multidev, 0);
return;
-Index: xen-4.5.0-testing/tools/libxl/libxl_device.c
+Index: xen-4.5.1-testing/tools/libxl/libxl_device.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_device.c
-+++ xen-4.5.0-testing/tools/libxl/libxl_device.c
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_device.c
++++ xen-4.5.1-testing/tools/libxl/libxl_device.c
@@ -541,6 +541,7 @@ void libxl__multidev_prepared(libxl__egc
* The following functions are defined:
* libxl__add_disks
@@ -556,10 +556,10 @@
/******************************************************************************/
int libxl__device_destroy(libxl__gc *gc, libxl__device *dev)
-Index: xen-4.5.0-testing/tools/libxl/libxl_internal.h
+Index: xen-4.5.1-testing/tools/libxl/libxl_internal.h
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_internal.h
-+++ xen-4.5.0-testing/tools/libxl/libxl_internal.h
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_internal.h
++++ xen-4.5.1-testing/tools/libxl/libxl_internal.h
@@ -1079,6 +1079,7 @@ _hidden int libxl__device_disk_setdefaul
_hidden int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
uint32_t domid);
@@ -579,7 +579,7 @@
/* Internal function to connect a vkb device */
_hidden int libxl__device_vkb_add(libxl__gc *gc, uint32_t domid,
libxl_device_vkb *vkb);
-@@ -3013,6 +3018,10 @@ _hidden void libxl__add_vtpms(libxl__egc
+@@ -3014,6 +3019,10 @@ _hidden void libxl__add_vtpms(libxl__egc
libxl_domain_config *d_config,
libxl__multidev *multidev);
@@ -590,10 +590,10 @@
/*----- device model creation -----*/
/* First layer; wraps libxl__spawn_spawn. */
-Index: xen-4.5.0-testing/tools/libxl/libxl_types.idl
+Index: xen-4.5.1-testing/tools/libxl/libxl_types.idl
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_types.idl
-+++ xen-4.5.0-testing/tools/libxl/libxl_types.idl
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_types.idl
++++ xen-4.5.1-testing/tools/libxl/libxl_types.idl
@@ -540,6 +540,26 @@ libxl_device_channel = Struct("device_ch
])),
])
@@ -659,10 +659,10 @@
libxl_vcpuinfo = Struct("vcpuinfo", [
("vcpuid", uint32),
("cpu", uint32),
-Index: xen-4.5.0-testing/tools/libxl/libxl_types_internal.idl
+Index: xen-4.5.1-testing/tools/libxl/libxl_types_internal.idl
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_types_internal.idl
-+++ xen-4.5.0-testing/tools/libxl/libxl_types_internal.idl
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_types_internal.idl
++++ xen-4.5.1-testing/tools/libxl/libxl_types_internal.idl
@@ -22,6 +22,7 @@ libxl__device_kind = Enumeration("device
(6, "VKBD"),
(7, "CONSOLE"),
@@ -671,10 +671,10 @@
])
libxl__console_backend = Enumeration("console_backend", [
-Index: xen-4.5.0-testing/tools/libxl/xl.h
+Index: xen-4.5.1-testing/tools/libxl/xl.h
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/xl.h
-+++ xen-4.5.0-testing/tools/libxl/xl.h
+--- xen-4.5.1-testing.orig/tools/libxl/xl.h
++++ xen-4.5.1-testing/tools/libxl/xl.h
@@ -83,6 +83,9 @@ int main_channellist(int argc, char **ar
int main_blockattach(int argc, char **argv);
int main_blocklist(int argc, char **argv);
@@ -685,10 +685,10 @@
int main_vtpmattach(int argc, char **argv);
int main_vtpmlist(int argc, char **argv);
int main_vtpmdetach(int argc, char **argv);
-Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
+Index: xen-4.5.1-testing/tools/libxl/xl_cmdimpl.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/xl_cmdimpl.c
-+++ xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
+--- xen-4.5.1-testing.orig/tools/libxl/xl_cmdimpl.c
++++ xen-4.5.1-testing/tools/libxl/xl_cmdimpl.c
@@ -17,6 +17,7 @@
#include "libxl_osdeps.h"
@@ -1161,10 +1161,10 @@
int main_vtpmattach(int argc, char **argv)
{
int opt;
-Index: xen-4.5.0-testing/tools/libxl/xl_cmdtable.c
+Index: xen-4.5.1-testing/tools/libxl/xl_cmdtable.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/xl_cmdtable.c
-+++ xen-4.5.0-testing/tools/libxl/xl_cmdtable.c
+--- xen-4.5.1-testing.orig/tools/libxl/xl_cmdtable.c
++++ xen-4.5.1-testing/tools/libxl/xl_cmdtable.c
@@ -372,6 +372,21 @@ struct cmd_spec cmd_table[] = {
"Destroy a domain's virtual block device",
"<Domain> <DevId>",
++++++ libxl.set-migration-constraints-from-cmdline.patch ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:50:55.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:50:55.000000000 +0200
@@ -88,10 +88,10 @@
tools/libxl/xl_cmdtable.c | 23 ++++++++++++++-------
12 files changed, 159 insertions(+), 21 deletions(-)
-Index: xen-4.5.0-testing/docs/man/xl.pod.1
+Index: xen-4.5.1-testing/docs/man/xl.pod.1
===================================================================
---- xen-4.5.0-testing.orig/docs/man/xl.pod.1
-+++ xen-4.5.0-testing/docs/man/xl.pod.1
+--- xen-4.5.1-testing.orig/docs/man/xl.pod.1
++++ xen-4.5.1-testing/docs/man/xl.pod.1
@@ -428,6 +428,26 @@ Send <config> instead of config file fro
Print huge (!) amount of debug during the migration process.
@@ -119,10 +119,10 @@
=back
=item B<remus> [I<OPTIONS>] I<domain-id> I<host>
-Index: xen-4.5.0-testing/tools/libxc/include/xenguest.h
+Index: xen-4.5.1-testing/tools/libxc/include/xenguest.h
===================================================================
---- xen-4.5.0-testing.orig/tools/libxc/include/xenguest.h
-+++ xen-4.5.0-testing/tools/libxc/include/xenguest.h
+--- xen-4.5.1-testing.orig/tools/libxc/include/xenguest.h
++++ xen-4.5.1-testing/tools/libxc/include/xenguest.h
@@ -28,6 +28,7 @@
#define XCFLAGS_HVM (1 << 2)
#define XCFLAGS_STDVGA (1 << 3)
@@ -143,10 +143,10 @@
/* callbacks provided by xc_domain_restore */
struct restore_callbacks {
-Index: xen-4.5.0-testing/tools/libxc/xc_domain_save.c
+Index: xen-4.5.1-testing/tools/libxc/xc_domain_save.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxc/xc_domain_save.c
-+++ xen-4.5.0-testing/tools/libxc/xc_domain_save.c
+--- xen-4.5.1-testing.orig/tools/libxc/xc_domain_save.c
++++ xen-4.5.1-testing/tools/libxc/xc_domain_save.c
@@ -44,6 +44,7 @@
*/
#define DEF_MAX_ITERS 29 /* limit us to 30 times round loop */
@@ -219,10 +219,10 @@
/*
* Local variables:
* mode: C
-Index: xen-4.5.0-testing/tools/libxc/xc_nomigrate.c
+Index: xen-4.5.1-testing/tools/libxc/xc_nomigrate.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxc/xc_nomigrate.c
-+++ xen-4.5.0-testing/tools/libxc/xc_nomigrate.c
+--- xen-4.5.1-testing.orig/tools/libxc/xc_nomigrate.c
++++ xen-4.5.1-testing/tools/libxc/xc_nomigrate.c
@@ -21,6 +21,15 @@
#include
#include
@@ -239,10 +239,10 @@
int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
uint32_t max_factor, uint32_t flags,
struct save_callbacks* callbacks, int hvm)
-Index: xen-4.5.0-testing/tools/libxl/libxl.c
+Index: xen-4.5.1-testing/tools/libxl/libxl.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl.c
-+++ xen-4.5.0-testing/tools/libxl/libxl.c
+--- xen-4.5.1-testing.orig/tools/libxl/libxl.c
++++ xen-4.5.1-testing/tools/libxl/libxl.c
@@ -944,7 +944,8 @@ static void domain_suspend_cb(libxl__egc
}
@@ -291,11 +291,11 @@
int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid)
{
int ret;
-Index: xen-4.5.0-testing/tools/libxl/libxl.h
+Index: xen-4.5.1-testing/tools/libxl/libxl.h
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl.h
-+++ xen-4.5.0-testing/tools/libxl/libxl.h
-@@ -949,8 +949,23 @@ int libxl_domain_suspend(libxl_ctx *ctx,
+--- xen-4.5.1-testing.orig/tools/libxl/libxl.h
++++ xen-4.5.1-testing/tools/libxl/libxl.h
+@@ -959,8 +959,23 @@ int libxl_domain_suspend(libxl_ctx *ctx,
int flags, /* LIBXL_SUSPEND_* */
const libxl_asyncop_how *ao_how)
LIBXL_EXTERNAL_CALLERS_ONLY;
@@ -319,10 +319,10 @@
/* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )]
* If this parameter is true, use co-operative resume. The guest
-Index: xen-4.5.0-testing/tools/libxl/libxl_dom.c
+Index: xen-4.5.1-testing/tools/libxl/libxl_dom.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_dom.c
-+++ xen-4.5.0-testing/tools/libxl/libxl_dom.c
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_dom.c
++++ xen-4.5.1-testing/tools/libxl/libxl_dom.c
@@ -1808,6 +1808,7 @@ void libxl__domain_suspend(libxl__egc *e
dss->xcflags = (live ? XCFLAGS_LIVE : 0)
@@ -331,10 +331,10 @@
| (dss->hvm ? XCFLAGS_HVM : 0);
dss->guest_evtchn.port = -1;
-Index: xen-4.5.0-testing/tools/libxl/libxl_internal.h
+Index: xen-4.5.1-testing/tools/libxl/libxl_internal.h
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_internal.h
-+++ xen-4.5.0-testing/tools/libxl/libxl_internal.h
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_internal.h
++++ xen-4.5.1-testing/tools/libxl/libxl_internal.h
@@ -2803,6 +2803,10 @@ struct libxl__domain_suspend_state {
libxl__ev_evtchn guest_evtchn;
int guest_evtchn_lockfd;
@@ -346,10 +346,10 @@
int xcflags;
int guest_responded;
libxl__xswait_state pvcontrol;
-Index: xen-4.5.0-testing/tools/libxl/libxl_save_callout.c
+Index: xen-4.5.1-testing/tools/libxl/libxl_save_callout.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_save_callout.c
-+++ xen-4.5.0-testing/tools/libxl/libxl_save_callout.c
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_save_callout.c
++++ xen-4.5.1-testing/tools/libxl/libxl_save_callout.c
@@ -110,7 +110,9 @@ void libxl__xc_domain_save(libxl__egc *e
}
@@ -361,10 +361,10 @@
toolstack_data_fd, toolstack_data_len,
cbflags,
};
-Index: xen-4.5.0-testing/tools/libxl/libxl_save_helper.c
+Index: xen-4.5.1-testing/tools/libxl/libxl_save_helper.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl_save_helper.c
-+++ xen-4.5.0-testing/tools/libxl/libxl_save_helper.c
+--- xen-4.5.1-testing.orig/tools/libxl/libxl_save_helper.c
++++ xen-4.5.1-testing/tools/libxl/libxl_save_helper.c
@@ -215,6 +215,7 @@ int main(int argc, char **argv)
uint32_t dom = strtoul(NEXTARG,0,10);
uint32_t max_iters = strtoul(NEXTARG,0,10);
@@ -383,10 +383,10 @@
&helper_save_callbacks, hvm);
complete(r);
-Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
+Index: xen-4.5.1-testing/tools/libxl/xl_cmdimpl.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/xl_cmdimpl.c
-+++ xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
+--- xen-4.5.1-testing.orig/tools/libxl/xl_cmdimpl.c
++++ xen-4.5.1-testing/tools/libxl/xl_cmdimpl.c
@@ -3880,6 +3880,8 @@ static void migrate_do_preamble(int send
}
@@ -477,10 +477,10 @@
return 0;
}
#endif
-Index: xen-4.5.0-testing/tools/libxl/xl_cmdtable.c
+Index: xen-4.5.1-testing/tools/libxl/xl_cmdtable.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/xl_cmdtable.c
-+++ xen-4.5.0-testing/tools/libxl/xl_cmdtable.c
+--- xen-4.5.1-testing.orig/tools/libxl/xl_cmdtable.c
++++ xen-4.5.1-testing/tools/libxl/xl_cmdtable.c
@@ -155,14 +155,21 @@ struct cmd_spec cmd_table[] = {
&main_migrate, 0, 1,
"Migrate a domain to another host",
++++++ local_attach_support_for_phy.patch ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:50:55.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:50:55.000000000 +0200
@@ -10,11 +10,11 @@
Suggested-by: Ian Campbell
-Index: xen-4.5.0-testing/tools/libxl/libxl.c
+Index: xen-4.5.1-testing/tools/libxl/libxl.c
===================================================================
---- xen-4.5.0-testing.orig/tools/libxl/libxl.c
-+++ xen-4.5.0-testing/tools/libxl/libxl.c
-@@ -3006,6 +3006,16 @@ void libxl__device_disk_local_initiate_a
+--- xen-4.5.1-testing.orig/tools/libxl/libxl.c
++++ xen-4.5.1-testing/tools/libxl/libxl.c
+@@ -3053,6 +3053,16 @@ void libxl__device_disk_local_initiate_a
switch (disk->backend) {
case LIBXL_DISK_BACKEND_PHY:
@@ -31,7 +31,7 @@
LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "locally attaching PHY disk %s",
disk->pdev_path);
dev = disk->pdev_path;
-@@ -3085,7 +3095,7 @@ static void local_device_attach_cb(libxl
+@@ -3132,7 +3142,7 @@ static void local_device_attach_cb(libxl
}
dev = GCSPRINTF("/dev/%s", disk->vdev);
@@ -40,7 +40,7 @@
rc = libxl__device_from_disk(gc, LIBXL_TOOLSTACK_DOMID, disk, &device);
if (rc < 0)
-@@ -3125,6 +3135,7 @@ void libxl__device_disk_local_initiate_d
+@@ -3172,6 +3182,7 @@ void libxl__device_disk_local_initiate_d
if (!dls->diskpath) goto out;
switch (disk->backend) {
@@ -48,7 +48,7 @@
case LIBXL_DISK_BACKEND_QDISK:
if (disk->vdev != NULL) {
GCNEW(device);
-@@ -3142,7 +3153,6 @@ void libxl__device_disk_local_initiate_d
+@@ -3189,7 +3200,6 @@ void libxl__device_disk_local_initiate_d
/* disk->vdev == NULL; fall through */
default:
/*
++++++ qemu-MSI-X-enable-maskall.patch ++++++
References: bsc#907514 bsc#910258 bsc#918984 bsc#923967
xen/MSI-X: drive maskall and enable bits through hypercalls
Particularly the maskall bit has to be under exclusive hypervisor
control (and since they live in the same config space field, the
enable bit has to follow suit). Use the replacement hypercall
interfaces.
Signed-off-by: Jan Beulich
Index: xen-4.5.1-testing/tools/qemu-xen-traditional-dir-remote/hw/pass-through.c
===================================================================
--- xen-4.5.1-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pass-through.c
+++ xen-4.5.1-testing/tools/qemu-xen-traditional-dir-remote/hw/pass-through.c
@@ -814,9 +814,12 @@ static struct pt_reg_info_tbl pt_emu_reg
.offset = PCI_MSI_FLAGS, // 2
.size = 2,
.init_val = 0x0000,
- .res_mask = 0x3800,
- .ro_mask = 0x07FF,
- .emu_mask = 0x0000,
+ /* This must not be split into res_mask (0x3800) and ro_mask (0x07FF)
+ * because even in permissive mode there must not be any write back
+ * to this register.
+ */
+ .ro_mask = 0x3FFF,
+ .emu_mask = 0xC000,
.init = pt_msixctrl_reg_init,
.u.w.read = pt_word_reg_read,
.u.w.write = pt_msixctrl_reg_write,
@@ -4135,30 +4138,52 @@ static int pt_msixctrl_reg_write(struct
uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
+ uint16_t writable_mask, val;
uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
uint16_t old_ctrl = cfg_entry->data;
/* modify emulate register */
writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
+ val = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
+ cfg_entry->data = val;
/* create value for writing to I/O device register */
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
/* update MSI-X */
- if ((*value & PCI_MSIX_ENABLE) && !(*value & PCI_MSIX_MASK))
+ if ((val & PCI_MSIX_ENABLE) && !(val & PCI_MSIX_MASK))
{
if (ptdev->msi_trans_en) {
PT_LOG("guest enabling MSI-X, disable MSI-INTx translation\n");
pt_disable_msi_translate(ptdev);
}
+ if (!ptdev->msix->enabled) {
+ if (!ptdev->msix->maskall)
+ pt_msix_maskall(ptdev, 1);
+ pt_msix_enable(ptdev);
+ }
pt_msix_update(ptdev);
- } else if (!(*value & PCI_MSIX_ENABLE) && ptdev->msix->enabled) {
- pt_msix_disable(ptdev);
+ ptdev->msix->enabled = 1;
+ ptdev->msix->maskall = 0;
+ pt_msix_maskall(ptdev, 0);
+ } else if (ptdev->msix->enabled) {
+ if (!(val & PCI_MSIX_ENABLE)) {
+ pt_msix_disable(ptdev);
+ ptdev->msix->enabled = 0;
+ } else if (!ptdev->msix->maskall) {
+ ptdev->msix->maskall = 1;
+ pt_msix_maskall(ptdev, 1);
+ }
}
- ptdev->msix->enabled = !!(*value & PCI_MSIX_ENABLE);
+ dev_value = pci_read_word(ptdev->pci_dev, ptdev->msix->ctrl_offset);
+
+ if (ptdev->msix->enabled && !(dev_value & PCI_MSIX_ENABLE))
+ PT_ERR("MSI-X unexpectedly disabled\n");
+ else if ((dev_value & PCI_MSIX_ENABLE) &&
+ ptdev->msix->maskall &&
+ !(dev_value & PCI_MSIX_MASK))
+ PT_ERR("MSI-X unexpectedly unmasked\n");
return 0;
}
Index: xen-4.5.1-testing/tools/qemu-xen-traditional-dir-remote/hw/pass-through.h
===================================================================
--- xen-4.5.1-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pass-through.h
+++ xen-4.5.1-testing/tools/qemu-xen-traditional-dir-remote/hw/pass-through.h
@@ -206,6 +206,7 @@ struct msix_entry_info {
struct pt_msix_info {
uint32_t ctrl_offset;
int enabled;
+ int maskall;
int total_entries;
int bar_index;
uint64_t table_base;
Index: xen-4.5.1-testing/tools/qemu-xen-traditional-dir-remote/hw/pt-msi.c
===================================================================
--- xen-4.5.1-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pt-msi.c
+++ xen-4.5.1-testing/tools/qemu-xen-traditional-dir-remote/hw/pt-msi.c
@@ -41,20 +41,12 @@ void msi_set_enable(struct pt_dev *dev,
static void msix_set_enable(struct pt_dev *dev, int en)
{
- uint16_t val = 0;
- uint32_t address = 0;
if (!dev->msix)
return;
- address = dev->msix->ctrl_offset;
- if (!address)
- return;
-
- val = pci_read_word(dev->pci_dev, address);
- val &= ~PCI_MSIX_ENABLE;
- if (en)
- val |= PCI_MSIX_ENABLE;
- pci_write_word(dev->pci_dev, address, val);
+ xc_physdev_msix_enable(xc_handle, dev->pci_dev->domain, dev->pci_dev->bus,
+ PCI_DEVFN(dev->pci_dev->dev, dev->pci_dev->func),
+ en);
}
/* MSI virtuailization functions */
@@ -349,6 +341,11 @@ int pt_msix_update(struct pt_dev *dev)
return 0;
}
+void pt_msix_enable(struct pt_dev *dev)
+{
+ msix_set_enable(dev, 1);
+}
+
void pt_msix_disable(struct pt_dev *dev)
{
PCIDevice *d = &dev->dev;
@@ -394,6 +391,15 @@ void pt_msix_disable(struct pt_dev *dev)
}
}
+int pt_msix_maskall(struct pt_dev *dev, int mask)
+{
+ return xc_physdev_msix_mask_all(xc_handle, dev->pci_dev->domain,
+ dev->pci_dev->bus,
+ PCI_DEVFN(dev->pci_dev->dev,
+ dev->pci_dev->func),
+ mask);
+}
+
int pt_msix_update_remap(struct pt_dev *dev, int bar_index)
{
struct msix_entry_info *entry;
Index: xen-4.5.1-testing/tools/qemu-xen-traditional-dir-remote/hw/pt-msi.h
===================================================================
--- xen-4.5.1-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pt-msi.h
+++ xen-4.5.1-testing/tools/qemu-xen-traditional-dir-remote/hw/pt-msi.h
@@ -106,9 +106,15 @@ int
pt_msix_update(struct pt_dev *dev);
void
+pt_msix_enable(struct pt_dev *dev);
+
+void
pt_msix_disable(struct pt_dev *dev);
int
+pt_msix_maskall(struct pt_dev *dev, int mask);
+
+int
has_msix_mapping(struct pt_dev *dev, int bar_index);
int
Index: xen-4.5.1-testing/tools/qemu-xen-dir-remote/hw/xen/xen_pt.h
===================================================================
--- xen-4.5.1-testing.orig/tools/qemu-xen-dir-remote/hw/xen/xen_pt.h
+++ xen-4.5.1-testing/tools/qemu-xen-dir-remote/hw/xen/xen_pt.h
@@ -181,6 +181,7 @@ typedef struct XenPTMSIXEntry {
typedef struct XenPTMSIX {
uint32_t ctrl_offset;
bool enabled;
+ bool maskall;
int total_entries;
int bar_index;
uint64_t table_base;
@@ -293,7 +294,9 @@ int xen_pt_msix_init(XenPCIPassthroughSt
void xen_pt_msix_delete(XenPCIPassthroughState *s);
int xen_pt_msix_update(XenPCIPassthroughState *s);
int xen_pt_msix_update_remap(XenPCIPassthroughState *s, int bar_index);
+void xen_pt_msix_enable(XenPCIPassthroughState *s);
void xen_pt_msix_disable(XenPCIPassthroughState *s);
+int xen_pt_msix_maskall(XenPCIPassthroughState *s, bool mask);
static inline bool xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar)
{
Index: xen-4.5.1-testing/tools/qemu-xen-dir-remote/hw/xen/xen_pt_config_init.c
===================================================================
--- xen-4.5.1-testing.orig/tools/qemu-xen-dir-remote/hw/xen/xen_pt_config_init.c
+++ xen-4.5.1-testing/tools/qemu-xen-dir-remote/hw/xen/xen_pt_config_init.c
@@ -1436,32 +1436,58 @@ static int xen_pt_msixctrl_reg_write(Xen
uint16_t dev_value, uint16_t valid_mask)
{
XenPTRegInfo *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
+ uint16_t writable_mask, value;
uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
int debug_msix_enabled_old;
/* modify emulate register */
writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
+ value = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
+ cfg_entry->data = value;
/* create value for writing to I/O device register */
*val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
+ debug_msix_enabled_old = s->msix->enabled;
+
/* update MSI-X */
- if ((*val & PCI_MSIX_FLAGS_ENABLE)
- && !(*val & PCI_MSIX_FLAGS_MASKALL)) {
+ if ((value & PCI_MSIX_FLAGS_ENABLE)
+ && !(value & PCI_MSIX_FLAGS_MASKALL)) {
+ if (!s->msix->enabled) {
+ if (!s->msix->maskall) {
+ xen_pt_msix_maskall(s, true);
+ }
+ xen_pt_msix_enable(s);
+ }
xen_pt_msix_update(s);
- } else if (!(*val & PCI_MSIX_FLAGS_ENABLE) && s->msix->enabled) {
- xen_pt_msix_disable(s);
+ s->msix->enabled = true;
+ s->msix->maskall = false;
+ xen_pt_msix_maskall(s, false);
+ } else if (s->msix->enabled) {
+ if (!(value & PCI_MSIX_FLAGS_ENABLE)) {
+ xen_pt_msix_disable(s);
+ s->msix->enabled = false;
+ } else if (!s->msix->maskall) {
+ s->msix->maskall = true;
+ xen_pt_msix_maskall(s, true);
+ }
}
- debug_msix_enabled_old = s->msix->enabled;
- s->msix->enabled = !!(*val & PCI_MSIX_FLAGS_ENABLE);
if (s->msix->enabled != debug_msix_enabled_old) {
XEN_PT_LOG(&s->dev, "%s MSI-X\n",
s->msix->enabled ? "enable" : "disable");
}
+ xen_host_pci_get_word(&s->real_device, s->msix->ctrl_offset, &dev_value);
+
+ if (s->msix->enabled && !(dev_value & PCI_MSIX_FLAGS_ENABLE)) {
+ XEN_PT_ERR(&s->dev, "MSI-X unexpectedly disabled\n");
+ } else if ((dev_value & PCI_MSIX_FLAGS_ENABLE) &&
+ s->msix->maskall &&
+ !(dev_value & PCI_MSIX_FLAGS_MASKALL)) {
+ XEN_PT_ERR(&s->dev, "MSI-X unexpectedly unmasked\n");
+ }
+
return 0;
}
@@ -1483,9 +1509,12 @@ static XenPTRegInfo xen_pt_emu_reg_msix[
.offset = PCI_MSI_FLAGS,
.size = 2,
.init_val = 0x0000,
- .res_mask = 0x3800,
- .ro_mask = 0x07FF,
- .emu_mask = 0x0000,
+ /* This must not be split into res_mask (0x3800) and ro_mask (0x07FF)
+ * because even in permissive mode there must not be any write back
+ * to this register.
+ */
+ .ro_mask = 0x3FFF,
+ .emu_mask = 0xC000,
.init = xen_pt_msixctrl_reg_init,
.u.w.read = xen_pt_word_reg_read,
.u.w.write = xen_pt_msixctrl_reg_write,
Index: xen-4.5.1-testing/tools/qemu-xen-dir-remote/hw/xen/xen_pt_msi.c
===================================================================
--- xen-4.5.1-testing.orig/tools/qemu-xen-dir-remote/hw/xen/xen_pt_msi.c
+++ xen-4.5.1-testing/tools/qemu-xen-dir-remote/hw/xen/xen_pt_msi.c
@@ -301,8 +301,11 @@ static int msix_set_enable(XenPCIPassthr
return -1;
}
- return msi_msix_enable(s, s->msix->ctrl_offset, PCI_MSIX_FLAGS_ENABLE,
- enabled);
+ return xc_physdev_msix_enable(xen_xc, s->real_device.domain,
+ s->real_device.bus,
+ PCI_DEVFN(s->real_device.dev,
+ s->real_device.func),
+ enabled);
}
static int xen_pt_msix_update_one(XenPCIPassthroughState *s, int entry_nr)
@@ -361,6 +364,11 @@ int xen_pt_msix_update(XenPCIPassthrough
return 0;
}
+void xen_pt_msix_enable(XenPCIPassthroughState *s)
+{
+ msix_set_enable(s, true);
+}
+
void xen_pt_msix_disable(XenPCIPassthroughState *s)
{
int i = 0;
@@ -378,6 +386,15 @@ void xen_pt_msix_disable(XenPCIPassthrou
}
}
+int xen_pt_msix_maskall(XenPCIPassthroughState *s, bool mask)
+{
+ return xc_physdev_msix_mask_all(xen_xc, s->real_device.domain,
+ s->real_device.bus,
+ PCI_DEVFN(s->real_device.dev,
+ s->real_device.func),
+ mask);
+}
+
int xen_pt_msix_update_remap(XenPCIPassthroughState *s, int bar_index)
{
XenPTMSIXEntry *entry;
++++++ qemu-MSI-X-latch-writes.patch ++++++
References: bsc#931627
xen/MSI-X: latch MSI-X table writes
The remaining log message in pci_msix_write() is wrong, as there guest
behavior may only appear to be wrong: For one, the old logic didn't
take the mask-all bit into account. And then this shouldn't depend on
host device state (i.e. the host may have masked the entry without the
guest having done so). Plus these writes shouldn't be dropped even when
an entry gets unmasked. Instead, if they can't be made take effect
right away, they should take effect on the next unmasking or enabling
operation - the specification explicitly describes such caching
behavior.
Signed-off-by: Jan Beulich
--- trunk.orig/tools/qemu-xen-dir-remote/hw/xen/xen_pt.h 2015-06-10 00:00:00.000000000 +0200
+++ trunk/tools/qemu-xen-dir-remote/hw/xen/xen_pt.h 2015-04-14 08:58:43.000000000 +0200
@@ -175,9 +175,8 @@ typedef struct XenPTMSIXEntry {
int pirq;
uint64_t addr;
uint32_t data;
- uint32_t vector_ctrl;
+ uint32_t latch[4];
bool updated; /* indicate whether MSI ADDR or DATA is updated */
- bool warned; /* avoid issuing (bogus) warning more than once */
} XenPTMSIXEntry;
typedef struct XenPTMSIX {
uint32_t ctrl_offset;
--- trunk.orig/tools/qemu-xen-dir-remote/hw/xen/xen_pt_msi.c 2015-06-10 00:00:00.000000000 +0200
+++ trunk/tools/qemu-xen-dir-remote/hw/xen/xen_pt_msi.c 2015-05-07 12:46:09.000000000 +0200
@@ -25,6 +25,7 @@
#define XEN_PT_GFLAGSSHIFT_DELIV_MODE 12
#define XEN_PT_GFLAGSSHIFT_TRG_MODE 15
+#define latch(fld) latch[PCI_MSIX_ENTRY_##fld / sizeof(uint32_t)]
/*
* Helpers
@@ -322,6 +323,13 @@ static int xen_pt_msix_update_one(XenPCI
pirq = entry->pirq;
+ if (pirq == XEN_PT_UNASSIGNED_PIRQ || s->msix->maskall ||
+ (entry->latch(VECTOR_CTRL) & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
+ entry->addr = entry->latch(LOWER_ADDR) |
+ ((uint64_t)entry->latch(UPPER_ADDR) << 32);
+ entry->data = entry->latch(DATA);
+ }
+
rc = msi_msix_setup(s, entry->addr, entry->data, &pirq, true, entry_nr,
entry->pirq == XEN_PT_UNASSIGNED_PIRQ);
if (rc) {
@@ -396,35 +404,15 @@ int xen_pt_msix_update_remap(XenPCIPasst
static uint32_t get_entry_value(XenPTMSIXEntry *e, int offset)
{
- switch (offset) {
- case PCI_MSIX_ENTRY_LOWER_ADDR:
- return e->addr & UINT32_MAX;
- case PCI_MSIX_ENTRY_UPPER_ADDR:
- return e->addr >> 32;
- case PCI_MSIX_ENTRY_DATA:
- return e->data;
- case PCI_MSIX_ENTRY_VECTOR_CTRL:
- return e->vector_ctrl;
- default:
- return 0;
- }
+ return !(offset % sizeof(*e->latch))
+ ? e->latch[offset / sizeof(*e->latch)] : 0;
}
static void set_entry_value(XenPTMSIXEntry *e, int offset, uint32_t val)
{
- switch (offset) {
- case PCI_MSIX_ENTRY_LOWER_ADDR:
- e->addr = (e->addr & ((uint64_t)UINT32_MAX << 32)) | val;
- break;
- case PCI_MSIX_ENTRY_UPPER_ADDR:
- e->addr = (uint64_t)val << 32 | (e->addr & UINT32_MAX);
- break;
- case PCI_MSIX_ENTRY_DATA:
- e->data = val;
- break;
- case PCI_MSIX_ENTRY_VECTOR_CTRL:
- e->vector_ctrl = val;
- break;
+ if (!(offset % sizeof(*e->latch)))
+ {
+ e->latch[offset / sizeof(*e->latch)] = val;
}
}
@@ -444,39 +432,28 @@ static void pci_msix_write(void *opaque,
offset = addr % PCI_MSIX_ENTRY_SIZE;
if (offset != PCI_MSIX_ENTRY_VECTOR_CTRL) {
- const volatile uint32_t *vec_ctrl;
-
if (get_entry_value(entry, offset) == val
&& entry->pirq != XEN_PT_UNASSIGNED_PIRQ) {
return;
}
+ entry->updated = true;
+ } else if (msix->enabled && entry->updated &&
+ !(val & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
+ const volatile uint32_t *vec_ctrl;
+
/*
* If Xen intercepts the mask bit access, entry->vec_ctrl may not be
* up-to-date. Read from hardware directly.
*/
vec_ctrl = s->msix->phys_iomem_base + entry_nr * PCI_MSIX_ENTRY_SIZE
+ PCI_MSIX_ENTRY_VECTOR_CTRL;
+ set_entry_value(entry, offset, *vec_ctrl);
- if (msix->enabled && !(*vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
- if (!entry->warned) {
- entry->warned = true;
- XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is"
- " already enabled.\n", entry_nr);
- }
- return;
- }
-
- entry->updated = true;
+ xen_pt_msix_update_one(s, entry_nr);
}
set_entry_value(entry, offset, val);
-
- if (offset == PCI_MSIX_ENTRY_VECTOR_CTRL) {
- if (msix->enabled && !(val & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
- xen_pt_msix_update_one(s, entry_nr);
- }
- }
}
static uint64_t pci_msix_read(void *opaque, hwaddr addr,
++++++ qemu-xen-dir-remote.tar.bz2 ++++++
/work/SRC/openSUSE:Factory/xen/qemu-xen-dir-remote.tar.bz2 /work/SRC/openSUSE:Factory/.xen.new/qemu-xen-dir-remote.tar.bz2 differ: char 11, line 1
++++++ qemu-xen-traditional-dir-remote.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tools/qemu-xen-traditional-dir-remote/hw/cirrus_vga.c new/tools/qemu-xen-traditional-dir-remote/hw/cirrus_vga.c
--- old/tools/qemu-xen-traditional-dir-remote/hw/cirrus_vga.c 2015-01-14 18:45:44.000000000 +0100
+++ new/tools/qemu-xen-traditional-dir-remote/hw/cirrus_vga.c 2015-06-26 15:39:01.000000000 +0200
@@ -1658,8 +1658,8 @@
default:
#ifdef DEBUG_CIRRUS
printf("cirrus: inport cr_index %02x\n", reg_index);
- *reg_value = 0xff;
#endif
+ *reg_value = 0xff;
break;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tools/qemu-xen-traditional-dir-remote/hw/fdc.c new/tools/qemu-xen-traditional-dir-remote/hw/fdc.c
--- old/tools/qemu-xen-traditional-dir-remote/hw/fdc.c 2015-01-14 18:45:44.000000000 +0100
+++ new/tools/qemu-xen-traditional-dir-remote/hw/fdc.c 2015-06-26 15:39:01.000000000 +0200
@@ -1318,7 +1318,7 @@
{
fdrive_t *cur_drv;
uint32_t retval = 0;
- int pos;
+ uint32_t pos;
cur_drv = get_cur_drv(fdctrl);
fdctrl->dsr &= ~FD_DSR_PWRDOWN;
@@ -1327,8 +1327,8 @@
return 0;
}
pos = fdctrl->data_pos;
+ pos %= FD_SECTOR_LEN;
if (fdctrl->msr & FD_MSR_NONDMA) {
- pos %= FD_SECTOR_LEN;
if (pos == 0) {
if (fdctrl->data_pos != 0)
if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
@@ -1673,10 +1673,13 @@
static void fdctrl_handle_drive_specification_command (fdctrl_t *fdctrl, int direction)
{
fdrive_t *cur_drv = get_cur_drv(fdctrl);
+ uint32_t pos;
- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {
+ pos = fdctrl->data_pos - 1;
+ pos %= FD_SECTOR_LEN;
+ if (fdctrl->fifo[pos] & 0x80) {
/* Command parameters done */
- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {
+ if (fdctrl->fifo[pos] & 0x40) {
fdctrl->fifo[0] = fdctrl->fifo[1];
fdctrl->fifo[2] = 0;
fdctrl->fifo[3] = 0;
@@ -1771,7 +1774,7 @@
static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value)
{
fdrive_t *cur_drv;
- int pos;
+ uint32_t pos;
/* Reset mode */
if (!(fdctrl->dor & FD_DOR_nRESET)) {
@@ -1817,7 +1820,9 @@
}
FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
- fdctrl->fifo[fdctrl->data_pos++] = value;
+ pos = fdctrl->data_pos++;
+ pos %= FD_SECTOR_LEN;
+ fdctrl->fifo[pos] = value;
if (fdctrl->data_pos == fdctrl->data_len) {
/* We now have all parameters
* and will be able to treat the command
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tools/qemu-xen-traditional-dir-remote/hw/pass-through.c new/tools/qemu-xen-traditional-dir-remote/hw/pass-through.c
--- old/tools/qemu-xen-traditional-dir-remote/hw/pass-through.c 2015-01-14 18:45:44.000000000 +0100
+++ new/tools/qemu-xen-traditional-dir-remote/hw/pass-through.c 2015-06-26 15:39:01.000000000 +0200
@@ -147,6 +147,10 @@
struct pt_reg_info_tbl *reg, uint32_t real_offset);
static uint32_t pt_msgdata_reg_init(struct pt_dev *ptdev,
struct pt_reg_info_tbl *reg, uint32_t real_offset);
+static uint32_t pt_mask_reg_init(struct pt_dev *ptdev,
+ struct pt_reg_info_tbl *reg, uint32_t real_offset);
+static uint32_t pt_pending_reg_init(struct pt_dev *ptdev,
+ struct pt_reg_info_tbl *reg, uint32_t real_offset);
static uint32_t pt_msixctrl_reg_init(struct pt_dev *ptdev,
struct pt_reg_info_tbl *reg, uint32_t real_offset);
static uint32_t pt_header_type_reg_init(struct pt_dev *ptdev,
@@ -172,15 +176,9 @@
static int pt_long_reg_read(struct pt_dev *ptdev,
struct pt_reg_tbl *cfg_entry,
uint32_t *value, uint32_t valid_mask);
-static int pt_cmd_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t valid_mask);
static int pt_bar_reg_read(struct pt_dev *ptdev,
struct pt_reg_tbl *cfg_entry,
uint32_t *value, uint32_t valid_mask);
-static int pt_pmcsr_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t valid_mask);
static int pt_byte_reg_write(struct pt_dev *ptdev,
struct pt_reg_tbl *cfg_entry,
uint8_t *value, uint8_t dev_value, uint8_t valid_mask);
@@ -285,10 +283,10 @@
.offset = PCI_COMMAND,
.size = 2,
.init_val = 0x0000,
- .ro_mask = 0xF880,
- .emu_mask = 0x0740,
+ .res_mask = 0xF880,
+ .emu_mask = 0x0743,
.init = pt_common_reg_init,
- .u.w.read = pt_cmd_reg_read,
+ .u.w.read = pt_word_reg_read,
.u.w.write = pt_cmd_reg_write,
.u.w.restore = pt_cmd_reg_restore,
},
@@ -312,7 +310,8 @@
.offset = PCI_STATUS,
.size = 2,
.init_val = 0x0000,
- .ro_mask = 0x06FF,
+ .res_mask = 0x0007,
+ .ro_mask = 0x06F8,
.emu_mask = 0x0010,
.init = pt_status_reg_init,
.u.w.read = pt_word_reg_read,
@@ -457,7 +456,7 @@
.offset = PCI_INTEL_OPREGION,
.size = 4,
.init_val = 0,
- .no_wb = 1,
+ .emu_mask = 0xFFFFFFFF,
.u.dw.read = pt_intel_opregion_read,
.u.dw.write = pt_intel_opregion_write,
.u.dw.restore = NULL,
@@ -493,15 +492,29 @@
.u.w.write = pt_word_reg_write,
.u.w.restore = NULL,
},
- /* PCI Power Management Control/Status reg */
+ /* PCI Power Management Control/Status reg (->power_mgmt on) */
{
.offset = PCI_PM_CTRL,
.size = 2,
.init_val = 0x0008,
- .ro_mask = 0xE1FC,
+ .res_mask = 0x00F0,
+ .ro_mask = 0xE10C,
.emu_mask = 0x8100,
.init = pt_pmcsr_reg_init,
- .u.w.read = pt_pmcsr_reg_read,
+ .u.w.read = pt_word_reg_read,
+ .u.w.write = pt_pmcsr_reg_write,
+ .u.w.restore = pt_pmcsr_reg_restore,
+ },
+ /* PCI Power Management Control/Status reg (->power_mgmt off) */
+ {
+ .offset = PCI_PM_CTRL,
+ .size = 2,
+ .init_val = 0x0008,
+ .res_mask = 0x00F0,
+ .ro_mask = 0xE10C,
+ .emu_mask = 0x810B,
+ .init = pt_pmcsr_reg_init,
+ .u.w.read = pt_word_reg_read,
.u.w.write = pt_pmcsr_reg_write,
.u.w.restore = pt_pmcsr_reg_restore,
},
@@ -525,6 +538,16 @@
.u.b.restore = NULL,
},
{
+ .offset = PCI_VPD_ADDR,
+ .size = 2,
+ .ro_mask = 0x0003,
+ .emu_mask = 0x0003,
+ .init = pt_common_reg_init,
+ .u.w.read = pt_word_reg_read,
+ .u.w.write = pt_word_reg_write,
+ .u.w.restore = pt_word_reg_restore,
+ },
+ {
.size = 0,
},
};
@@ -567,7 +590,7 @@
.offset = PCI_EXP_DEVCAP,
.size = 4,
.init_val = 0x00000000,
- .ro_mask = 0x1FFCFFFF,
+ .ro_mask = 0xFFFFFFFF,
.emu_mask = 0x10000000,
.init = pt_common_reg_init,
.u.dw.read = pt_long_reg_read,
@@ -586,6 +609,17 @@
.u.w.write = pt_word_reg_write,
.u.w.restore = pt_word_reg_restore,
},
+ /* Device Status reg */
+ {
+ .offset = PCI_EXP_DEVSTA,
+ .size = 2,
+ .res_mask = 0xFFC0,
+ .ro_mask = 0x0030,
+ .init = pt_common_reg_init,
+ .u.w.read = pt_word_reg_read,
+ .u.w.write = pt_word_reg_write,
+ .u.w.restore = pt_word_reg_restore,
+ },
/* Link Control reg */
{
.offset = PCI_EXP_LNKCTL,
@@ -598,6 +632,16 @@
.u.w.write = pt_word_reg_write,
.u.w.restore = pt_word_reg_restore,
},
+ /* Link Status reg */
+ {
+ .offset = PCI_EXP_LNKSTA,
+ .size = 2,
+ .ro_mask = 0x3FFF,
+ .init = pt_common_reg_init,
+ .u.w.read = pt_word_reg_read,
+ .u.w.write = pt_word_reg_write,
+ .u.w.restore = pt_word_reg_restore,
+ },
/* Device Control 2 reg */
{
.offset = 0x28,
@@ -646,8 +690,9 @@
.offset = PCI_MSI_FLAGS, // 2
.size = 2,
.init_val = 0x0000,
- .ro_mask = 0xFF8E,
- .emu_mask = 0x007F,
+ .res_mask = 0xFE00,
+ .ro_mask = 0x018E,
+ .emu_mask = 0x017E,
.init = pt_msgctrl_reg_init,
.u.w.read = pt_word_reg_read,
.u.w.write = pt_msgctrl_reg_write,
@@ -660,7 +705,6 @@
.init_val = 0x00000000,
.ro_mask = 0x00000003,
.emu_mask = 0xFFFFFFFF,
- .no_wb = 1,
.init = pt_common_reg_init,
.u.dw.read = pt_long_reg_read,
.u.dw.write = pt_msgaddr32_reg_write,
@@ -673,7 +717,6 @@
.init_val = 0x00000000,
.ro_mask = 0x00000000,
.emu_mask = 0xFFFFFFFF,
- .no_wb = 1,
.init = pt_msgaddr64_reg_init,
.u.dw.read = pt_long_reg_read,
.u.dw.write = pt_msgaddr64_reg_write,
@@ -686,7 +729,6 @@
.init_val = 0x0000,
.ro_mask = 0x0000,
.emu_mask = 0xFFFF,
- .no_wb = 1,
.init = pt_msgdata_reg_init,
.u.w.read = pt_word_reg_read,
.u.w.write = pt_msgdata_reg_write,
@@ -699,12 +741,55 @@
.init_val = 0x0000,
.ro_mask = 0x0000,
.emu_mask = 0xFFFF,
- .no_wb = 1,
.init = pt_msgdata_reg_init,
.u.w.read = pt_word_reg_read,
.u.w.write = pt_msgdata_reg_write,
.u.w.restore = NULL,
},
+ /* Mask reg (if PCI_MSI_FLAGS_MASK_BIT set, for 32-bit devices) */
+ {
+ .offset = PCI_MSI_MASK_32,
+ .size = 4,
+ .init_val = 0x00000000,
+ .ro_mask = 0xFFFFFFFF,
+ .emu_mask = 0xFFFFFFFF,
+ .init = pt_mask_reg_init,
+ .u.dw.read = pt_long_reg_read,
+ .u.dw.write = pt_long_reg_write,
+ },
+ /* Mask reg (if PCI_MSI_FLAGS_MASK_BIT set, for 64-bit devices) */
+ {
+ .offset = PCI_MSI_MASK_64,
+ .size = 4,
+ .init_val = 0x00000000,
+ .ro_mask = 0xFFFFFFFF,
+ .emu_mask = 0xFFFFFFFF,
+ .init = pt_mask_reg_init,
+ .u.dw.read = pt_long_reg_read,
+ .u.dw.write = pt_long_reg_write,
+ },
+ /* Pending reg (if PCI_MSI_FLAGS_MASK_BIT set, for 32-bit devices) */
+ {
+ .offset = PCI_MSI_MASK_32 + 4,
+ .size = 4,
+ .init_val = 0x00000000,
+ .ro_mask = 0xFFFFFFFF,
+ .emu_mask = 0x00000000,
+ .init = pt_pending_reg_init,
+ .u.dw.read = pt_long_reg_read,
+ .u.dw.write = pt_long_reg_write,
+ },
+ /* Pending reg (if PCI_MSI_FLAGS_MASK_BIT set, for 64-bit devices) */
+ {
+ .offset = PCI_MSI_MASK_64 + 4,
+ .size = 4,
+ .init_val = 0x00000000,
+ .ro_mask = 0xFFFFFFFF,
+ .emu_mask = 0x00000000,
+ .init = pt_pending_reg_init,
+ .u.dw.read = pt_long_reg_read,
+ .u.dw.write = pt_long_reg_write,
+ },
{
.size = 0,
},
@@ -729,7 +814,8 @@
.offset = PCI_MSI_FLAGS, // 2
.size = 2,
.init_val = 0x0000,
- .ro_mask = 0x3FFF,
+ .res_mask = 0x3800,
+ .ro_mask = 0x07FF,
.emu_mask = 0x0000,
.init = pt_msixctrl_reg_init,
.u.w.read = pt_word_reg_read,
@@ -1527,10 +1613,10 @@
uint32_t find_addr = address;
uint32_t real_offset = 0;
uint32_t valid_mask = 0xFFFFFFFF;
- uint32_t read_val = 0;
+ uint32_t read_val = 0, wb_mask, wp_mask;
uint8_t *ptr_val = NULL;
int emul_len = 0;
- int index = 0;
+ int index = 0, wp_flag = 0;
int ret = 0;
#ifdef PT_DEBUG_PCI_CONFIG_ACCESS
@@ -1600,11 +1686,21 @@
{
PT_LOG("Error: pci_read_block failed. return value[%d].\n", ret);
memset((uint8_t *)&read_val, 0xff, len);
+ wb_mask = 0;
}
+ else
+ wb_mask = 0xFFFFFFFF >> ((4 - len) << 3);
/* pass directly to libpci for passthrough type register group */
if (reg_grp_entry == NULL)
+ {
+ if (!assigned_device->permissive)
+ {
+ wb_mask = 0;
+ wp_flag = 1;
+ }
goto out;
+ }
/* adjust the read and write value to appropriate CFC-CFF window */
read_val <<= ((address & 3) << 3);
@@ -1623,6 +1719,12 @@
valid_mask = (0xFFFFFFFF >> ((4 - emul_len) << 3));
valid_mask <<= ((find_addr - real_offset) << 3);
ptr_val = ((uint8_t *)&val + (real_offset & 3));
+ wp_mask = reg->emu_mask | reg->ro_mask;
+ if (!assigned_device->permissive)
+ wp_mask |= reg->res_mask;
+ if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3)))
+ wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3))
+ << ((len - emul_len) << 3));
/* do emulation depend on register size */
switch (reg->size) {
@@ -1671,6 +1773,16 @@
/* nothing to do with passthrough type register,
* continue to find next byte
*/
+ if (!assigned_device->permissive)
+ {
+ wb_mask &= ~(0xff << ((len - emul_len) << 3));
+ /* Unused BARs will make it here, but we don't want to issue
+ * warnings for writes to them (bogus writes get dealt with
+ * above).
+ */
+ if (index < 0)
+ wp_flag = 1;
+ }
emul_len--;
find_addr++;
}
@@ -1680,8 +1792,28 @@
val >>= ((address & 3) << 3);
out:
- if (!(reg && reg->no_wb)) { /* unknown regs are passed through */
- ret = pci_write_block(pci_dev, address, (uint8_t *)&val, len);
+ if (wp_flag && !assigned_device->permissive_warned)
+ {
+ assigned_device->permissive_warned = 1;
+ PT_LOG("Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n",
+ addr, len * 2, wb_mask);
+ PT_LOG("If device %02x:%02x.%o doesn't work, try enabling permissive\n",
+ pci_bus_num(d->bus), PCI_SLOT(d->devfn), PCI_FUNC(d->devfn));
+ PT_LOG("mode (unsafe) and if it helps report the problem to xen-devel\n");
+ }
+ for (index = 0; wb_mask; index += len) {
+ /* unknown regs are passed through */
+ while (!(wb_mask & 0xff)) {
+ index++;
+ wb_mask >>= 8;
+ }
+ len = 0;
+ do {
+ len++;
+ wb_mask >>= 8;
+ } while (wb_mask & 0xff);
+ ret = pci_write_block(pci_dev, address + index,
+ (uint8_t *)&val + index, len);
if (!ret)
PT_LOG("Error: pci_write_block failed. return value[%d].\n", ret);
@@ -1905,7 +2037,7 @@
return rc;
}
-static int pt_register_regions(struct pt_dev *assigned_device)
+static int pt_register_regions(struct pt_dev *assigned_device, uint16_t *cmd)
{
int i = 0;
uint32_t bar_data = 0;
@@ -1925,17 +2057,26 @@
/* Register current region */
if ( pci_dev->base_addr[i] & PCI_ADDRESS_SPACE_IO )
+ {
pci_register_io_region((PCIDevice *)assigned_device, i,
(uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_IO,
pt_ioport_map);
+ *cmd |= PCI_COMMAND_IO;
+ }
else if ( pci_dev->base_addr[i] & PCI_ADDRESS_SPACE_MEM_PREFETCH )
+ {
pci_register_io_region((PCIDevice *)assigned_device, i,
(uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM_PREFETCH,
pt_iomem_map);
+ *cmd |= PCI_COMMAND_MEMORY;
+ }
else
+ {
pci_register_io_region((PCIDevice *)assigned_device, i,
(uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM,
pt_iomem_map);
+ *cmd |= PCI_COMMAND_MEMORY;
+ }
PT_LOG("IO region registered (size=0x%08x base_addr=0x%08x)\n",
(uint32_t)(pci_dev->size[i]),
@@ -2848,6 +2989,7 @@
return reg->init_val;
}
+/* this function will be called twice (for ->power_mgmt on and off cases) */
/* initialize PCI Power Management Control/Status register */
static uint32_t pt_pmcsr_reg_init(struct pt_dev *ptdev,
struct pt_reg_info_tbl *reg, uint32_t real_offset)
@@ -2855,8 +2997,23 @@
PCIDevice *d = &ptdev->dev;
uint16_t cap_ver = 0;
- if (!ptdev->power_mgmt)
- return reg->init_val;
+ switch (reg->emu_mask & (PCI_PM_CTRL_STATE_MASK |
+ PCI_PM_CTRL_NO_SOFT_RESET))
+ {
+ case 0:
+ if (!ptdev->power_mgmt)
+ return PT_INVALID_REG;
+ break;
+ case PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET:
+ if (!ptdev->power_mgmt)
+ return reg->init_val;
+ return PT_INVALID_REG;
+ default:
+ /* exit I/O emulator */
+ PT_LOG("Internal error: Invalid PMCSR emulation mask %04x."
+ " I/O emulator exit.\n", reg->emu_mask);
+ exit(1);
+ }
/* check PCI Power Management support version */
cap_ver = ptdev->pm_state->pmc_field & PCI_PM_CAP_VER_MASK;
@@ -3000,6 +3157,42 @@
return PT_INVALID_REG;
}
+/* this function will be called twice (for 32 bit and 64 bit type) */
+/* initialize Mask register */
+static uint32_t pt_mask_reg_init(struct pt_dev *ptdev,
+ struct pt_reg_info_tbl *reg, uint32_t real_offset)
+{
+ uint32_t flags = ptdev->msi->flags;
+ uint32_t offset = reg->offset;
+
+ if (!(flags & PCI_MSI_FLAGS_MASK_BIT))
+ return PT_INVALID_REG;
+
+ if (offset == (flags & PCI_MSI_FLAGS_64BIT ?
+ PCI_MSI_MASK_64 : PCI_MSI_MASK_32))
+ return reg->init_val;
+
+ return PT_INVALID_REG;
+}
+
+/* this function will be called twice (for 32 bit and 64 bit type) */
+/* initialize Pending register */
+static uint32_t pt_pending_reg_init(struct pt_dev *ptdev,
+ struct pt_reg_info_tbl *reg, uint32_t real_offset)
+{
+ uint32_t flags = ptdev->msi->flags;
+ uint32_t offset = reg->offset;
+
+ if (!(flags & PCI_MSI_FLAGS_MASK_BIT))
+ return PT_INVALID_REG;
+
+ if (offset == (flags & PCI_MSI_FLAGS_64BIT ?
+ PCI_MSI_MASK_64 + 4 : PCI_MSI_MASK_32 + 4))
+ return reg->init_val;
+
+ return PT_INVALID_REG;
+}
+
/* initialize Message Control register for MSI-X */
static uint32_t pt_msixctrl_reg_init(struct pt_dev *ptdev,
struct pt_reg_info_tbl *reg, uint32_t real_offset)
@@ -3263,27 +3456,6 @@
return 0;
}
-/* read Command register */
-static int pt_cmd_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t valid_emu_mask = 0;
- uint16_t emu_mask = reg->emu_mask;
-
- if ( ptdev->is_virtfn )
- emu_mask |= PCI_COMMAND_MEMORY;
- if ( pt_is_iomul(ptdev) )
- emu_mask |= PCI_COMMAND_IO;
-
- /* emulate word register */
- valid_emu_mask = emu_mask & valid_mask;
- *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask);
-
- return 0;
-}
-
/* read BAR */
static int pt_bar_reg_read(struct pt_dev *ptdev,
struct pt_reg_tbl *cfg_entry,
@@ -3331,24 +3503,18 @@
}
-/* read Power Management Control/Status register */
-static int pt_pmcsr_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t valid_mask)
+static uint32_t get_throughable_mask(const struct pt_dev *ptdev,
+ const struct pt_reg_info_tbl *reg,
+ uint32_t valid_mask)
{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t valid_emu_mask = reg->emu_mask;
-
- if (!ptdev->power_mgmt)
- valid_emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET;
+ uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask);
- valid_emu_mask = valid_emu_mask & valid_mask ;
- *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask);
+ if (!ptdev->permissive)
+ throughable_mask &= ~reg->res_mask;
- return 0;
+ return throughable_mask & valid_mask;
}
-
/* write byte size emulate register */
static int pt_byte_reg_write(struct pt_dev *ptdev,
struct pt_reg_tbl *cfg_entry,
@@ -3356,14 +3522,13 @@
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint8_t writable_mask = 0;
- uint8_t throughable_mask = 0;
+ uint8_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
/* modify emulate register */
writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
/* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
return 0;
@@ -3376,14 +3541,13 @@
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
/* modify emulate register */
writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
/* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
return 0;
@@ -3396,14 +3560,13 @@
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
+ uint32_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
/* modify emulate register */
writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
/* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
return 0;
@@ -3416,22 +3579,14 @@
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
uint16_t wr_value = *value;
- uint16_t emu_mask = reg->emu_mask;
-
- if ( ptdev->is_virtfn )
- emu_mask |= PCI_COMMAND_MEMORY;
- if ( pt_is_iomul(ptdev) )
- emu_mask |= PCI_COMMAND_IO;
/* modify emulate register */
writable_mask = ~reg->ro_mask & valid_mask;
cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
/* create value for writing to I/O device register */
- throughable_mask = ~emu_mask & valid_mask;
-
if (*value & PCI_COMMAND_DISABLE_INTx)
{
if (ptdev->msi_trans_en)
@@ -3477,7 +3632,6 @@
PCIDevice *d = (PCIDevice *)&ptdev->dev;
PCIIORegion *r;
uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
uint32_t bar_emu_mask = 0;
uint32_t bar_ro_mask = 0;
uint32_t new_addr, last_addr;
@@ -3604,8 +3758,7 @@
exit:
/* create value for writing to I/O device register */
- throughable_mask = ~bar_emu_mask & valid_mask;
- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
+ *value = PT_MERGE_VALUE(*value, dev_value, 0);
/* After BAR reg update, we need to remap BAR*/
reg_grp_entry = pt_find_reg_grp(ptdev, PCI_COMMAND);
@@ -3632,9 +3785,8 @@
PCIDevice *d = (PCIDevice *)&ptdev->dev;
PCIIORegion *r;
uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
+ uint32_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
uint32_t r_size = 0;
- uint32_t bar_emu_mask = 0;
uint32_t bar_ro_mask = 0;
r = &d->io_regions[PCI_ROM_SLOT];
@@ -3644,7 +3796,6 @@
PT_GET_EMUL_SIZE(base->bar_flag, r_size);
/* set emulate mask and read-only mask */
- bar_emu_mask = reg->emu_mask;
bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE;
/* modify emulate register */
@@ -3664,7 +3815,6 @@
r->addr = cfg_entry->data;
/* create value for writing to I/O device register */
- throughable_mask = ~bar_emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
/* After BAR reg update, we need to remap BAR*/
@@ -3688,22 +3838,18 @@
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
PCIDevice *d = &ptdev->dev;
- uint16_t emu_mask = reg->emu_mask;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
struct pt_pm_info *pm_state = ptdev->pm_state;
uint16_t read_val = 0;
- if (!ptdev->power_mgmt)
- emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET;
-
/* modify emulate register */
- writable_mask = emu_mask & ~reg->ro_mask & valid_mask;
+ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
/* create value for writing to I/O device register */
- throughable_mask = ~emu_mask & valid_mask;
- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
+ *value = PT_MERGE_VALUE(*value, dev_value & ~PCI_PM_CTRL_PME_STATUS,
+ throughable_mask);
if (!ptdev->power_mgmt)
return 0;
@@ -3810,7 +3956,7 @@
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
uint16_t old_ctrl = cfg_entry->data;
PCIDevice *pd = (PCIDevice *)ptdev;
uint16_t val;
@@ -3821,6 +3967,11 @@
/* modify emulate register */
writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
+ /* also emulate MSI_ENABLE bit for MSI-INTx translation */
+ if (ptdev->msi_trans_en) {
+ writable_mask |= PCI_MSI_FLAGS_ENABLE & valid_mask;
+ throughable_mask &= ~PCI_MSI_FLAGS_ENABLE;
+ }
cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
/* update the msi_info too */
ptdev->msi->flags |= cfg_entry->data &
@@ -3828,7 +3979,6 @@
/* create value for writing to I/O device register */
val = *value;
- throughable_mask = ~reg->emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
/* update MSI */
@@ -3872,12 +4022,6 @@
}
}
- /* pass through MSI_ENABLE bit when no MSI-INTx translation */
- if (!ptdev->msi_trans_en) {
- *value &= ~PCI_MSI_FLAGS_ENABLE;
- *value |= val & PCI_MSI_FLAGS_ENABLE;
- }
-
return 0;
}
@@ -3888,7 +4032,6 @@
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
uint32_t old_addr = cfg_entry->data;
/* modify emulate register */
@@ -3898,8 +4041,7 @@
ptdev->msi->addr_lo = cfg_entry->data;
/* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
+ *value = PT_MERGE_VALUE(*value, dev_value, 0);
/* update MSI */
if (cfg_entry->data != old_addr)
@@ -3918,7 +4060,6 @@
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
uint32_t old_addr = cfg_entry->data;
/* check whether the type is 64 bit or not */
@@ -3936,8 +4077,7 @@
ptdev->msi->addr_hi = cfg_entry->data;
/* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
+ *value = PT_MERGE_VALUE(*value, dev_value, 0);
/* update MSI */
if (cfg_entry->data != old_addr)
@@ -3957,7 +4097,6 @@
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
uint16_t old_data = cfg_entry->data;
uint32_t flags = ptdev->msi->flags;
uint32_t offset = reg->offset;
@@ -3978,8 +4117,7 @@
ptdev->msi->data = cfg_entry->data;
/* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
+ *value = PT_MERGE_VALUE(*value, dev_value, 0);
/* update MSI */
if (cfg_entry->data != old_data)
@@ -3998,7 +4136,7 @@
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
uint16_t old_ctrl = cfg_entry->data;
/* modify emulate register */
@@ -4006,7 +4144,6 @@
cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
/* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
/* update MSI-X */
@@ -4211,8 +4348,9 @@
struct pt_dev *assigned_device = NULL;
struct pci_dev *pci_dev;
uint8_t e_device, e_intx;
+ uint16_t cmd = 0;
char *key, *val;
- int msi_translate, power_mgmt;
+ int msi_translate, power_mgmt, permissive = 0;
PT_LOG("Assigning real physical device %02x:%02x.%x ...\n",
r_bus, r_dev, r_func);
@@ -4256,6 +4394,8 @@
else
PT_LOG("Error: unrecognized value for msitranslate=\n");
}
+ else if (strcmp(key, "permissive") == 0)
+ permissive = 1;
else if (strcmp(key, "power_mgmt") == 0)
{
if (strcmp(val, "0") == 0)
@@ -4293,6 +4433,7 @@
assigned_device->msi_trans_cap = msi_translate;
assigned_device->power_mgmt = power_mgmt;
assigned_device->is_virtfn = pt_dev_is_virtfn(pci_dev);
+ assigned_device->permissive = permissive;
pt_iomul_init(assigned_device, r_bus, r_dev, r_func);
/* Initialize virtualized PCI configuration (Extended 256 Bytes) */
@@ -4300,7 +4441,7 @@
assigned_device->dev.config[i] = pci_read_byte(pci_dev, i);
/* Handle real device's MMIO/PIO BARs */
- pt_register_regions(assigned_device);
+ pt_register_regions(assigned_device, &cmd);
/* Setup VGA bios for passthroughed gfx */
if ( setup_vga_pt(assigned_device) < 0 )
@@ -4378,6 +4519,10 @@
}
out:
+ if (cmd)
+ pci_write_word(pci_dev, PCI_COMMAND,
+ *(uint16_t *)(&assigned_device->dev.config[PCI_COMMAND]) | cmd);
+
PT_LOG("Real physical device %02x:%02x.%x registered successfuly!\n"
"IRQ type = %s\n", r_bus, r_dev, r_func,
assigned_device->msi_trans_en? "MSI-INTx":"INTx");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tools/qemu-xen-traditional-dir-remote/hw/pass-through.h new/tools/qemu-xen-traditional-dir-remote/hw/pass-through.h
--- old/tools/qemu-xen-traditional-dir-remote/hw/pass-through.h 2015-01-14 18:45:44.000000000 +0100
+++ new/tools/qemu-xen-traditional-dir-remote/hw/pass-through.h 2015-06-26 15:39:01.000000000 +0200
@@ -27,7 +27,7 @@
#include "qemu-timer.h"
/* Log acesss */
-#define PT_LOGGING_ENABLED
+/* #define PT_LOGGING_ENABLED */
/* Print errors even if logging is disabled */
#define PT_ERR(_f, _a...) fprintf(logfile, "%s: " _f, __func__, ##_a)
@@ -84,6 +84,12 @@
#define PCI_MSI_FLAGS_MASK_BIT 0x0100
#endif
+#ifndef PCI_MSI_MASK_32
+/* interrupt masking register */
+#define PCI_MSI_MASK_32 12
+#define PCI_MSI_MASK_64 16
+#endif
+
#ifndef PCI_EXP_TYPE_PCIE_BRIDGE
/* PCI/PCI-X to PCIE Bridge */
#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8
@@ -99,6 +105,14 @@
#define PCI_EXP_TYPE_ROOT_EC 0xa
#endif
+#ifndef PCI_VPD_ADDR
+/* Vital Product Data */
+#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */
+#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */
+#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */
+#define PCI_VPD_DATA 4 /* 32-bits of data returned here */
+#endif
+
#ifndef PCI_ERR_UNCOR_MASK
/* Uncorrectable Error Mask */
#define PCI_ERR_UNCOR_MASK 8
@@ -234,6 +248,8 @@
unsigned power_mgmt:1;
struct pt_pm_info *pm_state; /* PM virtualization */
unsigned is_virtfn:1;
+ unsigned permissive:1;
+ unsigned permissive_warned:1;
/* io port multiplexing */
#define PCI_IOMUL_INVALID_FD (-1)
@@ -368,12 +384,12 @@
uint32_t size;
/* reg initial value */
uint32_t init_val;
+ /* reg reserved field mask (ON:reserved, OFF:defined) */
+ uint32_t res_mask;
/* reg read only field mask (ON:RO/ROS, OFF:other) */
uint32_t ro_mask;
/* reg emulate field mask (ON:emu, OFF:passthrough) */
uint32_t emu_mask;
- /* no write back allowed */
- uint32_t no_wb;
/* emul reg initialize method */
conf_reg_init init;
union {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tools/qemu-xen-traditional-dir-remote/hw/pcnet.c new/tools/qemu-xen-traditional-dir-remote/hw/pcnet.c
--- old/tools/qemu-xen-traditional-dir-remote/hw/pcnet.c 2015-01-14 18:45:44.000000000 +0100
+++ new/tools/qemu-xen-traditional-dir-remote/hw/pcnet.c 2015-06-26 15:39:01.000000000 +0200
@@ -1250,7 +1250,7 @@
target_phys_addr_t xmit_cxda = 0;
int count = CSR_XMTRL(s)-1;
int add_crc = 0;
-
+ int bcnt;
s->xmit_pos = -1;
if (!CSR_TXON(s)) {
@@ -1276,34 +1276,47 @@
if (BCR_SWSTYLE(s) != 1)
add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS);
}
+
+ if (s->xmit_pos < 0) {
+ goto txdone;
+ }
+
+ bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
+
+ /* if multi-tmd packet outsizes s->buffer then skip it silently.
+ Note: this is not what real hw does */
+ if (s->xmit_pos + bcnt > sizeof(s->buffer)) {
+ s->xmit_pos = -1;
+ goto txdone;
+ }
+
+ s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
+ s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
+ s->xmit_pos += bcnt;
+
if (!GET_FIELD(tmd.status, TMDS, ENP)) {
- int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
- s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
- s->xmit_pos += bcnt;
- } else if (s->xmit_pos >= 0) {
- int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
- s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
- s->xmit_pos += bcnt;
+ goto txdone;
+ }
#ifdef PCNET_DEBUG
- printf("pcnet_transmit size=%d\n", s->xmit_pos);
+ printf("pcnet_transmit size=%d\n", s->xmit_pos);
#endif
- if (CSR_LOOP(s)) {
- if (BCR_SWSTYLE(s) == 1)
- add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
- s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
- pcnet_receive(s, s->buffer, s->xmit_pos);
- s->looptest = 0;
- } else
- if (s->vc)
- qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
-
- s->csr[0] &= ~0x0008; /* clear TDMD */
- s->csr[4] |= 0x0004; /* set TXSTRT */
- s->xmit_pos = -1;
+ if (CSR_LOOP(s)) {
+ if (BCR_SWSTYLE(s) == 1)
+ add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
+ s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
+ pcnet_receive(s, s->buffer, s->xmit_pos);
+ s->looptest = 0;
+ } else {
+ if (s->vc) {
+ qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
+ }
}
+ s->csr[0] &= ~0x0008; /* clear TDMD */
+ s->csr[4] |= 0x0004; /* set TXSTRT */
+ s->xmit_pos = -1;
+
+ txdone:
SET_FIELD(&tmd.status, TMDS, OWN, 0);
TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))
++++++ seabios-dir-remote.tar.bz2 ++++++
++++++ stubdom.tar.bz2 ++++++
/work/SRC/openSUSE:Factory/xen/stubdom.tar.bz2 /work/SRC/openSUSE:Factory/.xen.new/stubdom.tar.bz2 differ: char 11, line 1
++++++ tmp_build.patch ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:50:58.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:50:58.000000000 +0200
@@ -2,10 +2,10 @@
tools/xenstore/Makefile | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
-Index: xen-4.5.0-testing/tools/xenstore/Makefile
+Index: xen-4.5.1-testing/tools/xenstore/Makefile
===================================================================
---- xen-4.5.0-testing.orig/tools/xenstore/Makefile
-+++ xen-4.5.0-testing/tools/xenstore/Makefile
+--- xen-4.5.1-testing.orig/tools/xenstore/Makefile
++++ xen-4.5.1-testing/tools/xenstore/Makefile
@@ -91,6 +91,7 @@ $(CLIENTS_DOMU): xenstore
xenstore: xenstore_client.o $(LIBXENSTORE)
@@ -14,7 +14,12 @@
xenstore-control: xenstore_control.o $(LIBXENSTORE)
$(CC) $< $(LDFLAGS) $(LDLIBS_libxenstore) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
-@@ -141,10 +142,11 @@ endif
+@@ -136,14 +137,16 @@ ifeq ($(XENSTORE_XENSTORED),y)
+ $(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
+ $(INSTALL_DIR) $(DESTDIR)$(XEN_LIB_STORED)
+ $(INSTALL_PROG) xenstored $(DESTDIR)$(SBINDIR)
++ $(INSTALL_DIR) $(DESTDIR)/bin
+ endif
$(INSTALL_PROG) xenstore-control $(DESTDIR)$(BINDIR)
$(INSTALL_PROG) xenstore $(DESTDIR)$(BINDIR)
set -e ; for c in $(CLIENTS) ; do \
@@ -23,7 +28,7 @@
done
+ $(INSTALL_PROG) domu-xenstore $(DESTDIR)/bin
for client in $(CLIENTS_DOMU); do \
-- $(INSTALL_PROG) $$client $(DESTDIR)/bin/$${client/domu-}; \
+- $(INSTALL_PROG) $$client $(DESTDIR)/$(BINDIR)/$${client/domu-}; \
+ ln -fs domu-xenstore $(DESTDIR)/bin/$${client/domu-}; \
done
$(INSTALL_DIR) $(DESTDIR)$(LIBDIR)
++++++ x86-MSI-X-enable.patch ++++++
References: bsc#907514 bsc#910258 bsc#918984 bsc#923967
x86/MSI-X: access MSI-X table only after having enabled MSI-X
As done in Linux by f598282f51 ("PCI: Fix the NIU MSI-X problem in a
better way") and its broken predecessor, make sure we don't access the
MSI-X table without having enabled MSI-X first, using the mask-all flag
instead to prevent interrupts from occurring.
Signed-off-by: Jan Beulich
Reviewed-by: Andrew Cooper
---
v3: temporarily enable MSI-X in setup_msi_irq() if not already enabled
--- trunk.orig/xen/arch/x86/msi.c 2015-03-25 09:35:38.000000000 +0100
+++ trunk/xen/arch/x86/msi.c 2015-05-18 11:39:36.000000000 +0200
@@ -142,6 +142,17 @@ static bool_t memory_decoded(const struc
PCI_COMMAND_MEMORY);
}
+static bool_t msix_memory_decoded(const struct pci_dev *dev, unsigned int pos)
+{
+ u16 control = pci_conf_read16(dev->seg, dev->bus, PCI_SLOT(dev->devfn),
+ PCI_FUNC(dev->devfn), msix_control_reg(pos));
+
+ if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
+ return 0;
+
+ return memory_decoded(dev);
+}
+
/*
* MSI message composition
*/
@@ -219,7 +230,8 @@ static bool_t read_msi_msg(struct msi_de
void __iomem *base;
base = entry->mask_base;
- if ( unlikely(!memory_decoded(entry->dev)) )
+ if ( unlikely(!msix_memory_decoded(entry->dev,
+ entry->msi_attrib.pos)) )
return 0;
msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
@@ -285,7 +297,8 @@ static int write_msi_msg(struct msi_desc
void __iomem *base;
base = entry->mask_base;
- if ( unlikely(!memory_decoded(entry->dev)) )
+ if ( unlikely(!msix_memory_decoded(entry->dev,
+ entry->msi_attrib.pos)) )
return -ENXIO;
writel(msg->address_lo,
base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
@@ -379,7 +392,7 @@ static bool_t msi_set_mask_bit(struct ir
{
struct msi_desc *entry = desc->msi_desc;
struct pci_dev *pdev;
- u16 seg;
+ u16 seg, control;
u8 bus, slot, func;
ASSERT(spin_is_locked(&desc->lock));
@@ -401,35 +414,38 @@ static bool_t msi_set_mask_bit(struct ir
}
break;
case PCI_CAP_ID_MSIX:
+ control = pci_conf_read16(seg, bus, slot, func,
+ msix_control_reg(entry->msi_attrib.pos));
+ if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) )
+ pci_conf_write16(seg, bus, slot, func,
+ msix_control_reg(entry->msi_attrib.pos),
+ control | (PCI_MSIX_FLAGS_ENABLE |
+ PCI_MSIX_FLAGS_MASKALL));
if ( likely(memory_decoded(pdev)) )
{
writel(flag, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
readl(entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
- break;
+ if ( likely(control & PCI_MSIX_FLAGS_ENABLE) )
+ break;
+ flag = 1;
}
- if ( flag )
+ else if ( flag && !(control & PCI_MSIX_FLAGS_MASKALL) )
{
- u16 control;
domid_t domid = pdev->domain->domain_id;
- control = pci_conf_read16(seg, bus, slot, func,
- msix_control_reg(entry->msi_attrib.pos));
- if ( control & PCI_MSIX_FLAGS_MASKALL )
- break;
- pci_conf_write16(seg, bus, slot, func,
- msix_control_reg(entry->msi_attrib.pos),
- control | PCI_MSIX_FLAGS_MASKALL);
+ control |= PCI_MSIX_FLAGS_MASKALL;
if ( pdev->msix->warned != domid )
{
pdev->msix->warned = domid;
printk(XENLOG_G_WARNING
- "cannot mask IRQ %d: masked MSI-X on Dom%d's %04x:%02x:%02x.%u\n",
+ "cannot mask IRQ %d: masking MSI-X on Dom%d's %04x:%02x:%02x.%u\n",
desc->irq, domid, pdev->seg, pdev->bus,
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
}
- break;
}
- /* fall through */
+ pci_conf_write16(seg, bus, slot, func,
+ msix_control_reg(entry->msi_attrib.pos), control);
+ return flag;
default:
return 0;
}
@@ -454,7 +470,8 @@ static int msi_get_mask_bit(const struct
entry->msi.mpos) >>
entry->msi_attrib.entry_nr) & 1;
case PCI_CAP_ID_MSIX:
- if ( unlikely(!memory_decoded(entry->dev)) )
+ if ( unlikely(!msix_memory_decoded(entry->dev,
+ entry->msi_attrib.pos)) )
break;
return readl(entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET) & 1;
}
@@ -543,9 +560,31 @@ static struct msi_desc *alloc_msi_entry(
int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)
{
- return __setup_msi_irq(desc, msidesc,
- msi_maskable_irq(msidesc) ? &pci_msi_maskable
- : &pci_msi_nonmaskable);
+ const struct pci_dev *pdev = msidesc->dev;
+ unsigned int cpos = msix_control_reg(msidesc->msi_attrib.pos);
+ u16 control = ~0;
+ int rc;
+
+ if ( msidesc->msi_attrib.type == PCI_CAP_ID_MSIX )
+ {
+ control = pci_conf_read16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn), cpos);
+ if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
+ pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn), cpos,
+ control | (PCI_MSIX_FLAGS_ENABLE |
+ PCI_MSIX_FLAGS_MASKALL));
+ }
+
+ rc = __setup_msi_irq(desc, msidesc,
+ msi_maskable_irq(msidesc) ? &pci_msi_maskable
+ : &pci_msi_nonmaskable);
+
+ if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
+ pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn), cpos, control);
+
+ return rc;
}
int __setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc,
@@ -785,16 +824,32 @@ static int msix_capability_init(struct p
pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
control = pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos));
- msix_set_enable(dev, 0);/* Ensure msix is disabled as I set it up */
+ /*
+ * Ensure MSI-X interrupts are masked during setup. Some devices require
+ * MSI-X to be enabled before we can touch the MSI-X registers. We need
+ * to mask all the vectors to prevent interrupts coming in before they're
+ * fully set up.
+ */
+ pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+ control | (PCI_MSIX_FLAGS_ENABLE |
+ PCI_MSIX_FLAGS_MASKALL));
if ( unlikely(!memory_decoded(dev)) )
+ {
+ pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+ control & ~PCI_MSIX_FLAGS_ENABLE);
return -ENXIO;
+ }
if ( desc )
{
entry = alloc_msi_entry(1);
if ( !entry )
+ {
+ pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+ control & ~PCI_MSIX_FLAGS_ENABLE);
return -ENOMEM;
+ }
ASSERT(msi);
}
@@ -825,6 +880,8 @@ static int msix_capability_init(struct p
{
if ( !msi || !msi->table_base )
{
+ pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+ control & ~PCI_MSIX_FLAGS_ENABLE);
xfree(entry);
return -ENXIO;
}
@@ -867,6 +924,8 @@ static int msix_capability_init(struct p
if ( idx < 0 )
{
+ pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+ control & ~PCI_MSIX_FLAGS_ENABLE);
xfree(entry);
return idx;
}
@@ -922,8 +981,7 @@ static int msix_capability_init(struct p
++msix->used_entries;
/* Restore MSI-X enabled bits */
- pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
- control & ~PCI_MSIX_FLAGS_MASKALL);
+ pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
return 0;
}
@@ -1072,7 +1130,10 @@ static void __pci_disable_msix(struct ms
pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
control = pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos));
- msix_set_enable(dev, 0);
+ if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) )
+ pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+ control | (PCI_MSIX_FLAGS_ENABLE |
+ PCI_MSIX_FLAGS_MASKALL));
BUG_ON(list_empty(&dev->msi_list));
@@ -1198,6 +1259,8 @@ int pci_restore_msi_state(struct pci_dev
list_for_each_entry_safe( entry, tmp, &pdev->msi_list, list )
{
unsigned int i = 0, nr = 1;
+ u16 control = 0;
+ u8 slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
irq = entry->irq;
desc = &irq_desc[irq];
@@ -1224,10 +1287,18 @@ int pci_restore_msi_state(struct pci_dev
}
else if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX )
{
- msix_set_enable(pdev, 0);
+ control = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
+ msix_control_reg(entry->msi_attrib.pos));
+ pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+ msix_control_reg(entry->msi_attrib.pos),
+ control | (PCI_MSIX_FLAGS_ENABLE |
+ PCI_MSIX_FLAGS_MASKALL));
if ( unlikely(!memory_decoded(pdev)) )
{
spin_unlock_irqrestore(&desc->lock, flags);
+ pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+ msix_control_reg(entry->msi_attrib.pos),
+ control & ~PCI_MSIX_FLAGS_ENABLE);
return -ENXIO;
}
}
@@ -1256,11 +1327,9 @@ int pci_restore_msi_state(struct pci_dev
if ( entry->msi_attrib.type == PCI_CAP_ID_MSI )
{
unsigned int cpos = msi_control_reg(entry->msi_attrib.pos);
- u16 control = pci_conf_read16(pdev->seg, pdev->bus,
- PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn), cpos);
- control &= ~PCI_MSI_FLAGS_QSIZE;
+ control = pci_conf_read16(pdev->seg, pdev->bus, slot, func, cpos) &
+ ~PCI_MSI_FLAGS_QSIZE;
multi_msi_enable(control, entry->msi.nvec);
pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn), cpos, control);
@@ -1268,7 +1337,9 @@ int pci_restore_msi_state(struct pci_dev
msi_set_enable(pdev, 1);
}
else if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX )
- msix_set_enable(pdev, 1);
+ pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+ msix_control_reg(entry->msi_attrib.pos),
+ control | PCI_MSIX_FLAGS_ENABLE);
}
return 0;
++++++ x86-MSI-X-guest-mask.patch ++++++
References: bsc#907514 bsc#910258 bsc#918984 bsc#923967
x86/MSI: track host and guest masking separately
In particular we want to avoid losing track of our own intention to
have an entry masked. Physical unmasking now happens only when both
host and guest requested so.
Signed-off-by: Jan Beulich
Reviewed-by: Andrew Cooper
--- trunk.orig/xen/arch/x86/hpet.c 2015-01-14 18:44:18.000000000 +0100
+++ trunk/xen/arch/x86/hpet.c 2015-03-09 09:44:33.000000000 +0100
@@ -240,7 +240,7 @@ static void hpet_msi_unmask(struct irq_d
cfg = hpet_read32(HPET_Tn_CFG(ch->idx));
cfg |= HPET_TN_ENABLE;
hpet_write32(cfg, HPET_Tn_CFG(ch->idx));
- ch->msi.msi_attrib.masked = 0;
+ ch->msi.msi_attrib.host_masked = 0;
}
static void hpet_msi_mask(struct irq_desc *desc)
@@ -251,7 +251,7 @@ static void hpet_msi_mask(struct irq_des
cfg = hpet_read32(HPET_Tn_CFG(ch->idx));
cfg &= ~HPET_TN_ENABLE;
hpet_write32(cfg, HPET_Tn_CFG(ch->idx));
- ch->msi.msi_attrib.masked = 1;
+ ch->msi.msi_attrib.host_masked = 1;
}
static int hpet_msi_write(struct hpet_event_channel *ch, struct msi_msg *msg)
--- trunk.orig/xen/arch/x86/hvm/vmsi.c 2015-01-14 18:44:18.000000000 +0100
+++ trunk/xen/arch/x86/hvm/vmsi.c 2015-03-09 14:40:46.000000000 +0100
@@ -216,7 +216,6 @@ static int msixtbl_read(
{
unsigned long offset;
struct msixtbl_entry *entry;
- void *virt;
unsigned int nr_entry, index;
int r = X86EMUL_UNHANDLEABLE;
@@ -240,10 +239,16 @@ static int msixtbl_read(
}
else
{
- virt = msixtbl_addr_to_virt(entry, address);
+ const struct msi_desc *msi_desc;
+ void *virt = msixtbl_addr_to_virt(entry, address);
+
if ( !virt )
goto out;
- *pval = readl(virt);
+ msi_desc = virt_to_msi_desc(entry->pdev, virt);
+ if ( !msi_desc )
+ goto out;
+ *pval = MASK_INSR(msi_desc->msi_attrib.guest_masked,
+ PCI_MSIX_VECTOR_BITMASK);
}
r = X86EMUL_OKAY;
@@ -261,7 +266,7 @@ static int msixtbl_write(struct vcpu *v,
void *virt;
unsigned int nr_entry, index;
int r = X86EMUL_UNHANDLEABLE;
- unsigned long flags, orig;
+ unsigned long flags;
struct irq_desc *desc;
if ( len != 4 || (address & 3) )
@@ -313,37 +318,7 @@ static int msixtbl_write(struct vcpu *v,
ASSERT(msi_desc == desc->msi_desc);
- orig = readl(virt);
-
- /*
- * Do not allow guest to modify MSI-X control bit if it is masked
- * by Xen. We'll only handle the case where Xen thinks that
- * bit is unmasked, but hardware has silently masked the bit
- * (in case of SR-IOV VF reset, etc). On the other hand, if Xen
- * thinks that the bit is masked, but it's really not,
- * we log a warning.
- */
- if ( msi_desc->msi_attrib.masked )
- {
- if ( !(orig & PCI_MSIX_VECTOR_BITMASK) )
- printk(XENLOG_WARNING "MSI-X control bit is unmasked when"
- " it is expected to be masked [%04x:%02x:%02x.%u]\n",
- entry->pdev->seg, entry->pdev->bus,
- PCI_SLOT(entry->pdev->devfn),
- PCI_FUNC(entry->pdev->devfn));
-
- goto unlock;
- }
-
- /*
- * The mask bit is the only defined bit in the word. But we
- * ought to preserve the reserved bits. Clearing the reserved
- * bits can result in undefined behaviour (see PCI Local Bus
- * Specification revision 2.3).
- */
- val &= PCI_MSIX_VECTOR_BITMASK;
- val |= (orig & ~PCI_MSIX_VECTOR_BITMASK);
- writel(val, virt);
+ guest_mask_msi_irq(desc, !!(val & PCI_MSIX_VECTOR_BITMASK));
unlock:
spin_unlock_irqrestore(&desc->lock, flags);
--- trunk.orig/xen/arch/x86/msi.c 2015-05-18 11:39:36.000000000 +0200
+++ trunk/xen/arch/x86/msi.c 2015-05-18 11:44:39.000000000 +0200
@@ -388,12 +388,13 @@ int msi_maskable_irq(const struct msi_de
|| entry->msi_attrib.maskbit;
}
-static bool_t msi_set_mask_bit(struct irq_desc *desc, int flag)
+static bool_t msi_set_mask_bit(struct irq_desc *desc, bool_t host, bool_t guest)
{
struct msi_desc *entry = desc->msi_desc;
struct pci_dev *pdev;
u16 seg, control;
u8 bus, slot, func;
+ bool_t flag = host || guest;
ASSERT(spin_is_locked(&desc->lock));
BUG_ON(!entry || !entry->dev);
@@ -449,7 +450,8 @@ static bool_t msi_set_mask_bit(struct ir
default:
return 0;
}
- entry->msi_attrib.masked = !!flag;
+ entry->msi_attrib.host_masked = host;
+ entry->msi_attrib.guest_masked = guest;
return 1;
}
@@ -480,22 +482,39 @@ static int msi_get_mask_bit(const struct
void mask_msi_irq(struct irq_desc *desc)
{
- if ( unlikely(!msi_set_mask_bit(desc, 1)) )
+ if ( unlikely(!msi_set_mask_bit(desc, 1,
+ desc->msi_desc->msi_attrib.guest_masked)) )
BUG_ON(!(desc->status & IRQ_DISABLED));
}
void unmask_msi_irq(struct irq_desc *desc)
{
- if ( unlikely(!msi_set_mask_bit(desc, 0)) )
+ if ( unlikely(!msi_set_mask_bit(desc, 0,
+ desc->msi_desc->msi_attrib.guest_masked)) )
WARN();
}
+void guest_mask_msi_irq(struct irq_desc *desc, bool_t mask)
+{
+ msi_set_mask_bit(desc, desc->msi_desc->msi_attrib.host_masked, mask);
+}
+
static unsigned int startup_msi_irq(struct irq_desc *desc)
{
- unmask_msi_irq(desc);
+ bool_t guest_masked = (desc->status & IRQ_GUEST) &&
+ is_hvm_domain(desc->msi_desc->dev->domain);
+
+ if ( unlikely(!msi_set_mask_bit(desc, 0, guest_masked)) )
+ WARN();
return 0;
}
+static void shutdown_msi_irq(struct irq_desc *desc)
+{
+ if ( unlikely(!msi_set_mask_bit(desc, 1, 1)) )
+ BUG_ON(!(desc->status & IRQ_DISABLED));
+}
+
void ack_nonmaskable_msi_irq(struct irq_desc *desc)
{
irq_complete_move(desc);
@@ -520,7 +539,7 @@ void end_nonmaskable_msi_irq(struct irq_
static hw_irq_controller pci_msi_maskable = {
.typename = "PCI-MSI/-X",
.startup = startup_msi_irq,
- .shutdown = mask_msi_irq,
+ .shutdown = shutdown_msi_irq,
.enable = unmask_msi_irq,
.disable = mask_msi_irq,
.ack = ack_maskable_msi_irq,
@@ -690,7 +709,8 @@ static int msi_capability_init(struct pc
entry[i].msi_attrib.is_64 = is_64bit_address(control);
entry[i].msi_attrib.entry_nr = i;
entry[i].msi_attrib.maskbit = is_mask_bit_support(control);
- entry[i].msi_attrib.masked = 1;
+ entry[i].msi_attrib.host_masked = 1;
+ entry[i].msi_attrib.guest_masked = 0;
entry[i].msi_attrib.pos = pos;
if ( entry[i].msi_attrib.maskbit )
entry[i].msi.mpos = mpos;
@@ -939,7 +959,8 @@ static int msix_capability_init(struct p
entry->msi_attrib.is_64 = 1;
entry->msi_attrib.entry_nr = msi->entry_nr;
entry->msi_attrib.maskbit = 1;
- entry->msi_attrib.masked = 1;
+ entry->msi_attrib.host_masked = 1;
+ entry->msi_attrib.guest_masked = 1;
entry->msi_attrib.pos = pos;
entry->irq = msi->irq;
entry->dev = dev;
@@ -1309,7 +1330,8 @@ int pci_restore_msi_state(struct pci_dev
for ( i = 0; ; )
{
if ( unlikely(!msi_set_mask_bit(desc,
- entry[i].msi_attrib.masked)) )
+ entry[i].msi_attrib.host_masked,
+ entry[i].msi_attrib.guest_masked)) )
BUG();
if ( !--nr )
@@ -1462,7 +1484,7 @@ static void dump_msi(unsigned char key)
else
mask = '?';
printk(" %-6s%4u vec=%02x%7s%6s%3sassert%5s%7s"
- " dest=%08x mask=%d/%d/%c\n",
+ " dest=%08x mask=%d/%c%c/%c\n",
type, irq,
(data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT,
data & MSI_DATA_DELIVERY_LOWPRI ? "lowest" : "fixed",
@@ -1470,7 +1492,10 @@ static void dump_msi(unsigned char key)
data & MSI_DATA_LEVEL_ASSERT ? "" : "de",
addr & MSI_ADDR_DESTMODE_LOGIC ? "log" : "phys",
addr & MSI_ADDR_REDIRECTION_LOWPRI ? "lowest" : "cpu",
- dest32, attr.maskbit, attr.masked, mask);
+ dest32, attr.maskbit,
+ attr.host_masked ? 'H' : ' ',
+ attr.guest_masked ? 'G' : ' ',
+ mask);
}
}
--- trunk.orig/xen/drivers/passthrough/amd/iommu_init.c 2015-01-14 18:44:18.000000000 +0100
+++ trunk/xen/drivers/passthrough/amd/iommu_init.c 2015-03-09 09:44:48.000000000 +0100
@@ -451,7 +451,7 @@ static void iommu_msi_unmask(struct irq_
spin_lock_irqsave(&iommu->lock, flags);
amd_iommu_msi_enable(iommu, IOMMU_CONTROL_ENABLED);
spin_unlock_irqrestore(&iommu->lock, flags);
- iommu->msi.msi_attrib.masked = 0;
+ iommu->msi.msi_attrib.host_masked = 0;
}
static void iommu_msi_mask(struct irq_desc *desc)
@@ -464,7 +464,7 @@ static void iommu_msi_mask(struct irq_de
spin_lock_irqsave(&iommu->lock, flags);
amd_iommu_msi_enable(iommu, IOMMU_CONTROL_DISABLED);
spin_unlock_irqrestore(&iommu->lock, flags);
- iommu->msi.msi_attrib.masked = 1;
+ iommu->msi.msi_attrib.host_masked = 1;
}
static unsigned int iommu_msi_startup(struct irq_desc *desc)
--- trunk.orig/xen/drivers/passthrough/vtd/iommu.c 2015-05-19 23:16:48.000000000 +0200
+++ trunk/xen/drivers/passthrough/vtd/iommu.c 2015-03-09 09:44:58.000000000 +0100
@@ -996,7 +996,7 @@ static void dma_msi_unmask(struct irq_de
spin_lock_irqsave(&iommu->register_lock, flags);
dmar_writel(iommu->reg, DMAR_FECTL_REG, 0);
spin_unlock_irqrestore(&iommu->register_lock, flags);
- iommu->msi.msi_attrib.masked = 0;
+ iommu->msi.msi_attrib.host_masked = 0;
}
static void dma_msi_mask(struct irq_desc *desc)
@@ -1008,7 +1008,7 @@ static void dma_msi_mask(struct irq_desc
spin_lock_irqsave(&iommu->register_lock, flags);
dmar_writel(iommu->reg, DMAR_FECTL_REG, DMA_FECTL_IM);
spin_unlock_irqrestore(&iommu->register_lock, flags);
- iommu->msi.msi_attrib.masked = 1;
+ iommu->msi.msi_attrib.host_masked = 1;
}
static unsigned int dma_msi_startup(struct irq_desc *desc)
--- trunk.orig/xen/include/asm-x86/msi.h 2015-01-14 18:44:18.000000000 +0100
+++ trunk/xen/include/asm-x86/msi.h 2015-03-09 09:42:49.000000000 +0100
@@ -90,12 +90,13 @@ extern unsigned int pci_msix_get_table_l
struct msi_desc {
struct msi_attrib {
- __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */
- __u8 maskbit : 1; /* mask-pending bit supported ? */
- __u8 masked : 1;
+ __u8 type; /* {0: unused, 5h:MSI, 11h:MSI-X} */
+ __u8 pos; /* Location of the MSI capability */
+ __u8 maskbit : 1; /* mask/pending bit supported ? */
__u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */
- __u8 pos; /* Location of the msi capability */
- __u16 entry_nr; /* specific enabled entry */
+ __u8 host_masked : 1;
+ __u8 guest_masked : 1;
+ __u16 entry_nr; /* specific enabled entry */
} msi_attrib;
struct list_head list;
@@ -236,6 +237,7 @@ void msi_compose_msg(unsigned vector, co
void __msi_set_enable(u16 seg, u8 bus, u8 slot, u8 func, int pos, int enable);
void mask_msi_irq(struct irq_desc *);
void unmask_msi_irq(struct irq_desc *);
+void guest_mask_msi_irq(struct irq_desc *, bool_t mask);
void ack_nonmaskable_msi_irq(struct irq_desc *);
void end_nonmaskable_msi_irq(struct irq_desc *, u8 vector);
void set_msi_affinity(struct irq_desc *, const cpumask_t *);
++++++ x86-MSI-X-maskall.patch ++++++
References: bsc#907514 bsc#910258 bsc#918984 bsc#923967
x86/MSI-X: provide hypercall interface for mask-all control
Qemu shouldn't be fiddling with this bit directly, as the hypervisor
may (and now does) use it for its own purposes. Provide it with a
replacement interface, allowing the hypervisor to track host and guest
masking intentions independently (clearing the bit only when both want
it clear).
Signed-off-by: Jan Beulich
---
Whether the permission check should really be an XSM_TARGET one needs
to be determined: That allowing the guest to issue the hypercalls on
itself means permitting it to bypass the device model, and thus render
device model state stale.
--- trunk.orig/tools/libxc/include/xenctrl.h 2015-01-14 18:44:18.000000000 +0100
+++ trunk/tools/libxc/include/xenctrl.h 2015-03-25 13:51:05.000000000 +0100
@@ -1793,6 +1793,17 @@ int xc_physdev_unmap_pirq(xc_interface *
int domid,
int pirq);
+int xc_physdev_msix_enable(xc_interface *xch,
+ int segment,
+ int bus,
+ int devfn,
+ int on);
+int xc_physdev_msix_mask_all(xc_interface *xch,
+ int segment,
+ int bus,
+ int devfn,
+ int mask);
+
int xc_hvm_set_pci_intx_level(
xc_interface *xch, domid_t dom,
uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
--- trunk.orig/tools/libxc/xc_physdev.c 2013-07-09 20:57:12.000000000 +0200
+++ trunk/tools/libxc/xc_physdev.c 2015-03-24 15:59:43.000000000 +0100
@@ -108,3 +108,38 @@ int xc_physdev_unmap_pirq(xc_interface *
return rc;
}
+int xc_physdev_msix_enable(xc_interface *xch,
+ int segment,
+ int bus,
+ int devfn,
+ int on)
+{
+ struct physdev_pci_device dev = {
+ .seg = segment,
+ .bus = bus,
+ .devfn = devfn
+ };
+
+ return do_physdev_op(xch,
+ on ? PHYSDEVOP_msix_enable
+ : PHYSDEVOP_msix_disable,
+ &dev, sizeof(dev));
+}
+
+int xc_physdev_msix_mask_all(xc_interface *xch,
+ int segment,
+ int bus,
+ int devfn,
+ int mask)
+{
+ struct physdev_pci_device dev = {
+ .seg = segment,
+ .bus = bus,
+ .devfn = devfn
+ };
+
+ return do_physdev_op(xch,
+ mask ? PHYSDEVOP_msix_mask_all
+ : PHYSDEVOP_msix_unmask_all,
+ &dev, sizeof(dev));
+}
--- trunk.orig/xen/arch/x86/msi.c 2015-05-18 11:44:39.000000000 +0200
+++ trunk/xen/arch/x86/msi.c 2015-06-10 12:53:52.000000000 +0200
@@ -394,7 +394,7 @@ static bool_t msi_set_mask_bit(struct ir
struct pci_dev *pdev;
u16 seg, control;
u8 bus, slot, func;
- bool_t flag = host || guest;
+ bool_t flag = host || guest, maskall;
ASSERT(spin_is_locked(&desc->lock));
BUG_ON(!entry || !entry->dev);
@@ -415,13 +415,17 @@ static bool_t msi_set_mask_bit(struct ir
}
break;
case PCI_CAP_ID_MSIX:
+ maskall = pdev->msix->host_maskall;
control = pci_conf_read16(seg, bus, slot, func,
msix_control_reg(entry->msi_attrib.pos));
if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) )
+ {
+ pdev->msix->host_maskall = 1;
pci_conf_write16(seg, bus, slot, func,
msix_control_reg(entry->msi_attrib.pos),
control | (PCI_MSIX_FLAGS_ENABLE |
PCI_MSIX_FLAGS_MASKALL));
+ }
if ( likely(memory_decoded(pdev)) )
{
writel(flag, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
@@ -434,7 +438,7 @@ static bool_t msi_set_mask_bit(struct ir
{
domid_t domid = pdev->domain->domain_id;
- control |= PCI_MSIX_FLAGS_MASKALL;
+ maskall = 1;
if ( pdev->msix->warned != domid )
{
pdev->msix->warned = domid;
@@ -444,6 +448,9 @@ static bool_t msi_set_mask_bit(struct ir
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
}
}
+ pdev->msix->host_maskall = maskall;
+ if ( maskall || pdev->msix->guest_maskall )
+ control |= PCI_MSIX_FLAGS_MASKALL;
pci_conf_write16(seg, bus, slot, func,
msix_control_reg(entry->msi_attrib.pos), control);
return flag;
@@ -839,6 +846,7 @@ static int msix_capability_init(struct p
u8 bus = dev->bus;
u8 slot = PCI_SLOT(dev->devfn);
u8 func = PCI_FUNC(dev->devfn);
+ bool_t maskall = msix->host_maskall;
ASSERT(spin_is_locked(&pcidevs_lock));
@@ -850,6 +858,7 @@ static int msix_capability_init(struct p
* to mask all the vectors to prevent interrupts coming in before they're
* fully set up.
*/
+ msix->host_maskall = 1;
pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
control | (PCI_MSIX_FLAGS_ENABLE |
PCI_MSIX_FLAGS_MASKALL));
@@ -972,6 +981,10 @@ static int msix_capability_init(struct p
if ( !msix->used_entries )
{
+ maskall = 0;
+ msix->guest_maskall = 0;
+ control &= ~PCI_MSIX_FLAGS_MASKALL;
+
if ( rangeset_add_range(mmio_ro_ranges, msix->table.first,
msix->table.last) )
WARN();
@@ -1002,6 +1015,7 @@ static int msix_capability_init(struct p
++msix->used_entries;
/* Restore MSI-X enabled bits */
+ msix->host_maskall = maskall;
pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
return 0;
@@ -1142,6 +1156,7 @@ static void __pci_disable_msix(struct ms
int pos;
u16 control, seg;
u8 bus, slot, func;
+ bool_t maskall;
dev = entry->dev;
seg = dev->seg;
@@ -1151,10 +1166,14 @@ static void __pci_disable_msix(struct ms
pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
control = pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos));
+ maskall = dev->msix->host_maskall;
if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) )
+ {
+ dev->msix->host_maskall = 1;
pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
control | (PCI_MSIX_FLAGS_ENABLE |
PCI_MSIX_FLAGS_MASKALL));
+ }
BUG_ON(list_empty(&dev->msi_list));
@@ -1166,8 +1185,11 @@ static void __pci_disable_msix(struct ms
"cannot disable IRQ %d: masking MSI-X on %04x:%02x:%02x.%u\n",
entry->irq, dev->seg, dev->bus,
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
- control |= PCI_MSIX_FLAGS_MASKALL;
+ maskall = 1;
}
+ dev->msix->host_maskall = maskall;
+ if ( maskall || dev->msix->guest_maskall )
+ control |= PCI_MSIX_FLAGS_MASKALL;
pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
_pci_cleanup_msix(dev->msix);
@@ -1211,6 +1233,62 @@ int pci_prepare_msix(u16 seg, u8 bus, u8
return rc;
}
+int pci_msix_enable(u16 seg, u8 bus, u8 devfn, bool_t on)
+{
+ int rc;
+ struct pci_dev *pdev;
+
+ if ( !use_msi )
+ return -EOPNOTSUPP;
+
+ spin_lock(&pcidevs_lock);
+ pdev = pci_get_pdev(seg, bus, devfn);
+ if ( !pdev || !pdev->msix || !pdev->domain )
+ rc = -ENODEV;
+ else if ( !is_hvm_domain(pdev->domain) )
+ rc = -ENXIO;
+ else if ( (rc = xsm_manage_domain_pirq(XSM_TARGET, pdev->domain)) == 0 )
+ msix_set_enable(pdev, on);
+ spin_unlock(&pcidevs_lock);
+
+ return rc;
+}
+
+int pci_msix_maskall(u16 seg, u8 bus, u8 devfn, bool_t mask)
+{
+ int rc;
+ struct pci_dev *pdev;
+ u8 slot = PCI_SLOT(devfn), func = PCI_FUNC(devfn);
+
+ if ( !use_msi )
+ return -EOPNOTSUPP;
+
+ spin_lock(&pcidevs_lock);
+ pdev = pci_get_pdev(seg, bus, devfn);
+ if ( !pdev || !pdev->msix || !pdev->domain )
+ rc = -ENODEV;
+ else if ( !is_hvm_domain(pdev->domain) )
+ rc = -ENXIO;
+ else if ( (rc = xsm_manage_domain_pirq(XSM_TARGET, pdev->domain)) == 0 )
+ {
+ unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
+ PCI_CAP_ID_MSIX);
+ u16 control = pci_conf_read16(seg, bus, slot, func,
+ msix_control_reg(pos));
+
+ BUG_ON(!pos);
+ pdev->msix->guest_maskall = mask;
+ if ( pdev->msix->host_maskall || mask )
+ control |= PCI_MSIX_FLAGS_MASKALL;
+ else
+ control &= ~PCI_MSIX_FLAGS_MASKALL;
+ pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
+ }
+ spin_unlock(&pcidevs_lock);
+
+ return rc;
+}
+
/*
* Notice: only construct the msi_desc
* no change to irq_desc here, and the interrupt is masked
--- trunk.orig/xen/arch/x86/physdev.c 2015-01-14 18:44:18.000000000 +0100
+++ trunk/xen/arch/x86/physdev.c 2015-03-25 14:02:24.000000000 +0100
@@ -648,6 +648,30 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
break;
}
+ case PHYSDEVOP_msix_enable:
+ case PHYSDEVOP_msix_disable: {
+ struct physdev_pci_device dev;
+
+ if ( copy_from_guest(&dev, arg, 1) )
+ ret = -EFAULT;
+ else
+ ret = pci_msix_enable(dev.seg, dev.bus, dev.devfn,
+ cmd == PHYSDEVOP_msix_enable);
+ break;
+ }
+
+ case PHYSDEVOP_msix_mask_all:
+ case PHYSDEVOP_msix_unmask_all: {
+ struct physdev_pci_device dev;
+
+ if ( copy_from_guest(&dev, arg, 1) )
+ ret = -EFAULT;
+ else
+ ret = pci_msix_maskall(dev.seg, dev.bus, dev.devfn,
+ cmd == PHYSDEVOP_msix_mask_all);
+ break;
+ }
+
case PHYSDEVOP_pci_mmcfg_reserved: {
struct physdev_pci_mmcfg_reserved info;
--- trunk.orig/xen/include/asm-x86/msi.h 2015-03-09 09:42:49.000000000 +0100
+++ trunk/xen/include/asm-x86/msi.h 2015-03-25 14:01:00.000000000 +0100
@@ -78,6 +78,8 @@ struct msi_desc;
extern int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc);
extern void pci_disable_msi(struct msi_desc *desc);
extern int pci_prepare_msix(u16 seg, u8 bus, u8 devfn, bool_t off);
+extern int pci_msix_enable(u16 seg, u8 bus, u8 devfn, bool_t on);
+extern int pci_msix_maskall(u16 seg, u8 bus, u8 devfn, bool_t mask);
extern void pci_cleanup_msi(struct pci_dev *pdev);
extern int setup_msi_irq(struct irq_desc *, struct msi_desc *);
extern int __setup_msi_irq(struct irq_desc *, struct msi_desc *,
@@ -228,6 +230,7 @@ struct arch_msix {
int table_refcnt[MAX_MSIX_TABLE_PAGES];
int table_idx[MAX_MSIX_TABLE_PAGES];
spinlock_t table_lock;
+ bool_t host_maskall, guest_maskall;
domid_t warned;
};
--- trunk.orig/xen/include/public/physdev.h 2013-12-24 18:25:25.000000000 +0100
+++ trunk/xen/include/public/physdev.h 2015-03-24 15:54:54.000000000 +0100
@@ -310,6 +310,14 @@ DEFINE_XEN_GUEST_HANDLE(physdev_pci_devi
*/
#define PHYSDEVOP_prepare_msix 30
#define PHYSDEVOP_release_msix 31
+/*
+ * The device model domain for a guest should be using these instead of
+ * fiddling with the respective flags in the MSI-X capability structure.
+ */
+#define PHYSDEVOP_msix_enable 32
+#define PHYSDEVOP_msix_disable 33
+#define PHYSDEVOP_msix_mask_all 34
+#define PHYSDEVOP_msix_unmask_all 35
struct physdev_pci_device {
/* IN */
uint16_t seg;
--- trunk.orig/xen/include/xsm/dummy.h 2015-01-14 18:44:18.000000000 +0100
+++ trunk/xen/include/xsm/dummy.h 2015-03-23 11:13:16.000000000 +0100
@@ -439,6 +439,12 @@ static XSM_INLINE int xsm_map_domain_irq
return xsm_default_action(action, current->domain, d);
}
+static XSM_INLINE int xsm_manage_domain_pirq(XSM_DEFAULT_ARG struct domain *d)
+{
+ XSM_ASSERT_ACTION(XSM_TARGET);
+ return xsm_default_action(action, current->domain, d);
+}
+
static XSM_INLINE int xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d)
{
XSM_ASSERT_ACTION(XSM_TARGET);
--- trunk.orig/xen/include/xsm/xsm.h 2015-01-14 18:44:18.000000000 +0100
+++ trunk/xen/include/xsm/xsm.h 2015-05-15 10:28:19.000000000 +0200
@@ -105,6 +105,7 @@ struct xsm_operations {
char *(*show_irq_sid) (int irq);
int (*map_domain_pirq) (struct domain *d);
int (*map_domain_irq) (struct domain *d, int irq, void *data);
+ int (*manage_domain_pirq) (struct domain *d);
int (*unmap_domain_pirq) (struct domain *d);
int (*unmap_domain_irq) (struct domain *d, int irq, void *data);
int (*irq_permission) (struct domain *d, int pirq, uint8_t allow);
@@ -409,6 +410,11 @@ static inline int xsm_map_domain_irq (xs
return xsm_ops->map_domain_irq(d, irq, data);
}
+static inline int xsm_manage_domain_pirq(xsm_default_t def, struct domain *d)
+{
+ return xsm_ops->manage_domain_pirq(d);
+}
+
static inline int xsm_unmap_domain_pirq (xsm_default_t def, struct domain *d)
{
return xsm_ops->unmap_domain_pirq(d);
--- trunk.orig/xen/xsm/dummy.c 2015-01-14 18:44:18.000000000 +0100
+++ trunk/xen/xsm/dummy.c 2015-05-15 10:27:35.000000000 +0200
@@ -79,6 +79,7 @@ void xsm_fixup_ops (struct xsm_operation
set_to_dummy_if_null(ops, show_irq_sid);
set_to_dummy_if_null(ops, map_domain_pirq);
set_to_dummy_if_null(ops, map_domain_irq);
+ set_to_dummy_if_null(ops, manage_domain_pirq);
set_to_dummy_if_null(ops, unmap_domain_pirq);
set_to_dummy_if_null(ops, unmap_domain_irq);
set_to_dummy_if_null(ops, irq_permission);
--- trunk.orig/xen/xsm/flask/hooks.c 2015-01-14 18:44:18.000000000 +0100
+++ trunk/xen/xsm/flask/hooks.c 2015-05-15 10:27:50.000000000 +0200
@@ -875,6 +875,11 @@ static int flask_map_domain_irq (struct
return rc;
}
+static int flask_manage_domain_pirq(struct domain *d)
+{
+ return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__USE);
+}
+
static int flask_unmap_domain_pirq (struct domain *d)
{
return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
@@ -1556,6 +1561,7 @@ static struct xsm_operations flask_ops =
.map_domain_pirq = flask_map_domain_pirq,
.map_domain_irq = flask_map_domain_irq,
+ .manage_domain_pirq = flask_manage_domain_pirq,
.unmap_domain_pirq = flask_unmap_domain_pirq,
.unmap_domain_irq = flask_unmap_domain_irq,
.irq_permission = flask_irq_permission,
++++++ x86-MSI-X-teardown.patch ++++++
References: bsc#907514 bsc#910258 bsc#918984 bsc#923967
x86/MSI-X: be more careful during teardown
When a device gets detached from a guest, pciback will clear its
command register, thus disabling both memory and I/O decoding. The
disabled memory decoding, however, has an effect on the MSI-X table
accesses the hypervisor does: These won't have the intended effect
anymore. Even worse, for PCIe devices (but not SR-IOV virtual
functions) such accesses may (will?) be treated as Unsupported
Requests, causing respective errors to be surfaced, potentially in the
form of NMIs that may be fatal to the hypervisor or Dom0 is different
ways. Hence rather than carrying out these accesses, we should avoid
them where we can, and use alternative (e.g. PCI config space based)
mechanisms to achieve at least the same effect.
At this time it continues to be unclear whether this is fixing an
actual bug or is rather just working around bogus (but apparently
common) system behavior.
Signed-off-by: Jan Beulich
Reviewed-by: Andrew Cooper
---
The use of the mask-all bit here collides with qemu's incorreect use
of that same bit. This would become a security issue if released that
way. A later patch in this series will provide the infrastructure for
qemu to stop direct access to that bit. A qemu series including a patch
making use of the new interface will be sent subsequently.
Backporting note (largely to myself):
Depends on (not yet backported to 4.4 and earlier) commit 061eebe0e
"x86/MSI: drop workaround for insecure Dom0 kernels" (due to re-use
of struct arch_msix's warned field).
--- trunk.orig/xen/arch/x86/irq.c 2015-06-03 16:55:05.000000000 +0200
+++ trunk/xen/arch/x86/irq.c 2015-03-25 09:36:52.000000000 +0100
@@ -217,9 +217,9 @@ void destroy_irq(unsigned int irq)
}
spin_lock_irqsave(&desc->lock, flags);
- desc->status |= IRQ_DISABLED;
desc->status &= ~IRQ_GUEST;
desc->handler->shutdown(desc);
+ desc->status |= IRQ_DISABLED;
action = desc->action;
desc->action = NULL;
desc->msi_desc = NULL;
@@ -995,8 +995,8 @@ void __init release_irq(unsigned int irq
spin_lock_irqsave(&desc->lock,flags);
action = desc->action;
desc->action = NULL;
- desc->status |= IRQ_DISABLED;
desc->handler->shutdown(desc);
+ desc->status |= IRQ_DISABLED;
spin_unlock_irqrestore(&desc->lock,flags);
/* Wait to make sure it's not being used on another CPU */
@@ -1732,8 +1732,8 @@ static irq_guest_action_t *__pirq_guest_
BUG_ON(action->in_flight != 0);
/* Disabling IRQ before releasing the desc_lock avoids an IRQ storm. */
- desc->status |= IRQ_DISABLED;
desc->handler->disable(desc);
+ desc->status |= IRQ_DISABLED;
/*
* Mark any remaining pending EOIs as ready to flush.
--- trunk.orig/xen/arch/x86/msi.c 2015-05-19 23:16:48.000000000 +0200
+++ trunk/xen/arch/x86/msi.c 2015-03-25 09:35:38.000000000 +0100
@@ -121,6 +121,27 @@ static void msix_put_fixmap(struct arch_
spin_unlock(&msix->table_lock);
}
+static bool_t memory_decoded(const struct pci_dev *dev)
+{
+ u8 bus, slot, func;
+
+ if ( !dev->info.is_virtfn )
+ {
+ bus = dev->bus;
+ slot = PCI_SLOT(dev->devfn);
+ func = PCI_FUNC(dev->devfn);
+ }
+ else
+ {
+ bus = dev->info.physfn.bus;
+ slot = PCI_SLOT(dev->info.physfn.devfn);
+ func = PCI_FUNC(dev->info.physfn.devfn);
+ }
+
+ return !!(pci_conf_read16(dev->seg, bus, slot, func, PCI_COMMAND) &
+ PCI_COMMAND_MEMORY);
+}
+
/*
* MSI message composition
*/
@@ -162,7 +183,7 @@ void msi_compose_msg(unsigned vector, co
}
}
-static void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
+static bool_t read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
switch ( entry->msi_attrib.type )
{
@@ -198,6 +219,8 @@ static void read_msi_msg(struct msi_desc
void __iomem *base;
base = entry->mask_base;
+ if ( unlikely(!memory_decoded(entry->dev)) )
+ return 0;
msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
@@ -209,6 +232,8 @@ static void read_msi_msg(struct msi_desc
if ( iommu_intremap )
iommu_read_msi_from_ire(entry, msg);
+
+ return 1;
}
static int write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
@@ -260,6 +285,8 @@ static int write_msi_msg(struct msi_desc
void __iomem *base;
base = entry->mask_base;
+ if ( unlikely(!memory_decoded(entry->dev)) )
+ return -ENXIO;
writel(msg->address_lo,
base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
writel(msg->address_hi,
@@ -287,7 +314,8 @@ void set_msi_affinity(struct irq_desc *d
ASSERT(spin_is_locked(&desc->lock));
memset(&msg, 0, sizeof(msg));
- read_msi_msg(msi_desc, &msg);
+ if ( !read_msi_msg(msi_desc, &msg) )
+ return;
msg.data &= ~MSI_DATA_VECTOR_MASK;
msg.data |= MSI_DATA_VECTOR(desc->arch.vector);
@@ -347,20 +375,24 @@ int msi_maskable_irq(const struct msi_de
|| entry->msi_attrib.maskbit;
}
-static void msi_set_mask_bit(struct irq_desc *desc, int flag)
+static bool_t msi_set_mask_bit(struct irq_desc *desc, int flag)
{
struct msi_desc *entry = desc->msi_desc;
+ struct pci_dev *pdev;
+ u16 seg;
+ u8 bus, slot, func;
ASSERT(spin_is_locked(&desc->lock));
BUG_ON(!entry || !entry->dev);
+ pdev = entry->dev;
+ seg = pdev->seg;
+ bus = pdev->bus;
+ slot = PCI_SLOT(pdev->devfn);
+ func = PCI_FUNC(pdev->devfn);
switch (entry->msi_attrib.type) {
case PCI_CAP_ID_MSI:
if (entry->msi_attrib.maskbit) {
u32 mask_bits;
- u16 seg = entry->dev->seg;
- u8 bus = entry->dev->bus;
- u8 slot = PCI_SLOT(entry->dev->devfn);
- u8 func = PCI_FUNC(entry->dev->devfn);
mask_bits = pci_conf_read32(seg, bus, slot, func, entry->msi.mpos);
mask_bits &= ~((u32)1 << entry->msi_attrib.entry_nr);
@@ -369,24 +401,52 @@ static void msi_set_mask_bit(struct irq_
}
break;
case PCI_CAP_ID_MSIX:
- {
- int offset = PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
- writel(flag, entry->mask_base + offset);
- readl(entry->mask_base + offset);
- break;
- }
+ if ( likely(memory_decoded(pdev)) )
+ {
+ writel(flag, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+ readl(entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+ break;
+ }
+ if ( flag )
+ {
+ u16 control;
+ domid_t domid = pdev->domain->domain_id;
+
+ control = pci_conf_read16(seg, bus, slot, func,
+ msix_control_reg(entry->msi_attrib.pos));
+ if ( control & PCI_MSIX_FLAGS_MASKALL )
+ break;
+ pci_conf_write16(seg, bus, slot, func,
+ msix_control_reg(entry->msi_attrib.pos),
+ control | PCI_MSIX_FLAGS_MASKALL);
+ if ( pdev->msix->warned != domid )
+ {
+ pdev->msix->warned = domid;
+ printk(XENLOG_G_WARNING
+ "cannot mask IRQ %d: masked MSI-X on Dom%d's %04x:%02x:%02x.%u\n",
+ desc->irq, domid, pdev->seg, pdev->bus,
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+ }
+ break;
+ }
+ /* fall through */
default:
- BUG();
- break;
+ return 0;
}
entry->msi_attrib.masked = !!flag;
+
+ return 1;
}
static int msi_get_mask_bit(const struct msi_desc *entry)
{
- switch (entry->msi_attrib.type) {
+ if ( !entry->dev )
+ return -1;
+
+ switch ( entry->msi_attrib.type )
+ {
case PCI_CAP_ID_MSI:
- if (!entry->dev || !entry->msi_attrib.maskbit)
+ if ( !entry->msi_attrib.maskbit )
break;
return (pci_conf_read32(entry->dev->seg, entry->dev->bus,
PCI_SLOT(entry->dev->devfn),
@@ -394,6 +454,8 @@ static int msi_get_mask_bit(const struct
entry->msi.mpos) >>
entry->msi_attrib.entry_nr) & 1;
case PCI_CAP_ID_MSIX:
+ if ( unlikely(!memory_decoded(entry->dev)) )
+ break;
return readl(entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET) & 1;
}
return -1;
@@ -401,12 +463,14 @@ static int msi_get_mask_bit(const struct
void mask_msi_irq(struct irq_desc *desc)
{
- msi_set_mask_bit(desc, 1);
+ if ( unlikely(!msi_set_mask_bit(desc, 1)) )
+ BUG_ON(!(desc->status & IRQ_DISABLED));
}
void unmask_msi_irq(struct irq_desc *desc)
{
- msi_set_mask_bit(desc, 0);
+ if ( unlikely(!msi_set_mask_bit(desc, 0)) )
+ WARN();
}
static unsigned int startup_msi_irq(struct irq_desc *desc)
@@ -723,6 +787,9 @@ static int msix_capability_init(struct p
control = pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos));
msix_set_enable(dev, 0);/* Ensure msix is disabled as I set it up */
+ if ( unlikely(!memory_decoded(dev)) )
+ return -ENXIO;
+
if ( desc )
{
entry = alloc_msi_entry(1);
@@ -855,7 +922,8 @@ static int msix_capability_init(struct p
++msix->used_entries;
/* Restore MSI-X enabled bits */
- pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
+ pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+ control & ~PCI_MSIX_FLAGS_MASKALL);
return 0;
}
@@ -1008,8 +1076,16 @@ static void __pci_disable_msix(struct ms
BUG_ON(list_empty(&dev->msi_list));
- writel(1, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
-
+ if ( likely(memory_decoded(dev)) )
+ writel(1, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+ else if ( !(control & PCI_MSIX_FLAGS_MASKALL) )
+ {
+ printk(XENLOG_WARNING
+ "cannot disable IRQ %d: masking MSI-X on %04x:%02x:%02x.%u\n",
+ entry->irq, dev->seg, dev->bus,
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+ control |= PCI_MSIX_FLAGS_MASKALL;
+ }
pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
_pci_cleanup_msix(dev->msix);
@@ -1147,14 +1223,23 @@ int pci_restore_msi_state(struct pci_dev
nr = entry->msi.nvec;
}
else if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX )
+ {
msix_set_enable(pdev, 0);
+ if ( unlikely(!memory_decoded(pdev)) )
+ {
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return -ENXIO;
+ }
+ }
msg = entry->msg;
write_msi_msg(entry, &msg);
for ( i = 0; ; )
{
- msi_set_mask_bit(desc, entry[i].msi_attrib.masked);
+ if ( unlikely(!msi_set_mask_bit(desc,
+ entry[i].msi_attrib.masked)) )
+ BUG();
if ( !--nr )
break;
++++++ xen-4.5.0-testing-src.tar.bz2 -> xen-4.5.1-testing-src.tar.bz2 ++++++
++++ 4434 lines of diff (skipped)
++++++ xen-destdir.patch ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:51:00.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:51:00.000000000 +0200
@@ -1,7 +1,5 @@
-Index: xen-4.5.0-testing/tools/xenstore/Makefile
-===================================================================
---- xen-4.5.0-testing.orig/tools/xenstore/Makefile
-+++ xen-4.5.0-testing/tools/xenstore/Makefile
+--- a/tools/xenstore/Makefile
++++ b/tools/xenstore/Makefile
@@ -19,6 +19,7 @@ LDFLAGS += $(LDFLAGS-y)
CLIENTS := xenstore-exists xenstore-list xenstore-read xenstore-rm xenstore-chmod
@@ -38,19 +36,12 @@
$(RM) $(DEPS)
.PHONY: TAGS
-@@ -132,12 +136,16 @@ ifeq ($(XENSTORE_XENSTORED),y)
- $(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
- $(INSTALL_DIR) $(DESTDIR)$(XEN_LIB_STORED)
- $(INSTALL_PROG) xenstored $(DESTDIR)$(SBINDIR)
-+ $(INSTALL_DIR) $(DESTDIR)/bin
- endif
- $(INSTALL_PROG) xenstore-control $(DESTDIR)$(BINDIR)
- $(INSTALL_PROG) xenstore $(DESTDIR)$(BINDIR)
+@@ -138,6 +142,9 @@ ifeq ($(XENSTORE_XENSTORED),y)
set -e ; for c in $(CLIENTS) ; do \
ln -f $(DESTDIR)$(BINDIR)/xenstore $(DESTDIR)$(BINDIR)/$${c} ; \
done
+ for client in $(CLIENTS_DOMU); do \
-+ $(INSTALL_PROG) $$client $(DESTDIR)/bin/$${client/domu-}; \
++ $(INSTALL_PROG) $$client $(DESTDIR)/$(BINDIR)/$${client/domu-}; \
+ done
$(INSTALL_DIR) $(DESTDIR)$(LIBDIR)
$(INSTALL_SHLIB) libxenstore.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)
++++++ xen-dom0-modules.service ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:51:00.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:51:00.000000000 +0200
@@ -2,6 +2,7 @@
Description=Load dom0 backend drivers
ConditionPathExists=/proc/xen
Before=proc-xen.mount
+DefaultDependencies=no
[Install]
WantedBy=multi-user.target
++++++ xen.build-compare.xen_compile_h.patch ++++++
--- /var/tmp/diff_new_pack.JjbkfL/_old 2015-07-05 17:51:00.000000000 +0200
+++ /var/tmp/diff_new_pack.JjbkfL/_new 2015-07-05 17:51:00.000000000 +0200
@@ -1,8 +1,8 @@
Use stable strings to reduce build-compare noise.
-Index: xen-4.5.0-testing/xen/Makefile
+Index: xen-4.5.1-testing/xen/Makefile
===================================================================
---- xen-4.5.0-testing.orig/xen/Makefile
-+++ xen-4.5.0-testing/xen/Makefile
+--- xen-4.5.1-testing.orig/xen/Makefile
++++ xen-4.5.1-testing/xen/Makefile
@@ -8,6 +8,9 @@ export XEN_FULLVERSION = $(XEN_VERSION
export XEN_WHOAMI ?= $(USER)