The package rpms/xen.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/xen.git/commit/?id=ba63a02fbc348b...
https://src.fedoraproject.org/cgit/rpms/xen.git/commit/?id=937578a14e8f0f....
Change:
-%ifarch x86_64
-%ifnarch armv7hl aarch64
Thanks.
Full change:
============
commit 852b076a0e9b1a196a814c632e357950b743a8f7
Author: Michael Young <m.a.young(a)durham.ac.uk>
Date: Fri Apr 5 21:08:20 2019 +0100
drop systemd_postun and renumber patches
diff --git a/.gitignore b/.gitignore
index 130be34..7d62d29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,4 @@ lwip-1.3.0.tar.gz
pciutils-2.2.9.tar.bz2
zlib-1.2.3.tar.gz
polarssl-1.1.4-gpl.tgz
-/xen-4.11.1.tar.gz
+/xen-4.12.0.tar.gz
diff --git a/sources b/sources
index f2266d9..b5efa23 100644
--- a/sources
+++ b/sources
@@ -4,4 +4,4 @@ SHA512 (newlib-1.16.0.tar.gz) =
40eb96bbc6736a16b6399e0cdb73e853d0d90b685c967e77
SHA512 (zlib-1.2.3.tar.gz) =
021b958fcd0d346c4ba761bcf0cc40f3522de6186cf5a0a6ea34a70504ce9622b1c2626fce40675bc8282cf5f5ade18473656abc38050f72f5d6480507a2106e
SHA512 (polarssl-1.1.4-gpl.tgz) =
88da614e4d3f4409c4fd3bb3e44c7587ba051e3fed4e33d526069a67e8180212e1ea22da984656f50e290049f60ddca65383e5983c0f8884f648d71f698303ad
SHA512 (pciutils-2.2.9.tar.bz2) =
2b3d98d027e46d8c08037366dde6f0781ca03c610ef2b380984639e4ef39899ed8d8b8e4cd9c9dc54df101279b95879bd66bfd4d04ad07fef41e847ea7ae32b5
-SHA512 (xen-4.11.1.tar.gz) =
c1655c5decdaed95a2b9a99652318cfc72f6cfdae957cfe60d635f7787e8850f33e8fafc4c4b8d61fb579c9b9d93028a6382903e71808a0418b931e76d72a649
+SHA512 (xen-4.12.0.tar.gz) =
0ce366dcac607c9b592c5e9c0f40652eef743913b246bed4b0c380b8d59ac23a6adcd05befec37fc799a61476f47df76d4911cbf1da6ceb51441c546bf2464de
diff --git a/xen.spec b/xen.spec
index b122ac8..56421b0 100644
--- a/xen.spec
+++ b/xen.spec
@@ -58,7 +58,7 @@
Summary: Xen is a virtual machine monitor
Name: xen
Version: 4.12.0
-Release: 0%{?dist}
+Release: 1%{?dist}
License: GPLv2+ and LGPLv2+ and BSD
URL:
http://xen.org/
Source0:
https://downloads.xenproject.org/release/xen/%{version}/xen-%{version}.ta...
@@ -109,10 +109,10 @@ Patch36: qemu.trad.CVE-2017-7718.patch
Patch37: droplibvirtconflict.patch
Patch38: qemu.trad.CVE-2017-8309.patch
Patch39: qemu.trad.CVE-2017-9330.patch
-Patch41: xen.drop.brctl.patch
-Patch45: xen.python.env.patch
-Patch46: xen.gcc9.fixes.patch
-Patch47: xen.python3.patch
+Patch40: xen.drop.brctl.patch
+Patch41: xen.python.env.patch
+Patch42: xen.gcc9.fixes.patch
+Patch43: xen.python3.patch
%if %build_qemutrad
@@ -172,7 +172,6 @@ BuildRequires: ocaml, ocaml-findlib
%if %with_systemd_presets
Requires(post): systemd
Requires(preun): systemd
-Requires(postun): systemd
BuildRequires: systemd
%endif
BuildRequires: systemd-devel
@@ -307,10 +306,10 @@ manage Xen virtual machines.
%patch34 -p1
%patch37 -p1
%patch3 -p1
+%patch40 -p1
%patch41 -p1
-%patch45 -p1
-%patch46 -p1
-%patch47 -p1
+%patch42 -p1
+%patch43 -p1
# qemu-xen-traditional patches
pushd tools/qemu-xen-traditional
@@ -544,11 +543,6 @@ if [ $1 == 0 ]; then
fi
%endif
-%if %with_systemd_presets
-%postun
-%systemd_postun
-%endif
-
%post runtime
%if %with_systemd_presets
%systemd_post xenstored.service xenconsoled.service
@@ -569,11 +563,6 @@ if [ $1 == 0 ]; then
fi
%endif
-%if %with_systemd_presets
-%postun runtime
-%systemd_postun
-%endif
-
%posttrans runtime
if [ ! -L /usr/lib/xen -a -d /usr/lib/xen -a -z "$(ls -A /usr/lib/xen)" ]; then
rmdir /usr/lib/xen
@@ -624,11 +613,6 @@ if [ $1 == 0 ]; then
/bin/systemctl disable oxenstored.service
fi
%endif
-
-%if %with_systemd_presets
-%postun ocaml
-%systemd_postun
-%endif
%endif
# Base package only contains XenD/xm python stuff
@@ -858,7 +842,7 @@ fi
%endif
%changelog
-* Thu Apr 04 2019 Michael Young <m.a.young(a)durham.ac.uk> - 4.12.0-0
+* Fri Apr 05 2019 Michael Young <m.a.young(a)durham.ac.uk> - 4.12.0-1
- update to 4.12.0 (#1694695)
remove patches for issues now fixed upstream
replace xen.use.fedora.ipxe.patch with --with-system-ipxe
@@ -870,6 +854,7 @@ fi
xen-ringwatch xen-bugtool have been dropped
- remove remaining traces of efiming and efi_flags logic
- switch from python2 to python3
+- drop systemd_postun and renumber patches
* Tue Mar 05 2019 Michael Young <m.a.young(a)durham.ac.uk> - 4.11.1-4
- xen: various flaws (#1685577)
commit 995f98f00005c045b58d0524f7841267898d8094
Author: Michael Young <m.a.young(a)durham.ac.uk>
Date: Fri Apr 5 20:55:26 2019 +0100
switch from python2 to python3
diff --git a/xen.python.env.patch b/xen.python.env.patch
index 8844b18..3b8c1e6 100644
--- a/xen.python.env.patch
+++ b/xen.python.env.patch
@@ -37,7 +37,7 @@
+++ xen-4.11.0/tools/misc/xencov_split 2018-09-18 21:56:07.397893895 +0100
@@ -1,4 +1,4 @@
-#!/usr/bin/python
-+#!/usr/bin/python2
++#!/usr/bin/python3
import sys, os, os.path as path, struct, errno
from optparse import OptionParser
diff --git a/xen.python3.patch b/xen.python3.patch
new file mode 100644
index 0000000..a89b4d9
--- /dev/null
+++ b/xen.python3.patch
@@ -0,0 +1,1749 @@
+From a9047a722ba5de38e7c1d762ffcfb74c36725fe2 Mon Sep 17 00:00:00 2001
+From: Andrew Cooper <andrew.cooper3(a)citrix.com>
+Date: Mon, 11 Mar 2019 19:18:40 +0000
+Subject: [PATCH] tools/xen-foreign: Update python scripts to be Py3 compatible
+
+The issues are:
+ * dict.has_key() was completely removed in Py3
+ * dict.keys() is an iterable rather than list in Py3, so .sort() doesn't work.
+ * list.sort(cmp=) was deprecated in Py2.4 and removed in Py3.
+
+The has_key() issue is trivially fixed by switching to using the in keyword.
+The sorting issue could be trivially fixed, but take the opportunity to
+improve the code.
+
+The reason for the sorting is to ensure that "unsigned long" gets replaced
+before "long", and the only reason sorting is necessary is because
+inttypes[arch] is needlessly a dictionary. Update inttypes[arch] to be a list
+of tuples rather than a dictionary, and process them in list order.
+
+Reported-by: George Dunlap <george.dunlap(a)eu.citrix.com>
+Signed-off-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+Acked-by: Wei Liu <wei.liu2(a)citrix.com>
+---
+ tools/include/xen-foreign/mkchecker.py | 2 +-
+ tools/include/xen-foreign/mkheader.py | 58 +++++++++++++-------------
+ 2 files changed, 29 insertions(+), 31 deletions(-)
+
+diff --git a/tools/include/xen-foreign/mkchecker.py
b/tools/include/xen-foreign/mkchecker.py
+index fdad869a91..199b0eebbc 100644
+--- a/tools/include/xen-foreign/mkchecker.py
++++ b/tools/include/xen-foreign/mkchecker.py
+@@ -37,7 +37,7 @@ for struct in structs:
+ f.write('\tprintf("%%-25s |", "%s");\n' % struct);
+ for a in archs:
+ s = struct + "_" + a;
+- if compat_arches.has_key(a):
++ if a in compat_arches:
+ compat = compat_arches[a]
+ c = struct + "_" + compat;
+ else:
+diff --git a/tools/include/xen-foreign/mkheader.py
b/tools/include/xen-foreign/mkheader.py
+index 97e0c7a984..fb268f0dce 100644
+--- a/tools/include/xen-foreign/mkheader.py
++++ b/tools/include/xen-foreign/mkheader.py
+@@ -17,13 +17,13 @@ header = {};
+ footer = {};
+
+ #arm
+-inttypes["arm32"] = {
+- "unsigned long" : "__danger_unsigned_long_on_arm32",
+- "long" : "__danger_long_on_arm32",
+- "xen_pfn_t" : "uint64_t",
+- "xen_ulong_t" : "uint64_t",
+- "uint64_t" : "__align8__ uint64_t",
+-};
++inttypes["arm32"] = [
++ ("unsigned long", "__danger_unsigned_long_on_arm32"),
++ ("long", "__danger_long_on_arm32"),
++ ("xen_pfn_t", "uint64_t"),
++ ("xen_ulong_t", "uint64_t"),
++ ("uint64_t", "__align8__ uint64_t"),
++]
+ header["arm32"] = """
+ #define __arm___ARM32 1
+ #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+@@ -38,13 +38,13 @@ footer["arm32"] = """
+ #undef __DECL_REG
+ """
+
+-inttypes["arm64"] = {
+- "unsigned long" : "__danger_unsigned_long_on_arm64",
+- "long" : "__danger_long_on_arm64",
+- "xen_pfn_t" : "uint64_t",
+- "xen_ulong_t" : "uint64_t",
+- "uint64_t" : "__align8__ uint64_t",
+-};
++inttypes["arm64"] = [
++ ("unsigned long", "__danger_unsigned_long_on_arm64"),
++ ("long", "__danger_long_on_arm64"),
++ ("xen_pfn_t", "uint64_t"),
++ ("xen_ulong_t", "uint64_t"),
++ ("uint64_t", "__align8__ uint64_t"),
++]
+ header["arm64"] = """
+ #define __aarch64___ARM64 1
+ #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+@@ -60,12 +60,12 @@ footer["arm64"] = """
+ """
+
+ # x86_32
+-inttypes["x86_32"] = {
+- "unsigned long" : "uint32_t",
+- "long" : "uint32_t",
+- "xen_pfn_t" : "uint32_t",
+- "xen_ulong_t" : "uint32_t",
+-};
++inttypes["x86_32"] = [
++ ("unsigned long", "uint32_t"),
++ ("long", "uint32_t"),
++ ("xen_pfn_t", "uint32_t"),
++ ("xen_ulong_t", "uint32_t"),
++]
+ header["x86_32"] = """
+ #define __DECL_REG_LO8(which) uint32_t e ## which ## x
+ #define __DECL_REG_LO16(name) uint32_t e ## name
+@@ -79,12 +79,12 @@ footer["x86_32"] = """
+ """;
+
+ # x86_64
+-inttypes["x86_64"] = {
+- "unsigned long" : "__align8__ uint64_t",
+- "long" : "__align8__ uint64_t",
+- "xen_pfn_t" : "__align8__ uint64_t",
+- "xen_ulong_t" : "__align8__ uint64_t",
+-};
++inttypes["x86_64"] = [
++ ("unsigned long", "__align8__ uint64_t"),
++ ("long", "__align8__ uint64_t"),
++ ("xen_pfn_t", "__align8__ uint64_t"),
++ ("xen_ulong_t", "__align8__ uint64_t"),
++]
+ header["x86_64"] = """
+ #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+ # define __DECL_REG(name) union { uint64_t r ## name, e ## name; }
+@@ -205,10 +205,8 @@ for struct in structs:
+ output = re.sub("\\b(%s)_t\\b" % struct, "\\1_%s_t" % arch,
output);
+
+ # replace: integer types
+-integers = inttypes[arch].keys();
+-integers.sort(lambda a, b: cmp(len(b),len(a)));
+-for type in integers:
+- output = re.sub("\\b%s\\b" % type, inttypes[arch][type], output);
++for old, new in inttypes[arch]:
++ output = re.sub("\\b%s\\b" % old, new, output)
+
+ # print results
+ f = open(outfile, "w");
+--
+2.17.2
+
+From 72288c156662e764cc47605f51842b4d0fcc3582 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Mon, 11 Mar 2019 17:16:45 +0000
+Subject: [PATCH 1/8] Update Python requirement to 2.6
+
+CentOS 5, which was the reason for the 2.4 restriction, is EOL. CentOS
+6 ships 2.6.
+
+Bump the version to 2.6 in README. Update configure.
+
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Acked-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ README | 4 ++--
+ tools/configure | 8 ++++----
+ tools/configure.ac | 2 +-
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/README b/README
+index 6346825bc0..d00715c2fd 100644
+--- a/README
++++ b/README
+@@ -46,7 +46,7 @@ provided by your OS distributor:
+ - GCC 4.8 or later
+ - GNU Binutils 2.24 or later
+ * Development install of zlib (e.g., zlib-dev)
+- * Development install of Python 2, v2.4 or later (e.g., python-dev)
++ * Development install of Python 2, v2.6 or later (e.g., python-dev)
+ * Development install of curses (e.g., libncurses-dev)
+ * Development install of openssl (e.g., openssl-dev)
+ * Development install of x11 (e.g. xorg-x11-dev)
+@@ -177,7 +177,7 @@ Python Runtime Libraries
+
+ Various tools, such as pygrub, have the following runtime dependencies:
+
+- * Python 2, v2.4 or later.
++ * Python 2, v2.6 or later.
+ URL:
http://www.python.org/
+ Debian: python
+
+diff --git a/tools/configure b/tools/configure
+index acc857510e..d0065b811d 100755
+--- a/tools/configure
++++ b/tools/configure
+@@ -7002,15 +7002,15 @@ if test x"${PYTHONPATH}" = x"no"
+ then
+ as_fn_error $? "Unable to find $PYTHON, please install $PYTHON"
"$LINENO" 5
+ fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for python version >= 2.3
" >&5
+-$as_echo_n "checking for python version >= 2.3 ... " >&6; }
+-`$PYTHON -c 'import sys; sys.exit(eval("sys.version_info < (2,
3)"))'`
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for python version >= 2.6
" >&5
++$as_echo_n "checking for python version >= 2.6 ... " >&6; }
++`$PYTHON -c 'import sys; sys.exit(eval("sys.version_info < (2,
6)"))'`
+ if test "$?" != "0"
+ then
+ python_version=`$PYTHON -V 2>&1`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+- as_fn_error $? "$python_version is too old, minimum required version is
2.3" "$LINENO" 5
++ as_fn_error $? "$python_version is too old, minimum required version is
2.6" "$LINENO" 5
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ $as_echo "yes" >&6; }
+diff --git a/tools/configure.ac b/tools/configure.ac
+index 1499344ce6..c9fd69ddfa 100644
+--- a/tools/configure.ac
++++ b/tools/configure.ac
+@@ -358,7 +358,7 @@ AS_IF([echo "$PYTHON" | grep -q "^/"], [
+ ],[test -z "$PYTHON"], [PYTHON="python"],
+ [AC_MSG_ERROR([PYTHON specified, but is not an absolute path])])
+ AX_PATH_PROG_OR_FAIL([PYTHONPATH], [$PYTHON])
+-AX_CHECK_PYTHON_VERSION([2], [3])
++AX_CHECK_PYTHON_VERSION([2], [6])
+
+ AS_IF([test "$cross_compiling" != yes], [
+ AX_CHECK_PYTHON_DEVEL()
+--
+2.17.2
+
+
+From e81209fd4ea705f4de4b61d05e6ab0aea9bb0b88 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Mon, 11 Mar 2019 12:58:05 +0000
+Subject: [PATCH 2/8] pygrub/fsimage: drop unused struct
+
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ tools/pygrub/src/fsimage/fsimage.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/tools/pygrub/src/fsimage/fsimage.c b/tools/pygrub/src/fsimage/fsimage.c
+index 743a3fb7b8..780207791c 100644
+--- a/tools/pygrub/src/fsimage/fsimage.c
++++ b/tools/pygrub/src/fsimage/fsimage.c
+@@ -43,13 +43,6 @@ typedef struct fsimage_file {
+ fsi_file_t *file;
+ } fsimage_file_t;
+
+-struct foo {
+- int ref;
+- int size;
+- long hash;
+- int state;
+-};
+-
+ static PyObject *
+ fsimage_file_read(fsimage_file_t *file, PyObject *args, PyObject *kwargs)
+ {
+--
+2.17.2
+
+
+From b9e1368af14ded6aee3bdf64e8329628b16291ff Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Mon, 11 Mar 2019 12:55:29 +0000
+Subject: [PATCH 3/8] pygrub: change tabs into spaces
+
+Not sure why Python 2 never complained, but Python 3 does.
+
+Change tabs to spaces.
+
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ tools/pygrub/src/pygrub | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
+index 52a8965ad9..1189b1ca48 100755
+--- a/tools/pygrub/src/pygrub
++++ b/tools/pygrub/src/pygrub
+@@ -858,7 +858,7 @@ if __name__ == "__main__":
+ output_directory = a
+
+ if debug:
+- logging.basicConfig(level=logging.DEBUG)
++ logging.basicConfig(level=logging.DEBUG)
+
+
+ try:
+@@ -917,7 +917,7 @@ if __name__ == "__main__":
+ # IOErrors raised by fsimage.open
+ # RuntimeErrors raised by run_grub if no menu.lst present
+ if debug:
+- traceback.print_exc()
++ traceback.print_exc()
+ fs = None
+ continue
+
+--
+2.17.2
+
+
+From 16cc3362aed39e3093419b9df6ec73269071d063 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Tue, 5 Mar 2019 12:32:06 +0000
+Subject: [PATCH 4/8] build/m4: make python_devel.m4 work with both python 2
+ and 3
+
+Do the following:
+
+1. Change the form of "print".
+2. Use AC_CHECK_FUNC to avoid the need to generate library name.
+3. Remove unused stuff.
+
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Reviewed-by: Anthony PERARD <anthony.perard(a)citrix.com>
+---
+ m4/python_devel.m4 | 23 ++++++-----------
+ tools/configure | 64 ++++++----------------------------------------
+ 2 files changed, 16 insertions(+), 71 deletions(-)
+
+diff --git a/m4/python_devel.m4 b/m4/python_devel.m4
+index 05ea4ef7e2..f9cb23aee1 100644
+--- a/m4/python_devel.m4
++++ b/m4/python_devel.m4
+@@ -1,38 +1,31 @@
+ AC_DEFUN([AX_CHECK_PYTHON_DEVEL], [
+ ac_previous_cppflags=$CPPFLAGS
+ ac_previous_ldflags=$LDFLAGS
+-ac_python_version=`$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("VERSION")'`
+ AC_PATH_PROG([pyconfig], [$PYTHON-config], [no])
+ AS_IF([test x"$pyconfig" = x"no"], [
+ dnl For those that don't have python-config
+ CPPFLAGS="$CFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+ print "-I" +
distutils.sysconfig.get_config_var("INCLUDEPY")'`"
+ CPPFLAGS="$CPPFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("CFLAGS")'`"
+- PYTHON_LIBS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("LIBS")'`"
+- PYTHON_LIBS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("SYSLIBS")'`"
++ print(distutils.sysconfig.get_config_var("CFLAGS"))'`"
+ LDFLAGS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print "-L" + distutils.sysconfig.get_python_lib(plat_specific=1,\
+- standard_lib=1) + "/config"'`"
++ print("-L" + distutils.sysconfig.get_python_lib(plat_specific=1,\
++ standard_lib=1) + "/config")'`"
+ LDFLAGS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("LINKFORSHARED")'`"
++
print(distutils.sysconfig.get_config_var("LINKFORSHARED"))'`"
+ LDFLAGS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("LDFLAGS")'`"
++ print(distutils.sysconfig.get_config_var("LDFLAGS"))'`"
+ ], [
+ dnl If python-config is found use it
+ CPPFLAGS="$CFLAGS `$PYTHON-config --cflags`"
+ LDFLAGS="$LDFLAGS `$PYTHON-config --ldflags`"
+- PYTHON_LIBS="$LIBS `$PYTHON-config --libs`"
+ ])
+
+ AC_CHECK_HEADER([Python.h], [],
+ [AC_MSG_ERROR([Unable to find Python development headers])],)
+-AC_CHECK_LIB(python$ac_python_version, PyArg_ParseTuple, [],
+- [AC_MSG_ERROR([Unable to find a suitable python development library])],
+- [$PYTHON_LIBS])
++AC_CHECK_FUNC([PyArg_ParseTuple], [],
++ [AC_MSG_ERROR([Unable to find a suitable python development library])])
++
+ CPPFLAGS=$ac_previous_cppflags
+ LDFLAGS=$ac_previous_ldflags
+ ])
+diff --git a/tools/configure b/tools/configure
+index d0065b811d..e1fa5d6b0f 100755
+--- a/tools/configure
++++ b/tools/configure
+@@ -7418,8 +7418,6 @@ if test "$cross_compiling" != yes; then :
+
+ ac_previous_cppflags=$CPPFLAGS
+ ac_previous_ldflags=$LDFLAGS
+-ac_python_version=`$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("VERSION")'`
+ # Extract the first word of "$PYTHON-config", so it can be a program name with
args.
+ set dummy $PYTHON-config; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+@@ -7466,24 +7464,19 @@ if test x"$pyconfig" = x"no"; then :
+ CPPFLAGS="$CFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+ print "-I" +
distutils.sysconfig.get_config_var("INCLUDEPY")'`"
+ CPPFLAGS="$CPPFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("CFLAGS")'`"
+- PYTHON_LIBS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("LIBS")'`"
+- PYTHON_LIBS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("SYSLIBS")'`"
++ print(distutils.sysconfig.get_config_var("CFLAGS"))'`"
+ LDFLAGS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print "-L" + distutils.sysconfig.get_python_lib(plat_specific=1,\
+- standard_lib=1) + "/config"'`"
++ print("-L" + distutils.sysconfig.get_python_lib(plat_specific=1,\
++ standard_lib=1) + "/config")'`"
+ LDFLAGS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("LINKFORSHARED")'`"
++
print(distutils.sysconfig.get_config_var("LINKFORSHARED"))'`"
+ LDFLAGS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+- print distutils.sysconfig.get_config_var("LDFLAGS")'`"
++ print(distutils.sysconfig.get_config_var("LDFLAGS"))'`"
+
+ else
+
+ CPPFLAGS="$CFLAGS `$PYTHON-config --cflags`"
+ LDFLAGS="$LDFLAGS `$PYTHON-config --ldflags`"
+- PYTHON_LIBS="$LIBS `$PYTHON-config --libs`"
+
+ fi
+
+@@ -7495,55 +7488,14 @@ else
+ fi
+
+
+-as_ac_Lib=`$as_echo
"ac_cv_lib_python$ac_python_version''_PyArg_ParseTuple" | $as_tr_sh`
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PyArg_ParseTuple in
-lpython$ac_python_version" >&5
+-$as_echo_n "checking for PyArg_ParseTuple in -lpython$ac_python_version... "
>&6; }
+-if eval \${$as_ac_Lib+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lpython$ac_python_version $PYTHON_LIBS $LIBS"
+-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+-
+-/* Override any GCC internal prototype to avoid an error.
+- Use char because int might match the return type of a GCC
+- builtin and then its argument prototype would still apply. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-char PyArg_ParseTuple ();
+-int
+-main ()
+-{
+-return PyArg_ParseTuple ();
+- ;
+- return 0;
+-}
+-_ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+- eval "$as_ac_Lib=yes"
+-else
+- eval "$as_ac_Lib=no"
+-fi
+-rm -f core conftest.err conftest.$ac_objext \
+- conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
+-fi
+-eval ac_res=\$$as_ac_Lib
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+-$as_echo "$ac_res" >&6; }
+-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+- cat >>confdefs.h <<_ACEOF
+-#define `$as_echo "HAVE_LIBpython$ac_python_version" | $as_tr_cpp` 1
+-_ACEOF
+-
+- LIBS="-lpython$ac_python_version $LIBS"
++ac_fn_c_check_func "$LINENO" "PyArg_ParseTuple"
"ac_cv_func_PyArg_ParseTuple"
++if test "x$ac_cv_func_PyArg_ParseTuple" = xyes; then :
+
+ else
+ as_fn_error $? "Unable to find a suitable python development library"
"$LINENO" 5
+ fi
+
++
+ CPPFLAGS=$ac_previous_cppflags
+ LDFLAGS=$ac_previous_ldflags
+
+--
+2.17.2
+
+
+From 660d2dd863802ef464c90b32f187cb65861f8185 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Thu, 7 Mar 2019 12:33:38 +0000
+Subject: [PATCH 5/8] libxl: make python scripts work with python 2.6 and up
+
+Go through transformations suggested by 2to3 and pick the necessary
+ones.
+
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ tools/libxl/gentest.py | 4 +++-
+ tools/libxl/gentypes.py | 12 +++++++-----
+ tools/libxl/idl.py | 15 ++++++++-------
+ 3 files changed, 18 insertions(+), 13 deletions(-)
+
+diff --git a/tools/libxl/gentest.py b/tools/libxl/gentest.py
+index 989959fc68..1cc7eebc82 100644
+--- a/tools/libxl/gentest.py
++++ b/tools/libxl/gentest.py
+@@ -1,5 +1,7 @@
+ #!/usr/bin/python
+
++from __future__ import print_function
++
+ import os
+ import sys
+ import re
+@@ -86,7 +88,7 @@ def gen_rand_init(ty, v, indent = " ", parent = None):
+
+ if __name__ == '__main__':
+ if len(sys.argv) < 3:
+- print >>sys.stderr, "Usage: gentest.py <idl>
<implementation>"
++ print("Usage: gentest.py <idl> <implementation>",
file=sys.stderr)
+ sys.exit(1)
+
+ random.seed(os.getenv('LIBXL_TESTIDL_SEED'))
+diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
+index 88e5c5f30e..6417c9dd8c 100644
+--- a/tools/libxl/gentypes.py
++++ b/tools/libxl/gentypes.py
+@@ -1,5 +1,7 @@
+ #!/usr/bin/python
+
++from __future__ import print_function
++
+ import sys
+ import re
+
+@@ -576,14 +578,14 @@ def libxl_C_enum_from_string(ty, str, e, indent = "
"):
+
+ if __name__ == '__main__':
+ if len(sys.argv) != 6:
+- print >>sys.stderr, "Usage: gentypes.py <idl> <header>
<header-private> <header-json> <implementation>"
++ print("Usage: gentypes.py <idl> <header> <header-private>
<header-json> <implementation>", file=sys.stderr)
+ sys.exit(1)
+
+ (_, idlname, header, header_private, header_json, impl) = sys.argv
+
+ (builtins,types) = idl.parse(idlname)
+
+- print "outputting libxl type definitions to %s" % header
++ print("outputting libxl type definitions to %s" % header)
+
+ f = open(header, "w")
+
+@@ -633,7 +635,7 @@ if __name__ == '__main__':
+ f.write("""#endif /* %s */\n""" % (header_define))
+ f.close()
+
+- print "outputting libxl JSON definitions to %s" % header_json
++ print("outputting libxl JSON definitions to %s" % header_json)
+
+ f = open(header_json, "w")
+
+@@ -657,7 +659,7 @@ if __name__ == '__main__':
+ f.write("""#endif /* %s */\n""" % header_json_define)
+ f.close()
+
+- print "outputting libxl type internal definitions to %s" % header_private
++ print("outputting libxl type internal definitions to %s" %
header_private)
+
+ f = open(header_private, "w")
+
+@@ -683,7 +685,7 @@ if __name__ == '__main__':
+ f.write("""#endif /* %s */\n""" % header_json_define)
+ f.close()
+
+- print "outputting libxl type implementations to %s" % impl
++ print("outputting libxl type implementations to %s" % impl)
+
+ f = open(impl, "w")
+ f.write("""
+diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
+index 2a7f3c44fe..d7367503b4 100644
+--- a/tools/libxl/idl.py
++++ b/tools/libxl/idl.py
+@@ -1,3 +1,5 @@
++from __future__ import print_function
++
+ import sys
+
+ PASS_BY_VALUE = 1
+@@ -11,7 +13,7 @@ DIR_BOTH = 3
+ _default_namespace = ""
+ def namespace(s):
+ if type(s) != str:
+- raise TypeError, "Require a string for the default namespace."
++ raise TypeError("Require a string for the default namespace.")
+ global _default_namespace
+ _default_namespace = s
+
+@@ -346,7 +348,7 @@ class OrderedDict(dict):
+ return [(x,self[x]) for x in self.__ordered]
+
+ def parse(f):
+- print >>sys.stderr, "Parsing %s" % f
++ print("Parsing %s" % f, file=sys.stderr)
+
+ globs = {}
+ locs = OrderedDict()
+@@ -362,11 +364,10 @@ def parse(f):
+ globs[n] = t
+
+ try:
+- execfile(f, globs, locs)
+- except SyntaxError,e:
+- raise SyntaxError, \
+- "Errors were found at line %d while processing %s:\n\t%s"\
+- %(e.lineno,f,e.text)
++ exec(compile(open(f).read(), f, 'exec'), globs, locs)
++ except SyntaxError as e:
++ raise SyntaxError("Errors were found at line %d while processing
%s:\n\t%s"
++ % (e.lineno, f, e.text))
+
+ types = [t for t in locs.ordered_values() if isinstance(t,Type)]
+
+--
+2.17.2
+
+
+From 0aabd89dcfee9ee2a6caaa2ec7a475daf5cada53 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Thu, 7 Mar 2019 12:45:47 +0000
+Subject: [PATCH 6/8] pygrub: make python scripts work with 2.6 and up
+
+Run 2to3 and pick the sensible suggestions.
+
+Import print_function and absolute_import so 2.6 can work.
+
+There has never been a curses.wrapper module according to 2.x and 3.x
+doc, only a function, so "import curses.wrapper" is not correct. It
+happened to work because 2.x implemented a (undocumented) module.
+
+We only need to import curses to make curses.wrapper available to
+pygrub.
+
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ tools/pygrub/src/ExtLinuxConf.py | 19 +++++----
+ tools/pygrub/src/GrubConf.py | 39 ++++++++++--------
+ tools/pygrub/src/LiloConf.py | 19 +++++----
+ tools/pygrub/src/pygrub | 71 ++++++++++++++++----------------
+ 4 files changed, 78 insertions(+), 70 deletions(-)
+
+diff --git a/tools/pygrub/src/ExtLinuxConf.py b/tools/pygrub/src/ExtLinuxConf.py
+index d1789bf020..9fd635b9cf 100644
+--- a/tools/pygrub/src/ExtLinuxConf.py
++++ b/tools/pygrub/src/ExtLinuxConf.py
+@@ -10,9 +10,11 @@
+ # along with this program; If not, see <
http://www.gnu.org/licenses/>.
+ #
+
++from __future__ import print_function, absolute_import
++
+ import sys, re, os
+ import logging
+-import GrubConf
++from . import GrubConf
+
+ class ExtLinuxImage(object):
+ def __init__(self, lines, path):
+@@ -32,7 +34,8 @@ class ExtLinuxImage(object):
+ self.lines = []
+ self.path = path
+ self.root = ""
+- map(self.set_from_line, lines)
++ for line in lines:
++ self.set_from_line(line)
+
+ def set_from_line(self, line, replace = None):
+ (com, arg) = GrubConf.grub_exact_split(line, 2)
+@@ -67,7 +70,7 @@ class ExtLinuxImage(object):
+ setattr(self, "initrd", a.replace("initrd=",
""))
+ arg = arg.replace(a, "")
+
+- if com is not None and self.commands.has_key(com):
++ if com is not None and com in self.commands:
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], re.sub('^"(.+)"$',
r"\1", arg.strip()))
+ else:
+@@ -136,7 +139,7 @@ class ExtLinuxConfigFile(object):
+ def parse(self, buf = None):
+ if buf is None:
+ if self.filename is None:
+- raise ValueError, "No config file defined to parse!"
++ raise ValueError("No config file defined to parse!")
+
+ f = open(self.filename, 'r')
+ lines = f.readlines()
+@@ -167,7 +170,7 @@ class ExtLinuxConfigFile(object):
+
+ (com, arg) = GrubConf.grub_exact_split(l, 2)
+ com = com.lower()
+- if self.commands.has_key(com):
++ if com in self.commands:
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], arg.strip())
+ else:
+@@ -207,8 +210,8 @@ class ExtLinuxConfigFile(object):
+
+ if __name__ == "__main__":
+ if len(sys.argv) < 2:
+- raise RuntimeError, "Need a configuration file to read"
++ raise RuntimeError("Need a configuration file to read")
+ g = ExtLinuxConfigFile(sys.argv[1])
+ for i in g.images:
+- print i
+- print g.default
++ print(i)
++ print(g.default)
+diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py
+index dc810d55cb..f8d3799dc0 100644
+--- a/tools/pygrub/src/GrubConf.py
++++ b/tools/pygrub/src/GrubConf.py
+@@ -12,6 +12,8 @@
+ # along with this program; If not, see <
http://www.gnu.org/licenses/>.
+ #
+
++from __future__ import print_function, absolute_import
++
+ import os, sys
+ import logging
+ import re
+@@ -44,7 +46,7 @@ def get_path(s):
+ return (None, s)
+ idx = s.find(')')
+ if idx == -1:
+- raise ValueError, "Unable to find matching ')'"
++ raise ValueError("Unable to find matching ')'")
+ d = s[:idx]
+ return (GrubDiskPart(d), s[idx + 1:])
+
+@@ -100,7 +102,8 @@ class _GrubImage(object):
+ " initrd: %s\n" %(self.title, self.root, self.kernel,
+ self.args, self.initrd))
+ def _parse(self, lines):
+- map(self.set_from_line, lines)
++ for line in lines:
++ self.set_from_line(line)
+
+ def reset(self, lines):
+ self._root = self._initrd = self._kernel = self._args = None
+@@ -141,7 +144,7 @@ class GrubImage(_GrubImage):
+ def set_from_line(self, line, replace = None):
+ (com, arg) = grub_exact_split(line, 2)
+
+- if self.commands.has_key(com):
++ if com in self.commands:
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], arg.strip())
+ else:
+@@ -177,7 +180,7 @@ class _GrubConfigFile(object):
+ self.parse()
+
+ def parse(self, buf = None):
+- raise RuntimeError, "unimplemented parse function"
++ raise RuntimeError("unimplemented parse function")
+
+ def hasPasswordAccess(self):
+ return self.passwordAccess
+@@ -201,7 +204,7 @@ class _GrubConfigFile(object):
+ import crypt
+ if crypt.crypt(password, pwd[1]) == pwd[1]:
+ return True
+- except Exception, e:
++ except Exception as e:
+ self.passExc = "Can't verify password: %s" % str(e)
+ return False
+
+@@ -213,7 +216,7 @@ class _GrubConfigFile(object):
+
+ def set(self, line):
+ (com, arg) = grub_exact_split(line, 2)
+- if self.commands.has_key(com):
++ if com in self.commands:
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], arg.strip())
+ else:
+@@ -233,7 +236,7 @@ class _GrubConfigFile(object):
+ self._default = val
+
+ if self._default < 0:
+- raise ValueError, "default must be positive number"
++ raise ValueError("default must be positive number")
+ default = property(_get_default, _set_default)
+
+ def set_splash(self, val):
+@@ -265,7 +268,7 @@ class GrubConfigFile(_GrubConfigFile):
+ def parse(self, buf = None):
+ if buf is None:
+ if self.filename is None:
+- raise ValueError, "No config file defined to parse!"
++ raise ValueError("No config file defined to parse!")
+
+ f = open(self.filename, 'r')
+ lines = f.readlines()
+@@ -296,7 +299,7 @@ class GrubConfigFile(_GrubConfigFile):
+ continue
+
+ (com, arg) = grub_exact_split(l, 2)
+- if self.commands.has_key(com):
++ if com in self.commands:
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], arg.strip())
+ else:
+@@ -328,7 +331,7 @@ class Grub2Image(_GrubImage):
+ if com == "set":
+ (com,arg) = grub2_handle_set(arg)
+
+- if self.commands.has_key(com):
++ if com in self.commands:
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], arg.strip())
+ else:
+@@ -364,7 +367,7 @@ class Grub2ConfigFile(_GrubConfigFile):
+ def parse(self, buf = None):
+ if buf is None:
+ if self.filename is None:
+- raise ValueError, "No config file defined to parse!"
++ raise ValueError("No config file defined to parse!")
+
+ f = open(self.filename, 'r')
+ lines = f.readlines()
+@@ -398,7 +401,7 @@ class Grub2ConfigFile(_GrubConfigFile):
+ title_match = re.match('^menuentry ["\'](.*?)["\']
(.*){', l)
+ if title_match:
+ if img is not None:
+- raise RuntimeError, "syntax error: cannot nest menuentry (%d
%s)" % (len(img),img)
++ raise RuntimeError("syntax error: cannot nest menuentry (%d
%s)" % (len(img),img))
+ img = []
+ title = title_match.group(1)
+ continue
+@@ -413,7 +416,7 @@ class Grub2ConfigFile(_GrubConfigFile):
+ menu_level -= 1
+ continue
+ else:
+- raise RuntimeError, "syntax error: closing brace without
menuentry"
++ raise RuntimeError("syntax error: closing brace without
menuentry")
+
+ self.add_image(Grub2Image(title, img))
+ img = None
+@@ -428,7 +431,7 @@ class Grub2ConfigFile(_GrubConfigFile):
+ if com == "set":
+ (com,arg) = grub2_handle_set(arg)
+
+- if self.commands.has_key(com):
++ if com in self.commands:
+ if self.commands[com] is not None:
+ arg_strip = arg.strip()
+ if arg_strip == "${saved_entry}" or arg_strip ==
"${next_entry}":
+@@ -443,7 +446,7 @@ class Grub2ConfigFile(_GrubConfigFile):
+ logging.warning("Unknown directive %s" %(com,))
+
+ if img is not None:
+- raise RuntimeError, "syntax error: end of file with open menuentry(%d
%s)" % (len(img),img)
++ raise RuntimeError("syntax error: end of file with open menuentry(%d
%s)" % (len(img),img))
+
+ if self.hasPassword():
+ self.setPasswordAccess(False)
+@@ -462,12 +465,12 @@ class Grub2ConfigFile(_GrubConfigFile):
+
+ if __name__ == "__main__":
+ if len(sys.argv) < 3:
+- raise RuntimeError, "Need a grub version (\"grub\" or
\"grub2\") and a grub.conf or grub.cfg to read"
++ raise RuntimeError('Need a grub version ("grub" or
"grub2") and a grub.conf or grub.cfg to read')
+ if sys.argv[1] == "grub":
+ g = GrubConfigFile(sys.argv[2])
+ elif sys.argv[1] == "grub2":
+ g = Grub2ConfigFile(sys.argv[2])
+ else:
+- raise RuntimeError, "Unknown config type %s" % sys.argv[1]
++ raise RuntimeError("Unknown config type %s" % sys.argv[1])
+ for i in g.images:
+- print i #, i.title, i.root, i.kernel, i.args, i.initrd
++ print(i) #, i.title, i.root, i.kernel, i.args, i.initrd
+diff --git a/tools/pygrub/src/LiloConf.py b/tools/pygrub/src/LiloConf.py
+index 2cb649f115..e3bfcb5244 100644
+--- a/tools/pygrub/src/LiloConf.py
++++ b/tools/pygrub/src/LiloConf.py
+@@ -2,9 +2,11 @@
+ #LiloConf.py
+ #
+
++from __future__ import print_function, absolute_import
++
+ import sys, re, os
+ import logging
+-import GrubConf
++from . import GrubConf
+
+ class LiloImage(object):
+ def __init__(self, lines, path):
+@@ -24,12 +26,13 @@ class LiloImage(object):
+ self.lines = []
+ self.path = path
+ self.root = ""
+- map(self.set_from_line, lines)
++ for line in lines:
++ self.set_from_line(line)
+
+ def set_from_line(self, line, replace = None):
+ (com, arg) = GrubConf.grub_exact_split(line, 2)
+
+- if self.commands.has_key(com):
++ if com in self.commands:
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], re.sub('^"(.+)"$',
r"\1", arg.strip()))
+ else:
+@@ -97,7 +100,7 @@ class LiloConfigFile(object):
+ def parse(self, buf = None):
+ if buf is None:
+ if self.filename is None:
+- raise ValueError, "No config file defined to parse!"
++ raise ValueError("No config file defined to parse!")
+
+ f = open(self.filename, 'r')
+ lines = f.readlines()
+@@ -127,7 +130,7 @@ class LiloConfigFile(object):
+ continue
+
+ (com, arg) = GrubConf.grub_exact_split(l, 2)
+- if self.commands.has_key(com):
++ if com in self.commands:
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], arg.strip())
+ else:
+@@ -170,8 +173,8 @@ class LiloConfigFile(object):
+
+ if __name__ == "__main__":
+ if len(sys.argv) < 2:
+- raise RuntimeError, "Need a lilo.conf to read"
++ raise RuntimeError("Need a lilo.conf to read")
+ g = LiloConfigFile(sys.argv[1])
+ for i in g.images:
+- print i #, i.title, i.root, i.kernel, i.args, i.initrd
+- print g.default
++ print(i) #, i.title, i.root, i.kernel, i.args, i.initrd
++ print(g.default)
+diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
+index 1189b1ca48..dbdce315c6 100755
+--- a/tools/pygrub/src/pygrub
++++ b/tools/pygrub/src/pygrub
+@@ -12,13 +12,15 @@
+ # along with this program; If not, see <
http://www.gnu.org/licenses/>.
+ #
+
++from __future__ import print_function
++
+ import os, sys, string, struct, tempfile, re, traceback, stat, errno
+ import copy
+ import logging
+ import platform
+ import xen.lowlevel.xc
+
+-import curses, _curses, curses.wrapper, curses.textpad, curses.ascii
++import curses, _curses, curses.textpad, curses.ascii
+ import getopt
+
+ import xenfsimage
+@@ -77,7 +79,7 @@ def get_solaris_slice(file, offset):
+ buf = os.read(fd, 512)
+ os.close(fd)
+ if struct.unpack("<H", buf[508:510])[0] != DKL_MAGIC:
+- raise RuntimeError, "Invalid disklabel magic"
++ raise RuntimeError("Invalid disklabel magic")
+
+ nslices = struct.unpack("<H", buf[30:32])[0]
+
+@@ -88,7 +90,7 @@ def get_solaris_slice(file, offset):
+ if slicetag == V_ROOT:
+ return slicesect * SECTOR_SIZE
+
+- raise RuntimeError, "No root slice found"
++ raise RuntimeError("No root slice found")
+
+ def get_fs_offset_gpt(file):
+ fd = os.open(file, os.O_RDONLY)
+@@ -423,20 +425,17 @@ class Grub:
+ we're being given a raw config file rather than a disk
image."""
+
+ if not os.access(fn, os.R_OK):
+- raise RuntimeError, "Unable to access %s" %(fn,)
++ raise RuntimeError("Unable to access %s" %(fn,))
+
+- cfg_list = map(lambda x: (x,grub.GrubConf.Grub2ConfigFile),
+- ["/boot/grub/grub.cfg", "/grub/grub.cfg",
+- "/boot/grub2/grub.cfg", "/grub2/grub.cfg"])
+ \
+- map(lambda x: (x,grub.ExtLinuxConf.ExtLinuxConfigFile),
+- ["/boot/isolinux/isolinux.cfg",
++ cfg_list = [(x,grub.GrubConf.Grub2ConfigFile) for x in
["/boot/grub/grub.cfg", "/grub/grub.cfg",
++ "/boot/grub2/grub.cfg", "/grub2/grub.cfg"]]
+ \
++ [(x,grub.ExtLinuxConf.ExtLinuxConfigFile) for x in
["/boot/isolinux/isolinux.cfg",
+ "/boot/extlinux/extlinux.conf",
+ "/boot/extlinux.conf",
+ "/extlinux/extlinux.conf",
+- "/extlinux.conf"]) + \
+- map(lambda x: (x,grub.GrubConf.GrubConfigFile),
+- ["/boot/grub/menu.lst",
"/boot/grub/grub.conf",
+- "/grub/menu.lst", "/grub/grub.conf"])
++ "/extlinux.conf"]] + \
++ [(x,grub.GrubConf.GrubConfigFile) for x in
["/boot/grub/menu.lst", "/boot/grub/grub.conf",
++ "/grub/menu.lst", "/grub/grub.conf"]]
+
+ if not fs:
+ # set the config file and parse it
+@@ -448,12 +447,12 @@ class Grub:
+
+ for f,parser in cfg_list:
+ if fs.file_exists(f):
+- print >>sys.stderr, "Using %s to parse %s" % (parser,f)
++ print("Using %s to parse %s" % (parser,f), file=sys.stderr)
+ self.cf = parser()
+ self.cf.filename = f
+ break
+ if self.__dict__.get('cf', None) is None:
+- raise RuntimeError, "couldn't find bootloader config file in the
image provided."
++ raise RuntimeError("couldn't find bootloader config file in the
image provided.")
+ f = fs.open_file(self.cf.filename)
+ # limit read size to avoid pathological cases
+ buf = f.read(FS_READ_MAX)
+@@ -628,11 +627,11 @@ def run_grub(file, entry, fs, cfg_args):
+ if list_entries:
+ for i in range(len(g.cf.images)):
+ img = g.cf.images[i]
+- print "title: %s" % img.title
+- print " root: %s" % img.root
+- print " kernel: %s" % img.kernel[1]
+- print " args: %s" % img.args
+- print " initrd: %s" % img.initrd[1]
++ print("title: %s" % img.title)
++ print(" root: %s" % img.root)
++ print(" kernel: %s" % img.kernel[1])
++ print(" args: %s" % img.args)
++ print(" initrd: %s" % img.initrd[1])
+
+ if interactive and not list_entries:
+ curses.wrapper(run_main)
+@@ -646,7 +645,7 @@ def run_grub(file, entry, fs, cfg_args):
+ sel = idx
+
+ if sel == -1:
+- print "No kernel image selected!"
++ print("No kernel image selected!")
+ sys.exit(1)
+
+ try:
+@@ -731,7 +730,7 @@ def format_sxp(kernel, ramdisk, args):
+ def format_simple(kernel, ramdisk, args, sep):
+ for check in (kernel, ramdisk, args):
+ if check is not None and sep in check:
+- raise RuntimeError, "simple format cannot represent
delimiter-containing value"
++ raise RuntimeError("simple format cannot represent delimiter-containing
value")
+ s = ("kernel %s" % kernel) + sep
+ if ramdisk:
+ s += ("ramdisk %s" % ramdisk) + sep
+@@ -744,7 +743,7 @@ if __name__ == "__main__":
+ sel = None
+
+ def usage():
+- print >> sys.stderr, "Usage: %s [-q|--quiet] [-i|--interactive]
[-l|--list-entries] [-n|--not-really] [--output=] [--kernel=] [--ramdisk=] [--args=]
[--entry=] [--output-directory=] [--output-format=sxp|simple|simple0] [--offset=]
<image>" %(sys.argv[0],)
++ print("Usage: %s [-q|--quiet] [-i|--interactive] [-l|--list-entries]
[-n|--not-really] [--output=] [--kernel=] [--ramdisk=] [--args=] [--entry=]
[--output-directory=] [--output-format=sxp|simple|simple0] [--offset=] <image>"
%(sys.argv[0],), file=sys.stderr)
+
+ def copy_from_image(fs, file_to_read, file_type, output_directory,
+ not_really):
+@@ -755,8 +754,8 @@ if __name__ == "__main__":
+ sys.exit("The requested %s file does not exist" % file_type)
+ try:
+ datafile = fs.open_file(file_to_read)
+- except Exception, e:
+- print >>sys.stderr, e
++ except Exception as e:
++ print(e, file=sys.stderr)
+ sys.exit("Error opening %s in guest" % file_to_read)
+ (tfd, ret) = tempfile.mkstemp(prefix="boot_"+file_type+".",
+ dir=output_directory)
+@@ -769,8 +768,8 @@ if __name__ == "__main__":
+ return ret
+ try:
+ os.write(tfd, data)
+- except Exception, e:
+- print >>sys.stderr, e
++ except Exception as e:
++ print(e, file=sys.stderr)
+ os.close(tfd)
+ os.unlink(ret)
+ del datafile
+@@ -834,7 +833,7 @@ if __name__ == "__main__":
+ try:
+ part_offs = [ int(a) ]
+ except ValueError:
+- print "offset value must be an integer"
++ print("offset value must be an integer")
+ usage()
+ sys.exit(1)
+ elif o in ("--entry",):
+@@ -847,13 +846,13 @@ if __name__ == "__main__":
+ debug = True
+ elif o in ("--output-format",):
+ if a not in ["sxp", "simple", "simple0"]:
+- print "unknown output format %s" % a
++ print("unknown output format %s" % a)
+ usage()
+ sys.exit(1)
+ output_format = a
+ elif o in ("--output-directory",):
+ if not os.path.isdir(a):
+- print "%s is not an existing directory" % a
++ print("%s is not an existing directory" % a)
+ sys.exit(1)
+ output_directory = a
+
+@@ -862,8 +861,8 @@ if __name__ == "__main__":
+
+
+ try:
+- os.makedirs(output_directory, 0700)
+- except OSError,e:
++ os.makedirs(output_directory, 0o700)
++ except OSError as e:
+ if (e.errno == errno.EEXIST) and os.path.isdir(output_directory):
+ pass
+ else:
+@@ -877,10 +876,10 @@ if __name__ == "__main__":
+ # debug
+ if isconfig:
+ chosencfg = run_grub(file, entry, fs, incfg["args"])
+- print " kernel: %s" % chosencfg["kernel"]
++ print(" kernel: %s" % chosencfg["kernel"])
+ if chosencfg["ramdisk"]:
+- print " initrd: %s" % chosencfg["ramdisk"]
+- print " args: %s" % chosencfg["args"]
++ print(" initrd: %s" % chosencfg["ramdisk"])
++ print(" args: %s" % chosencfg["args"])
+ sys.exit(0)
+
+ # if boot filesystem is set then pass to fsimage.open
+@@ -926,7 +925,7 @@ if __name__ == "__main__":
+
+ # Did looping through partitions find us a kernel?
+ if fs is None:
+- raise RuntimeError, "Unable to find partition containing kernel"
++ raise RuntimeError("Unable to find partition containing kernel")
+
+ bootcfg["kernel"] = copy_from_image(fs, chosencfg["kernel"],
"kernel",
+ output_directory, not_really)
+--
+2.17.2
+
+
+From 83a204e6951c6358f995da3b60dd61224e9d41ac Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Tue, 5 Mar 2019 14:13:17 +0000
+Subject: [PATCH 7/8] pygrub/fsimage: make it work with python 3
+
+With the help of two porting guides and cpython source code:
+
+1. Use PyBytes to replace PyString counterparts.
+2. Use PyVarObject_HEAD_INIT.
+3. Remove usage of Py_FindMethod.
+4. Use new module initialisation routine.
+
+For #3, Py_FindMethod was removed, yet an alternative wasn't
+documented. The code is the result of reverse-engineering cpython
+commit 6116d4a1d1
+
+https://docs.python.org/3/howto/cporting.html
+http://python3porting.com/cextensions.html
+
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ tools/pygrub/src/fsimage/fsimage.c | 123 ++++++++++++++++-------------
+ 1 file changed, 69 insertions(+), 54 deletions(-)
+
+diff --git a/tools/pygrub/src/fsimage/fsimage.c b/tools/pygrub/src/fsimage/fsimage.c
+index 780207791c..2ebbbe35df 100644
+--- a/tools/pygrub/src/fsimage/fsimage.c
++++ b/tools/pygrub/src/fsimage/fsimage.c
+@@ -26,12 +26,6 @@
+ #include <xenfsimage.h>
+ #include <stdlib.h>
+
+-#if (PYTHON_API_VERSION >= 1011)
+-#define PY_PAD 0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L
+-#else
+-#define PY_PAD 0L,0L,0L,0L
+-#endif
+-
+ typedef struct fsimage_fs {
+ PyObject_HEAD
+ fsi_t *fs;
+@@ -59,12 +53,24 @@ fsimage_file_read(fsimage_file_t *file, PyObject *args, PyObject
*kwargs)
+
+ bufsize = size ? size : 4096;
+
+- if ((buffer = PyString_FromStringAndSize(NULL, bufsize)) == NULL)
++ buffer =
++#if PY_MAJOR_VERSION < 3
++ PyString_FromStringAndSize(NULL, bufsize);
++#else
++ PyBytes_FromStringAndSize(NULL, bufsize);
++#endif
++
++ if (buffer == NULL)
+ return (NULL);
+
+ while (1) {
+ int err;
+- void *buf = PyString_AS_STRING(buffer) + bytesread;
++ void *buf =
++#if PY_MAJOR_VERSION < 3
++ PyString_AS_STRING(buffer) + bytesread;
++#else
++ PyBytes_AS_STRING(buffer) + bytesread;
++#endif
+
+ err = fsi_pread_file(file->file, buf, bufsize,
+ bytesread + offset);
+@@ -84,12 +90,20 @@ fsimage_file_read(fsimage_file_t *file, PyObject *args, PyObject
*kwargs)
+ if (bufsize == 0)
+ break;
+ } else {
++#if PY_MAJOR_VERSION < 3
+ if (_PyString_Resize(&buffer, bytesread + bufsize) < 0)
++#else
++ if (_PyBytes_Resize(&buffer, bytesread + bufsize) < 0)
++#endif
+ return (NULL);
+ }
+ }
+
++#if PY_MAJOR_VERSION < 3
+ _PyString_Resize(&buffer, bytesread);
++#else
++ _PyBytes_Resize(&buffer, bytesread);
++#endif
+ return (buffer);
+ }
+
+@@ -106,11 +120,13 @@ static struct PyMethodDef fsimage_file_methods[] = {
+ { NULL, NULL, 0, NULL }
+ };
+
++#if PY_MAJOR_VERSION < 3
+ static PyObject *
+ fsimage_file_getattr(fsimage_file_t *file, char *name)
+ {
+ return (Py_FindMethod(fsimage_file_methods, (PyObject *)file, name));
+ }
++#endif
+
+ static void
+ fsimage_file_dealloc(fsimage_file_t *file)
+@@ -123,29 +139,18 @@ fsimage_file_dealloc(fsimage_file_t *file)
+
+ static char fsimage_file_type__doc__[] = "Filesystem image file";
+ PyTypeObject fsimage_file_type = {
+- PyObject_HEAD_INIT(&PyType_Type)
+- 0, /* ob_size */
+- "xenfsimage.file", /* tp_name */
+- sizeof(fsimage_file_t), /* tp_size */
+- 0, /* tp_itemsize */
+- (destructor) fsimage_file_dealloc, /* tp_dealloc */
+- 0, /* tp_print */
+- (getattrfunc) fsimage_file_getattr, /* tp_getattr */
+- 0, /* tp_setattr */
+- 0, /* tp_compare */
+- 0, /* tp_repr */
+- 0, /* tp_as_number */
+- 0, /* tp_as_sequence */
+- 0, /* tp_as_mapping */
+- 0, /* tp_hash */
+- 0, /* tp_call */
+- 0, /* tp_str */
+- 0, /* tp_getattro */
+- 0, /* tp_setattro */
+- 0, /* tp_as_buffer */
+- Py_TPFLAGS_DEFAULT, /* tp_flags */
+- fsimage_file_type__doc__,
+- PY_PAD
++ PyVarObject_HEAD_INIT(&PyType_Type, 0)
++ .tp_name = "xenfsimage.file",
++ .tp_basicsize = sizeof(fsimage_file_t),
++ .tp_dealloc = (destructor) fsimage_file_dealloc,
++#if PY_MAJOR_VERSION < 3
++ .tp_getattr = (getattrfunc) fsimage_file_getattr,
++#endif
++ .tp_flags = Py_TPFLAGS_DEFAULT,
++ .tp_doc = fsimage_file_type__doc__,
++#if PY_MAJOR_VERSION >= 3
++ .tp_methods = fsimage_file_methods,
++#endif
+ };
+
+ static PyObject *
+@@ -208,11 +213,13 @@ static struct PyMethodDef fsimage_fs_methods[] = {
+ { NULL, NULL, 0, NULL }
+ };
+
++#if PY_MAJOR_VERSION < 3
+ static PyObject *
+ fsimage_fs_getattr(fsimage_fs_t *fs, char *name)
+ {
+ return (Py_FindMethod(fsimage_fs_methods, (PyObject *)fs, name));
+ }
++#endif
+
+ static void
+ fsimage_fs_dealloc (fsimage_fs_t *fs)
+@@ -225,29 +232,18 @@ fsimage_fs_dealloc (fsimage_fs_t *fs)
+ PyDoc_STRVAR(fsimage_fs_type__doc__, "Filesystem image");
+
+ PyTypeObject fsimage_fs_type = {
+- PyObject_HEAD_INIT(&PyType_Type)
+- 0, /* ob_size */
+- "xenfsimage.fs", /* tp_name */
+- sizeof(fsimage_fs_t), /* tp_size */
+- 0, /* tp_itemsize */
+- (destructor) fsimage_fs_dealloc, /* tp_dealloc */
+- 0, /* tp_print */
+- (getattrfunc) fsimage_fs_getattr, /* tp_getattr */
+- 0, /* tp_setattr */
+- 0, /* tp_compare */
+- 0, /* tp_repr */
+- 0, /* tp_as_number */
+- 0, /* tp_as_sequence */
+- 0, /* tp_as_mapping */
+- 0, /* tp_hash */
+- 0, /* tp_call */
+- 0, /* tp_str */
+- 0, /* tp_getattro */
+- 0, /* tp_setattro */
+- 0, /* tp_as_buffer */
+- Py_TPFLAGS_DEFAULT, /* tp_flags */
+- fsimage_fs_type__doc__,
+- PY_PAD
++ PyVarObject_HEAD_INIT(&PyType_Type, 0)
++ .tp_name = "xenfsimage.fs",
++ .tp_basicsize = sizeof(fsimage_fs_t),
++ .tp_dealloc = (destructor) fsimage_fs_dealloc,
++#if PY_MAJOR_VERSION < 3
++ .tp_getattr = (getattrfunc) fsimage_fs_getattr,
++#endif
++ .tp_flags = Py_TPFLAGS_DEFAULT,
++ .tp_doc = fsimage_fs_type__doc__,
++#if PY_MAJOR_VERSION >= 3
++ .tp_methods = fsimage_fs_methods,
++#endif
+ };
+
+ static PyObject *
+@@ -309,8 +305,27 @@ static struct PyMethodDef fsimage_module_methods[] = {
+ { NULL, NULL, 0, NULL }
+ };
+
++#if PY_MAJOR_VERSION >= 3
++static struct PyModuleDef fsimage_module_def = {
++ PyModuleDef_HEAD_INIT,
++ .m_name = "xenfsimage",
++ .m_size = -1,
++ .m_methods = fsimage_module_methods,
++};
++#endif
++
+ PyMODINIT_FUNC
++#if PY_MAJOR_VERSION >= 3
++PyInit_xenfsimage(void)
++#else
+ initxenfsimage(void)
++#endif
+ {
++#if PY_MAJOR_VERSION < 3
+ Py_InitModule("xenfsimage", fsimage_module_methods);
++#else
++ if (PyType_Ready(&fsimage_fs_type) < 0 || PyType_Ready(&fsimage_file_type)
< 0)
++ return NULL;
++ return PyModule_Create(&fsimage_module_def);
++#endif
+ }
+--
+2.17.2
+
+
+From 9b0bc91b3b32856df014fab9de40f463c89a8b1e Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Mon, 11 Mar 2019 17:19:19 +0000
+Subject: [PATCH 8/8] README: remove requirement on Python 2
+
+Now that all python scripts are compatible with Python 2.6 and above,
+remove the restriction.
+
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Acked-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ README | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/README b/README
+index d00715c2fd..23e4f7c3dc 100644
+--- a/README
++++ b/README
+@@ -46,7 +46,7 @@ provided by your OS distributor:
+ - GCC 4.8 or later
+ - GNU Binutils 2.24 or later
+ * Development install of zlib (e.g., zlib-dev)
+- * Development install of Python 2, v2.6 or later (e.g., python-dev)
++ * Development install of Python 2.6 or later (e.g., python-dev)
+ * Development install of curses (e.g., libncurses-dev)
+ * Development install of openssl (e.g., openssl-dev)
+ * Development install of x11 (e.g. xorg-x11-dev)
+@@ -177,16 +177,10 @@ Python Runtime Libraries
+
+ Various tools, such as pygrub, have the following runtime dependencies:
+
+- * Python 2, v2.6 or later.
++ * Python 2.6 or later.
+ URL:
http://www.python.org/
+ Debian: python
+
+-Note that the build system expects `python` to be python2. If your system
+-has `python` pointing to python3 (as in the case of Arch Linux or Anaconda),
+-you'll need to specify a path to a python2 binary when running configure:
+-
+- PYTHON=/usr/bin/python2 ./configure
+-
+ Intel(R) Trusted Execution Technology Support
+ =============================================
+
+--
+2.17.2
+
+From 38a85fe8d98b54da7f842f8d78bf8c54f7747735 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Wed, 13 Mar 2019 13:54:48 +0000
+Subject: [PATCH] build/m4: fix python library detection on Ubuntu systems
+
+16cc3362aed doesn't work on Ubuntu with gcc (but it does work with
+clang). Work around it by manipulating LIBS.
+
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Acked-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ m4/python_devel.m4 | 7 +++++++
+ tools/configure | 7 +++++++
+ 2 files changed, 14 insertions(+)
+
+diff --git a/m4/python_devel.m4 b/m4/python_devel.m4
+index f9cb23aee1..7f26381376 100644
+--- a/m4/python_devel.m4
++++ b/m4/python_devel.m4
+@@ -1,6 +1,7 @@
+ AC_DEFUN([AX_CHECK_PYTHON_DEVEL], [
+ ac_previous_cppflags=$CPPFLAGS
+ ac_previous_ldflags=$LDFLAGS
++ac_previous_libs=$LIBS
+ AC_PATH_PROG([pyconfig], [$PYTHON-config], [no])
+ AS_IF([test x"$pyconfig" = x"no"], [
+ dnl For those that don't have python-config
+@@ -15,10 +16,15 @@ AS_IF([test x"$pyconfig" = x"no"], [
+
print(distutils.sysconfig.get_config_var("LINKFORSHARED"))'`"
+ LDFLAGS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+ print(distutils.sysconfig.get_config_var("LDFLAGS"))'`"
++ LIBS="$LIBS `$PYTHON -c 'import distutils.sysconfig; \
++ print(distutils.sysconfig.get_config_var("LIBS"))'`"
++ LIBS="$LIBS `$PYTHON -c 'import distutils.sysconfig; \
++ print(distutils.sysconfig.get_config_var("SYSLIBS"))'`"
+ ], [
+ dnl If python-config is found use it
+ CPPFLAGS="$CFLAGS `$PYTHON-config --cflags`"
+ LDFLAGS="$LDFLAGS `$PYTHON-config --ldflags`"
++ LIBS="$LIBS `$PYTHON-config --libs`"
+ ])
+
+ AC_CHECK_HEADER([Python.h], [],
+@@ -28,4 +34,5 @@ AC_CHECK_FUNC([PyArg_ParseTuple], [],
+
+ CPPFLAGS=$ac_previous_cppflags
+ LDFLAGS=$ac_previous_ldflags
++LIBS=$ac_previous_libs
+ ])
+diff --git a/tools/configure b/tools/configure
+index 9ff879548a..b66d3f6fba 100755
+--- a/tools/configure
++++ b/tools/configure
+@@ -7418,6 +7418,7 @@ if test "$cross_compiling" != yes; then :
+
+ ac_previous_cppflags=$CPPFLAGS
+ ac_previous_ldflags=$LDFLAGS
++ac_previous_libs=$LIBS
+ # Extract the first word of "$PYTHON-config", so it can be a program name with
args.
+ set dummy $PYTHON-config; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+@@ -7472,11 +7473,16 @@ if test x"$pyconfig" = x"no"; then :
+
print(distutils.sysconfig.get_config_var("LINKFORSHARED"))'`"
+ LDFLAGS="$LDFLAGS `$PYTHON -c 'import distutils.sysconfig; \
+ print(distutils.sysconfig.get_config_var("LDFLAGS"))'`"
++ LIBS="$LIBS `$PYTHON -c 'import distutils.sysconfig; \
++ print(distutils.sysconfig.get_config_var("LIBS"))'`"
++ LIBS="$LIBS `$PYTHON -c 'import distutils.sysconfig; \
++ print(distutils.sysconfig.get_config_var("SYSLIBS"))'`"
+
+ else
+
+ CPPFLAGS="$CFLAGS `$PYTHON-config --cflags`"
+ LDFLAGS="$LDFLAGS `$PYTHON-config --ldflags`"
++ LIBS="$LIBS `$PYTHON-config --libs`"
+
+ fi
+
+@@ -7498,6 +7504,7 @@ fi
+
+ CPPFLAGS=$ac_previous_cppflags
+ LDFLAGS=$ac_previous_ldflags
++LIBS=$ac_previous_libs
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Python setup.py
brokenly enables -D_FORTIFY_SOURCE" >&5
+--
+2.17.2
+
+From 485079e816788d70169f45579e1f5a8f909dc1b3 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Mon, 1 Apr 2019 11:32:35 +0100
+Subject: [PATCH 1/4] pygrub: fix message in grub parser
+
+The code suggests 0 is allowed. Zero is not a positive number.
+
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Acked-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ tools/pygrub/src/GrubConf.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py
+index f8d3799dc0..0204d410ac 100644
+--- a/tools/pygrub/src/GrubConf.py
++++ b/tools/pygrub/src/GrubConf.py
+@@ -236,7 +236,7 @@ class _GrubConfigFile(object):
+ self._default = val
+
+ if self._default < 0:
+- raise ValueError("default must be positive number")
++ raise ValueError("default must be non-negative number")
+ default = property(_get_default, _set_default)
+
+ def set_splash(self, val):
+--
+2.17.2
+
+
+From 767ba397d34848c7e0c4e9cdfc5efa4e0cb61442 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Mon, 1 Apr 2019 11:32:36 +0100
+Subject: [PATCH 2/4] pygrub/grub: always use integer for default entry
+
+The original code set the default to either a string or an integer
+(0) and relies on a Python 2 specific behaviour to work (integer is
+allowed to be compared to string in Python 2 but not 3).
+
+Always use integer. The caller (pygrub) already has code to handle
+that.
+
+Reported-by: M A Young <m.a.young(a)durham.ac.uk>
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Acked-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ tools/pygrub/src/GrubConf.py | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py
+index 0204d410ac..594139bac7 100644
+--- a/tools/pygrub/src/GrubConf.py
++++ b/tools/pygrub/src/GrubConf.py
+@@ -233,7 +233,11 @@ class _GrubConfigFile(object):
+ if val == "saved":
+ self._default = 0
+ else:
+- self._default = val
++ try:
++ self._default = int(val)
++ except ValueError:
++ logging.warning("Invalid value %s, setting default to 0"
%(val,))
++ self._default = 0
+
+ if self._default < 0:
+ raise ValueError("default must be non-negative number")
+--
+2.17.2
+
+
+From ff915c8cacc264ae1380d51fea07267b8308d7ba Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Mon, 1 Apr 2019 11:32:37 +0100
+Subject: [PATCH 3/4] pygrub: encode / decode string in Python 3
+
+String is unicode in 3 but bytes in 2. We need to call encode / decode
+function when using Python 3.
+
+Reported-by: M A Young <m.a.young(a)durham.ac.uk>
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Acked-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+---
+ tools/pygrub/src/pygrub | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
+index dbdce315c6..ce7ab0eb8c 100755
+--- a/tools/pygrub/src/pygrub
++++ b/tools/pygrub/src/pygrub
+@@ -457,7 +457,10 @@ class Grub:
+ # limit read size to avoid pathological cases
+ buf = f.read(FS_READ_MAX)
+ del f
+- self.cf.parse(buf)
++ if sys.version_info[0] < 3:
++ self.cf.parse(buf)
++ else:
++ self.cf.parse(buf.decode())
+
+ def image_index(self):
+ if isinstance(self.cf.default, int):
+@@ -960,5 +963,8 @@ if __name__ == "__main__":
+ ostring = format_simple(bootcfg["kernel"],
bootcfg["ramdisk"], args, "\0")
+
+ sys.stdout.flush()
+- os.write(fd, ostring)
++ if sys.version_info[0] < 3:
++ os.write(fd, ostring)
++ else:
++ os.write(fd, ostring.encode())
+
+--
+2.17.2
+
+
+From a57a1b26ec0ae31f924cf2bbcf479637d007be44 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2(a)citrix.com>
+Date: Mon, 1 Apr 2019 11:32:38 +0100
+Subject: [PATCH 4/4] tools/ocaml: make python scripts 2 and 3 compatible
+
+1. Explicitly import reduce because that's required in 3.
+2. Change print to function.
+3. Eliminate invocations of has_key.
+
+Signed-off-by: M A Young <m.a.young(a)durham.ac.uk>
+Signed-off-by: Wei Liu <wei.liu2(a)citrix.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
+Acked-by: Christian Lindig <christian.lindig(a)citrix.com>
+---
+ tools/ocaml/libs/xentoollog/genlevels.py | 5 ++++-
+ tools/ocaml/libs/xl/genwrap.py | 17 ++++++++++-------
+ 2 files changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/tools/ocaml/libs/xentoollog/genlevels.py
b/tools/ocaml/libs/xentoollog/genlevels.py
+index 8c233c59b1..f9cf853e26 100755
+--- a/tools/ocaml/libs/xentoollog/genlevels.py
++++ b/tools/ocaml/libs/xentoollog/genlevels.py
+@@ -1,6 +1,9 @@
+ #!/usr/bin/python
+
++from __future__ import print_function
++
+ import sys
++from functools import reduce
+
+ def read_levels():
+ f = open('../../../libs/toollog/include/xentoollog.h', 'r')
+@@ -93,7 +96,7 @@ def autogen_header(open_comment, close_comment):
+
+ if __name__ == '__main__':
+ if len(sys.argv) < 3:
+- print >>sys.stderr, "Usage: genlevels.py <mli> <ml>
<c-inc>"
++ print("Usage: genlevels.py <mli> <ml> <c-inc>",
file=sys.stderr)
+ sys.exit(1)
+
+ levels, olevels = read_levels()
+diff --git a/tools/ocaml/libs/xl/genwrap.py b/tools/ocaml/libs/xl/genwrap.py
+index 815c1cb0e3..7bf26bdcd8 100644
+--- a/tools/ocaml/libs/xl/genwrap.py
++++ b/tools/ocaml/libs/xl/genwrap.py
+@@ -1,6 +1,9 @@
+ #!/usr/bin/python
+
++from __future__ import print_function
++
+ import sys,os
++from functools import reduce
+
+ import idl
+
+@@ -78,7 +81,7 @@ def ocaml_type_of(ty):
+ elif isinstance(ty,idl.Array):
+ return "%s array" % ocaml_type_of(ty.elem_type)
+ elif isinstance(ty,idl.Builtin):
+- if not builtins.has_key(ty.typename):
++ if ty.typename not in builtins:
+ raise NotImplementedError("Unknown Builtin %s (%s)" %
(ty.typename, type(ty)))
+ typename,_,_ = builtins[ty.typename]
+ if not typename:
+@@ -251,7 +254,7 @@ def gen_ocaml_ml(ty, interface, indent=""):
+ else:
+ s += "\texternal default : ctx -> %sunit -> t =
\"stub_libxl_%s_init\"\n" % (union_args, ty.rawname)
+
+- if functions.has_key(ty.rawname):
++ if ty.rawname in functions:
+ for name,args in functions[ty.rawname]:
+ s += "\texternal %s : " % name
+ s += " -> ".join(args)
+@@ -278,7 +281,7 @@ def c_val(ty, c, o, indent="", parent = None):
+ else:
+ s += "%s = Int_val(%s);" % (c, o)
+ elif isinstance(ty,idl.Builtin):
+- if not builtins.has_key(ty.typename):
++ if ty.typename not in builtins:
+ raise NotImplementedError("Unknown Builtin %s (%s)" %
(ty.typename, type(ty)))
+ _,fn,_ = builtins[ty.typename]
+ if not fn:
+@@ -375,7 +378,7 @@ def ocaml_Val(ty, o, c, indent="", parent = None):
+ else:
+ s += "%s = Val_int(%s);" % (o, c)
+ elif isinstance(ty,idl.Builtin):
+- if not builtins.has_key(ty.typename):
++ if ty.typename not in builtins:
+ raise NotImplementedError("Unknown Builtin %s (%s)" %
(ty.typename, type(ty)))
+ _,_,fn = builtins[ty.typename]
+ if not fn:
+@@ -520,7 +523,7 @@ def autogen_header(open_comment, close_comment):
+
+ if __name__ == '__main__':
+ if len(sys.argv) < 4:
+- print >>sys.stderr, "Usage: genwrap.py <idl> <mli>
<ml> <c-inc>"
++ print("Usage: genwrap.py <idl> <mli> <ml>
<c-inc>", file=sys.stderr)
+ sys.exit(1)
+
+ (_,types) = idl.parse(sys.argv[1])
+@@ -533,7 +536,7 @@ if __name__ == '__main__':
+
+ for t in blacklist:
+ if t not in [ty.rawname for ty in types]:
+- print "unknown type %s in blacklist" % t
++ print("unknown type %s in blacklist" % t)
+
+ types = [ty for ty in types if not ty.rawname in blacklist]
+
+@@ -564,7 +567,7 @@ if __name__ == '__main__':
+ cinc.write("\n")
+ cinc.write(gen_Val_ocaml(ty))
+ cinc.write("\n")
+- if functions.has_key(ty.rawname):
++ if ty.rawname in functions:
+ cinc.write(gen_c_stub_prototype(ty, functions[ty.rawname]))
+ cinc.write("\n")
+ if ty.init_fn is not None:
+--
+2.17.2
+
diff --git a/xen.spec b/xen.spec
index 6b9e4f7..b122ac8 100644
--- a/xen.spec
+++ b/xen.spec
@@ -112,6 +112,7 @@ Patch39: qemu.trad.CVE-2017-9330.patch
Patch41: xen.drop.brctl.patch
Patch45: xen.python.env.patch
Patch46: xen.gcc9.fixes.patch
+Patch47: xen.python3.patch
%if %build_qemutrad
@@ -124,7 +125,7 @@ BuildRequires: seabios-bin ipxe-roms-qemu
BuildRequires: dev86
%endif
%endif
-BuildRequires: python2-devel ncurses-devel
+BuildRequires: python3-devel ncurses-devel
BuildRequires: perl-interpreter perl-generators
%ifarch %{ix86} x86_64
# so that x86_64 builds pick up glibc32 correctly
@@ -157,7 +158,7 @@ BuildRequires: gcc-x86_64-linux-gnu
%endif
BuildRequires: gcc
Requires: iproute
-Requires: python2-lxml
+Requires: python3-lxml
Requires: xen-runtime = %{version}-%{release}
# Not strictly a dependency, but kpartx is by far the most useful tool right
# now for accessing domU data from within a dom0 so bring it in when the user
@@ -309,6 +310,7 @@ manage Xen virtual machines.
%patch41 -p1
%patch45 -p1
%patch46 -p1
+%patch47 -p1
# qemu-xen-traditional patches
pushd tools/qemu-xen-traditional
@@ -352,7 +354,7 @@ mkdir -p dist/install%{_libdir}/ocaml/stublibs
export EXTRA_CFLAGS_XEN_TOOLS="$RPM_OPT_FLAGS"
export EXTRA_CFLAGS_QEMU_TRADITIONAL="$RPM_OPT_FLAGS"
export EXTRA_CFLAGS_QEMU_XEN="$RPM_OPT_FLAGS"
-export PYTHON="/usr/bin/python2"
+export PYTHON="/usr/bin/python3"
%if %build_hyp
%if %build_crosshyp
XEN_TARGET_ARCH=x86_64 make %{?_smp_mflags} prefix=/usr xen
CC="/usr/bin/x86_64-linux-gnu-gcc `echo $RPM_OPT_FLAGS | sed -e 's/-m32//g'
-e 's/-march=i686//g' -e 's/-mtune=atom//g' -e
's/-specs=\/usr\/lib\/rpm\/redhat\/redhat-annobin-cc1//g' -e
's/-fstack-clash-protection//g' -e 's/-mcet//g' -e
's/-fcf-protection//g'`"
@@ -634,8 +636,8 @@ fi
%files
%doc COPYING README
%{_bindir}/xencons
-%{python2_sitearch}/%{name}
-%{python2_sitearch}/xen-*.egg-info
+%{python3_sitearch}/%{name}
+%{python3_sitearch}/xen-*.egg-info
# Guest autostart links
%dir %attr(0700,root,root) %{_sysconfdir}/%{name}/auto
@@ -708,9 +710,9 @@ fi
%{_mandir}/man7/xl-numa-placement.7.gz
%endif
-%{python2_sitearch}/xenfsimage.so
-%{python2_sitearch}/grub
-%{python2_sitearch}/pygrub-*.egg-info
+%{python3_sitearch}/xenfsimage*.so
+%{python3_sitearch}/grub
+%{python3_sitearch}/pygrub-*.egg-info
# The firmware
%ifarch %{ix86} x86_64
@@ -867,6 +869,7 @@ fi
fs libdir is now xenfsimage libdir
xen-ringwatch xen-bugtool have been dropped
- remove remaining traces of efiming and efi_flags logic
+- switch from python2 to python3
* Tue Mar 05 2019 Michael Young <m.a.young(a)durham.ac.uk> - 4.11.1-4
- xen: various flaws (#1685577)
commit ba63a02fbc348bb04d2b0d95d1818ae458d3560f
Author: Michael Young <m.a.young(a)durham.ac.uk>
Date: Thu Apr 4 21:00:20 2019 +0100
remove traces of efiming and efi_flags logic from spec file
diff --git a/xen.spec b/xen.spec
index 7835edc..6b9e4f7 100644
--- a/xen.spec
+++ b/xen.spec
@@ -46,15 +46,6 @@
%ifnarch x86_64 aarch64 %{ix86}
%define build_efi 0
%endif
-%if %build_efi && "%dist" < ".fc26"
-%ifarch x86_64
-%define efiming 1
-%else
-%define efiming 0
-%endif
-%else
-%define efiming 0
-%endif
%if "%dist" >= ".fc20"
%define with_systemd_presets 1
%else
@@ -177,10 +168,6 @@ ExclusiveArch: %{ix86} x86_64 armv7hl aarch64
%if %with_ocaml
BuildRequires: ocaml, ocaml-findlib
%endif
-# efi image needs an ld that has -mi386pep option
-%if %efiming
-BuildRequires: mingw64-binutils
-%endif
%if %with_systemd_presets
Requires(post): systemd
Requires(preun): systemd
@@ -350,9 +337,6 @@ cp -v %{SOURCE21} xen/.config
%if !%build_ocaml
%define ocaml_flags OCAML_TOOLS=n
%endif
-%if %efiming
-%define efi_flags LD_EFI=/usr/x86_64-w64-mingw32/bin/ld
-%endif
%if %build_efi
mkdir -p dist/install/boot/efi/efi/fedora
%endif
@@ -371,16 +355,15 @@ export EXTRA_CFLAGS_QEMU_XEN="$RPM_OPT_FLAGS"
export PYTHON="/usr/bin/python2"
%if %build_hyp
%if %build_crosshyp
-%define efi_flags LD_EFI=false
-XEN_TARGET_ARCH=x86_64 make %{?_smp_mflags} %{?efi_flags} prefix=/usr xen
CC="/usr/bin/x86_64-linux-gnu-gcc `echo $RPM_OPT_FLAGS | sed -e 's/-m32//g'
-e 's/-march=i686//g' -e 's/-mtune=atom//g' -e
's/-specs=\/usr\/lib\/rpm\/redhat\/redhat-annobin-cc1//g' -e
's/-fstack-clash-protection//g' -e 's/-mcet//g' -e
's/-fcf-protection//g'`"
+XEN_TARGET_ARCH=x86_64 make %{?_smp_mflags} prefix=/usr xen
CC="/usr/bin/x86_64-linux-gnu-gcc `echo $RPM_OPT_FLAGS | sed -e 's/-m32//g'
-e 's/-march=i686//g' -e 's/-mtune=atom//g' -e
's/-specs=\/usr\/lib\/rpm\/redhat\/redhat-annobin-cc1//g' -e
's/-fstack-clash-protection//g' -e 's/-mcet//g' -e
's/-fcf-protection//g'`"
%else
%ifarch armv7hl
-make %{?_smp_mflags} %{?efi_flags} prefix=/usr xen CC="gcc `echo $RPM_OPT_FLAGS |
sed -e 's/-mfloat-abi=hard//g' -e 's/-march=armv7-a//g'`"
+make %{?_smp_mflags} prefix=/usr xen CC="gcc `echo $RPM_OPT_FLAGS | sed -e
's/-mfloat-abi=hard//g' -e 's/-march=armv7-a//g'`"
%else
%ifarch aarch64
-make %{?_smp_mflags} %{?efi_flags} prefix=/usr xen CC="gcc $RPM_OPT_FLAGS"
+make %{?_smp_mflags} prefix=/usr xen CC="gcc $RPM_OPT_FLAGS"
%else
-make %{?_smp_mflags} %{?efi_flags} prefix=/usr xen CC="gcc `echo $RPM_OPT_FLAGS |
sed -e 's/-specs=\/usr\/lib\/rpm\/redhat\/redhat-annobin-cc1//g' -e
's/-fcf-protection//g'`"
+make %{?_smp_mflags} prefix=/usr xen CC="gcc `echo $RPM_OPT_FLAGS | sed -e
's/-specs=\/usr\/lib\/rpm\/redhat\/redhat-annobin-cc1//g' -e
's/-fcf-protection//g'`"
%endif
%endif
%endif
@@ -883,6 +866,7 @@ fi
kdd is now xen-kdd, xenmon.py is now xenmon, fsimage.so is now xenfsimage.so
fs libdir is now xenfsimage libdir
xen-ringwatch xen-bugtool have been dropped
+- remove remaining traces of efiming and efi_flags logic
* Tue Mar 05 2019 Michael Young <m.a.young(a)durham.ac.uk> - 4.11.1-4
- xen: various flaws (#1685577)
commit 937578a14e8f0f063d58632bf018917c0af0bbf4
Author: Michael Young <m.a.young(a)durham.ac.uk>
Date: Thu Apr 4 20:48:28 2019 +0100
update to xen-4.12.0
diff --git a/xen.gcc8.temp.fix.patch b/xen.gcc8.temp.fix.patch
deleted file mode 100644
index 74321aa..0000000
--- a/xen.gcc8.temp.fix.patch
+++ /dev/null
@@ -1,70 +0,0 @@
---- xen-4.10.0/tools/Makefile.orig 2017-12-13 11:37:59.000000000 +0000
-+++ xen-4.10.0/tools/Makefile 2018-02-27 12:04:44.376192357 +0000
-@@ -8,7 +8,7 @@
- SUBDIRS-y += libs
- SUBDIRS-y += libxc
- SUBDIRS-y += flask
--SUBDIRS-y += fuzz
-+#SUBDIRS-y += fuzz
- SUBDIRS-y += xenstore
- SUBDIRS-y += misc
- SUBDIRS-y += examples
---- xen-4.10.0/tools/debugger/kdd/kdd.c.orig 2018-02-22 12:31:57.007039159 +0000
-+++ xen-4.10.0/tools/debugger/kdd/kdd.c 2018-02-22 18:27:37.213653422 +0000
-@@ -687,7 +687,7 @@
- }
- } else {
- /* 32-bit control-register space starts at 0x[2]cc, for 84 bytes */
-- uint32_t offset = addr;
-+/* uint32_t offset = addr;
- if (offset > 0x200)
- offset -= 0x200;
- offset -= 0xcc;
-@@ -696,7 +696,9 @@
- len = 0;
- } else {
- memcpy(buf, ((uint8_t *)&ctrl.c32) + offset, len);
-- }
-+ } */
-+ /* disable above code due to compile issue for now */
-+ len = 0;
- }
-
- s->txp.cmd.mem.addr = addr;
---- xen-4.10.0/tools/libxl/libxl_arm_acpi.c.orig 2017-12-13 11:37:59.000000000 +0000
-+++ xen-4.10.0/tools/libxl/libxl_arm_acpi.c 2018-02-28 12:37:08.887221211 +0000
-@@ -190,7 +190,7 @@
- struct acpi_table_rsdp *rsdp = (void *)dom->acpi_modules[0].data + offset;
-
- memcpy(rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
-- memcpy(rsdp->oem_id, ACPI_OEM_ID, sizeof(rsdp->oem_id));
-+ memcpy(rsdp->oem_id, ACPI_OEM_ID, sizeof(ACPI_OEM_ID));
- rsdp->length = acpitables[RSDP].size;
- rsdp->revision = 0x02;
- rsdp->xsdt_physical_address = acpitables[XSDT].addr;
-@@ -205,11 +205,11 @@
- memcpy(h->signature, sig, 4);
- h->length = len;
- h->revision = rev;
-- memcpy(h->oem_id, ACPI_OEM_ID, sizeof(h->oem_id));
-- memcpy(h->oem_table_id, ACPI_OEM_TABLE_ID, sizeof(h->oem_table_id));
-+ memcpy(h->oem_id, ACPI_OEM_ID, sizeof(ACPI_OEM_ID));
-+ memcpy(h->oem_table_id, ACPI_OEM_TABLE_ID, sizeof(ACPI_OEM_TABLE_ID));
- h->oem_revision = 0;
- memcpy(h->asl_compiler_id, ACPI_ASL_COMPILER_ID,
-- sizeof(h->asl_compiler_id));
-+ sizeof(ACPI_ASL_COMPILER_ID));
- h->asl_compiler_revision = 0;
- h->checksum = 0;
- }
---- xen-4.10.0/tools/xenpmd/xenpmd.c.orig 2018-02-28 16:18:50.377726049 +0000
-+++ xen-4.10.0/tools/xenpmd/xenpmd.c 2018-02-28 16:20:31.502426829 +0000
-@@ -352,7 +352,7 @@
- strlen(info->model_number) +
- strlen(info->serial_number) +
- strlen(info->battery_type) +
-- strlen(info->oem_info) + 4));
-+ strlen(info->oem_info) + 4) & 0xff);
- write_ulong_lsb_first(val+2, info->present);
- write_ulong_lsb_first(val+10, info->design_capacity);
- write_ulong_lsb_first(val+18, info->last_full_capacity);
diff --git a/xen.gcc9.fixes.patch b/xen.gcc9.fixes.patch
index 7c8244b..111b063 100644
--- a/xen.gcc9.fixes.patch
+++ b/xen.gcc9.fixes.patch
@@ -24,7 +24,7 @@
+++ xen-4.11.1/xen/arch/x86/cpu/mtrr/generic.c 2019-02-10 19:24:09.378805103 +0000
@@ -171,6 +171,9 @@
printk("%sMTRR variable ranges %sabled:\n", level,
- mtrr_state.enabled & 2 ? "en" : "dis");
+ mtrr_state.enabled ? "en" : "dis");
width = (paddr_bits - PAGE_SHIFT + 3) / 4;
+ if ( width > 64 ) {
+ width=64;
@@ -32,14 +32,3 @@
for (i = 0; i < num_var_ranges; ++i) {
if (mtrr_state.var_ranges[i].mask & MTRR_PHYSMASK_VALID)
---- xen-4.11.1/tools/firmware/rombios/32bit/rombios_compat.h.orig 2018-11-29
14:04:11.000000000 +0000
-+++ xen-4.11.1/tools/firmware/rombios/32bit/rombios_compat.h 2019-02-14
21:16:28.660456669 +0000
-@@ -52,7 +52,7 @@
- Bit16u filler4;
- } r8;
- } u;
--} __attribute__((packed)) pushad_regs_t;
-+} pushad_regs_t;
-
-
-
diff --git a/xen.glibcfix.patch b/xen.glibcfix.patch
deleted file mode 100644
index 7b264d5..0000000
--- a/xen.glibcfix.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- xen-4.7.0/tools/blktap2/control/tap-ctl-allocate.c.orig 2016-06-20 11:38:15.000000000
+0100
-+++ xen-4.7.0/tools/blktap2/control/tap-ctl-allocate.c 2016-09-02 10:07:55.964084808
+0100
-@@ -36,6 +36,7 @@
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/ioctl.h>
-+#include <sys/sysmacros.h>
- #include <linux/major.h>
-
- #include "tap-ctl.h"
---- xen-4.7.0/tools/libxl/libxl_internal.h.orig 2016-06-20 11:38:15.000000000 +0100
-+++ xen-4.7.0/tools/libxl/libxl_internal.h 2016-09-02 17:35:24.853783711 +0100
-@@ -47,6 +47,7 @@
- #include <sys/socket.h>
- #include <sys/file.h>
- #include <sys/ioctl.h>
-+#include <sys/sysmacros.h>
-
- #include <xenevtchn.h>
- #include <xenstore.h>
diff --git a/xen.hypervisor.config b/xen.hypervisor.config
index 50b237c..e3d9369 100644
--- a/xen.hypervisor.config
+++ b/xen.hypervisor.config
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
-# Xen/x86 4.10.0 Configuration
+# Xen/x86 4.12.0 Configuration
#
CONFIG_X86_64=y
CONFIG_X86=y
@@ -17,6 +17,7 @@ CONFIG_SHADOW_PAGING=y
# CONFIG_BIGMEM is not set
# CONFIG_HVM_FEP is not set
CONFIG_TBOOT=y
+# CONFIG_XEN_GUEST is not set
#
# Common Features
@@ -25,27 +26,30 @@ CONFIG_COMPAT=y
CONFIG_CORE_PARKING=y
CONFIG_HAS_ALTERNATIVE=y
CONFIG_HAS_EX_TABLE=y
-CONFIG_HAS_MEM_ACCESS=y
+CONFIG_MEM_ACCESS_ALWAYS_ON=y
+CONFIG_MEM_ACCESS=y
CONFIG_HAS_MEM_PAGING=y
CONFIG_HAS_MEM_SHARING=y
CONFIG_HAS_PDX=y
+CONFIG_HAS_UBSAN=y
CONFIG_HAS_KEXEC=y
CONFIG_HAS_GDBSX=y
CONFIG_HAS_IOPORTS=y
+CONFIG_NEEDS_LIBELF=y
CONFIG_KEXEC=y
-CONFIG_TMEM=y
CONFIG_XENOPROF=y
# CONFIG_XSM is not set
CONFIG_SCHED_CREDIT=y
CONFIG_SCHED_CREDIT2=y
CONFIG_SCHED_RTDS=y
-CONFIG_SCHED_ARINC653=y
+# CONFIG_SCHED_ARINC653 is not set
CONFIG_SCHED_NULL=y
-CONFIG_SCHED_DEFAULT="credit"
+CONFIG_SCHED_DEFAULT="credit2"
CONFIG_CRYPTO=y
CONFIG_LIVEPATCH=y
CONFIG_FAST_SYMBOL_LOOKUP=y
CONFIG_CMDLINE=""
+CONFIG_DOM0_MEM=""
#
# Device Drivers
@@ -60,14 +64,31 @@ CONFIG_HAS_PASSTHROUGH=y
CONFIG_HAS_PCI=y
CONFIG_VIDEO=y
CONFIG_VGA=y
+CONFIG_HAS_VPCI=y
+
+#
+# Deprecated Functionality
+#
+# CONFIG_PV_LDT_PAGING is not set
CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
-CONFIG_XEN_GUEST=n
+CONFIG_ARCH_SUPPORTS_INT128=y
#
# Debugging Options
#
# CONFIG_DEBUG is not set
+# ARM64 settings
+CONFIG_64BIT=y
+CONFIG_ARM_64=y
+CONFIG_ARM=y
+CONFIG_GICV3=y
+# CONFIG_NEW_VGIC is not set
+CONFIG_SBSA_VUART_CONSOLE=y
+CONFIG_ARM_SSBD=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
+
+#
# ARM errata workaround via the alternative framework
#
CONFIG_ARM64_ERRATUM_827319=y
@@ -75,6 +96,24 @@ CONFIG_ARM64_ERRATUM_824069=y
CONFIG_ARM64_ERRATUM_819472=y
CONFIG_ARM64_ERRATUM_832075=y
CONFIG_ARM64_ERRATUM_834220=y
+CONFIG_ARM64_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_ALL_PLAT=y
+# CONFIG_QEMU is not set
+# CONFIG_RCAR3 is not set
+# CONFIG_MPSOC is not set
+# CONFIG_NO_PLAT is not set
+CONFIG_ALL64_PLAT=y
+CONFIG_MPSOC_PLATFORM=y
+CONFIG_HAS_DEVICE_TREE=y
+CONFIG_HAS_CADENCE_UART=y
+CONFIG_HAS_MVEBU=y
+CONFIG_HAS_PL011=y
+CONFIG_HAS_SCIF=y
+CONFIG_ARM_SMMU=y
-CONFIG_SBSA_VUART_CONSOLE=y
-# CONFIG_NEW_VGIC is not set
+# ARM32 settings
+CONFIG_ALL32_PLAT=y
+CONFIG_ARM32_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_ARM_32=y
+CONFIG_HAS_EXYNOS4210=y
+CONFIG_HAS_OMAP=y
diff --git a/xen.python.env.patch b/xen.python.env.patch
index e33d370..8844b18 100644
--- a/xen.python.env.patch
+++ b/xen.python.env.patch
@@ -4,19 +4,11 @@
$(INSTALL_DIR) $(DESTDIR)$(sbindir)
$(INSTALL_PROG) xenbaked $(DESTDIR)$(sbindir)/xenbaked
$(INSTALL_PROG) xentrace_setmask $(DESTDIR)$(sbindir)/xentrace_setmask
-- $(INSTALL_PROG) xenmon.py $(DESTDIR)$(sbindir)/xenmon.py
-+ $(INSTALL_PYTHON_PROG) xenmon.py $(DESTDIR)$(sbindir)/xenmon.py
+- $(INSTALL_PROG) xenmon.py $(DESTDIR)$(sbindir)/xenmon
++ $(INSTALL_PYTHON_PROG) xenmon.py $(DESTDIR)$(sbindir)/xenmon
.PHONY: uninstall
uninstall:
---- xen-4.11.0/tools/misc/xen-ringwatch.orig 2018-07-09 14:47:19.000000000 +0100
-+++ xen-4.11.0/tools/misc/xen-ringwatch 2018-09-10 21:18:53.191063128 +0100
-@@ -1,4 +1,4 @@
--#!/usr/bin/python
-+#!/usr/bin/python2
- #
- # Copyright (C) 2011 Citrix Systems, Inc.
- #
--- xen-4.11.0/tools/python/Makefile.orig 2018-07-09 14:47:19.000000000 +0100
+++ xen-4.11.0/tools/python/Makefile 2018-09-10 21:21:07.097979007 +0100
@@ -20,8 +20,8 @@
diff --git a/xen.spec b/xen.spec
index b11a535..7835edc 100644
--- a/xen.spec
+++ b/xen.spec
@@ -62,12 +62,12 @@
%endif
# Hypervisor ABI
-%define hv_abi 4.11
+%define hv_abi 4.12
Summary: Xen is a virtual machine monitor
Name: xen
-Version: 4.11.1
-Release: 4%{?dist}
+Version: 4.12.0
+Release: 0%{?dist}
License: GPLv2+ and LGPLv2+ and BSD
URL:
http://xen.org/
Source0:
https://downloads.xenproject.org/release/xen/%{version}/xen-%{version}.ta...
@@ -83,7 +83,6 @@ Source15: polarssl-1.1.4-gpl.tgz
Source21: xen.hypervisor.config
Patch1: xen-net-disable-iptables-on-bridge.patch
-Patch2: xen.use.fedora.ipxe.patch
Patch3: xen.fedora.efi.build.patch
Patch4: CVE-2014-0150.patch
Patch5: xen.fedora.systemd.patch
@@ -108,7 +107,6 @@ Patch23: qemu.trad.CVE-2016-4441.patch
Patch24: qemu.trad.CVE-2016-5238.patch
Patch25: qemu.trad.CVE-2016-5338.patch
Patch27: qemu.trad.CVE-2016-6351.patch
-Patch28: xen.glibcfix.patch
Patch29: qemu.trad.CVE-2016-8669.patch
Patch30: qemu.trad.CVE-2016-8910.patch
Patch31: qemu.trad.bug1399055.patch
@@ -120,23 +118,9 @@ Patch36: qemu.trad.CVE-2017-7718.patch
Patch37: droplibvirtconflict.patch
Patch38: qemu.trad.CVE-2017-8309.patch
Patch39: qemu.trad.CVE-2017-9330.patch
-Patch40: xen.gcc8.temp.fix.patch
Patch41: xen.drop.brctl.patch
-Patch42: xen.stubdom.build.patch
-Patch44: xen.vwprintw.fix.patch
Patch45: xen.python.env.patch
Patch46: xen.gcc9.fixes.patch
-Patch47: xsa284.patch
-Patch48: xsa285-4.11.patch
-Patch49: xsa287-4.11.patch
-Patch50: xsa288-4.11.patch
-Patch51: xsa290-4.11-1.patch
-Patch52: xsa290-4.11-2.patch
-Patch53: xsa291-4.11.patch
-Patch54: xsa292.patch
-Patch55: xsa293-4.11-1.patch
-Patch56: xsa293-4.11-2.patch
-Patch57: xsa294-4.11.patch
%if %build_qemutrad
@@ -331,29 +315,13 @@ manage Xen virtual machines.
%patch23 -p1
%patch24 -p1
%patch25 -p1
-%patch28 -p1
%patch33 -p1
%patch34 -p1
%patch37 -p1
-%patch2 -p1
%patch3 -p1
-%patch40 -p1
%patch41 -p1
-%patch42 -p1
-%patch44 -p1
%patch45 -p1
%patch46 -p1
-%patch47 -p1
-%patch48 -p1
-%patch49 -p1
-%patch50 -p1
-%patch51 -p1
-%patch52 -p1
-%patch53 -p1
-%patch54 -p1
-%patch55 -p1
-%patch56 -p1
-%patch57 -p1
# qemu-xen-traditional patches
pushd tools/qemu-xen-traditional
@@ -425,6 +393,9 @@ CONFIG_EXTRA=""
%if %build_ovmf
CONFIG_EXTRA="$CONFIG_EXTRA
--with-system-ovmf=%{_libexecdir}/%{name}/boot/ovmf.bin"
%endif
+%ifnarch armv7hl aarch64
+CONFIG_EXTRA="$CONFIG_EXTRA --with-system-ipxe=/usr/share/ipxe"
+%endif
./configure --prefix=%{_prefix} --libdir=%{_libdir} --libexecdir=%{_libexecdir}
--with-system-seabios=%{seabiosloc} --with-system-qemu=/usr/bin/qemu-system-i386
--with-linux-backend-modules="xen-evtchn xen-gntdev xen-gntalloc xen-blkback
xen-netback xen-pciback xen-scsiback xen-acpi-processor" $CONFIG_EXTRA
make %{?_smp_mflags} %{?ocaml_flags} prefix=/usr tools
%if %build_docs
@@ -692,7 +663,7 @@ fi
%files libs
%{_libdir}/*.so.*
-%{_libdir}/fs
+%{_libdir}/xenfsimage
# All runtime stuff except for XenD/xm python stuff
%files runtime
@@ -754,7 +725,7 @@ fi
%{_mandir}/man7/xl-numa-placement.7.gz
%endif
-%{python2_sitearch}/fsimage.so
+%{python2_sitearch}/xenfsimage.so
%{python2_sitearch}/grub
%{python2_sitearch}/pygrub-*.egg-info
@@ -804,9 +775,8 @@ fi
%{_bindir}/xencov_split
%ifnarch armv7hl aarch64
%{_sbindir}/gdbsx
-%{_sbindir}/kdd
+%{_sbindir}/xen-kdd
%endif
-%{_sbindir}/xen-bugtool
%ifnarch armv7hl aarch64
%{_sbindir}/xen-hptool
%{_sbindir}/xen-hvmcrash
@@ -815,7 +785,7 @@ fi
%{_sbindir}/xen-tmem-list-parse
%{_sbindir}/xenconsoled
%{_sbindir}/xenlockprof
-%{_sbindir}/xenmon.py*
+%{_sbindir}/xenmon
%{_sbindir}/xentop
%{_sbindir}/xentrace_setmask
%{_sbindir}/xenbaked
@@ -828,14 +798,11 @@ fi
%ifnarch armv7hl aarch64
%{_sbindir}/xen-lowmemd
%endif
-%{_sbindir}/xen-ringwatch
%{_sbindir}/xencov
%ifnarch armv7hl aarch64
%{_sbindir}/xen-mfndump
%endif
-%ifnarch armv7hl aarch64
%{_bindir}/xenalyze
-%endif
%{_sbindir}/xentrace
%{_sbindir}/xentrace_setsize
%ifnarch armv7hl aarch64
@@ -843,6 +810,7 @@ fi
%endif
%{_sbindir}/xen-livepatch
%{_sbindir}/xen-diag
+/usr/lib/debug/usr/bin/xenstore*
# Xen logfiles
%dir %attr(0700,root,root) %{_localstatedir}/log/xen
@@ -905,6 +873,17 @@ fi
%endif
%changelog
+* Thu Apr 04 2019 Michael Young <m.a.young(a)durham.ac.uk> - 4.12.0-0
+- update to 4.12.0 (#1694695)
+ remove patches for issues now fixed upstream
+ replace xen.use.fedora.ipxe.patch with --with-system-ipxe
+ drop xen.glibcfix.patch xen.gcc8.temp.fix.patch which are no longer needed
+ adjust xen.python.env.patch xen.gcc9.fixes.patch
+ xen.hypervisor.config refresh
+ kdd is now xen-kdd, xenmon.py is now xenmon, fsimage.so is now xenfsimage.so
+ fs libdir is now xenfsimage libdir
+ xen-ringwatch xen-bugtool have been dropped
+
* Tue Mar 05 2019 Michael Young <m.a.young(a)durham.ac.uk> - 4.11.1-4
- xen: various flaws (#1685577)
grant table transfer issues on large hosts [XSA-284]
diff --git a/xen.stubdom.build.patch b/xen.stubdom.build.patch
deleted file mode 100644
index 05d1b7c..0000000
--- a/xen.stubdom.build.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- xen-4.11.0/stubdom/Makefile.orig 2018-07-09 14:47:19.000000000 +0100
-+++ xen-4.11.0/stubdom/Makefile 2018-07-11 22:33:00.764078143 +0100
-@@ -87,7 +87,7 @@
- patch -d $@ -p0 < newlib.patch
- patch -d $@ -p0 < newlib-chk.patch
- patch -d $@ -p1 < newlib-stdint-size_max-fix-from-1.17.0.patch
-- find $@ -type f | xargs perl -i.bak \
-+ find $@ -type f | xargs egrep -l "tzname|daylight|timezone" | xargs perl
-i.bak \
- -pe 's/\b_(tzname|daylight|timezone)\b/$$1/g'
- touch $@
-
diff --git a/xen.use.fedora.ipxe.patch b/xen.use.fedora.ipxe.patch
deleted file mode 100644
index 49871c6..0000000
--- a/xen.use.fedora.ipxe.patch
+++ /dev/null
@@ -1,33 +0,0 @@
---- xen-4.2.0/tools/firmware/hvmloader/Makefile.orig 2012-05-27 21:57:04.481812859 +0100
-+++ xen-4.2.0/tools/firmware/hvmloader/Makefile 2012-06-02 18:52:44.935034128 +0100
-@@ -48,7 +48,7 @@
- else
- CIRRUSVGA_ROM := ../vgabios/VGABIOS-lgpl-latest.cirrus.bin
- endif
--ETHERBOOT_ROMS := $(addprefix ../etherboot/ipxe/src/bin/, $(addsuffix .rom,
$(ETHERBOOT_NICS)))
-+ETHERBOOT_ROMS := $(addprefix /usr/share/ipxe/, $(addsuffix .rom, $(ETHERBOOT_NICS)))
- endif
-
- ROMS :=
---- xen-4.2.0/Config.mk.orig 2012-05-27 21:57:04.479812884 +0100
-+++ xen-4.2.0/Config.mk 2012-06-02 18:55:14.087169469 +0100
-@@ -206,7 +206,7 @@
-
- SEABIOS_UPSTREAM_REVISION ?= rel-1.11.1
-
--ETHERBOOT_NICS ?= rtl8139 8086100e
-+ETHERBOOT_NICS ?= 10ec8139 8086100e
-
-
- QEMU_TRADITIONAL_REVISION ?= xen-4.11.1
---- xen-4.2.0/tools/firmware/Makefile.orig 2012-05-27 21:57:04.480812871 +0100
-+++ xen-4.2.0/tools/firmware/Makefile 2012-06-02 19:03:52.254691484 +0100
-@@ -10,7 +10,7 @@
- SUBDIRS-$(CONFIG_SEABIOS) += seabios-dir
- SUBDIRS-$(CONFIG_ROMBIOS) += rombios
- SUBDIRS-$(CONFIG_ROMBIOS) += vgabios
--SUBDIRS-$(CONFIG_ROMBIOS) += etherboot
-+#SUBDIRS-$(CONFIG_ROMBIOS) += etherboot
- SUBDIRS-$(CONFIG_PV_SHIM) += xen-dir
- SUBDIRS-y += hvmloader
-
diff --git a/xen.vwprintw.fix.patch b/xen.vwprintw.fix.patch
deleted file mode 100644
index 5223f67..0000000
--- a/xen.vwprintw.fix.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- xen-4.11.0/tools/xenstat/xentop/xentop.c.orig 2018-07-09 14:47:19.000000000 +0100
-+++ xen-4.11.0/tools/xenstat/xentop/xentop.c 2018-08-14 22:41:08.035898962 +0100
-@@ -301,7 +301,7 @@
- if (!batch) {
- if((current_row() < lines()-1)) {
- va_start(args, fmt);
-- vwprintw(stdscr, (curses_str_t)fmt, args);
-+ vw_printw(stdscr, (curses_str_t)fmt, args);
- va_end(args);
- }
- } else {
diff --git a/xsa284.patch b/xsa284.patch
deleted file mode 100644
index 0b5dcd0..0000000
--- a/xsa284.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Jan Beulich <jbeulich(a)suse.com>
-Subject: gnttab: set page refcount for copy-on-grant-transfer
-
-Commit 5cc77f9098 ("32-on-64: Fix domain address-size clamping,
-implement"), which introduced this functionality, took care of clearing
-the old page's PGC_allocated, but failed to set the bit (and install the
-associated reference) on the newly allocated one. Furthermore the "mfn"
-local variable was never updated, and hence the wrong MFN was passed to
-guest_physmap_add_page() (and back to the destination domain) in this
-case, leading to an IOMMU mapping into an unowned page.
-
-Ideally the code would use assign_pages(), but the call to
-gnttab_prepare_for_transfer() sits in the middle of the actions
-mirroring that function.
-
-This is XSA-284.
-
-Signed-off-by: Jan Beulich <jbeulich(a)suse.com>
-Acked-by: George Dunlap <george.dunlap(a)citrix.com>
-
---- a/xen/common/grant_table.c
-+++ b/xen/common/grant_table.c
-@@ -2183,6 +2183,8 @@ gnttab_transfer(
- page->count_info &= ~(PGC_count_mask|PGC_allocated);
- free_domheap_page(page);
- page = new_page;
-+ page->count_info = PGC_allocated | 1;
-+ mfn = page_to_mfn(page);
- }
-
- spin_lock(&e->page_alloc_lock);
diff --git a/xsa285-4.11.patch b/xsa285-4.11.patch
deleted file mode 100644
index 4d1cde4..0000000
--- a/xsa285-4.11.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From: Jan Beulich <jbeulich(a)suse.com>
-Subject: IOMMU/x86: fix type ref-counting race upon IOMMU page table construction
-
-When arch_iommu_populate_page_table() gets invoked for an already
-running guest, simply looking at page types once isn't enough, as they
-may change at any time. Add logic to re-check the type after having
-mapped the page, unmapping it again if needed.
-
-This is XSA-285.
-
-Signed-off-by: Jan Beulich <jbeulich(a)suse.com>
-Tentatively-Acked-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
-
---- a/xen/drivers/passthrough/x86/iommu.c
-+++ b/xen/drivers/passthrough/x86/iommu.c
-@@ -68,6 +68,27 @@ int arch_iommu_populate_page_table(struct domain *d)
- rc = hd->platform_ops->map_page(d, gfn, mfn,
- IOMMUF_readable |
- IOMMUF_writable);
-+
-+ /*
-+ * We may be working behind the back of a running guest, which
-+ * may change the type of a page at any time. We can't prevent
-+ * this (for instance, by bumping the type count while mapping
-+ * the page) without causing legitimate guest type-change
-+ * operations to fail. So after adding the page to the IOMMU,
-+ * check again to make sure this is still valid. NB that the
-+ * writable entry in the iommu is harmless until later, when
-+ * the actual device gets assigned.
-+ */
-+ if ( !rc && !is_hvm_domain(d) &&
-+ ((page->u.inuse.type_info & PGT_type_mask) !=
-+ PGT_writable_page) )
-+ {
-+ rc = hd->platform_ops->unmap_page(d, gfn);
-+ /* If the type changed yet again, simply force a retry. */
-+ if ( !rc && ((page->u.inuse.type_info &
PGT_type_mask) ==
-+ PGT_writable_page) )
-+ rc = -ERESTART;
-+ }
- }
- if ( rc )
- {
diff --git a/xsa287-4.11.patch b/xsa287-4.11.patch
deleted file mode 100644
index 8563560..0000000
--- a/xsa287-4.11.patch
+++ /dev/null
@@ -1,328 +0,0 @@
-From 67620c1ccb13f7b58645f48248ba1f408b021fdc Mon Sep 17 00:00:00 2001
-From: George Dunlap <george.dunlap(a)citrix.com>
-Date: Fri, 18 Jan 2019 15:00:34 +0000
-Subject: [PATCH] steal_page: Get rid of bogus struct page states
-
-The original rules for `struct page` required the following invariants
-at all times:
-
-- refcount > 0 implies owner != NULL
-- PGC_allocated implies refcount > 0
-
-steal_page, in a misguided attempt to protect against unknown races,
-violates both of these rules, thus introducing other races:
-
-- Temporarily, the count_info has the refcount go to 0 while
- PGC_allocated is set
-
-- It explicitly returns the page PGC_allocated set, but owner == NULL
- and page not on the page_list.
-
-The second one meant that page_get_owner_and_reference() could return
-NULL even after having successfully grabbed a reference on the page,
-leading the caller to leak the reference (since "couldn't get ref" and
-"got ref but no owner" look the same).
-
-Furthermore, rather than grabbing a page reference to ensure that the
-owner doesn't change under its feet, it appears to rely on holding
-d->page_alloc lock to prevent this.
-
-Unfortunately, this is ineffective: page->owner remains non-NULL for
-some time after the count has been set to 0; meaning that it would be
-entirely possible for the page to be freed and re-allocated to a
-different domain between the page_get_owner() check and the count_info
-check.
-
-Modify steal_page to instead follow the appropriate access discipline,
-taking the page through series of states similar to being freed and
-then re-allocated with MEMF_no_owner:
-
-- Grab an extra reference to make sure we don't race with anyone else
- freeing the page
-
-- Drop both references and PGC_allocated atomically, so that (if
-successful), anyone else trying to grab a reference will fail
-
-- Attempt to reset Xen's mappings
-
-- Reset the rest of the state.
-
-Then, modify the two callers appropriately:
-
-- Leave count_info alone (it's already been cleared)
-- Call free_domheap_page() directly if appropriate
-- Call assign_pages() rather than open-coding a partial assign
-
-With all callers to assign_pages() now passing in pages with the
-type_info field clear, tighten the respective assertion there.
-
-This is XSA-287.
-
-Signed-off-by: George Dunlap <george.dunlap(a)citrix.com>
-Signed-off-by: Jan Beulich <jbeulich(a)suse.com>
----
- xen/arch/x86/mm.c | 84 ++++++++++++++++++++++++++++------------
- xen/common/grant_table.c | 20 +++++-----
- xen/common/memory.c | 19 +++++----
- xen/common/page_alloc.c | 2 +-
- 4 files changed, 83 insertions(+), 42 deletions(-)
-
-diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
-index 6509035a5c..d8ff58c901 100644
---- a/xen/arch/x86/mm.c
-+++ b/xen/arch/x86/mm.c
-@@ -3966,70 +3966,106 @@ int donate_page(
- return -EINVAL;
- }
-
-+/*
-+ * Steal page will attempt to remove `page` from domain `d`. Upon
-+ * return, `page` will be in a state similar to the state of a page
-+ * returned from alloc_domheap_page() with MEMF_no_owner set:
-+ * - refcount 0
-+ * - type count cleared
-+ * - owner NULL
-+ * - page caching attributes cleaned up
-+ * - removed from the domain's page_list
-+ *
-+ * If MEMF_no_refcount is not set, the domain's tot_pages will be
-+ * adjusted. If this results in the page count falling to 0,
-+ * put_domain() will be called.
-+ *
-+ * The caller should either call free_domheap_page() to free the
-+ * page, or assign_pages() to put it back on some domain's page list.
-+ */
- int steal_page(
- struct domain *d, struct page_info *page, unsigned int memflags)
- {
- unsigned long x, y;
- bool drop_dom_ref = false;
-- const struct domain *owner = dom_xen;
-+ const struct domain *owner;
-+ int rc;
-
- if ( paging_mode_external(d) )
- return -EOPNOTSUPP;
-
-- spin_lock(&d->page_alloc_lock);
--
-- if ( is_xen_heap_page(page) || ((owner = page_get_owner(page)) != d) )
-+ /* Grab a reference to make sure the page doesn't change under our feet */
-+ rc = -EINVAL;
-+ if ( !(owner = page_get_owner_and_reference(page)) )
- goto fail;
-
-+ if ( owner != d || is_xen_heap_page(page) )
-+ goto fail_put;
-+
- /*
-- * We require there is just one reference (PGC_allocated). We temporarily
-- * drop this reference now so that we can safely swizzle the owner.
-+ * We require there are exactly two references -- the one we just
-+ * took, and PGC_allocated. We temporarily drop both these
-+ * references so that the page becomes effectively non-"live" for
-+ * the domain.
- */
- y = page->count_info;
- do {
- x = y;
-- if ( (x & (PGC_count_mask|PGC_allocated)) != (1 | PGC_allocated) )
-- goto fail;
-- y = cmpxchg(&page->count_info, x, x & ~PGC_count_mask);
-+ if ( (x & (PGC_count_mask|PGC_allocated)) != (2 | PGC_allocated) )
-+ goto fail_put;
-+ y = cmpxchg(&page->count_info, x, x &
~(PGC_count_mask|PGC_allocated));
- } while ( y != x );
-
- /*
-- * With the sole reference dropped temporarily, no-one can update type
-- * information. Type count also needs to be zero in this case, but e.g.
-- * PGT_seg_desc_page may still have PGT_validated set, which we need to
-- * clear before transferring ownership (as validation criteria vary
-- * depending on domain type).
-+ * NB this is safe even if the page ends up being given back to
-+ * the domain, because the count is zero: subsequent mappings will
-+ * cause the cache attributes to be re-instated inside
-+ * get_page_from_l1e().
-+ */
-+ if ( (rc = cleanup_page_cacheattr(page)) )
-+ {
-+ /*
-+ * Couldn't fixup Xen's mappings; put things the way we found
-+ * it and return an error
-+ */
-+ page->count_info |= PGC_allocated | 1;
-+ goto fail;
-+ }
-+
-+ /*
-+ * With the reference count now zero, nobody can grab references
-+ * to do anything else with the page. Return the page to a state
-+ * that it might be upon return from alloc_domheap_pages with
-+ * MEMF_no_owner set.
- */
-+ spin_lock(&d->page_alloc_lock);
-+
- BUG_ON(page->u.inuse.type_info & (PGT_count_mask | PGT_locked |
- PGT_pinned));
- page->u.inuse.type_info = 0;
--
-- /* Swizzle the owner then reinstate the PGC_allocated reference. */
- page_set_owner(page, NULL);
-- y = page->count_info;
-- do {
-- x = y;
-- BUG_ON((x & (PGC_count_mask|PGC_allocated)) != PGC_allocated);
-- } while ( (y = cmpxchg(&page->count_info, x, x | 1)) != x );
-+ page_list_del(page, &d->page_list);
-
- /* Unlink from original owner. */
- if ( !(memflags & MEMF_no_refcount) && !domain_adjust_tot_pages(d, -1)
)
- drop_dom_ref = true;
-- page_list_del(page, &d->page_list);
-
- spin_unlock(&d->page_alloc_lock);
-+
- if ( unlikely(drop_dom_ref) )
- put_domain(d);
-+
- return 0;
-
-+ fail_put:
-+ put_page(page);
- fail:
-- spin_unlock(&d->page_alloc_lock);
- gdprintk(XENLOG_WARNING, "Bad steal mfn %" PRI_mfn
- " from d%d (owner d%d) caf=%08lx taf=%" PRtype_info
"\n",
- mfn_x(page_to_mfn(page)), d->domain_id,
- owner ? owner->domain_id : DOMID_INVALID,
- page->count_info, page->u.inuse.type_info);
-- return -EINVAL;
-+ return rc;
- }
-
- static int __do_update_va_mapping(
-diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
-index c0585d33f4..656fad1b42 100644
---- a/xen/common/grant_table.c
-+++ b/xen/common/grant_table.c
-@@ -2179,7 +2179,7 @@ gnttab_transfer(
- rcu_unlock_domain(e);
- put_gfn_and_copyback:
- put_gfn(d, gop.mfn);
-- page->count_info &= ~(PGC_count_mask|PGC_allocated);
-+ /* The count_info has already been cleaned */
- free_domheap_page(page);
- goto copyback;
- }
-@@ -2202,10 +2202,9 @@ gnttab_transfer(
-
- copy_domain_page(page_to_mfn(new_page), mfn);
-
-- page->count_info &= ~(PGC_count_mask|PGC_allocated);
-+ /* The count_info has already been cleared */
- free_domheap_page(page);
- page = new_page;
-- page->count_info = PGC_allocated | 1;
- mfn = page_to_mfn(page);
- }
-
-@@ -2245,12 +2244,17 @@ gnttab_transfer(
- */
- spin_unlock(&e->page_alloc_lock);
- okay = gnttab_prepare_for_transfer(e, d, gop.ref);
-- spin_lock(&e->page_alloc_lock);
-
-- if ( unlikely(!okay) || unlikely(e->is_dying) )
-+ if ( unlikely(!okay || assign_pages(e, page, 0, MEMF_no_refcount)) )
- {
-- bool_t drop_dom_ref = !domain_adjust_tot_pages(e, -1);
-+ bool drop_dom_ref;
-
-+ /*
-+ * Need to grab this again to safely free our "reserved"
-+ * page in the page total
-+ */
-+ spin_lock(&e->page_alloc_lock);
-+ drop_dom_ref = !domain_adjust_tot_pages(e, -1);
- spin_unlock(&e->page_alloc_lock);
-
- if ( okay /* i.e. e->is_dying due to the surrounding if() */ )
-@@ -2263,10 +2267,6 @@ gnttab_transfer(
- goto unlock_and_copyback;
- }
-
-- page_list_add_tail(page, &e->page_list);
-- page_set_owner(page, e);
--
-- spin_unlock(&e->page_alloc_lock);
- put_gfn(d, gop.mfn);
-
- TRACE_1D(TRC_MEM_PAGE_GRANT_TRANSFER, e->domain_id);
-diff --git a/xen/common/memory.c b/xen/common/memory.c
-index 4fb7962c79..f71163221f 100644
---- a/xen/common/memory.c
-+++ b/xen/common/memory.c
-@@ -675,20 +675,22 @@ static long
memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg)
- * Success! Beyond this point we cannot fail for this chunk.
- */
-
-- /* Destroy final reference to each input page. */
-+ /*
-+ * These pages have already had owner and reference cleared.
-+ * Do the final two steps: Remove from the physmap, and free
-+ * them.
-+ */
- while ( (page = page_list_remove_head(&in_chunk_list)) )
- {
- unsigned long gfn;
-
-- if ( !test_and_clear_bit(_PGC_allocated, &page->count_info) )
-- BUG();
- mfn = page_to_mfn(page);
- gfn = mfn_to_gmfn(d, mfn_x(mfn));
- /* Pages were unshared above */
- BUG_ON(SHARED_M2P(gfn));
- if ( guest_physmap_remove_page(d, _gfn(gfn), mfn, 0) )
- domain_crash(d);
-- put_page(page);
-+ free_domheap_page(page);
- }
-
- /* Assign each output page to the domain. */
-@@ -761,13 +763,16 @@ static long
memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg)
- * chunks succeeded.
- */
- fail:
-- /* Reassign any input pages we managed to steal. */
-+ /*
-+ * Reassign any input pages we managed to steal. NB that if the assign
-+ * fails again, we're on the hook for freeing the page, since we've already
-+ * cleared PGC_allocated.
-+ */
- while ( (page = page_list_remove_head(&in_chunk_list)) )
- if ( assign_pages(d, page, 0, MEMF_no_refcount) )
- {
- BUG_ON(!d->is_dying);
-- if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
-- put_page(page);
-+ free_domheap_page(page);
- }
-
- dying:
-diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
-index 482f0988f7..52da7762e3 100644
---- a/xen/common/page_alloc.c
-+++ b/xen/common/page_alloc.c
-@@ -2221,7 +2221,7 @@ int assign_pages(
- for ( i = 0; i < (1 << order); i++ )
- {
- ASSERT(page_get_owner(&pg[i]) == NULL);
-- ASSERT((pg[i].count_info & ~(PGC_allocated | 1)) == 0);
-+ ASSERT(!pg[i].count_info);
- page_set_owner(&pg[i], d);
- smp_wmb(); /* Domain pointer must be visible before updating refcnt. */
- pg[i].count_info = PGC_allocated | 1;
---
-2.20.1
-
diff --git a/xsa288-4.11.patch b/xsa288-4.11.patch
deleted file mode 100644
index 9dc4e37..0000000
--- a/xsa288-4.11.patch
+++ /dev/null
@@ -1,308 +0,0 @@
-From 5d3a02e320f88747b75e3794c2e694284ae64c3e Mon Sep 17 00:00:00 2001
-From: George Dunlap <george.dunlap(a)citrix.com>
-Date: Wed, 23 Jan 2019 11:57:46 +0000
-Subject: [PATCH] xen: Make coherent PV IOMMU discipline
-
-In order for a PV domain to set up DMA from a passed-through device to
-one of its pages, the page must be mapped in the IOMMU. On the other
-hand, before a PV page may be used as a "special" page type (such as a
-pagetable or descriptor table), it _must not_ be writable in the IOMMU
-(otherwise a malicious guest could DMA arbitrary page tables into the
-memory, bypassing Xen's safety checks); and Xen's current rule is to
-have such pages not in the IOMMU at all.
-
-At the moment, in order to accomplish this, the code borrows HVM
-domain's "physmap" concept: When a page is assigned to a guest,
-guess_physmap_add_entry() is called, which for PV guests, will create
-a writable IOMMU mapping; and when a page is removed,
-guest_physmap_remove_entry() is called, which will remove the mapping.
-
-Additionally, when a page gains the PGT_writable page type, the page
-will be added into the IOMMU; and when the page changes away from a
-PGT_writable type, the page will be removed from the IOMMU.
-
-Unfortunately, borrowing the "physmap" concept from HVM domains is
-problematic. HVM domains have a lock on their p2m tables, ensuring
-synchronization between modifications to the p2m; and all hypercall
-parameters must first be translated through the p2m before being used.
-
-Trying to mix this locked-and-gated approach with PV's lock-free
-approach leads to several races and inconsistencies:
-
-* A race between a page being assigned and it being put into the
- physmap; for example:
- - P1: call populate_physmap() { A = allocate_domheap_pages() }
- - P2: Guess page A's mfn, and call decrease_reservation(A). A is owned by the
domain,
- and so Xen will clear the PGC_allocated bit and free the page
- - P1: finishes populate_physmap() { guest_physmap_add_entry() }
-
- Now the domain has a writable IOMMU mapping to a page it no longer owns.
-
-* Pages start out as type PGT_none, but with a writable IOMMU mapping.
- If a guest uses a page as a page table without ever having created a
- writable mapping, the IOMMU mapping will not be removed; the guest
- will have a writable IOMMU mapping to a page it is currently using
- as a page table.
-
-* A newly-allocated page can be DMA'd into with no special actions on
- the part of the guest; However, if a page is promoted to a
- non-writable type, the page must be mapped with a writable type before
- DMA'ing to it again, or the transaction will fail.
-
-To fix this, do away with the "PV physmap" concept entirely, and
-replace it with the following IOMMU discipline for PV guests:
- - (type == PGT_writable) <=> in iommu (even if type_count == 0)
- - Upon a final put_page(), check to see if type is PGT_writable; if so,
- iommu_unmap.
-
-In order to achieve that:
-
-- Remove PV IOMMU related code from guest_physmap_*
-
-- Repurpose cleanup_page_cacheattr() into a general
- cleanup_page_mappings() function, which will both fix up Xen
- mappings for pages with special cache attributes, and also check for
- a PGT_writable type and remove pages if appropriate.
-
-- For compatibility with current guests, grab-and-release a
- PGT_writable_page type for PV guests in guest_physmap_add_entry().
- This will cause most "normal" guest pages to start out life with
- PGT_writable_page type (and thus an IOMMU mapping), but no type
- count (so that they can be used as special cases at will).
-
-Also, note that there is one exception to to the "PGT_writable => in
-iommu" rule: xenheap pages shared with guests may be given a
-PGT_writable type with one type reference. This reference prevents
-the type from changing, which in turn prevents page from gaining an
-IOMMU mapping in get_page_type(). It's not clear whether this was
-intentional or not, but it's not something to change in a security
-update.
-
-This is XSA-288.
-
-Reported-by: Paul Durrant <paul.durrant(a)citrix.com>
-Signed-off-by: George Dunlap <george.dunlap(a)citrix.com>
-Signed-off-by: Jan Beulich <jbeulich(a)suse.com>
----
- xen/arch/x86/mm.c | 95 +++++++++++++++++++++++++++++++++++++++----
- xen/arch/x86/mm/p2m.c | 57 ++++++++++++--------------
- 2 files changed, 111 insertions(+), 41 deletions(-)
-
-diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
-index d8ff58c901..ad8aacad68 100644
---- a/xen/arch/x86/mm.c
-+++ b/xen/arch/x86/mm.c
-@@ -81,6 +81,22 @@
- * OS's, which will generally use the WP bit to simplify copy-on-write
- * implementation (in that case, OS wants a fault when it writes to
- * an application-supplied buffer).
-+ *
-+ * PV domUs and IOMMUs:
-+ * --------------------
-+ * For a guest to be able to DMA into a page, that page must be in the
-+ * domain's IOMMU. However, we *must not* allow DMA into 'special'
-+ * pages (such as page table pages, descriptor tables, &c); and we
-+ * must also ensure that mappings are removed from the IOMMU when the
-+ * page is freed. Finally, it is inherently racy to make any changes
-+ * based on a page with a non-zero type count.
-+ *
-+ * To that end, we put the page in the IOMMU only when a page gains
-+ * the PGT_writeable type; and we remove the page when it loses the
-+ * PGT_writeable type (not when the type count goes to zero). This
-+ * effectively protects the IOMMU status update with the type count we
-+ * have just acquired. We must also check for PGT_writable type when
-+ * doing the final put_page(), and remove it from the iommu if so.
- */
-
- #include <xen/init.h>
-@@ -2275,19 +2291,79 @@ static int mod_l4_entry(l4_pgentry_t *pl4e,
- return rc;
- }
-
--static int cleanup_page_cacheattr(struct page_info *page)
-+/*
-+ * In the course of a page's use, it may have caused other secondary
-+ * mappings to have changed:
-+ * - Xen's mappings may have been changed to accomodate the requested
-+ * cache attibutes
-+ * - A page may have been put into the IOMMU of a PV guest when it
-+ * gained a writable mapping.
-+ *
-+ * Now that the page is being freed, clean up these mappings if
-+ * appropriate. NB that at this point the page is still "allocated",
-+ * but not "live" (i.e., its refcount is 0), so it's safe to read the
-+ * count_info, owner, and type_info without synchronization.
-+ */
-+static int cleanup_page_mappings(struct page_info *page)
- {
- unsigned int cacheattr =
- (page->count_info & PGC_cacheattr_mask) >> PGC_cacheattr_base;
-+ int rc = 0;
-+ unsigned long mfn = mfn_x(page_to_mfn(page));
-
-- if ( likely(cacheattr == 0) )
-- return 0;
-+ /*
-+ * If we've modified xen mappings as a result of guest cache
-+ * attributes, restore them to the "normal" state.
-+ */
-+ if ( unlikely(cacheattr) )
-+ {
-+ page->count_info &= ~PGC_cacheattr_mask;
-
-- page->count_info &= ~PGC_cacheattr_mask;
-+ BUG_ON(is_xen_heap_page(page));
-
-- BUG_ON(is_xen_heap_page(page));
-+ rc = update_xen_mappings(mfn, 0);
-+ }
-
-- return update_xen_mappings(mfn_x(page_to_mfn(page)), 0);
-+ /*
-+ * If this may be in a PV domain's IOMMU, remove it.
-+ *
-+ * NB that writable xenheap pages have their type set and cleared by
-+ * implementation-specific code, rather than by get_page_type(). As such:
-+ * - They aren't expected to have an IOMMU mapping, and
-+ * - We don't necessarily expect the type count to be zero when the final
-+ * put_page happens.
-+ *
-+ * Go ahead and attemp to call iommu_unmap() on xenheap pages anyway, just
-+ * in case; but only ASSERT() that the type count is zero and remove the
-+ * PGT_writable type for non-xenheap pages.
-+ */
-+ if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page )
-+ {
-+ struct domain *d = page_get_owner(page);
-+
-+ if ( d && is_pv_domain(d) && unlikely(need_iommu(d)) )
-+ {
-+ int rc2 = iommu_unmap_page(d, mfn);
-+
-+ if ( !rc )
-+ rc = rc2;
-+ }
-+
-+ if ( likely(!is_xen_heap_page(page)) )
-+ {
-+ ASSERT((page->u.inuse.type_info &
-+ (PGT_type_mask | PGT_count_mask)) == PGT_writable_page);
-+ /*
-+ * Clear the type to record the fact that all writable mappings
-+ * have been removed. But if either operation failed, leave
-+ * type_info alone.
-+ */
-+ if ( likely(!rc) )
-+ page->u.inuse.type_info &= ~(PGT_type_mask | PGT_count_mask);
-+ }
-+ }
-+
-+ return rc;
- }
-
- void put_page(struct page_info *page)
-@@ -2303,7 +2379,7 @@ void put_page(struct page_info *page)
-
- if ( unlikely((nx & PGC_count_mask) == 0) )
- {
-- if ( cleanup_page_cacheattr(page) == 0 )
-+ if ( !cleanup_page_mappings(page) )
- free_domheap_page(page);
- else
- gdprintk(XENLOG_WARNING,
-@@ -4020,9 +4096,10 @@ int steal_page(
- * NB this is safe even if the page ends up being given back to
- * the domain, because the count is zero: subsequent mappings will
- * cause the cache attributes to be re-instated inside
-- * get_page_from_l1e().
-+ * get_page_from_l1e(), or the page to be added back to the IOMMU
-+ * upon the type changing to PGT_writeable, as appropriate.
- */
-- if ( (rc = cleanup_page_cacheattr(page)) )
-+ if ( (rc = cleanup_page_mappings(page)) )
- {
- /*
- * Couldn't fixup Xen's mappings; put things the way we found
-diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
-index c53cab44d9..2b62bc61dd 100644
---- a/xen/arch/x86/mm/p2m.c
-+++ b/xen/arch/x86/mm/p2m.c
-@@ -708,23 +708,9 @@ p2m_remove_page(struct p2m_domain *p2m, unsigned long gfn_l,
unsigned long mfn,
- p2m_type_t t;
- p2m_access_t a;
-
-+ /* IOMMU for PV guests is handled in get_page_type() and put_page(). */
- if ( !paging_mode_translate(p2m->domain) )
-- {
-- int rc = 0;
--
-- if ( need_iommu(p2m->domain) )
-- {
-- for ( i = 0; i < (1 << page_order); i++ )
-- {
-- int ret = iommu_unmap_page(p2m->domain, mfn + i);
--
-- if ( !rc )
-- rc = ret;
-- }
-- }
--
-- return rc;
-- }
-+ return 0;
-
- ASSERT(gfn_locked_by_me(p2m, gfn));
- P2M_DEBUG("removing gfn=%#lx mfn=%#lx\n", gfn_l, mfn);
-@@ -769,26 +755,33 @@ guest_physmap_add_entry(struct domain *d, gfn_t gfn, mfn_t mfn,
- int pod_count = 0;
- int rc = 0;
-
-+ /* IOMMU for PV guests is handled in get_page_type() and put_page(). */
- if ( !paging_mode_translate(d) )
- {
-- if ( need_iommu(d) && t == p2m_ram_rw )
-- {
-- for ( i = 0; i < (1 << page_order); i++ )
-- {
-- rc = iommu_map_page(d, mfn_x(mfn_add(mfn, i)),
-- mfn_x(mfn_add(mfn, i)),
-- IOMMUF_readable|IOMMUF_writable);
-- if ( rc != 0 )
-- {
-- while ( i-- > 0 )
-- /* If statement to satisfy __must_check. */
-- if ( iommu_unmap_page(d, mfn_x(mfn_add(mfn, i))) )
-- continue;
-+ struct page_info *page = mfn_to_page(mfn);
-
-- return rc;
-- }
-- }
-+ /*
-+ * Our interface for PV guests wrt IOMMU entries hasn't been very
-+ * clear; but historically, pages have started out with IOMMU mappings,
-+ * and only lose them when changed to a different page type.
-+ *
-+ * Retain this property by grabbing a writable type ref and then
-+ * dropping it immediately. The result will be pages that have a
-+ * writable type (and an IOMMU entry), but a count of 0 (such that
-+ * any guest-requested type changes succeed and remove the IOMMU
-+ * entry).
-+ */
-+ if ( !need_iommu(d) || t != p2m_ram_rw )
-+ return 0;
-+
-+ for ( i = 0; i < (1UL << page_order); ++i, ++page )
-+ {
-+ if ( get_page_and_type(page, d, PGT_writable_page) )
-+ put_page_and_type(page);
-+ else
-+ return -EINVAL;
- }
-+
- return 0;
- }
-
---
-2.20.1
-
diff --git a/xsa290-4.11-1.patch b/xsa290-4.11-1.patch
deleted file mode 100644
index 38ddb56..0000000
--- a/xsa290-4.11-1.patch
+++ /dev/null
@@ -1,237 +0,0 @@
-From: Jan Beulich <jbeulich(a)suse.com>
-Subject: x86/mm: also allow L2 (un)validation to be preemptible
-
-Commit c612481d1c ("x86/mm: Plumbing to allow any PTE update to fail
-with -ERESTART") added assertions next to the {alloc,free}_l2_table()
-invocations to document (and validate in debug builds) that L2
-(un)validations are always preemptible.
-
-The assertion in free_page_type() was now observed to trigger when
-recursive L2 page tables get cleaned up.
-
-In particular put_page_from_l2e()'s assumption that _put_page_type()
-would always succeed is now wrong, resulting in a partially un-validated
-page left in a domain, which has no other means of getting cleaned up
-later on. If not causing any problems earlier, this would ultimately
-trigger the check for ->u.inuse.type_info having a zero count when
-freeing the page during cleanup after the domain has died.
-
-As a result it should be considered a mistake to not have extended
-preemption fully to L2 when it was added to L3/L4 table handling, which
-this change aims to correct.
-
-The validation side additions are done just for symmetry.
-
-This is part of XSA-290.
-
-Reported-by: Manuel Bouyer <bouyer(a)antioche.eu.org>
-Tested-by: Manuel Bouyer <bouyer(a)antioche.eu.org>
-Signed-off-by: Jan Beulich <jbeulich(a)suse.com>
-Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
-
---- a/xen/arch/x86/mm.c
-+++ b/xen/arch/x86/mm.c
-@@ -1126,7 +1126,7 @@ get_page_from_l1e(
- define_get_linear_pagetable(l2);
- static int
- get_page_from_l2e(
-- l2_pgentry_t l2e, unsigned long pfn, struct domain *d)
-+ l2_pgentry_t l2e, unsigned long pfn, struct domain *d, int partial)
- {
- unsigned long mfn = l2e_get_pfn(l2e);
- int rc;
-@@ -1141,7 +1141,8 @@ get_page_from_l2e(
- return -EINVAL;
- }
-
-- rc = get_page_and_type_from_mfn(_mfn(mfn), PGT_l1_page_table, d, 0, 0);
-+ rc = get_page_and_type_from_mfn(_mfn(mfn), PGT_l1_page_table, d,
-+ partial, false);
- if ( unlikely(rc == -EINVAL) && get_l2_linear_pagetable(l2e, pfn, d) )
- rc = 0;
-
-@@ -1295,8 +1296,11 @@ void put_page_from_l1e(l1_pgentry_t l1e,
- * NB. Virtual address 'l2e' maps to a machine address within frame
'pfn'.
- * Note also that this automatically deals correctly with linear p.t.'s.
- */
--static int put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn)
-+static int put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn,
-+ int partial, bool defer)
- {
-+ int rc = 0;
-+
- if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) || (l2e_get_pfn(l2e) == pfn) )
- return 1;
-
-@@ -1311,13 +1315,27 @@ static int put_page_from_l2e(l2_pgentry_
- else
- {
- struct page_info *pg = l2e_get_page(l2e);
-- int rc = _put_page_type(pg, false, mfn_to_page(_mfn(pfn)));
-+ struct page_info *ptpg = mfn_to_page(_mfn(pfn));
-
-- ASSERT(!rc);
-- put_page(pg);
-+ if ( unlikely(partial > 0) )
-+ {
-+ ASSERT(!defer);
-+ rc = _put_page_type(pg, true, ptpg);
-+ }
-+ else if ( defer )
-+ {
-+ current->arch.old_guest_ptpg = ptpg;
-+ current->arch.old_guest_table = pg;
-+ }
-+ else
-+ {
-+ rc = _put_page_type(pg, true, ptpg);
-+ if ( likely(!rc) )
-+ put_page(pg);
-+ }
- }
-
-- return 0;
-+ return rc;
- }
-
- static int put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn,
-@@ -1487,11 +1505,12 @@ static int alloc_l2_table(struct page_in
- unsigned long pfn = mfn_x(page_to_mfn(page));
- l2_pgentry_t *pl2e;
- unsigned int i;
-- int rc = 0;
-+ int rc = 0, partial = page->partial_pte;
-
- pl2e = map_domain_page(_mfn(pfn));
-
-- for ( i = page->nr_validated_ptes; i < L2_PAGETABLE_ENTRIES; i++ )
-+ for ( i = page->nr_validated_ptes; i < L2_PAGETABLE_ENTRIES;
-+ i++, partial = 0 )
- {
- if ( i > page->nr_validated_ptes && hypercall_preempt_check() )
- {
-@@ -1501,23 +1520,33 @@ static int alloc_l2_table(struct page_in
- }
-
- if ( !is_guest_l2_slot(d, type, i) ||
-- (rc = get_page_from_l2e(pl2e[i], pfn, d)) > 0 )
-+ (rc = get_page_from_l2e(pl2e[i], pfn, d, partial)) > 0 )
- continue;
-
-- if ( unlikely(rc == -ERESTART) )
-+ if ( rc == -ERESTART )
- {
- page->nr_validated_ptes = i;
-- break;
-+ page->partial_pte = partial ?: 1;
- }
--
-- if ( rc < 0 )
-+ else if ( rc == -EINTR && i )
-+ {
-+ page->nr_validated_ptes = i;
-+ page->partial_pte = 0;
-+ rc = -ERESTART;
-+ }
-+ else if ( rc < 0 && rc != -EINTR )
- {
- gdprintk(XENLOG_WARNING, "Failure in alloc_l2_table: slot %#x\n",
i);
-- while ( i-- > 0 )
-- if ( is_guest_l2_slot(d, type, i) )
-- put_page_from_l2e(pl2e[i], pfn);
-- break;
-+ if ( i )
-+ {
-+ page->nr_validated_ptes = i;
-+ page->partial_pte = 0;
-+ current->arch.old_guest_ptpg = NULL;
-+ current->arch.old_guest_table = page;
-+ }
- }
-+ if ( rc < 0 )
-+ break;
-
- pl2e[i] = adjust_guest_l2e(pl2e[i], d);
- }
-@@ -1797,28 +1826,50 @@ static int free_l2_table(struct page_inf
- struct domain *d = page_get_owner(page);
- unsigned long pfn = mfn_x(page_to_mfn(page));
- l2_pgentry_t *pl2e;
-- unsigned int i = page->nr_validated_ptes - 1;
-- int err = 0;
-+ int rc = 0, partial = page->partial_pte;
-+ unsigned int i = page->nr_validated_ptes - !partial;
-
- pl2e = map_domain_page(_mfn(pfn));
-
-- ASSERT(page->nr_validated_ptes);
-- do {
-- if ( is_guest_l2_slot(d, page->u.inuse.type_info, i) &&
-- put_page_from_l2e(pl2e[i], pfn) == 0 &&
-- i && hypercall_preempt_check() )
-+ for ( ; ; )
-+ {
-+ if ( is_guest_l2_slot(d, page->u.inuse.type_info, i) )
-+ rc = put_page_from_l2e(pl2e[i], pfn, partial, false);
-+ if ( rc < 0 )
-+ break;
-+
-+ partial = 0;
-+
-+ if ( !i-- )
-+ break;
-+
-+ if ( hypercall_preempt_check() )
- {
-- page->nr_validated_ptes = i;
-- err = -ERESTART;
-+ rc = -EINTR;
-+ break;
- }
-- } while ( !err && i-- );
-+ }
-
- unmap_domain_page(pl2e);
-
-- if ( !err )
-+ if ( rc >= 0 )
-+ {
- page->u.inuse.type_info &= ~PGT_pae_xen_l2;
-+ rc = 0;
-+ }
-+ else if ( rc == -ERESTART )
-+ {
-+ page->nr_validated_ptes = i;
-+ page->partial_pte = partial ?: -1;
-+ }
-+ else if ( rc == -EINTR && i < L2_PAGETABLE_ENTRIES - 1 )
-+ {
-+ page->nr_validated_ptes = i + 1;
-+ page->partial_pte = 0;
-+ rc = -ERESTART;
-+ }
-
-- return err;
-+ return rc;
- }
-
- static int free_l3_table(struct page_info *page)
-@@ -2138,7 +2189,7 @@ static int mod_l2_entry(l2_pgentry_t *pl
- return -EBUSY;
- }
-
-- if ( unlikely((rc = get_page_from_l2e(nl2e, pfn, d)) < 0) )
-+ if ( unlikely((rc = get_page_from_l2e(nl2e, pfn, d, 0)) < 0) )
- return rc;
-
- nl2e = adjust_guest_l2e(nl2e, d);
-@@ -2157,7 +2208,8 @@ static int mod_l2_entry(l2_pgentry_t *pl
- return -EBUSY;
- }
-
-- put_page_from_l2e(ol2e, pfn);
-+ put_page_from_l2e(ol2e, pfn, 0, true);
-+
- return rc;
- }
-
diff --git a/xsa290-4.11-2.patch b/xsa290-4.11-2.patch
deleted file mode 100644
index 9355e02..0000000
--- a/xsa290-4.11-2.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From: Jan Beulich <jbeulich(a)suse.com>
-Subject: x86/mm: add explicit preemption checks to L3 (un)validation
-
-When recursive page tables are used at the L3 level, unvalidation of a
-single L4 table may incur unvalidation of two levels of L3 tables, i.e.
-a maximum iteration count of 512^3 for unvalidating an L4 table. The
-preemption check in free_l2_table() as well as the one in
-_put_page_type() may never be reached, so explicit checking is needed in
-free_l3_table().
-
-When recursive page tables are used at the L4 level, the iteration count
-at L4 alone is capped at 512^2. As soon as a present L3 entry is hit
-which itself needs unvalidation (and hence requiring another nested loop
-with 512 iterations), the preemption checks added here kick in, so no
-further preemption checking is needed at L4 (until we decide to permit
-5-level paging for PV guests).
-
-The validation side additions are done just for symmetry.
-
-This is part of XSA-290.
-
-Signed-off-by: Jan Beulich <jbeulich(a)suse.com>
-Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
-
---- a/xen/arch/x86/mm.c
-+++ b/xen/arch/x86/mm.c
-@@ -1581,6 +1581,13 @@ static int alloc_l3_table(struct page_in
- for ( i = page->nr_validated_ptes; i < L3_PAGETABLE_ENTRIES;
- i++, partial = 0 )
- {
-+ if ( i > page->nr_validated_ptes && hypercall_preempt_check() )
-+ {
-+ page->nr_validated_ptes = i;
-+ rc = -ERESTART;
-+ break;
-+ }
-+
- if ( is_pv_32bit_domain(d) && (i == 3) )
- {
- if ( !(l3e_get_flags(pl3e[i]) & _PAGE_PRESENT) ||
-@@ -1882,15 +1889,25 @@ static int free_l3_table(struct page_inf
-
- pl3e = map_domain_page(_mfn(pfn));
-
-- do {
-+ for ( ; ; )
-+ {
- rc = put_page_from_l3e(pl3e[i], pfn, partial, 0);
- if ( rc < 0 )
- break;
-+
- partial = 0;
-- if ( rc > 0 )
-- continue;
-- pl3e[i] = unadjust_guest_l3e(pl3e[i], d);
-- } while ( i-- );
-+ if ( rc == 0 )
-+ pl3e[i] = unadjust_guest_l3e(pl3e[i], d);
-+
-+ if ( !i-- )
-+ break;
-+
-+ if ( hypercall_preempt_check() )
-+ {
-+ rc = -EINTR;
-+ break;
-+ }
-+ }
-
- unmap_domain_page(pl3e);
-
diff --git a/xsa291-4.11.patch b/xsa291-4.11.patch
deleted file mode 100644
index 392e8e7..0000000
--- a/xsa291-4.11.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From: Jan Beulich <jbeulich(a)suse.com>
-Subject: x86/mm: don't retain page type reference when IOMMU operation fails
-
-The IOMMU update in _get_page_type() happens between recording of the
-new reference and validation of the page for its new type (if
-necessary). If the IOMMU operation fails, there's no point in actually
-carrying out validation. Furthermore, with this resulting in failure
-getting indicated to the caller, the recorded type reference also needs
-to be dropped again.
-
-Note that in case of failure of alloc_page_type() there's no need to
-undo the IOMMU operation: Only special types get handed to the function.
-The function, upon failure, clears ->u.inuse.type_info, effectively
-converting the page to PGT_none. The IOMMU mapping, however, solely
-depends on whether the type is PGT_writable_page.
-
-This is XSA-291.
-
-Reported-by: Igor Druzhinin <igor.druzhinin(a)citrix.com>
-Reported-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
-Signed-off-by: Jan Beulich <jbeulich(a)suse.com>
-Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
-
---- a/xen/arch/x86/mm.c
-+++ b/xen/arch/x86/mm.c
-@@ -2751,6 +2751,13 @@ static int _get_page_type(struct page_in
- iommu_ret = iommu_map_page(d, gfn_x(gfn),
- mfn_x(page_to_mfn(page)),
- IOMMUF_readable|IOMMUF_writable);
-+
-+ if ( unlikely(iommu_ret) )
-+ {
-+ _put_page_type(page, false, NULL);
-+ rc = iommu_ret;
-+ goto out;
-+ }
- }
- }
-
-@@ -2765,12 +2772,10 @@ static int _get_page_type(struct page_in
- rc = alloc_page_type(page, type, preemptible);
- }
-
-+ out:
- if ( (x & PGT_partial) && !(nx & PGT_partial) )
- put_page(page);
-
-- if ( !rc )
-- rc = iommu_ret;
--
- return rc;
- }
-
diff --git a/xsa292.patch b/xsa292.patch
deleted file mode 100644
index 198fd4f..0000000
--- a/xsa292.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From: Jan Beulich <jbeulich(a)suse.com>
-Subject: x86/mm: properly flush TLB in switch_cr3_cr4()
-
-The CR3 values used for contexts run with PCID enabled uniformly have
-CR3.NOFLUSH set, resulting in the CR3 write itself to not cause any
-flushing at all. When the second CR4 write is skipped or doesn't do any
-flushing, there's nothing so far which would purge TLB entries which may
-have accumulated again if the PCID doesn't change; the "just in case"
-flush only affects the case where the PCID actually changes. (There may
-be particularly many TLB entries re-accumulated in case of a watchdog
-NMI kicking in during the critical time window.)
-
-Suppress the no-flush behavior of the CR3 write in this particular case.
-
-Similarly the second CR4 write may not cause any flushing of TLB entries
-established again while the original PCID was still in use - it may get
-performed because of unrelated bits changing. The flush of the old PCID
-needs to happen nevertheless.
-
-At the same time also eliminate a possible race with lazy context
-switch: Just like for CR4, CR3 may change at any time while interrupts
-are enabled, due to the __sync_local_execstate() invocation from the
-flush IPI handler. It is for that reason that the CR3 read, just like
-the CR4 one, must happen only after interrupts have been turned off.
-
-This is XSA-292.
-
-Reported-by: Sergey Dyasli <sergey.dyasli(a)citrix.com>
-Reported-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
-Tested-by: Sergey Dyasli <sergey.dyasli(a)citrix.com>
-Signed-off-by: Jan Beulich <jbeulich(a)suse.com>
-Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
----
-v3: Adjust comments. Drop old_cr4 from the PGE check in the expression
- controlling the invocation of invpcid_flush_single_context(), as PGE
- is always clear there.
-v2: Decouple invpcid_flush_single_context() from 2nd CR4 write.
-
---- a/xen/arch/x86/flushtlb.c
-+++ b/xen/arch/x86/flushtlb.c
-@@ -103,9 +103,8 @@ static void do_tlb_flush(void)
-
- void switch_cr3_cr4(unsigned long cr3, unsigned long cr4)
- {
-- unsigned long flags, old_cr4;
-+ unsigned long flags, old_cr4, old_pcid;
- u32 t;
-- unsigned long old_pcid = cr3_pcid(read_cr3());
-
- /* This non-reentrant function is sometimes called in interrupt context. */
- local_irq_save(flags);
-@@ -133,15 +132,38 @@ void switch_cr3_cr4(unsigned long cr3, u
- */
- invpcid_flush_all_nonglobals();
-
-+ /*
-+ * If we don't change PCIDs, the CR3 write below needs to flush this very
-+ * PCID, even when a full flush was performed above, as we are currently
-+ * accumulating TLB entries again from the old address space.
-+ * NB: Clearing the bit when we don't use PCID is benign (as it is clear
-+ * already in that case), but allows the if() to be more simple.
-+ */
-+ old_pcid = cr3_pcid(read_cr3());
-+ if ( old_pcid == cr3_pcid(cr3) )
-+ cr3 &= ~X86_CR3_NOFLUSH;
-+
- write_cr3(cr3);
-
- if ( old_cr4 != cr4 )
- write_cr4(cr4);
-- else if ( old_pcid != cr3_pcid(cr3) )
-- /*
-- * Make sure no TLB entries related to the old PCID created between
-- * flushing the TLB and writing the new %cr3 value remain in the TLB.
-- */
-+
-+ /*
-+ * Make sure no TLB entries related to the old PCID created between
-+ * flushing the TLB and writing the new %cr3 value remain in the TLB.
-+ *
-+ * The write to CR4 just above has performed a wider flush in certain
-+ * cases, which therefore get excluded here. Since that write is
-+ * conditional, note in particular that it won't be skipped if PCIDE
-+ * transitions from 1 to 0. This is because the CR4 write further up will
-+ * have been skipped in this case, as PCIDE and PGE won't both be set at
-+ * the same time.
-+ *
-+ * Note also that PGE is always clear in old_cr4.
-+ */
-+ if ( old_pcid != cr3_pcid(cr3) &&
-+ !(cr4 & X86_CR4_PGE) &&
-+ (old_cr4 & X86_CR4_PCIDE) <= (cr4 & X86_CR4_PCIDE) )
- invpcid_flush_single_context(old_pcid);
-
- post_flush(t);
diff --git a/xsa293-4.11-1.patch b/xsa293-4.11-1.patch
deleted file mode 100644
index 0b8499f..0000000
--- a/xsa293-4.11-1.patch
+++ /dev/null
@@ -1,317 +0,0 @@
-From: Andrew Cooper <andrew.cooper3(a)citrix.com>
-Subject: x86/pv: Rewrite guest %cr4 handling from scratch
-
-The PV cr4 logic is almost impossible to follow, and leaks bits into guest
-context which definitely shouldn't be visible (in particular, VMXE).
-
-The biggest problem however, and source of the complexity, is that it derives
-new real and guest cr4 values from the current value in hardware - this is
-context dependent and an inappropriate source of information.
-
-Rewrite the cr4 logic to be invariant of the current value in hardware.
-
-First of all, modify write_ptbase() to always use mmu_cr4_features for IDLE
-and HVM contexts. mmu_cr4_features *is* the correct value to use, and makes
-the ASSERT() obviously redundant.
-
-For PV guests, curr->arch.pv.ctrlreg[4] remains the guests view of cr4, but
-all logic gets reworked in terms of this and mmu_cr4_features only.
-
-Two masks are introduced; bits which the guest has control over, and bits
-which are forwarded from Xen's settings. One guest-visible change here is
-that Xen's VMXE setting is no longer visible at all.
-
-pv_make_cr4() follows fairly closely from pv_guest_cr4_to_real_cr4(), but
-deliberately starts with mmu_cr4_features, and only alters the minimal subset
-of bits.
-
-The boot-time {compat_,}pv_cr4_mask variables are removed, as they are a
-remnant of the pre-CPUID policy days. pv_fixup_guest_cr4() gains a related
-derivation from the policy.
-
-Another guest visible change here is that a 32bit PV guest can now flip
-FSGSBASE in its view of CR4. While the {RD,WR}{FS,GS}BASE instructions are
-unusable outside of a 64bit code segment, the ability to modify FSGSBASE
-matches real hardware behaviour, and avoids the need for any 32bit/64bit
-differences in the logic.
-
-Overall, this patch shouldn't have a practical change in guest behaviour.
-VMXE will disappear from view, and an inquisitive 32bit kernel can now see
-FSGSBASE changing, but this new logic is otherwise bug-compatible with before.
-
-This is part of XSA-293
-
-Signed-off-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
-Reviewed-by: Jan Beulich <jbeulich(a)suse.com>
-
-diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
-index b1e50d1..675152a 100644
---- a/xen/arch/x86/domain.c
-+++ b/xen/arch/x86/domain.c
-@@ -733,49 +733,6 @@ int arch_domain_soft_reset(struct domain *d)
- return ret;
- }
-
--/*
-- * These are the masks of CR4 bits (subject to hardware availability) which a
-- * PV guest may not legitimiately attempt to modify.
-- */
--static unsigned long __read_mostly pv_cr4_mask, compat_pv_cr4_mask;
--
--static int __init init_pv_cr4_masks(void)
--{
-- unsigned long common_mask = ~X86_CR4_TSD;
--
-- /*
-- * All PV guests may attempt to modify TSD, DE and OSXSAVE.
-- */
-- if ( cpu_has_de )
-- common_mask &= ~X86_CR4_DE;
-- if ( cpu_has_xsave )
-- common_mask &= ~X86_CR4_OSXSAVE;
--
-- pv_cr4_mask = compat_pv_cr4_mask = common_mask;
--
-- /*
-- * 64bit PV guests may attempt to modify FSGSBASE.
-- */
-- if ( cpu_has_fsgsbase )
-- pv_cr4_mask &= ~X86_CR4_FSGSBASE;
--
-- return 0;
--}
--__initcall(init_pv_cr4_masks);
--
--unsigned long pv_guest_cr4_fixup(const struct vcpu *v, unsigned long guest_cr4)
--{
-- unsigned long hv_cr4 = real_cr4_to_pv_guest_cr4(read_cr4());
-- unsigned long mask = is_pv_32bit_vcpu(v) ? compat_pv_cr4_mask : pv_cr4_mask;
--
-- if ( (guest_cr4 & mask) != (hv_cr4 & mask) )
-- printk(XENLOG_G_WARNING
-- "d%d attempted to change %pv's CR4 flags %08lx ->
%08lx\n",
-- current->domain->domain_id, v, hv_cr4, guest_cr4);
--
-- return (hv_cr4 & mask) | (guest_cr4 & ~mask);
--}
--
- #define xen_vcpu_guest_context vcpu_guest_context
- #define fpu_ctxt fpu_ctxt.x
- CHECK_FIELD_(struct, vcpu_guest_context, fpu_ctxt);
-@@ -789,7 +746,7 @@ int arch_set_info_guest(
- struct domain *d = v->domain;
- unsigned long cr3_gfn;
- struct page_info *cr3_page;
-- unsigned long flags, cr4;
-+ unsigned long flags;
- unsigned int i;
- int rc = 0, compat;
-
-@@ -978,9 +935,8 @@ int arch_set_info_guest(
- v->arch.pv_vcpu.ctrlreg[0] &= X86_CR0_TS;
- v->arch.pv_vcpu.ctrlreg[0] |= read_cr0() & ~X86_CR0_TS;
-
-- cr4 = v->arch.pv_vcpu.ctrlreg[4];
-- v->arch.pv_vcpu.ctrlreg[4] = cr4 ? pv_guest_cr4_fixup(v, cr4) :
-- real_cr4_to_pv_guest_cr4(mmu_cr4_features);
-+ v->arch.pv_vcpu.ctrlreg[4] =
-+ pv_fixup_guest_cr4(v, v->arch.pv_vcpu.ctrlreg[4]);
-
- memset(v->arch.debugreg, 0, sizeof(v->arch.debugreg));
- for ( i = 0; i < 8; i++ )
-diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
-index 6509035..08634b7 100644
---- a/xen/arch/x86/mm.c
-+++ b/xen/arch/x86/mm.c
-@@ -505,33 +505,13 @@ void make_cr3(struct vcpu *v, mfn_t mfn)
- v->arch.cr3 |= get_pcid_bits(v, false);
- }
-
--unsigned long pv_guest_cr4_to_real_cr4(const struct vcpu *v)
--{
-- const struct domain *d = v->domain;
-- unsigned long cr4;
--
-- cr4 = v->arch.pv_vcpu.ctrlreg[4] & ~X86_CR4_DE;
-- cr4 |= mmu_cr4_features & (X86_CR4_PSE | X86_CR4_SMEP | X86_CR4_SMAP |
-- X86_CR4_OSXSAVE | X86_CR4_FSGSBASE);
--
-- if ( d->arch.pv_domain.pcid )
-- cr4 |= X86_CR4_PCIDE;
-- else if ( !d->arch.pv_domain.xpti )
-- cr4 |= X86_CR4_PGE;
--
-- cr4 |= d->arch.vtsc ? X86_CR4_TSD : 0;
--
-- return cr4;
--}
--
- void write_ptbase(struct vcpu *v)
- {
- struct cpu_info *cpu_info = get_cpu_info();
- unsigned long new_cr4;
-
- new_cr4 = (is_pv_vcpu(v) && !is_idle_vcpu(v))
-- ? pv_guest_cr4_to_real_cr4(v)
-- : ((read_cr4() & ~(X86_CR4_PCIDE | X86_CR4_TSD)) | X86_CR4_PGE);
-+ ? pv_make_cr4(v) : mmu_cr4_features;
-
- if ( is_pv_vcpu(v) && v->domain->arch.pv_domain.xpti )
- {
-@@ -550,8 +530,6 @@ void write_ptbase(struct vcpu *v)
- switch_cr3_cr4(v->arch.cr3, new_cr4);
- cpu_info->pv_cr3 = 0;
- }
--
-- ASSERT(is_pv_vcpu(v) || read_cr4() == mmu_cr4_features);
- }
-
- /*
-diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
-index b75ff6b..3965959 100644
---- a/xen/arch/x86/pv/domain.c
-+++ b/xen/arch/x86/pv/domain.c
-@@ -97,6 +97,52 @@ static void release_compat_l4(struct vcpu *v)
- v->arch.guest_table_user = pagetable_null();
- }
-
-+unsigned long pv_fixup_guest_cr4(const struct vcpu *v, unsigned long cr4)
-+{
-+ const struct cpuid_policy *p = v->domain->arch.cpuid;
-+
-+ /* Discard attempts to set guest controllable bits outside of the policy. */
-+ cr4 &= ~((p->basic.tsc ? 0 : X86_CR4_TSD) |
-+ (p->basic.de ? 0 : X86_CR4_DE) |
-+ (p->feat.fsgsbase ? 0 : X86_CR4_FSGSBASE) |
-+ (p->basic.xsave ? 0 : X86_CR4_OSXSAVE));
-+
-+ /* Masks expected to be disjoint sets. */
-+ BUILD_BUG_ON(PV_CR4_GUEST_MASK & PV_CR4_GUEST_VISIBLE_MASK);
-+
-+ /*
-+ * A guest sees the policy subset of its own choice of guest controllable
-+ * bits, and a subset of Xen's choice of certain hardware settings.
-+ */
-+ return ((cr4 & PV_CR4_GUEST_MASK) |
-+ (mmu_cr4_features & PV_CR4_GUEST_VISIBLE_MASK));
-+}
-+
-+unsigned long pv_make_cr4(const struct vcpu *v)
-+{
-+ const struct domain *d = v->domain;
-+ unsigned long cr4 = mmu_cr4_features &
-+ ~(X86_CR4_PCIDE | X86_CR4_PGE | X86_CR4_TSD);
-+
-+ /*
-+ * PCIDE or PGE depends on the PCID/XPTI settings, but must not both be
-+ * set, as it impacts the safety of TLB flushing.
-+ */
-+ if ( d->arch.pv_domain.pcid )
-+ cr4 |= X86_CR4_PCIDE;
-+ else if ( !d->arch.pv_domain.xpti )
-+ cr4 |= X86_CR4_PGE;
-+
-+ /*
-+ * TSD is needed if either the guest has elected to use it, or Xen is
-+ * virtualising the TSC value the guest sees.
-+ */
-+ if ( d->arch.vtsc || (v->arch.pv_vcpu.ctrlreg[4] & X86_CR4_TSD) )
-+ cr4 |= X86_CR4_TSD;
-+
-+ return cr4;
-+}
-+
- int switch_compat(struct domain *d)
- {
- struct vcpu *v;
-@@ -191,7 +237,7 @@ int pv_vcpu_initialise(struct vcpu *v)
- /* PV guests by default have a 100Hz ticker. */
- v->periodic_period = MILLISECS(10);
-
-- v->arch.pv_vcpu.ctrlreg[4] = real_cr4_to_pv_guest_cr4(mmu_cr4_features);
-+ v->arch.pv_vcpu.ctrlreg[4] = pv_fixup_guest_cr4(v, 0);
-
- if ( is_pv_32bit_domain(d) )
- {
-diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
-index ce2ec76..4abbc14 100644
---- a/xen/arch/x86/pv/emul-priv-op.c
-+++ b/xen/arch/x86/pv/emul-priv-op.c
-@@ -32,6 +32,7 @@
- #include <asm/hypercall.h>
- #include <asm/mc146818rtc.h>
- #include <asm/p2m.h>
-+#include <asm/pv/domain.h>
- #include <asm/pv/traps.h>
- #include <asm/shared.h>
- #include <asm/traps.h>
-@@ -785,8 +786,8 @@ static int write_cr(unsigned int reg, unsigned long val,
- }
-
- case 4: /* Write CR4 */
-- curr->arch.pv_vcpu.ctrlreg[4] = pv_guest_cr4_fixup(curr, val);
-- write_cr4(pv_guest_cr4_to_real_cr4(curr));
-+ curr->arch.pv_vcpu.ctrlreg[4] = pv_fixup_guest_cr4(curr, val);
-+ write_cr4(pv_make_cr4(curr));
- ctxt_switch_levelling(curr);
- return X86EMUL_OKAY;
- }
-diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
-index ec81d78..c8aa8a5 100644
---- a/xen/include/asm-x86/domain.h
-+++ b/xen/include/asm-x86/domain.h
-@@ -610,17 +610,6 @@ bool update_secondary_system_time(struct vcpu *,
- void vcpu_show_execution_state(struct vcpu *);
- void vcpu_show_registers(const struct vcpu *);
-
--/* Clean up CR4 bits that are not under guest control. */
--unsigned long pv_guest_cr4_fixup(const struct vcpu *, unsigned long guest_cr4);
--
--/* Convert between guest-visible and real CR4 values. */
--unsigned long pv_guest_cr4_to_real_cr4(const struct vcpu *v);
--
--#define real_cr4_to_pv_guest_cr4(c) \
-- ((c) & ~(X86_CR4_PGE | X86_CR4_PSE | X86_CR4_TSD | \
-- X86_CR4_OSXSAVE | X86_CR4_SMEP | \
-- X86_CR4_FSGSBASE | X86_CR4_SMAP | X86_CR4_PCIDE))
--
- #define domain_max_vcpus(d) (is_hvm_domain(d) ? HVM_MAX_VCPUS : MAX_VIRT_CPUS)
-
- static inline struct vcpu_guest_context *alloc_vcpu_guest_context(void)
-diff --git a/xen/include/asm-x86/pv/domain.h b/xen/include/asm-x86/pv/domain.h
-index 4fea764..4e4710c 100644
---- a/xen/include/asm-x86/pv/domain.h
-+++ b/xen/include/asm-x86/pv/domain.h
-@@ -59,6 +59,23 @@ int pv_vcpu_initialise(struct vcpu *v);
- void pv_domain_destroy(struct domain *d);
- int pv_domain_initialise(struct domain *d);
-
-+/*
-+ * Bits which a PV guest can toggle in its view of cr4. Some are loaded into
-+ * hardware, while some are fully emulated.
-+ */
-+#define PV_CR4_GUEST_MASK \
-+ (X86_CR4_TSD | X86_CR4_DE | X86_CR4_FSGSBASE | X86_CR4_OSXSAVE)
-+
-+/* Bits which a PV guest may observe from the real hardware settings. */
-+#define PV_CR4_GUEST_VISIBLE_MASK \
-+ (X86_CR4_PAE | X86_CR4_MCE | X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT)
-+
-+/* Given a new cr4 value, construct the resulting guest-visible cr4 value. */
-+unsigned long pv_fixup_guest_cr4(const struct vcpu *v, unsigned long cr4);
-+
-+/* Create a cr4 value to load into hardware, based on vcpu settings. */
-+unsigned long pv_make_cr4(const struct vcpu *v);
-+
- #else /* !CONFIG_PV */
-
- #include <xen/errno.h>
-@@ -68,6 +85,8 @@ static inline int pv_vcpu_initialise(struct vcpu *v) { return
-EOPNOTSUPP; }
- static inline void pv_domain_destroy(struct domain *d) {}
- static inline int pv_domain_initialise(struct domain *d) { return -EOPNOTSUPP; }
-
-+static inline unsigned long pv_make_cr4(const struct vcpu *v) { return ~0ul; }
-+
- #endif /* CONFIG_PV */
-
- void paravirt_ctxt_switch_from(struct vcpu *v);
diff --git a/xsa293-4.11-2.patch b/xsa293-4.11-2.patch
deleted file mode 100644
index a005021..0000000
--- a/xsa293-4.11-2.patch
+++ /dev/null
@@ -1,260 +0,0 @@
-From: Andrew Cooper <andrew.cooper3(a)citrix.com>
-Subject: x86/pv: Don't have %cr4.fsgsbase active behind a guest kernels back
-
-Currently, a 64bit PV guest can appear to set and clear FSGSBASE in %cr4, but
-the bit remains set in hardware. Therefore, the {RD,WR}{FS,GS}BASE are usable
-even when the guest kernel believes that they are disabled.
-
-The FSGSBASE feature isn't currently supported in Linux, and its context
-switch path has some optimisations which rely on userspace being unable to use
-the WR{FS,GS}BASE instructions. Xen's current behaviour undermines this
-expectation.
-
-In 64bit PV guest context, always load the guest kernels setting of FSGSBASE
-into %cr4. This requires adjusting how Xen uses the {RD,WR}{FS,GS}BASE
-instructions.
-
- * Delete the cpu_has_fsgsbase helper. It is no longer safe, as users need to
- check %cr4 directly.
- * The raw __rd{fs,gs}base() helpers are only safe to use when %cr4.fsgsbase
- is set. Comment this property.
- * The {rd,wr}{fs,gs}{base,shadow}() and read_msr() helpers are updated to use
- the current %cr4 value to determine which mechanism to use.
- * toggle_guest_mode() and save_segments() are update to avoid reading
- fs/gsbase if the values in hardware cannot be stale WRT struct vcpu. A
- consequence of this is that the write_cr() path needs to cache the current
- bases, as subsequent context switches will skip saving the values.
- * write_cr4() is updated to ensure that the shadow %cr4.fsgsbase value is
- observed in a safe way WRT the hardware setting, if an interrupt happens to
- hit in the middle.
- * pv_make_cr4() is updated for 64bit PV guests to use the guest kernels
- choice of FSGSBASE.
-
-This is part of XSA-293
-
-Reported-by: Andy Lutomirski <luto(a)kernel.org>
-Signed-off-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
-Reviewed-by: Jan Beulich <jbeulich(a)suse.com>
-
-diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
-index 675152a..29f892c 100644
---- a/xen/arch/x86/domain.c
-+++ b/xen/arch/x86/domain.c
-@@ -1433,7 +1433,8 @@ static void save_segments(struct vcpu *v)
- regs->fs = read_sreg(fs);
- regs->gs = read_sreg(gs);
-
-- if ( cpu_has_fsgsbase && !is_pv_32bit_vcpu(v) )
-+ /* %fs/%gs bases can only be stale if WR{FS,GS}BASE are usable. */
-+ if ( (read_cr4() & X86_CR4_FSGSBASE) && !is_pv_32bit_vcpu(v) )
- {
- v->arch.pv_vcpu.fs_base = __rdfsbase();
- if ( v->arch.flags & TF_kernel_mode )
-diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
-index 3965959..228a174 100644
---- a/xen/arch/x86/pv/domain.c
-+++ b/xen/arch/x86/pv/domain.c
-@@ -140,6 +140,16 @@ unsigned long pv_make_cr4(const struct vcpu *v)
- if ( d->arch.vtsc || (v->arch.pv_vcpu.ctrlreg[4] & X86_CR4_TSD) )
- cr4 |= X86_CR4_TSD;
-
-+ /*
-+ * The {RD,WR}{FS,GS}BASE are only useable in 64bit code segments. While
-+ * we must not have CR4.FSGSBASE set behind the back of a 64bit PV kernel,
-+ * we do leave it set in 32bit PV context to speed up Xen's context switch
-+ * path.
-+ */
-+ if ( !is_pv_32bit_domain(d) &&
-+ !(v->arch.pv_vcpu.ctrlreg[4] & X86_CR4_FSGSBASE) )
-+ cr4 &= ~X86_CR4_FSGSBASE;
-+
- return cr4;
- }
-
-@@ -375,7 +385,8 @@ void toggle_guest_mode(struct vcpu *v)
- {
- ASSERT(!is_pv_32bit_vcpu(v));
-
-- if ( cpu_has_fsgsbase )
-+ /* %fs/%gs bases can only be stale if WR{FS,GS}BASE are usable. */
-+ if ( read_cr4() & X86_CR4_FSGSBASE )
- {
- if ( v->arch.flags & TF_kernel_mode )
- v->arch.pv_vcpu.gs_base_kernel = __rdgsbase();
-diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
-index 4abbc14..312c1ee 100644
---- a/xen/arch/x86/pv/emul-priv-op.c
-+++ b/xen/arch/x86/pv/emul-priv-op.c
-@@ -786,6 +786,17 @@ static int write_cr(unsigned int reg, unsigned long val,
- }
-
- case 4: /* Write CR4 */
-+ /*
-+ * If this write will disable FSGSBASE, refresh Xen's idea of the
-+ * guest bases now that they can no longer change.
-+ */
-+ if ( (curr->arch.pv_vcpu.ctrlreg[4] & X86_CR4_FSGSBASE) &&
-+ !(val & X86_CR4_FSGSBASE) )
-+ {
-+ curr->arch.pv_vcpu.fs_base = __rdfsbase();
-+ curr->arch.pv_vcpu.gs_base_kernel = __rdgsbase();
-+ }
-+
- curr->arch.pv_vcpu.ctrlreg[4] = pv_fixup_guest_cr4(curr, val);
- write_cr4(pv_make_cr4(curr));
- ctxt_switch_levelling(curr);
-@@ -835,14 +846,15 @@ static int read_msr(unsigned int reg, uint64_t *val,
- case MSR_FS_BASE:
- if ( is_pv_32bit_domain(currd) )
- break;
-- *val = cpu_has_fsgsbase ? __rdfsbase() : curr->arch.pv_vcpu.fs_base;
-+ *val = (read_cr4() & X86_CR4_FSGSBASE) ? __rdfsbase()
-+ : curr->arch.pv_vcpu.fs_base;
- return X86EMUL_OKAY;
-
- case MSR_GS_BASE:
- if ( is_pv_32bit_domain(currd) )
- break;
-- *val = cpu_has_fsgsbase ? __rdgsbase()
-- : curr->arch.pv_vcpu.gs_base_kernel;
-+ *val = (read_cr4() & X86_CR4_FSGSBASE) ? __rdgsbase()
-+ : curr->arch.pv_vcpu.gs_base_kernel;
- return X86EMUL_OKAY;
-
- case MSR_SHADOW_GS_BASE:
-diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
-index ecb0149..a353d76 100644
---- a/xen/arch/x86/setup.c
-+++ b/xen/arch/x86/setup.c
-@@ -1567,7 +1567,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
-
- cr4_pv32_mask = mmu_cr4_features & XEN_CR4_PV32_BITS;
-
-- if ( cpu_has_fsgsbase )
-+ if ( boot_cpu_has(X86_FEATURE_FSGSBASE) )
- set_in_cr4(X86_CR4_FSGSBASE);
-
- if ( opt_invpcid && cpu_has_invpcid )
-diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
-index b237da1..861cb0a 100644
---- a/xen/include/asm-x86/cpufeature.h
-+++ b/xen/include/asm-x86/cpufeature.h
-@@ -90,7 +90,6 @@
- #define cpu_has_xsaves boot_cpu_has(X86_FEATURE_XSAVES)
-
- /* CPUID level 0x00000007:0.ebx */
--#define cpu_has_fsgsbase boot_cpu_has(X86_FEATURE_FSGSBASE)
- #define cpu_has_bmi1 boot_cpu_has(X86_FEATURE_BMI1)
- #define cpu_has_hle boot_cpu_has(X86_FEATURE_HLE)
- #define cpu_has_avx2 boot_cpu_has(X86_FEATURE_AVX2)
-diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h
-index afbeb7f..1ba6ee3 100644
---- a/xen/include/asm-x86/msr.h
-+++ b/xen/include/asm-x86/msr.h
-@@ -120,6 +120,14 @@ static inline uint64_t rdtsc_ordered(void)
- : "=a" (low), "=d" (high) \
- : "c" (counter))
-
-+/*
-+ * On hardware supporting FSGSBASE, the value loaded into hardware is the
-+ * guest kernel's choice for 64bit PV guests (Xen's choice for Idle, HVM and
-+ * 32bit PV).
-+ *
-+ * Therefore, the {RD,WR}{FS,GS}BASE instructions are only safe to use if
-+ * %cr4.fsgsbase is set.
-+ */
- static inline unsigned long __rdfsbase(void)
- {
- unsigned long base;
-@@ -150,7 +158,7 @@ static inline unsigned long rdfsbase(void)
- {
- unsigned long base;
-
-- if ( cpu_has_fsgsbase )
-+ if ( read_cr4() & X86_CR4_FSGSBASE )
- return __rdfsbase();
-
- rdmsrl(MSR_FS_BASE, base);
-@@ -162,7 +170,7 @@ static inline unsigned long rdgsbase(void)
- {
- unsigned long base;
-
-- if ( cpu_has_fsgsbase )
-+ if ( read_cr4() & X86_CR4_FSGSBASE )
- return __rdgsbase();
-
- rdmsrl(MSR_GS_BASE, base);
-@@ -174,7 +182,7 @@ static inline unsigned long rdgsshadow(void)
- {
- unsigned long base;
-
-- if ( cpu_has_fsgsbase )
-+ if ( read_cr4() & X86_CR4_FSGSBASE )
- {
- asm volatile ( "swapgs" );
- base = __rdgsbase();
-@@ -188,7 +196,7 @@ static inline unsigned long rdgsshadow(void)
-
- static inline void wrfsbase(unsigned long base)
- {
-- if ( cpu_has_fsgsbase )
-+ if ( read_cr4() & X86_CR4_FSGSBASE )
- #ifdef HAVE_AS_FSGSBASE
- asm volatile ( "wrfsbase %0" :: "r" (base) );
- #else
-@@ -200,7 +208,7 @@ static inline void wrfsbase(unsigned long base)
-
- static inline void wrgsbase(unsigned long base)
- {
-- if ( cpu_has_fsgsbase )
-+ if ( read_cr4() & X86_CR4_FSGSBASE )
- #ifdef HAVE_AS_FSGSBASE
- asm volatile ( "wrgsbase %0" :: "r" (base) );
- #else
-@@ -212,7 +220,7 @@ static inline void wrgsbase(unsigned long base)
-
- static inline void wrgsshadow(unsigned long base)
- {
-- if ( cpu_has_fsgsbase )
-+ if ( read_cr4() & X86_CR4_FSGSBASE )
- {
- asm volatile ( "swapgs\n\t"
- #ifdef HAVE_AS_FSGSBASE
-diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
-index 2bd9e69..8e253dc 100644
---- a/xen/include/asm-x86/processor.h
-+++ b/xen/include/asm-x86/processor.h
-@@ -305,11 +305,31 @@ static inline unsigned long read_cr4(void)
-
- static inline void write_cr4(unsigned long val)
- {
-+ struct cpu_info *info = get_cpu_info();
-+
- /* No global pages in case of PCIDs enabled! */
- ASSERT(!(val & X86_CR4_PGE) || !(val & X86_CR4_PCIDE));
-
-- get_cpu_info()->cr4 = val;
-- asm volatile ( "mov %0,%%cr4" : : "r" (val) );
-+ /*
-+ * On hardware supporting FSGSBASE, the value in %cr4 is the kernel's
-+ * choice for 64bit PV guests, which impacts whether Xen can use the
-+ * instructions.
-+ *
-+ * The {rd,wr}{fs,gs}base() helpers use info->cr4 to work out whether it
-+ * is safe to execute the {RD,WR}{FS,GS}BASE instruction, falling back to
-+ * the MSR path if not. Some users require interrupt safety.
-+ *
-+ * If FSGSBASE is currently or about to become clear, reflect this in
-+ * info->cr4 before updating %cr4, so an interrupt which hits in the
-+ * middle won't observe FSGSBASE set in info->cr4 but clear in %cr4.
-+ */
-+ info->cr4 = val & (info->cr4 | ~X86_CR4_FSGSBASE);
-+
-+ asm volatile ( "mov %[val], %%cr4"
-+ : "+m" (info->cr4) /* Force ordering without a barrier.
*/
-+ : [val] "r" (val) );
-+
-+ info->cr4 = val;
- }
-
- /* Clear and set 'TS' bit respectively */
diff --git a/xsa294-4.11.patch b/xsa294-4.11.patch
deleted file mode 100644
index a0784d9..0000000
--- a/xsa294-4.11.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From: Jan Beulich <JBeulich(a)suse.com>
-Subject: x86/pv: _toggle_guest_pt() may not skip TLB flush for shadow mode guests
-
-For shadow mode guests (e.g. PV ones forced into that mode as L1TF
-mitigation, or during migration) update_cr3() -> sh_update_cr3() may
-result in a change to the (shadow) root page table (compared to the
-previous one when running the same vCPU with the same PCID). This can,
-first and foremost, be a result of memory pressure on the shadow memory
-pool of the domain. Shadow code legitimately relies on the original
-(prior to commit 5c81d260c2 ["xen/x86: use PCID feature"]) behavior of
-the subsequent CR3 write to flush the TLB of entries still left from
-walks with an earlier, different (shadow) root page table.
-
-Restore the flushing behavior, also for the second CR3 write on the exit
-path to guest context when XPTI is active. For the moment accept that
-this will introduce more flushes than are strictly necessary - no flush
-would be needed when the (shadow) root page table doesn't actually
-change, but this information isn't readily (i.e. without introducing a
-layering violation) available here.
-
-This is XSA-294.
-
-Reported-by: XXX PERSON <XXX EMAIL>
-Signed-off-by: Jan Beulich <jbeulich(a)suse.com>
-Tested-by: Juergen Gross <jgross(a)suse.com>
-Reviewed-by: Andrew Cooper <andrew.cooper3(a)citrix.com>
-
-diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
-index b75ff6b..528413a 100644
---- a/xen/arch/x86/pv/domain.c
-+++ b/xen/arch/x86/pv/domain.c
-@@ -296,21 +296,35 @@ int pv_domain_initialise(struct domain *d)
- static void _toggle_guest_pt(struct vcpu *v)
- {
- const struct domain *d = v->domain;
-+ struct cpu_info *cpu_info = get_cpu_info();
-+ unsigned long cr3;
-
- v->arch.flags ^= TF_kernel_mode;
- update_cr3(v);
- if ( d->arch.pv_domain.xpti )
- {
-- struct cpu_info *cpu_info = get_cpu_info();
--
- cpu_info->root_pgt_changed = true;
- cpu_info->pv_cr3 = __pa(this_cpu(root_pgt)) |
- (d->arch.pv_domain.pcid
- ? get_pcid_bits(v, true) : 0);
- }
-
-- /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */
-- write_cr3(v->arch.cr3);
-+ /*
-+ * Don't flush user global mappings from the TLB. Don't tick TLB clock.
-+ *
-+ * In shadow mode, though, update_cr3() may need to be accompanied by a
-+ * TLB flush (for just the incoming PCID), as the top level page table may
-+ * have changed behind our backs. To be on the safe side, suppress the
-+ * no-flush unconditionally in this case. The XPTI CR3 write, if enabled,
-+ * will then need to be a flushing one too.
-+ */
-+ cr3 = v->arch.cr3;
-+ if ( shadow_mode_enabled(d) )
-+ {
-+ cr3 &= ~X86_CR3_NOFLUSH;
-+ cpu_info->pv_cr3 &= ~X86_CR3_NOFLUSH;
-+ }
-+ write_cr3(cr3);
-
- if ( !(v->arch.flags & TF_kernel_mode) )
- return;