[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#991817: unblock: xen/4.14.2+25-gb6a8c4f72d-2



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: team@security.debian.org

Hi,

Please unblock package xen

Bullseye currently has xen/4.14.1+11-gb0b734a8b3-1. On Jul 11 I uploaded
4.14.2+25-gb6a8c4f72d-1 which is a security update. (technically done in
the same way as a security update would be done after the release *) ).
It fixes all current open issues listed:

https://security-tracker.debian.org/tracker/source-package/xen

CVE-2021-28687 CVE-2021-28693 CVE-2021-28692 CVE-2021-0089
CVE-2021-26313 CVE-2021-28690

Additionally, I got a question from Moritz (security team) if I could
include some information somewhere in the package about the (already
known) end date of upstream security support for the Xen 4.14 stable
branch line.

This is indeed a good idea, which lead to uploading
4.14.2+25-gb6a8c4f72d-2 (today) which adds a little text file to the
docs of the xen-hypervisor-common binary package.

We think it would be good to release with all current security issues
fixed and this extra information for the user.

Attached are:
* source debdiff 4.14.1+11-gb0b734a8b3-1 -> 4.14.2+25-gb6a8c4f72d-1 (not
super useful)
* source debdiff 4.14.2+25-gb6a8c4f72d-1 -> 4.14.2+25-gb6a8c4f72d-2
(documentation change)
* last two changelog items in changelog.txt (for convenience)

Thanks,
Hans van Kranenburg

*) In stable Debian releases, the Xen packages follow the upstream
stable branch line (Xen 4.14 for Bullseye) which gets updated with
security fixes and stuff like important bug fixes for hardware (e.g.
errata and some new hardware support). Most often this happens through
the Debian security process, and sometimes in a stable point release.

unblock xen/4.14.2+25-gb6a8c4f72d-2
xen (4.14.2+25-gb6a8c4f72d-2) unstable; urgency=medium

  * Add README.Debian.security containing a note about the end of upstream
    security support for Xen 4.14. Install it into xen-hypervisor-common.

 -- Hans van Kranenburg <hans@knorrie.org>  Fri, 30 Jul 2021 16:57:52 +0200

xen (4.14.2+25-gb6a8c4f72d-1) unstable; urgency=medium

  * Update to new upstream version 4.14.2+25-gb6a8c4f72d, which also contains
    security fixes for the following issues:
    - HVM soft-reset crashes toolstack
      XSA-368 CVE-2021-28687
    - xen/arm: Boot modules are not scrubbed
      XSA-372 CVE-2021-28693
    - inappropriate x86 IOMMU timeout detection / handling
      XSA-373 CVE-2021-28692
    - Speculative Code Store Bypass
      XSA-375 CVE-2021-0089 CVE-2021-26313
    - x86: TSX Async Abort protections not restored after S3
      XSA-377 CVE-2021-28690
  * Note that the following XSA are not listed, because...
    - XSA-370 does not contain code changes.
    - XSA-365, XSA-367, XSA-369, XSA-371 and XSA-374 have patches for the
      Linux kernel.
    - XSA-366 only applies to Xen 4.11.

 -- Hans van Kranenburg <hans@knorrie.org>  Sun, 11 Jul 2021 14:29:13 +0200
diff -Nru xen-4.14.1+11-gb0b734a8b3/Config.mk xen-4.14.2+25-gb6a8c4f72d/Config.mk
--- xen-4.14.1+11-gb0b734a8b3/Config.mk	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/Config.mk	2021-06-17 20:45:39.000000000 +0200
@@ -245,15 +245,15 @@
 MINIOS_UPSTREAM_URL ?= git://xenbits.xen.org/mini-os.git
 endif
 OVMF_UPSTREAM_REVISION ?= 20d2e5a125e34fc8501026613a71549b2a1a3e54
-QEMU_UPSTREAM_REVISION ?= qemu-xen-4.14.1
-MINIOS_UPSTREAM_REVISION ?= xen-RELEASE-4.14.1
+QEMU_UPSTREAM_REVISION ?= qemu-xen-4.14.2
+MINIOS_UPSTREAM_REVISION ?= xen-RELEASE-4.14.2
 
 SEABIOS_UPSTREAM_REVISION ?= rel-1.13.0
 
 ETHERBOOT_NICS ?= rtl8139 8086100e
 
 
-QEMU_TRADITIONAL_REVISION ?= xen-4.14.1
+QEMU_TRADITIONAL_REVISION ?= xen-4.14.2
 
 # Specify which qemu-dm to use. This may be `ioemu' to use the old
 # Mercurial in-tree version, or a local directory, or a git URL.
diff -Nru xen-4.14.1+11-gb0b734a8b3/debian/changelog xen-4.14.2+25-gb6a8c4f72d/debian/changelog
--- xen-4.14.1+11-gb0b734a8b3/debian/changelog	2021-02-28 19:49:45.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/changelog	2021-07-11 14:29:13.000000000 +0200
@@ -1,3 +1,25 @@
+xen (4.14.2+25-gb6a8c4f72d-1) unstable; urgency=medium
+
+  * Update to new upstream version 4.14.2+25-gb6a8c4f72d, which also contains
+    security fixes for the following issues:
+    - HVM soft-reset crashes toolstack
+      XSA-368 CVE-2021-28687
+    - xen/arm: Boot modules are not scrubbed
+      XSA-372 CVE-2021-28693
+    - inappropriate x86 IOMMU timeout detection / handling
+      XSA-373 CVE-2021-28692
+    - Speculative Code Store Bypass
+      XSA-375 CVE-2021-0089 CVE-2021-26313
+    - x86: TSX Async Abort protections not restored after S3
+      XSA-377 CVE-2021-28690
+  * Note that the following XSA are not listed, because...
+    - XSA-370 does not contain code changes.
+    - XSA-365, XSA-367, XSA-369, XSA-371 and XSA-374 have patches for the
+      Linux kernel.
+    - XSA-366 only applies to Xen 4.11.
+
+ -- Hans van Kranenburg <hans@knorrie.org>  Sun, 11 Jul 2021 14:29:13 +0200
+
 xen (4.14.1+11-gb0b734a8b3-1) unstable; urgency=medium
 
   * Update to new upstream version 4.14.1+11-gb0b734a8b3, which also contains
diff -Nru xen-4.14.1+11-gb0b734a8b3/debian/.gitignore xen-4.14.2+25-gb6a8c4f72d/debian/.gitignore
--- xen-4.14.1+11-gb0b734a8b3/debian/.gitignore	2021-02-28 19:49:45.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/.gitignore	1970-01-01 01:00:00.000000000 +0100
@@ -1,39 +0,0 @@
-.debhelper
-*.debhelper.*
-*.preinst.debhelper
-*.postinst.debhelper
-*.prerm.debhelper
-*.postrm.debhelper
-*.substvars
-*.stamp
-tmp
-*-[0-9]*.bug-control
-*-[0-9]*.postinst
-*-[0-9]*.postrm
-*.tmp
-files
-xen-doc
-xen-hypervisor-common
-xen-system-amd64
-xen-system-armhf
-xen-system-arm64
-xen-hypervisor-[0-9]*[0-9]
-xen-hypervisor-[0-9]*[0-9].install
-xen-hypervisor-[0-9]*[0-9].lintian-overrides
-xen-utils-[0-9]*[0-9]
-xen-utils-[0-9]*[0-9].install
-xen-utils-[0-9]*[0-9].NEWS
-xen-utils-[0-9]*[0-9].README.Debian
-xen-utils-[0-9]*[0-9].lintian-overrides
-xen-utils-[0-9]*[0-9].prerm
-libxenmisc[0-9]*[0-9].lintian-overrides
-libxenmisc[0-9]*[0-9]
-libxenmisc[0-9]*[0-9].install
-libxenmisc[0-9]*[0-9].lintian-overrides
-libxen-dev
-libxen*[0-9]
-xen-utils-common
-xenstore-utils
-autoreconf.before
-autoreconf.after
-debhelper-build-stamp
diff -Nru xen-4.14.1+11-gb0b734a8b3/debian/patches/0003-version.patch xen-4.14.2+25-gb6a8c4f72d/debian/patches/0003-version.patch
--- xen-4.14.1+11-gb0b734a8b3/debian/patches/0003-version.patch	2021-02-28 19:49:45.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/patches/0003-version.patch	2021-07-11 14:29:13.000000000 +0200
@@ -12,7 +12,7 @@
  6 files changed, 31 insertions(+), 31 deletions(-)
 
 diff --git a/xen/Makefile b/xen/Makefile
-index 5ccbd64..4c85930 100644
+index 22362d7..e8a53a5 100644
 --- a/xen/Makefile
 +++ b/xen/Makefile
 @@ -382,7 +382,7 @@ delete-unfresh-files:
diff -Nru xen-4.14.1+11-gb0b734a8b3/debian/patches/0017-Fix-empty-fields-in-first-hypervisor-log-line.patch xen-4.14.2+25-gb6a8c4f72d/debian/patches/0017-Fix-empty-fields-in-first-hypervisor-log-line.patch
--- xen-4.14.1+11-gb0b734a8b3/debian/patches/0017-Fix-empty-fields-in-first-hypervisor-log-line.patch	2021-02-28 19:49:45.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/patches/0017-Fix-empty-fields-in-first-hypervisor-log-line.patch	2021-07-11 14:29:13.000000000 +0200
@@ -28,7 +28,7 @@
  1 file changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/xen/Makefile b/xen/Makefile
-index 4c85930..8fb291e 100644
+index e8a53a5..d875bd1 100644
 --- a/xen/Makefile
 +++ b/xen/Makefile
 @@ -394,9 +394,9 @@ include/xen/compile.h: include/xen/compile.h.in
diff -Nru xen-4.14.1+11-gb0b734a8b3/debian/patches/0032-xen-arm-Check-if-the-platform-is-not-using-ACPI-befo.patch xen-4.14.2+25-gb6a8c4f72d/debian/patches/0032-xen-arm-Check-if-the-platform-is-not-using-ACPI-befo.patch
--- xen-4.14.1+11-gb0b734a8b3/debian/patches/0032-xen-arm-Check-if-the-platform-is-not-using-ACPI-befo.patch	2021-02-28 19:49:45.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/patches/0032-xen-arm-Check-if-the-platform-is-not-using-ACPI-befo.patch	2021-07-11 14:29:13.000000000 +0200
@@ -24,16 +24,16 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
-index 7968cee..318b971 100644
+index 34b1c1a..fb2f45e 100644
 --- a/xen/arch/arm/setup.c
 +++ b/xen/arch/arm/setup.c
-@@ -975,7 +975,8 @@ void __init start_xen(unsigned long boot_phys_offset,
- 
-     system_state = SYS_STATE_active;
+@@ -961,7 +961,8 @@ void __init start_xen(unsigned long boot_phys_offset,
+     if ( construct_dom0(dom0) != 0)
+         panic("Could not set up DOM0 guest OS\n");
  
 -    create_domUs();
 +    if ( acpi_disabled )
 +        create_domUs();
  
-     domain_unpause_by_systemcontroller(dom0);
- 
+     /*
+      * This needs to be called **before** heap_init_late() so modules
diff -Nru xen-4.14.1+11-gb0b734a8b3/debian/patches/0033-xen-arm-Introduce-fw_unreserved_regions-and-use-it.patch xen-4.14.2+25-gb6a8c4f72d/debian/patches/0033-xen-arm-Introduce-fw_unreserved_regions-and-use-it.patch
--- xen-4.14.1+11-gb0b734a8b3/debian/patches/0033-xen-arm-Introduce-fw_unreserved_regions-and-use-it.patch	2021-02-28 19:49:45.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/patches/0033-xen-arm-Introduce-fw_unreserved_regions-and-use-it.patch	2021-07-11 14:29:13.000000000 +0200
@@ -41,10 +41,10 @@
      return 0;
  }
 diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
-index 318b971..de3b542 100644
+index fb2f45e..c94827e 100644
 --- a/xen/arch/arm/setup.c
 +++ b/xen/arch/arm/setup.c
-@@ -184,8 +184,9 @@ static void __init processor_id(void)
+@@ -183,8 +183,9 @@ static void __init processor_id(void)
      processor_setup();
  }
  
@@ -56,7 +56,7 @@
  {
      int i, nr = fdt_num_mem_rsv(device_tree_flattened);
  
-@@ -232,6 +233,17 @@ void __init dt_unreserved_regions(paddr_t s, paddr_t e,
+@@ -231,6 +232,17 @@ void __init dt_unreserved_regions(paddr_t s, paddr_t e,
      cb(s, e);
  }
  
@@ -74,7 +74,7 @@
  struct bootmodule __init *add_boot_module(bootmodule_kind kind,
                                            paddr_t start, paddr_t size,
                                            bool domU)
-@@ -393,7 +405,7 @@ void __init discard_initial_modules(void)
+@@ -392,7 +404,7 @@ void __init discard_initial_modules(void)
               !mfn_valid(maddr_to_mfn(e)) )
              continue;
  
@@ -83,7 +83,7 @@
      }
  
      mi->nr_mods = 0;
-@@ -700,7 +712,7 @@ static void __init setup_mm(void)
+@@ -699,7 +711,7 @@ static void __init setup_mm(void)
                  n = mfn_to_maddr(mfn_add(xenheap_mfn_start, xenheap_pages));
              }
  
@@ -92,7 +92,7 @@
  
              s = n;
          }
-@@ -753,7 +765,7 @@ static void __init setup_mm(void)
+@@ -752,7 +764,7 @@ static void __init setup_mm(void)
              if ( e > bank_end )
                  e = bank_end;
  
diff -Nru xen-4.14.1+11-gb0b734a8b3/debian/patches/0036-fix-spelling-errors.patch xen-4.14.2+25-gb6a8c4f72d/debian/patches/0036-fix-spelling-errors.patch
--- xen-4.14.1+11-gb0b734a8b3/debian/patches/0036-fix-spelling-errors.patch	2021-02-28 19:49:45.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/patches/0036-fix-spelling-errors.patch	2021-07-11 14:29:13.000000000 +0200
@@ -121,7 +121,7 @@
          xorw    %bx, %bx
          xorw    %di, %di
 diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
-index 1ed39ef..ab66736 100644
+index 0c3f378..fb1b296 100644
 --- a/xen/arch/x86/cpu/vpmu.c
 +++ b/xen/arch/x86/cpu/vpmu.c
 @@ -680,7 +680,7 @@ static void pvpmu_finish(struct domain *d, xen_pmu_params_t *params)
@@ -147,10 +147,10 @@
  		return -ENOSPC;
  	}
 diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
-index 9b29548..5d91f03 100644
+index f186ae6..bf17208 100644
 --- a/xen/arch/x86/x86_emulate/x86_emulate.c
 +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
-@@ -3243,7 +3243,7 @@ x86_decode(
+@@ -3244,7 +3244,7 @@ x86_decode(
              case 0x23: /* mov reg,dr */
                  /*
                   * Mov to/from cr/dr ignore the encoding of Mod, and behave as
diff -Nru xen-4.14.1+11-gb0b734a8b3/debian/patches/0038-x86-EFI-don-t-insert-timestamp-when-SOURCE_DATE_EPOC.patch xen-4.14.2+25-gb6a8c4f72d/debian/patches/0038-x86-EFI-don-t-insert-timestamp-when-SOURCE_DATE_EPOC.patch
--- xen-4.14.1+11-gb0b734a8b3/debian/patches/0038-x86-EFI-don-t-insert-timestamp-when-SOURCE_DATE_EPOC.patch	2021-02-28 19:49:45.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/patches/0038-x86-EFI-don-t-insert-timestamp-when-SOURCE_DATE_EPOC.patch	2021-07-11 14:29:13.000000000 +0200
@@ -21,7 +21,7 @@
  1 file changed, 6 insertions(+)
 
 diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
-index 26ff2a9..a51f916 100644
+index bbd11a4..d5c7002 100644
 --- a/xen/arch/x86/Makefile
 +++ b/xen/arch/x86/Makefile
 @@ -172,6 +172,12 @@ EFI_LDFLAGS += --major-image-version=$(XEN_VERSION)
diff -Nru xen-4.14.1+11-gb0b734a8b3/debian/patches/prefix-abiname/config-prefix.diff xen-4.14.2+25-gb6a8c4f72d/debian/patches/prefix-abiname/config-prefix.diff
--- xen-4.14.1+11-gb0b734a8b3/debian/patches/prefix-abiname/config-prefix.diff	2021-02-28 19:49:45.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/patches/prefix-abiname/config-prefix.diff	2021-07-11 14:29:13.000000000 +0200
@@ -9,7 +9,7 @@
  2 files changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/Config.mk b/Config.mk
-index bc4ee6f..1d72571 100644
+index 5c2eeef..4ba978c 100644
 --- a/Config.mk
 +++ b/Config.mk
 @@ -74,7 +74,7 @@ EXTRA_LIB += $(EXTRA_PREFIX)/lib
diff -Nru xen-4.14.1+11-gb0b734a8b3/docs/misc/arm/silicon-errata.txt xen-4.14.2+25-gb6a8c4f72d/docs/misc/arm/silicon-errata.txt
--- xen-4.14.1+11-gb0b734a8b3/docs/misc/arm/silicon-errata.txt	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/docs/misc/arm/silicon-errata.txt	2021-06-17 20:45:39.000000000 +0200
@@ -45,11 +45,15 @@
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319    |
 | ARM            | Cortex-A53      | #824069         | ARM64_ERRATUM_824069    |
 | ARM            | Cortex-A53      | #819472         | ARM64_ERRATUM_819472    |
+| ARM            | Cortex-A53      | #843419         | ARM64_ERRATUM_843419    |
+| ARM            | Cortex-A55      | #1530923        | N/A                     |
 | ARM            | Cortex-A57      | #852523         | N/A                     |
 | ARM            | Cortex-A57      | #832075         | ARM64_ERRATUM_832075    |
 | ARM            | Cortex-A57      | #834220         | ARM64_ERRATUM_834220    |
 | ARM            | Cortex-A57      | #1319537        | N/A                     |
 | ARM            | Cortex-A72      | #1319367        | N/A                     |
+| ARM            | Cortex-A72      | #853709         | N/A                     |
+| ARM            | Cortex-A73      | #858921         | ARM_ERRATUM_858921      |
 | ARM            | Cortex-A76      | #1165522        | N/A                     |
 | ARM            | Neoverse-N1     | #1165522        | N/A
 | ARM            | MMU-500         | #842869         | N/A                     |
diff -Nru xen-4.14.1+11-gb0b734a8b3/docs/misc/xen-command-line.pandoc xen-4.14.2+25-gb6a8c4f72d/docs/misc/xen-command-line.pandoc
--- xen-4.14.1+11-gb0b734a8b3/docs/misc/xen-command-line.pandoc	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/docs/misc/xen-command-line.pandoc	2021-06-17 20:45:39.000000000 +0200
@@ -1221,9 +1221,42 @@
 When the hmp-unsafe option is disabled (default), CPUs that are not
 identical to the boot CPU will be parked and not used by Xen.
 
+### hpet
+    = List of [ <bool> | broadcast=<bool> | legacy-replacement=<bool> ]
+
+    Applicability: x86
+
+Controls Xen's use of the system's High Precision Event Timer.  By default,
+Xen will use an HPET when available and not subject to errata.  Use of the
+HPET can be disabled by specifying `hpet=0`.
+
+ * The `broadcast` boolean is disabled by default, but forces Xen to keep
+   using the broadcast for CPUs in deep C-states even when an RTC interrupt is
+   enabled.  This then also affects raising of the RTC interrupt.
+
+ * The `legacy-replacement` boolean allows for control over whether Legacy
+   Replacement mode is enabled.
+
+   Legacy Replacement mode is intended for hardware which does not have an
+   8254 PIT, and allows the HPET to be configured into a compatible mode.
+   Intel chipsets from Skylake/ApolloLake onwards can turn the PIT off for
+   power saving reasons, and there is no platform-agnostic mechanism for
+   discovering this.
+
+   By default, Xen will not change hardware configuration, unless the PIT
+   appears to be absent, at which point Xen will try to enable Legacy
+   Replacement mode before falling back to pre-IO-APIC interrupt routing
+   options.
+
+   This behaviour can be inhibited by specifying `legacy-replacement=0`.
+   Alternatively, this mode can be enabled unconditionally (if available) by
+   specifying `legacy-replacement=1`.
+
 ### hpetbroadcast (x86)
 > `= <boolean>`
 
+Deprecated alternative of `hpet=broadcast`.
+
 ### hvm_debug (x86)
 > `= <integer>`
 
@@ -1372,7 +1405,9 @@
 *   The `qinval` boolean controls the Queued Invalidation sub-feature, and is
     active by default on compatible hardware.  Queued Invalidation is a
     feature in second-generation IOMMUs and is a functional prerequisite for
-    Interrupt Remapping.
+    Interrupt Remapping. Note that Xen disregards this setting for Intel VT-d
+    version 6 and greater as Registered-Based Invalidation isn't supported
+    by them.
 
 *   The `igfx` boolean is active by default, and controls whether the IOMMU in
     front of an Intel Graphics Device is enabled or not.
@@ -2196,14 +2231,27 @@
 
 Controls for the use of Transactional Synchronization eXtensions.
 
-On Intel parts released in Q3 2019 (with updated microcode), and future parts,
-a control has been introduced which allows TSX to be turned off.
+Several microcode updates are relevant:
 
-On systems with the ability to turn TSX off, this boolean offers system wide
-control of whether TSX is enabled or disabled.
+ * March 2019, fixing the TSX memory ordering errata on all TSX-enabled CPUs
+   to date.  Introduced MSR_TSX_FORCE_ABORT on SKL/SKX/KBL/WHL/CFL parts.  The
+   errata workaround uses Performance Counter 3, so the user can select
+   between working TSX and working perfcounters.
+
+ * November 2019, fixing the TSX Async Abort speculative vulnerability.
+   Introduced MSR_TSX_CTRL on all TSX-enabled MDS_NO parts to date,
+   CLX/WHL-R/CFL-R, with the controls becoming architectural moving forward
+   and formally retiring HLE from the architecture.  The user can disable TSX
+   to mitigate TAA, and elect to hide the HLE/RTM CPUID bits.
+
+ * June 2021, removing the workaround for March 2019 on client CPUs and
+   formally de-featured TSX on SKL/KBL/WHL/CFL (Note: SKX still retains the
+   March 2019 fix).  Introduced the ability to hide the HLE/RTM CPUID bits.
+   PCR3 works fine, and TSX is disabled by default, but the user can re-enable
+   TSX at their own risk, accepting that the memory order erratum is unfixed.
 
-On parts vulnerable to CVE-2019-11135 / TSX Asynchronous Abort, the following
-logic applies:
+On systems with the ability to configure TSX, this boolean offers system wide
+control of whether TSX is enabled or disabled.
 
  * An explicit `tsx=` choice is honoured, even if it is `true` and would
    result in a vulnerable system.
@@ -2211,10 +2259,21 @@
  * When no explicit `tsx=` choice is given, parts vulnerable to TAA will be
    mitigated by disabling TSX, as this is the lowest overhead option.
 
- * If the use of TSX is important, the more expensive TAA mitigations can be
+   If the use of TSX is important, the more expensive TAA mitigations can be
    opted in to with `smt=0 spec-ctrl=md-clear`, at which point TSX will remain
    active by default.
 
+ * When no explicit `tsx=` option is given, parts susceptible to the memory
+   ordering errata default to `true` to enable working TSX.  Alternatively,
+   selecting `tsx=0` will disable TSX and restore PCR3 to a working state.
+
+   SKX and SKL/KBL/WHL/CFL on pre-June 2021 microcode default to `true`.
+   Alternatively, selecting `tsx=0` will disable TSX and restore PCR3 to a
+   working state.
+
+   SKL/KBL/WHL/CFL on the June 2021 microcode or later default to `false`.
+   Alternatively, selecting `tsx=1` will re-enable TSX at the users own risk.
+
 ### ucode
 > `= List of [ <integer> | scan=<bool>, nmi=<bool> ]`
 
@@ -2351,20 +2410,7 @@
 
 *   The `arch` option allows access to the pre-defined architectural events.
 
-*   The `rtm-abort` boolean controls a trade-off between working Restricted
-    Transactional Memory, and working performance counters.
-
-    All processors released to date (Q1 2019) supporting Transactional Memory
-    Extensions suffer an erratum which has been addressed in microcode.
-
-    Processors based on the Skylake microarchitecture with up-to-date
-    microcode internally use performance counter 3 to work around the erratum.
-    A consequence is that the counter gets reprogrammed whenever an `XBEGIN`
-    instruction is executed.
-
-    An alternative mode exists where PCR3 behaves as before, at the cost of
-    `XBEGIN` unconditionally aborting.  Enabling `rtm-abort` mode will
-    activate this alternative mode.
+*   The `rtm-abort` boolean has been superseded.  Use `tsx=0` instead.
 
 *Warning:*
 As the virtualisation is not 100% safe, don't use the vpmu flag on
diff -Nru xen-4.14.1+11-gb0b734a8b3/MAINTAINERS xen-4.14.2+25-gb6a8c4f72d/MAINTAINERS
--- xen-4.14.1+11-gb0b734a8b3/MAINTAINERS	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/MAINTAINERS	2021-06-17 20:45:39.000000000 +0200
@@ -54,6 +54,15 @@
 will be listed in this section of the MAINTAINERS file in the
 appropriate branch.
 
+The maintainer for this branch is:
+
+	Jan Beulich <jbeulich@suse.com>
+
+Tools backport requests should also be copied to:
+
+	Ian Jackson <Ian.Jackson@eu.citrix.com>
+
+
 	Unstable Subsystem Maintainers
 	==============================
 
@@ -104,89 +113,6 @@
 	   xen-maintainers-<version format number of this file>
 
 
-	Check-in policy
-	===============
-
-In order for a patch to be checked in, in general, several conditions
-must be met:
-
-1. In order to get a change to a given file committed, it must have
-   the approval of at least one maintainer of that file.
-
-   A patch of course needs Acks from the maintainers of each file that
-   it changes; so a patch which changes xen/arch/x86/traps.c,
-   xen/arch/x86/mm/p2m.c, and xen/arch/x86/mm/shadow/multi.c would
-   require an Ack from each of the three sets of maintainers.
-
-   See below for rules on nested maintainership.
-
-2. It must have appropriate approval from someone other than the
-   submitter.  This can be either:
-
-  a. An Acked-by from a maintainer of the code being touched (a
-     co-maintainer if available, or a more general level maintainer if
-     not available; see the secton on nested maintainership)
-
-  b. A Reviewed-by by anyone of suitable stature in the community
-
-3. Sufficient time must have been given for anyone to respond.  This
-   depends in large part upon the urgency and nature of the patch.
-   For a straightforward uncontroversial patch, a day or two may be
-   sufficient; for a controversial patch, a week or two may be better.
-
-4. There must be no "open" objections.
-
-In a case where one person submits a patch and a maintainer gives an
-Ack, the Ack stands in for both the approval requirement (#1) and the
-Acked-by-non-submitter requirement (#2).
-
-In a case where a maintainer themselves submits a patch, the
-Signed-off-by meets the approval requirement (#1); so a Review
-from anyone in the community suffices for requirement #2.
-
-Before a maintainer checks in their own patch with another community
-member's R-b but no co-maintainer Ack, it is especially important to
-give their co-maintainer opportunity to give feedback, perhaps
-declaring their intention to check it in without their co-maintainers
-ack a day before doing so.
-
-Maintainers may choose to override non-maintainer objections in the
-case that consensus can't be reached.
-
-As always, no policy can cover all possible situations.  In
-exceptional circumstances, committers may commit a patch in absence of
-one or more of the above requirements, if they are reasonably
-confident that the other maintainers will approve of their decision in
-retrospect.
-
-       The meaning of nesting
-       ======================
-
-Many maintainership areas are "nested": for example, there are entries
-for xen/arch/x86 as well as xen/arch/x86/mm, and even
-xen/arch/x86/mm/shadow; and there is a section at the end called "THE
-REST" which lists all committers.  The meaning of nesting is that:
-
-1. Under normal circumstances, the Ack of the most specific maintainer
-is both necessary and sufficient to get a change to a given file
-committed.  So a change to xen/arch/x86/mm/shadow/multi.c requires the
-the Ack of the xen/arch/x86/mm/shadow maintainer for that part of the
-patch, but would not require the Ack of the xen/arch/x86 maintainer or
-the xen/arch/x86/mm maintainer.
-
-2. In unusual circumstances, a more general maintainer's Ack can stand
-in for or even overrule a specific maintainer's Ack.  Unusual
-circumstances might include:
- - The patch is fixing a high-priority issue causing immediate pain,
- and the more specific maintainer is not available.
- - The more specific maintainer has not responded either to the
- original patch, nor to "pings", within a reasonable amount of time.
- - The more general maintainer wants to overrule the more specific
- maintainer on some issue. (This should be exceptional.)
- - In the case of a disagreement between maintainers, THE REST can
- settle the matter by majority vote.  (This should be very exceptional
- indeed.)
-
 
 Maintainers List (try to look for most precise areas first)
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/SUPPORT.md xen-4.14.2+25-gb6a8c4f72d/SUPPORT.md
--- xen-4.14.1+11-gb0b734a8b3/SUPPORT.md	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/SUPPORT.md	2021-06-17 20:45:39.000000000 +0200
@@ -62,8 +62,8 @@
 
     Status, AMD IOMMU: Supported
     Status, Intel VT-d: Supported
-    Status, ARM SMMUv1: Supported
-    Status, ARM SMMUv2: Supported
+    Status, ARM SMMUv1: Supported, not security supported
+    Status, ARM SMMUv2: Supported, not security supported
     Status, Renesas IPMMU-VMSA: Tech Preview
 
 ### ARM/GICv3 ITS
@@ -80,7 +80,16 @@
 
 No hardware requirements
 
-    Status: Supported
+    Status, x86_64: Supported
+    Status, x86_32, shim: Supported
+    Status, x86_32, without shim: Supported, with caveats
+
+Due to architectural limitations,
+32-bit PV guests must be assumed to be able to read arbitrary host memory
+using speculative execution attacks.
+Advisories will continue to be issued
+for new vulnerabilities related to un-shimmed 32-bit PV guests
+enabling denial-of-service attacks or privilege escalation attacks.
 
 ### x86/HVM
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/golang/xenlight/gengotypes.py xen-4.14.2+25-gb6a8c4f72d/tools/golang/xenlight/gengotypes.py
--- xen-4.14.1+11-gb0b734a8b3/tools/golang/xenlight/gengotypes.py	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/golang/xenlight/gengotypes.py	2021-06-17 20:45:39.000000000 +0200
@@ -3,7 +3,7 @@
 import os
 import sys
 
-sys.path.append('{}/tools/libxl'.format(os.environ['XEN_ROOT']))
+sys.path.append('{0}/tools/libxl'.format(os.environ['XEN_ROOT']))
 import idl
 
 # Go versions of some builtin types.
@@ -73,14 +73,14 @@
 
     if ty.typename is not None:
         typename = xenlight_golang_fmt_name(ty.typename)
-        s += 'type {} int\n'.format(typename)
+        s += 'type {0} int\n'.format(typename)
 
     # Start const block
     s += 'const(\n'
 
     for v in ty.values:
         name = xenlight_golang_fmt_name(v.name)
-        s += '{} {} = {}\n'.format(name, typename, v.value)
+        s += '{0} {1} = {2}\n'.format(name, typename, v.value)
 
     # End const block
     s += ')\n'
@@ -99,9 +99,9 @@
 
     # Begin struct definition
     if nested:
-        s += '{} struct {{\n'.format(name)
+        s += '{0} struct {{\n'.format(name)
     else:
-        s += 'type {} struct {{\n'.format(name)
+        s += 'type {0} struct {{\n'.format(name)
 
     # Write struct fields
     for f in ty.fields:
@@ -111,13 +111,13 @@
                 typename = xenlight_golang_fmt_name(typename)
                 name     = xenlight_golang_fmt_name(f.name)
 
-                s += '{} []{}\n'.format(name, typename)
+                s += '{0} []{1}\n'.format(name, typename)
             else:
                 typename = f.type.typename
                 typename = xenlight_golang_fmt_name(typename)
                 name     = xenlight_golang_fmt_name(f.name)
 
-                s += '{} {}\n'.format(name, typename)
+                s += '{0} {1}\n'.format(name, typename)
 
         elif isinstance(f.type, idl.Struct):
             r = xenlight_golang_define_struct(f.type, typename=f.name, nested=True)
@@ -132,7 +132,7 @@
             extras.extend(r[1])
 
         else:
-            raise Exception('type {} not supported'.format(f.type))
+            raise Exception('type {0} not supported'.format(f.type))
 
     # End struct definition
     s += '}\n'
@@ -151,11 +151,11 @@
     s = ''
     extras = []
 
-    interface_name = '{}_{}_union'.format(struct_name, ty.keyvar.name)
+    interface_name = '{0}_{1}_union'.format(struct_name, ty.keyvar.name)
     interface_name = xenlight_golang_fmt_name(interface_name, exported=False)
 
-    s += 'type {} interface {{\n'.format(interface_name)
-    s += 'is{}()\n'.format(interface_name)
+    s += 'type {0} interface {{\n'.format(interface_name)
+    s += 'is{0}()\n'.format(interface_name)
     s += '}\n'
 
     extras.append(s)
@@ -165,7 +165,7 @@
             continue
 
         # Define struct
-        name = '{}_{}_union_{}'.format(struct_name, ty.keyvar.name, f.name)
+        name = '{0}_{1}_union_{2}'.format(struct_name, ty.keyvar.name, f.name)
         r = xenlight_golang_define_struct(f.type, typename=name)
         extras.append(r[0])
         extras.extend(r[1])
@@ -173,21 +173,21 @@
         # This typeof trick ensures that the fields used in the cgo struct
         # used for marshaling are the same as the fields of the union in the
         # actual C type, and avoids re-defining all of those fields.
-        s = 'typedef typeof(((struct {} *)NULL)->{}.{}){};'
+        s = 'typedef typeof(((struct {0} *)NULL)->{1}.{2}){3};'
         s = s.format(struct_name, union_name, f.name, name)
         cgo_helpers_preamble.append(s)
 
         # Define function to implement 'union' interface
         name = xenlight_golang_fmt_name(name)
-        s = 'func (x {}) is{}(){{}}\n'.format(name, interface_name)
+        s = 'func (x {0}) is{1}(){{}}\n'.format(name, interface_name)
         extras.append(s)
 
     fname = xenlight_golang_fmt_name(ty.keyvar.name)
     ftype = xenlight_golang_fmt_name(ty.keyvar.type.typename)
-    s = '{} {}\n'.format(fname, ftype)
+    s = '{0} {1}\n'.format(fname, ftype)
 
-    fname = xenlight_golang_fmt_name('{}_union'.format(ty.keyvar.name))
-    s += '{} {}\n'.format(fname, interface_name)
+    fname = xenlight_golang_fmt_name('{0}_union'.format(ty.keyvar.name))
+    s += '{0} {1}\n'.format(fname, interface_name)
 
     return (s,extras)
 
@@ -243,7 +243,7 @@
     Define the fromC marshaling function for the type
     represented by ty.
     """
-    func = 'func (x *{}) fromC(xc *C.{}) error {{\n {}\n return nil}}\n'
+    func = 'func (x *{0}) fromC(xc *C.{1}) error {{\n {2}\n return nil}}\n'
 
     goname = xenlight_golang_fmt_name(ty.typename)
     cname  = ty.typename
@@ -271,7 +271,7 @@
             extras.extend(r[1])
 
         else:
-            raise Exception('type {} not supported'.format(f.type))
+            raise Exception('type {0} not supported'.format(f.type))
 
     return (func.format(goname, cname, body), extras)
 
@@ -300,8 +300,8 @@
 
     # If outer_name is set, treat this as nested.
     if outer_name is not None:
-        goname = '{}.{}'.format(xenlight_golang_fmt_name(outer_name), goname)
-        cname  = '{}.{}'.format(outer_name, cname)
+        goname = '{0}.{1}'.format(xenlight_golang_fmt_name(outer_name), goname)
+        cname  = '{0}.{1}'.format(outer_name, cname)
 
     # Types that satisfy this condition can be easily casted or
     # converted to a Go builtin type.
@@ -312,15 +312,15 @@
     if not is_castable:
         # If the type is not castable, we need to call its fromC
         # function.
-        s += 'if err := x.{}.fromC(&{}.{});'.format(goname,cvarname,cname)
-        s += 'err != nil {{\nreturn fmt.Errorf("converting field {}: %v", err)\n}}\n'.format(goname)
+        s += 'if err := x.{0}.fromC(&{1}.{2});'.format(goname,cvarname,cname)
+        s += 'err != nil {{\nreturn fmt.Errorf("converting field {0}: %v", err)\n}}\n'.format(goname)
 
     elif gotypename == 'string':
         # Use the cgo helper for converting C strings.
-        s += 'x.{} = C.GoString({}.{})\n'.format(goname,cvarname,cname)
+        s += 'x.{0} = C.GoString({1}.{2})\n'.format(goname,cvarname,cname)
 
     else:
-        s += 'x.{} = {}({}.{})\n'.format(goname,gotypename,cvarname,cname)
+        s += 'x.{0} = {1}({2}.{3})\n'.format(goname,gotypename,cvarname,cname)
 
     return s
 
@@ -331,9 +331,9 @@
     gokeyname = xenlight_golang_fmt_name(keyname)
     keytype   = ty.keyvar.type.typename
     gokeytype = xenlight_golang_fmt_name(keytype)
-    field_name = xenlight_golang_fmt_name('{}_union'.format(keyname))
+    field_name = xenlight_golang_fmt_name('{0}_union'.format(keyname))
 
-    interface_name = '{}_{}_union'.format(struct_name, keyname)
+    interface_name = '{0}_{1}_union'.format(struct_name, keyname)
     interface_name = xenlight_golang_fmt_name(interface_name, exported=False)
 
     cgo_keyname = keyname
@@ -343,7 +343,7 @@
     cases = {}
 
     for f in ty.fields:
-        val = '{}_{}'.format(keytype, f.name)
+        val = '{0}_{1}'.format(keytype, f.name)
         val = xenlight_golang_fmt_name(val)
 
         # Add to list of cases to make for the switch
@@ -354,17 +354,17 @@
             continue
 
         # Define fromC func for 'union' struct.
-        typename   = '{}_{}_union_{}'.format(struct_name,keyname,f.name)
+        typename   = '{0}_{1}_union_{2}'.format(struct_name,keyname,f.name)
         gotypename = xenlight_golang_fmt_name(typename)
 
         # Define the function here. The cases for keyed unions are a little
         # different.
-        s = 'func (x *{}) fromC(xc *C.{}) error {{\n'.format(gotypename,struct_name)
-        s += 'if {}(xc.{}) != {} {{\n'.format(gokeytype,cgo_keyname,val)
-        err_string = '"expected union key {}"'.format(val)
-        s += 'return errors.New({})\n'.format(err_string)
+        s = 'func (x *{0}) fromC(xc *C.{1}) error {{\n'.format(gotypename,struct_name)
+        s += 'if {0}(xc.{1}) != {2} {{\n'.format(gokeytype,cgo_keyname,val)
+        err_string = '"expected union key {0}"'.format(val)
+        s += 'return errors.New({0})\n'.format(err_string)
         s += '}\n\n'
-        s += 'tmp := (*C.{})(unsafe.Pointer(&xc.{}[0]))\n'.format(typename,union_name)
+        s += 'tmp := (*C.{0})(unsafe.Pointer(&xc.{1}[0]))\n'.format(typename,union_name)
 
         for nf in f.type.fields:
             s += xenlight_golang_convert_from_C(nf,cvarname='tmp')
@@ -374,35 +374,35 @@
 
         extras.append(s)
 
-    s = 'x.{} = {}(xc.{})\n'.format(gokeyname,gokeytype,cgo_keyname)
-    s += 'switch x.{}{{\n'.format(gokeyname)
+    s = 'x.{0} = {1}(xc.{2})\n'.format(gokeyname,gokeytype,cgo_keyname)
+    s += 'switch x.{0}{{\n'.format(gokeyname)
 
     # Create switch statement to determine which 'union element'
     # to populate in the Go struct.
     for case_name, case_tuple in sorted(cases.items()):
         (case_val, case_type) = case_tuple
 
-        s += 'case {}:\n'.format(case_val)
+        s += 'case {0}:\n'.format(case_val)
 
         if case_type is None:
-            s += "x.{} = nil\n".format(field_name)
+            s += "x.{0} = nil\n".format(field_name)
             continue
 
-        gotype = '{}_{}_union_{}'.format(struct_name,keyname,case_name)
+        gotype = '{0}_{1}_union_{2}'.format(struct_name,keyname,case_name)
         gotype = xenlight_golang_fmt_name(gotype)
-        goname = '{}_{}'.format(keyname,case_name)
+        goname = '{0}_{1}'.format(keyname,case_name)
         goname = xenlight_golang_fmt_name(goname,exported=False)
 
-        s += 'var {} {}\n'.format(goname, gotype)
-        s += 'if err := {}.fromC(xc);'.format(goname)
-        s += 'err != nil {{\n return fmt.Errorf("converting field {}: %v", err)\n}}\n'.format(goname)
+        s += 'var {0} {1}\n'.format(goname, gotype)
+        s += 'if err := {0}.fromC(xc);'.format(goname)
+        s += 'err != nil {{\n return fmt.Errorf("converting field {0}: %v", err)\n}}\n'.format(goname)
 
-        s += 'x.{} = {}\n'.format(field_name, goname)
+        s += 'x.{0} = {1}\n'.format(field_name, goname)
 
     # End switch statement
     s += 'default:\n'
-    err_string = '"invalid union key \'%v\'", x.{}'.format(gokeyname)
-    s += 'return fmt.Errorf({})'.format(err_string)
+    err_string = '"invalid union key \'%v\'", x.{0}'.format(gokeyname)
+    s += 'return fmt.Errorf({0})'.format(err_string)
     s += '}\n'
 
     return (s,extras)
@@ -420,22 +420,22 @@
     goname     = xenlight_golang_fmt_name(ty.name)
     ctypename  = ty.type.elem_type.typename
     cname      = ty.name
-    cslice     = 'c{}'.format(goname)
+    cslice     = 'c{0}'.format(goname)
     clenvar    = ty.type.lenvar.name
 
-    s += 'x.{} = nil\n'.format(goname)
-    s += 'if n := int(xc.{}); n > 0 {{\n'.format(clenvar)
-    s += '{} := '.format(cslice)
-    s +='(*[1<<28]C.{})(unsafe.Pointer(xc.{}))[:n:n]\n'.format(ctypename, cname)
-    s += 'x.{} = make([]{}, n)\n'.format(goname, gotypename)
-    s += 'for i, v := range {} {{\n'.format(cslice)
+    s += 'x.{0} = nil\n'.format(goname)
+    s += 'if n := int(xc.{0}); n > 0 {{\n'.format(clenvar)
+    s += '{0} := '.format(cslice)
+    s +='(*[1<<28]C.{0})(unsafe.Pointer(xc.{1}))[:n:n]\n'.format(ctypename, cname)
+    s += 'x.{0} = make([]{1}, n)\n'.format(goname, gotypename)
+    s += 'for i, v := range {0} {{\n'.format(cslice)
 
     is_enum = isinstance(ty.type.elem_type,idl.Enumeration)
     if gotypename in go_builtin_types or is_enum:
-        s += 'x.{}[i] = {}(v)\n'.format(goname, gotypename)
+        s += 'x.{0}[i] = {1}(v)\n'.format(goname, gotypename)
     else:
-        s += 'if err := x.{}[i].fromC(&v); err != nil {{\n'.format(goname)
-        s += 'return fmt.Errorf("converting field {}: %v", err) }}\n'.format(goname)
+        s += 'if err := x.{0}[i].fromC(&v); err != nil {{\n'.format(goname)
+        s += 'return fmt.Errorf("converting field {0}: %v", err) }}\n'.format(goname)
 
     s += '}\n}\n'
 
@@ -446,11 +446,11 @@
     Define the toC marshaling function for the type
     represented by ty.
     """
-    func = 'func (x *{}) toC(xc *C.{}) (err error){{{}\n return nil\n }}\n'
+    func = 'func (x *{0}) toC(xc *C.{1}) (err error){{{2}\n return nil\n }}\n'
     body = ''
 
     if ty.dispose_fn is not None:
-        body += 'defer func(){{\nif err != nil{{\nC.{}(xc)}}\n}}()\n\n'.format(ty.dispose_fn)
+        body += 'defer func(){{\nif err != nil{{\nC.{0}(xc)}}\n}}()\n\n'.format(ty.dispose_fn)
 
     goname = xenlight_golang_fmt_name(ty.typename)
     cname  = ty.typename
@@ -471,7 +471,7 @@
             body += xenlight_golang_union_to_C(f.type, f.name, ty.typename)
 
         else:
-            raise Exception('type {} not supported'.format(f.type))
+            raise Exception('type {0} not supported'.format(f.type))
 
     return func.format(goname, cname, body)
 
@@ -506,26 +506,26 @@
 
     # If outer_name is set, treat this as nested.
     if outer_name is not None:
-        goname = '{}.{}'.format(xenlight_golang_fmt_name(outer_name), goname)
-        cname  = '{}.{}'.format(outer_name, cname)
+        goname = '{0}.{1}'.format(xenlight_golang_fmt_name(outer_name), goname)
+        cname  = '{0}.{1}'.format(outer_name, cname)
 
     is_castable = (ty.type.json_parse_type == 'JSON_INTEGER' or
                    isinstance(ty.type, idl.Enumeration) or
                    gotypename in go_builtin_types)
 
     if not is_castable:
-        s += 'if err := {}.{}.toC(&{}.{}); err != nil {{\n'.format(govarname,goname,
+        s += 'if err := {0}.{1}.toC(&{2}.{3}); err != nil {{\n'.format(govarname,goname,
                                                                    cvarname,cname)
-        s += 'return fmt.Errorf("converting field {}: %v", err)\n}}\n'.format(goname)
+        s += 'return fmt.Errorf("converting field {0}: %v", err)\n}}\n'.format(goname)
 
     elif gotypename == 'string':
         # Use the cgo helper for converting C strings.
-        s += 'if {}.{} != "" {{\n'.format(govarname,goname)
-        s += '{}.{} = C.CString({}.{})}}\n'.format(cvarname,cname,
+        s += 'if {0}.{1} != "" {{\n'.format(govarname,goname)
+        s += '{0}.{1} = C.CString({2}.{3})}}\n'.format(cvarname,cname,
                                                    govarname,goname)
 
     else:
-        s += '{}.{} = C.{}({}.{})\n'.format(cvarname,cname,ctypename,
+        s += '{0}.{1} = C.{2}({3}.{4})\n'.format(cvarname,cname,ctypename,
                                             govarname,goname)
 
     return s
@@ -537,7 +537,7 @@
     keytype   = ty.keyvar.type.typename
     gokeytype = xenlight_golang_fmt_name(keytype)
 
-    interface_name = '{}_{}_union'.format(struct_name, keyname)
+    interface_name = '{0}_{1}_union'.format(struct_name, keyname)
     interface_name = xenlight_golang_fmt_name(interface_name, exported=False)
 
     cgo_keyname = keyname
@@ -545,44 +545,44 @@
         cgo_keyname = '_' + cgo_keyname
 
 
-    s = 'xc.{} = C.{}(x.{})\n'.format(cgo_keyname,keytype,gokeyname)
-    s += 'switch x.{}{{\n'.format(gokeyname)
+    s = 'xc.{0} = C.{1}(x.{2})\n'.format(cgo_keyname,keytype,gokeyname)
+    s += 'switch x.{0}{{\n'.format(gokeyname)
 
     # Create switch statement to determine how to populate the C union.
     for f in ty.fields:
-        key_val = '{}_{}'.format(keytype, f.name)
+        key_val = '{0}_{1}'.format(keytype, f.name)
         key_val = xenlight_golang_fmt_name(key_val)
 
-        s += 'case {}:\n'.format(key_val)
+        s += 'case {0}:\n'.format(key_val)
 
         if f.type is None:
             s += "break\n"
             continue
 
-        cgotype = '{}_{}_union_{}'.format(struct_name,keyname,f.name)
+        cgotype = '{0}_{1}_union_{2}'.format(struct_name,keyname,f.name)
         gotype  = xenlight_golang_fmt_name(cgotype)
 
-        field_name = xenlight_golang_fmt_name('{}_union'.format(keyname))
-        s += 'tmp, ok := x.{}.({})\n'.format(field_name,gotype)
+        field_name = xenlight_golang_fmt_name('{0}_union'.format(keyname))
+        s += 'tmp, ok := x.{0}.({1})\n'.format(field_name,gotype)
         s += 'if !ok {\n'
-        s += 'return errors.New("wrong type for union key {}")\n'.format(keyname)
+        s += 'return errors.New("wrong type for union key {0}")\n'.format(keyname)
         s += '}\n'
 
-        s += 'var {} C.{}\n'.format(f.name,cgotype)
+        s += 'var {0} C.{1}\n'.format(f.name,cgotype)
         for uf in f.type.fields:
             s += xenlight_golang_convert_to_C(uf,cvarname=f.name,
                                               govarname='tmp')
 
         # The union is still represented as Go []byte.
-        s += '{}Bytes := C.GoBytes(unsafe.Pointer(&{}),C.sizeof_{})\n'.format(f.name,
+        s += '{0}Bytes := C.GoBytes(unsafe.Pointer(&{1}),C.sizeof_{2})\n'.format(f.name,
                                                                               f.name,
                                                                               cgotype)
-        s += 'copy(xc.{}[:],{}Bytes)\n'.format(union_name,f.name)
+        s += 'copy(xc.{0}[:],{1}Bytes)\n'.format(union_name,f.name)
 
     # End switch statement
     s += 'default:\n'
-    err_string = '"invalid union key \'%v\'", x.{}'.format(gokeyname)
-    s += 'return fmt.Errorf({})'.format(err_string)
+    err_string = '"invalid union key \'%v\'", x.{0}'.format(gokeyname)
+    s += 'return fmt.Errorf({0})'.format(err_string)
     s += '}\n'
 
     return s
@@ -599,29 +599,29 @@
 
     is_enum = isinstance(ty.type.elem_type,idl.Enumeration)
     if gotypename in go_builtin_types or is_enum:
-        s += 'if {} := len(x.{}); {} > 0 {{\n'.format(golenvar,goname,golenvar)
-        s += 'xc.{} = (*C.{})(C.malloc(C.size_t({}*{})))\n'.format(cname,ctypename,
+        s += 'if {0} := len(x.{1}); {2} > 0 {{\n'.format(golenvar,goname,golenvar)
+        s += 'xc.{0} = (*C.{1})(C.malloc(C.size_t({2}*{3})))\n'.format(cname,ctypename,
                                                                    golenvar,golenvar)
-        s += 'xc.{} = C.int({})\n'.format(clenvar,golenvar)
-        s += 'c{} := (*[1<<28]C.{})(unsafe.Pointer(xc.{}))[:{}:{}]\n'.format(goname,
+        s += 'xc.{0} = C.int({1})\n'.format(clenvar,golenvar)
+        s += 'c{0} := (*[1<<28]C.{1})(unsafe.Pointer(xc.{2}))[:{3}:{4}]\n'.format(goname,
                                                                       ctypename,cname,
                                                                       golenvar,golenvar)
-        s += 'for i,v := range x.{} {{\n'.format(goname)
-        s += 'c{}[i] = C.{}(v)\n'.format(goname,ctypename)
+        s += 'for i,v := range x.{0} {{\n'.format(goname)
+        s += 'c{0}[i] = C.{1}(v)\n'.format(goname,ctypename)
         s += '}\n}\n'
 
         return s
 
-    s += 'if {} := len(x.{}); {} > 0 {{\n'.format(golenvar,goname,golenvar)
-    s += 'xc.{} = (*C.{})(C.malloc(C.ulong({})*C.sizeof_{}))\n'.format(cname,ctypename,
+    s += 'if {0} := len(x.{1}); {2} > 0 {{\n'.format(golenvar,goname,golenvar)
+    s += 'xc.{0} = (*C.{1})(C.malloc(C.ulong({2})*C.sizeof_{3}))\n'.format(cname,ctypename,
                                                                    golenvar,ctypename)
-    s += 'xc.{} = C.int({})\n'.format(clenvar,golenvar)
-    s += 'c{} := (*[1<<28]C.{})(unsafe.Pointer(xc.{}))[:{}:{}]\n'.format(goname,
+    s += 'xc.{0} = C.int({1})\n'.format(clenvar,golenvar)
+    s += 'c{0} := (*[1<<28]C.{1})(unsafe.Pointer(xc.{2}))[:{3}:{4}]\n'.format(goname,
                                                                          ctypename,cname,
                                                                          golenvar,golenvar)
-    s += 'for i,v := range x.{} {{\n'.format(goname)
-    s += 'if err := v.toC(&c{}[i]); err != nil {{\n'.format(goname)
-    s += 'return fmt.Errorf("converting field {}: %v", err)\n'.format(goname)
+    s += 'for i,v := range x.{0} {{\n'.format(goname)
+    s += 'if err := v.toC(&c{0}[i]); err != nil {{\n'.format(goname)
+    s += 'return fmt.Errorf("converting field {0}: %v", err)\n'.format(goname)
     s += '}\n}\n}\n'
 
     return s
@@ -633,7 +633,7 @@
     gotypename = xenlight_golang_fmt_name(ctypename)
 
     # Since this func is exported, add a comment as per Go conventions.
-    s += '// New{} returns an instance of {}'.format(gotypename,gotypename)
+    s += '// New{0} returns an instance of {1}'.format(gotypename,gotypename)
     s += ' initialized with defaults.\n'
 
     # If a struct has a keyed union, an extra argument is
@@ -643,7 +643,7 @@
     init_fns = []
 
     # Add call to parent init_fn first.
-    init_fns.append('C.{}(&xc)'.format(ty.init_fn))
+    init_fns.append('C.{0}(&xc)'.format(ty.init_fn))
 
     for f in ty.fields:
         if not isinstance(f.type, idl.KeyedUnion):
@@ -658,24 +658,24 @@
         # Serveral keyed unions use 'type' as the key variable name. In
         # that case, prepend the first letter of the Go type name.
         if param_goname == 'type':
-            param_goname = '{}type'.format(param_gotype.lower()[0])
+            param_goname = '{0}type'.format(param_gotype.lower()[0])
 
         # Add call to keyed union's init_fn.
-        init_fns.append('C.{}_{}(&xc, C.{}({}))'.format(ty.init_fn,
+        init_fns.append('C.{0}_{1}(&xc, C.{2}({3}))'.format(ty.init_fn,
                                                         param.name,
                                                         param_ctype,
                                                         param_goname))
 
         # Add to params list.
-        params.append('{} {}'.format(param_goname, param_gotype))
+        params.append('{0} {1}'.format(param_goname, param_gotype))
 
     # Define function
-    s += 'func New{}({}) (*{}, error) {{\n'.format(gotypename,
+    s += 'func New{0}({1}) (*{2}, error) {{\n'.format(gotypename,
                                                    ','.join(params),
                                                    gotypename)
 
     # Declare variables.
-    s += 'var (\nx {}\nxc C.{})\n\n'.format(gotypename, ctypename)
+    s += 'var (\nx {0}\nxc C.{1})\n\n'.format(gotypename, ctypename)
 
     # Write init_fn calls.
     s += '\n'.join(init_fns)
@@ -684,7 +684,7 @@
     # Make sure dispose_fn get's called when constructor
     # returns.
     if ty.dispose_fn is not None:
-        s += 'defer C.{}(&xc)\n'.format(ty.dispose_fn)
+        s += 'defer C.{0}(&xc)\n'.format(ty.dispose_fn)
 
     s += '\n'
 
@@ -727,7 +727,7 @@
     header_comment="""// DO NOT EDIT.
 //
 // This file is generated by:
-// {}
+// {0}
 //
 
 """.format(' '.join(sys.argv))
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/libxc/xc_cpuid_x86.c xen-4.14.2+25-gb6a8c4f72d/tools/libxc/xc_cpuid_x86.c
--- xen-4.14.1+11-gb0b734a8b3/tools/libxc/xc_cpuid_x86.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/libxc/xc_cpuid_x86.c	2021-06-17 20:45:39.000000000 +0200
@@ -504,6 +504,8 @@
     if ( restore )
     {
         p->basic.rdrand = test_bit(X86_FEATURE_RDRAND, host_featureset);
+        p->feat.hle = test_bit(X86_FEATURE_HLE, host_featureset);
+        p->feat.rtm = test_bit(X86_FEATURE_RTM, host_featureset);
 
         if ( di.hvm )
         {
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/libxl/libxl_create.c xen-4.14.2+25-gb6a8c4f72d/tools/libxl/libxl_create.c
--- xen-4.14.1+11-gb0b734a8b3/tools/libxl/libxl_create.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/libxl/libxl_create.c	2021-06-17 20:45:39.000000000 +0200
@@ -2174,9 +2174,7 @@
     state->console_tty = libxl__strdup(gc, console_tty);
 
     dss->ao = ao;
-    dss->domid = dss->dsps.domid = domid;
-    dss->dsps.dm_savefile = GCSPRINTF(LIBXL_DEVICE_MODEL_SAVE_FILE".%d",
-                                      domid);
+    dss->domid = domid;
 
     rc = libxl__save_emulator_xenstore_data(dss, &srs->toolstack_buf,
                                             &srs->toolstack_len);
@@ -2186,6 +2184,11 @@
     }
 
     dss->dsps.ao = ao;
+    dss->dsps.domid = domid;
+    dss->dsps.live = false;
+    rc = libxl__domain_suspend_init(egc, &dss->dsps, d_config->b_info.type);
+    if (rc)
+        goto out;
     dss->dsps.callback_device_model_done = soft_reset_dm_suspended;
     libxl__domain_suspend_device_model(egc, &dss->dsps); /* must be last */
 
@@ -2204,6 +2207,8 @@
         CONTAINER_OF(dsps, *srs, dss.dsps);
     libxl__app_domain_create_state *cdcs = &srs->cdcs;
 
+    libxl__domain_suspend_dispose(gc, dsps);
+
     /*
      * Ask all backends to disconnect by removing the domain from
      * xenstore. On the creation path the domain will be introduced to
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/libxl/libxl_dom_suspend.c xen-4.14.2+25-gb6a8c4f72d/tools/libxl/libxl_dom_suspend.c
--- xen-4.14.1+11-gb0b734a8b3/tools/libxl/libxl_dom_suspend.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/libxl/libxl_dom_suspend.c	2021-06-17 20:45:39.000000000 +0200
@@ -67,6 +67,16 @@
     return rc;
 }
 
+void libxl__domain_suspend_dispose(libxl__gc *gc,
+                                   libxl__domain_suspend_state  *dsps)
+{
+    libxl__xswait_stop(gc, &dsps->pvcontrol);
+    libxl__ev_evtchn_cancel(gc, &dsps->guest_evtchn);
+    libxl__ev_xswatch_deregister(gc, &dsps->guest_watch);
+    libxl__ev_time_deregister(gc, &dsps->guest_timeout);
+    libxl__ev_qmp_dispose(gc, &dsps->qmp);
+}
+
 /*----- callbacks, called by xc_domain_save -----*/
 
 void libxl__domain_suspend_device_model(libxl__egc *egc,
@@ -388,10 +398,7 @@
 {
     EGC_GC;
     assert(!libxl__xswait_inuse(&dsps->pvcontrol));
-    libxl__ev_evtchn_cancel(gc, &dsps->guest_evtchn);
-    libxl__ev_xswatch_deregister(gc, &dsps->guest_watch);
-    libxl__ev_time_deregister(gc, &dsps->guest_timeout);
-    libxl__ev_qmp_dispose(gc, &dsps->qmp);
+    libxl__domain_suspend_dispose(gc, dsps);
     dsps->callback_common_done(egc, dsps, rc);
 }
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/libxl/libxl_internal.h xen-4.14.2+25-gb6a8c4f72d/tools/libxl/libxl_internal.h
--- xen-4.14.1+11-gb0b734a8b3/tools/libxl/libxl_internal.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/libxl/libxl_internal.h	2021-06-17 20:45:39.000000000 +0200
@@ -3615,6 +3615,8 @@
 int libxl__domain_suspend_init(libxl__egc *egc,
                                libxl__domain_suspend_state *dsps,
                                libxl_domain_type type);
+void libxl__domain_suspend_dispose(libxl__gc *gc,
+                                   libxl__domain_suspend_state  *dsps);
 
 /* calls dsps->callback_device_model_done when done
  * may synchronously calls this callback */
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/misc/xen-cpuid.c xen-4.14.2+25-gb6a8c4f72d/tools/misc/xen-cpuid.c
--- xen-4.14.1+11-gb0b734a8b3/tools/misc/xen-cpuid.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/misc/xen-cpuid.c	2021-06-17 20:45:39.000000000 +0200
@@ -161,7 +161,7 @@
     [ 4] = "fsrm",
 
     /*  8 */                [ 9] = "srbds-ctrl",
-    [10] = "md-clear",
+    [10] = "md-clear",      [11] = "rtm-always-abort",
     /* 12 */                [13] = "tsx-force-abort",
     [14] = "serialize",
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/ocaml/libs/xb/op.ml xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/libs/xb/op.ml
--- xen-4.14.1+11-gb0b734a8b3/tools/ocaml/libs/xb/op.ml	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/libs/xb/op.ml	2021-06-17 20:45:39.000000000 +0200
@@ -28,7 +28,7 @@
            Transaction_end; Introduce; Release;
            Getdomainpath; Write; Mkdir; Rm;
            Setperms; Watchevent; Error; Isintroduced;
-           Resume; Set_target; Reset_watches |]
+           Resume; Set_target; Invalid; Reset_watches |]
 let size = Array.length operation_c_mapping
 
 let array_search el a =
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/ocaml/libs/xb/xs_ring_stubs.c xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/libs/xb/xs_ring_stubs.c
--- xen-4.14.1+11-gb0b734a8b3/tools/ocaml/libs/xb/xs_ring_stubs.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/libs/xb/xs_ring_stubs.c	2021-06-17 20:45:39.000000000 +0200
@@ -32,6 +32,7 @@
 #include <caml/fail.h>
 #include <caml/callback.h>
 
+#include <sys/mman.h>
 #include "mmap_stubs.h"
 
 #define GET_C_STRUCT(a) ((struct mmap_interface *) a)
@@ -166,6 +167,8 @@
 {
 	CAMLparam2(interface, v);
 	struct xenstore_domain_interface *intf = GET_C_STRUCT(interface)->addr;
+	if (intf == (void*)MAP_FAILED)
+		caml_failwith("Interface closed");
 
 	intf->server_features = Int_val(v);
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/connection.ml xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/connection.ml
--- xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/connection.ml	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/connection.ml	2021-06-17 20:45:39.000000000 +0200
@@ -47,7 +47,7 @@
 
 let initial_next_tid = 1
 
-let reconnect con =
+let do_reconnect con =
 	Xenbus.Xb.reconnect con.xb;
 	(* dom is the same *)
 	Hashtbl.clear con.transactions;
@@ -158,18 +158,17 @@
 let is_dom0 con =
 	Perms.Connection.is_dom0 (get_perm con)
 
-let add_watch con path token =
+let add_watch con (path, apath) token =
 	if !Quota.activate && !Define.maxwatch > 0 &&
 	   not (is_dom0 con) && con.nb_watches > !Define.maxwatch then
 		raise Quota.Limit_reached;
-	let apath = get_watch_path con path in
 	let l = get_watches con apath in
 	if List.exists (fun w -> w.token = token) l then
 		raise Define.Already_exist;
 	let watch = watch_create ~con ~token ~path in
 	Hashtbl.replace con.watches apath (watch :: l);
 	con.nb_watches <- con.nb_watches + 1;
-	apath, watch
+	watch
 
 let del_watch con path token =
 	let apath = get_watch_path con path in
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/connections.ml xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/connections.ml
--- xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/connections.ml	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/connections.ml	2021-06-17 20:45:39.000000000 +0200
@@ -114,8 +114,10 @@
 	"" :: Store.Path.to_string_list path
 
 let add_watch cons con path token =
-	let apath, watch = Connection.add_watch con path token in
+	let apath = Connection.get_watch_path con path in
+	(* fail on invalid paths early by calling key_of_str before adding watch *)
 	let key = key_of_str apath in
+	let watch = Connection.add_watch con (path, apath) token in
 	let watches =
  		if Trie.mem cons.watches key
  		then Trie.find cons.watches key
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/history.ml xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/history.ml
--- xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/history.ml	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/history.ml	2021-06-17 20:45:39.000000000 +0200
@@ -53,6 +53,10 @@
 	trim ~txn ();
 	success
 
+let reconnect con =
+	trim ();
+	Connection.do_reconnect con
+
 let push (x: history_record) =
 	let dom = x.con.Connection.dom in
 	match dom with
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/process.ml xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/process.ml
--- xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/process.ml	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/process.ml	2021-06-17 20:45:39.000000000 +0200
@@ -566,7 +566,7 @@
 			Connection.do_input con
 		with Xenbus.Xb.Reconnect ->
 			info "%s requests a reconnect" (Connection.get_domstr con);
-			Connection.reconnect con;
+			History.reconnect con;
 			info "%s reconnection complete" (Connection.get_domstr con);
 			false
 		| Failure exp ->
@@ -605,7 +605,7 @@
 			ignore (Connection.do_output con)
 		with Xenbus.Xb.Reconnect ->
 			info "%s requests a reconnect" (Connection.get_domstr con);
-			Connection.reconnect con;
+			History.reconnect con;
 			info "%s reconnection complete" (Connection.get_domstr con)
 	)
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/store.ml xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/store.ml
--- xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/store.ml	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/store.ml	2021-06-17 20:45:39.000000000 +0200
@@ -421,6 +421,7 @@
 	(* It's upt to the mkdir logic to decide what to do with existing path *)
 	if not (existing || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota owner 0;
 	store.root <- path_mkdir store perm path;
+	if not existing then
 	Quota.add_entry store.quota owner
 
 let rm store perm path =
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/transaction.ml xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/transaction.ml
--- xen-4.14.1+11-gb0b734a8b3/tools/ocaml/xenstored/transaction.ml	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/ocaml/xenstored/transaction.ml	2021-06-17 20:45:39.000000000 +0200
@@ -165,7 +165,7 @@
 
 let mkdir ?(with_watch=true) t perm path =
 	Store.mkdir t.store perm path;
-	set_write_lowpath t path;
+	set_write_lowpath t (Store.Path.get_parent path);
 	if with_watch then
 		add_wop t Xenbus.Xb.Op.Mkdir path
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/tests/x86_emulator/testcase.mk xen-4.14.2+25-gb6a8c4f72d/tools/tests/x86_emulator/testcase.mk
--- xen-4.14.1+11-gb0b734a8b3/tools/tests/x86_emulator/testcase.mk	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/tests/x86_emulator/testcase.mk	2021-06-17 20:45:39.000000000 +0200
@@ -12,11 +12,11 @@
 %.bin: %.c
 	$(CC) $(filter-out -M% .%,$(CFLAGS)) -c $<
 	$(LD) $(LDFLAGS_DIRECT) -N -Ttext 0x100000 -o $*.tmp $*.o
-	$(OBJCOPY) -O binary $*.tmp $@
+	$(OBJCOPY) -O binary -R .note.gnu.property $*.tmp $@
 	rm -f $*.tmp
 
 %-opmask.bin: opmask.S
 	$(CC) $(filter-out -M% .%,$(CFLAGS)) -c $< -o $(basename $@).o
 	$(LD) $(LDFLAGS_DIRECT) -N -Ttext 0x100000 -o $(basename $@).tmp $(basename $@).o
-	$(OBJCOPY) -O binary $(basename $@).tmp $@
+	$(OBJCOPY) -O binary -R .note.gnu.property $(basename $@).tmp $@
 	rm -f $(basename $@).tmp
diff -Nru xen-4.14.1+11-gb0b734a8b3/tools/tests/x86_emulator/x86-emulate.c xen-4.14.2+25-gb6a8c4f72d/tools/tests/x86_emulator/x86-emulate.c
--- xen-4.14.1+11-gb0b734a8b3/tools/tests/x86_emulator/x86-emulate.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/tools/tests/x86_emulator/x86-emulate.c	2021-06-17 20:45:39.000000000 +0200
@@ -8,6 +8,13 @@
 
 #define ERR_PTR(val) NULL
 
+/* See gcc bug 100680, but here don't bother making this version dependent. */
+#define gcc11_wrap(x) ({                  \
+    unsigned long x_;                     \
+    __asm__ ( "" : "=g" (x_) : "0" (x) ); \
+    (typeof(x))x_;                        \
+})
+
 #define cpu_has_amd_erratum(nr) 0
 #define cpu_has_mpx false
 #define read_bndcfgu() 0
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/cpuerrata.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/cpuerrata.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/cpuerrata.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/cpuerrata.c	2021-06-17 20:45:39.000000000 +0200
@@ -476,6 +476,14 @@
         .matches = has_ssbd_mitigation,
     },
 #endif
+#ifdef CONFIG_ARM_ERRATUM_858921
+    {
+        /* Cortex-A73 (all versions) */
+        .desc = "ARM erratum 858921",
+        .capability = ARM_WORKAROUND_858921,
+        MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
+    },
+#endif
     {
         /* Neoverse r0p0 - r2p0 */
         .desc = "ARM erratum 1165522",
@@ -498,6 +506,12 @@
         .capability = ARM64_WORKAROUND_AT_SPECULATE,
         MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
     },
+    {
+        /* Cortex-A55 (All versions as erratum is open in SDEN v14) */
+        .desc = "ARM erratum 1530923",
+        .capability = ARM64_WORKAROUND_AT_SPECULATE,
+        MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
+    },
     {},
 };
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/domain_build.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/domain_build.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/domain_build.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/domain_build.c	2021-06-17 20:45:39.000000000 +0200
@@ -2515,8 +2515,6 @@
 
         if ( construct_domU(d, node) != 0 )
             panic("Could not set up domain %s\n", dt_node_name(node));
-
-        domain_unpause_by_systemcontroller(d);
     }
 }
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/domain.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/domain.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/domain.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/domain.c	2021-06-17 20:45:39.000000000 +0200
@@ -216,7 +216,8 @@
     WRITE_SYSREG64(n->arch.ttbr1, TTBR1_EL1);
 
     /*
-     * Erratum #852523: DACR32_EL2 must be restored before one of the
+     * Erratum #852523 (Cortex-A57) or erratum #853709 (Cortex-A72):
+     * DACR32_EL2 must be restored before one of the
      * following sysregs: SCTLR_EL1, TCR_EL1, TTBR0_EL1, TTBR1_EL1 or
      * CONTEXTIDR_EL1.
      */
@@ -245,7 +246,8 @@
 
     /*
      * This write to sysreg CONTEXTIDR_EL1 ensures we don't hit erratum
-     * #852523. I.e DACR32_EL2 is not correctly synchronized.
+     * #852523 (Cortex-A57) or #853709 (Cortex-A72).
+     * I.e DACR32_EL2 is not correctly synchronized.
      */
     WRITE_SYSREG(n->arch.contextidr, CONTEXTIDR_EL1);
     WRITE_SYSREG(n->arch.tpidr_el0, TPIDR_EL0);
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/Kconfig xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/Kconfig
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/Kconfig	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/Kconfig	2021-06-17 20:45:39.000000000 +0200
@@ -186,6 +186,25 @@
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_843419
+	bool "Cortex-A53: 843419: A load or store might access an incorrect address"
+	default y
+	depends on ARM_64
+	help
+	  This option adds an alternative code sequence to work around ARM
+	  erratum 843419 on Cortex-A53 parts up to r0p4.
+
+	  When executing in AArch64 state, a load or store instruction which uses
+	  the result of an ADRP instruction as a base register, or which uses a
+	  base register written by an instruction immediately after an ADRP to the
+	  same register, might access an incorrect address.
+
+	  The workaround enables the linker to check if the affected sequence is
+	  produced and it will fix it with an alternative not affected sequence
+	  that produce the same behavior.
+
+	  If unsure, say Y.
+
 config ARM64_ERRATUM_832075
 	bool "Cortex-A57: 832075: possible deadlock on mixing exclusive memory accesses with device loads"
 	default y
@@ -223,6 +242,24 @@
 	  Please note that this does not necessarily enable the workaround,
 	  as it depends on the alternative framework, which will only patch
 	  the kernel if an affected CPU is detected.
+
+	  If unsure, say Y.
+
+config ARM_ERRATUM_858921
+	bool "Cortex-A73: 858921: Possible wrong read value for CNTVCT or CNTPCT"
+	default y
+	help
+	  This option adds an alternative code sequence to work around ARM
+	  erratum 858921 on Cortex-A73 (all versions).
+
+	  Affected Cortex-A73 might return wrong read value for CNTVCT or CNTPCT
+	  when the counter crosses a 32bit boundary.
+
+	  The workaround involves performing the read twice, and to return
+	  one or the other value depending on whether a transition has taken place.
+	  Please note that this does not necessarily enable the workaround,
+	  as it depends on the alternative framework, which will only patch
+	  the kernel if an affected CPU is detected.
 
 	  If unsure, say Y.
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/Makefile xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/Makefile
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/Makefile	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/Makefile	2021-06-17 20:45:39.000000000 +0200
@@ -101,6 +101,14 @@
 	$(call if_changed,ld)
 endif
 
+ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
+    ifeq ($(call ld-option, --fix-cortex-a53-843419),n)
+        $(warning ld does not support --fix-cortex-a53-843419; xen may be susceptible to erratum)
+    else
+        XEN_LDFLAGS += --fix-cortex-a53-843419
+    endif
+endif
+
 targets += prelink.o
 
 $(TARGET)-syms: prelink.o xen.lds
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/mm.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/mm.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/mm.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/mm.c	2021-06-17 20:45:39.000000000 +0200
@@ -59,7 +59,7 @@
     {                                       \
         dprintk(XENLOG_ERR, fmt, ## args);  \
         WARN();                             \
-    } while (0);
+    } while (0)
 #endif
 
 /*
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/setup.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/setup.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/setup.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/setup.c	2021-06-17 20:45:39.000000000 +0200
@@ -75,7 +75,6 @@
     /* Must be done past setting system_state. */
     unregister_init_virtual_region();
 
-    discard_initial_modules();
     free_init_memory();
     startup_cpu_idle_loop();
 }
@@ -779,7 +778,7 @@
     int cpus, i;
     const char *cmdline;
     struct bootmodule *xen_bootmodule;
-    struct domain *dom0;
+    struct domain *dom0, *d;
     struct xen_domctl_createdomain dom0_cfg = {
         .flags = XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap,
         .max_evtchn_port = -1,
@@ -962,6 +961,14 @@
     if ( construct_dom0(dom0) != 0)
         panic("Could not set up DOM0 guest OS\n");
 
+    create_domUs();
+
+    /*
+     * This needs to be called **before** heap_init_late() so modules
+     * will be scrubbed (unless suppressed).
+     */
+    discard_initial_modules();
+
     heap_init_late();
 
     init_trace_bufs();
@@ -975,9 +982,8 @@
 
     system_state = SYS_STATE_active;
 
-    create_domUs();
-
-    domain_unpause_by_systemcontroller(dom0);
+    for_each_domain( d )
+        domain_unpause_by_systemcontroller(d);
 
     /* Switch on to the dynamically allocated stack for the idle vcpu
      * since the static one we're running on is about to be freed. */
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/vgic.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/vgic.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/vgic.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/vgic.c	2021-06-17 20:45:39.000000000 +0200
@@ -423,6 +423,53 @@
     }
 }
 
+void vgic_set_irqs_pending(struct vcpu *v, uint32_t r, unsigned int rank)
+{
+    const unsigned long mask = r;
+    unsigned int i;
+    /* The first rank is always per-vCPU */
+    bool private = rank == 0;
+
+    /* LPIs will never be set pending via this function */
+    ASSERT(!is_lpi(32 * rank + 31));
+
+    for_each_set_bit( i, &mask, 32 )
+    {
+        unsigned int irq = i + 32 * rank;
+
+        if ( !private )
+        {
+            struct pending_irq *p = spi_to_pending(v->domain, irq);
+
+            /*
+             * When the domain sets the pending state for a HW interrupt on
+             * the virtual distributor, we set the pending state on the
+             * physical distributor.
+             *
+             * XXX: Investigate whether we would be able to set the
+             * physical interrupt active and save an interruption. (This
+             * is what the new vGIC does).
+             */
+            if ( p->desc != NULL )
+            {
+                unsigned long flags;
+
+                spin_lock_irqsave(&p->desc->lock, flags);
+                gic_set_pending_state(p->desc, true);
+                spin_unlock_irqrestore(&p->desc->lock, flags);
+                continue;
+            }
+        }
+
+        /*
+         * If the interrupt is per-vCPU, then we want to inject the vIRQ
+         * to v, otherwise we should let the function figuring out the
+         * correct vCPU.
+         */
+        vgic_inject_irq(v->domain, private ? v : NULL, irq, true);
+    }
+}
+
 bool vgic_to_sgi(struct vcpu *v, register_t sgir, enum gic_sgi_mode irqmode,
                  int virq, const struct sgi_target *target)
 {
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/vgic-v2.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/vgic-v2.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/vgic-v2.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/vgic-v2.c	2021-06-17 20:45:39.000000000 +0200
@@ -472,10 +472,12 @@
 
     case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
-        printk(XENLOG_G_ERR
-               "%pv: vGICD: unhandled word write %#"PRIregister" to ISPENDR%d\n",
-               v, r, gicd_reg - GICD_ISPENDR);
-        return 0;
+        rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ISPENDR, DABT_WORD);
+        if ( rank == NULL ) goto write_ignore;
+
+        vgic_set_irqs_pending(v, r, rank->index);
+
+        return 1;
 
     case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/vgic-v3.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/vgic-v3.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/vgic-v3.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/vgic-v3.c	2021-06-17 20:45:39.000000000 +0200
@@ -808,10 +808,12 @@
 
     case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
-        printk(XENLOG_G_ERR
-               "%pv: %s: unhandled word write %#"PRIregister" to ISPENDR%d\n",
-               v, name, r, reg - GICD_ISPENDR);
-        return 0;
+        rank = vgic_rank_offset(v, 1, reg - GICD_ISPENDR, DABT_WORD);
+        if ( rank == NULL ) goto write_ignore;
+
+        vgic_set_irqs_pending(v, r, rank->index);
+
+        return 1;
 
     case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
@@ -975,6 +977,7 @@
     case VREG32(GICR_ICACTIVER0):
     case VREG32(GICR_ICFGR1):
     case VRANGE32(GICR_IPRIORITYR0, GICR_IPRIORITYR7):
+    case VREG32(GICR_ISPENDR0):
          /*
           * Above registers offset are common with GICD.
           * So handle common with GICD handling
@@ -982,13 +985,6 @@
         return __vgic_v3_distr_common_mmio_write("vGICR: SGI", v,
                                                  info, gicr_reg, r);
 
-    case VREG32(GICR_ISPENDR0):
-        if ( dabt.size != DABT_WORD ) goto bad_width;
-        printk(XENLOG_G_ERR
-               "%pv: vGICR: SGI: unhandled word write %#"PRIregister" to ISPENDR0\n",
-               v, r);
-        return 0;
-
     case VREG32(GICR_ICPENDR0):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/vtimer.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/vtimer.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/arm/vtimer.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/arm/vtimer.c	2021-06-17 20:45:39.000000000 +0200
@@ -62,7 +62,7 @@
 
 int domain_vtimer_init(struct domain *d, struct xen_arch_domainconfig *config)
 {
-    d->arch.virt_timer_base.offset = READ_SYSREG64(CNTPCT_EL0);
+    d->arch.virt_timer_base.offset = get_cycles();
     d->time_offset.seconds = ticks_to_ns(d->arch.virt_timer_base.offset - boot_count);
     do_div(d->time_offset.seconds, 1000000000);
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/acpi/cpu_idle.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/acpi/cpu_idle.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/acpi/cpu_idle.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/acpi/cpu_idle.c	2021-06-17 20:45:39.000000000 +0200
@@ -181,8 +181,13 @@
     case 0x55:
     case 0x5E:
     /* Ice Lake */
+    case 0x6A:
+    case 0x6C:
     case 0x7D:
     case 0x7E:
+    /* Tiger Lake */
+    case 0x8C:
+    case 0x8D:
     /* Kaby Lake */
     case 0x8E:
     case 0x9E:
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/acpi/power.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/acpi/power.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/acpi/power.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/acpi/power.c	2021-06-17 20:45:39.000000000 +0200
@@ -286,6 +286,8 @@
 
     microcode_update_one();
 
+    tsx_init(); /* Needs microcode.  May change HLE/RTM feature bits. */
+
     if ( !recheck_cpu_features(0) )
         panic("Missing previously available feature(s)\n");
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/apic.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/apic.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/apic.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/apic.c	2021-06-17 20:45:39.000000000 +0200
@@ -46,7 +46,7 @@
 static bool __initdata tdt_enable = true;
 boolean_param("tdt", tdt_enable);
 
-static bool __read_mostly iommu_x2apic_enabled;
+bool __read_mostly iommu_x2apic_enabled;
 
 static struct {
     int active;
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/cpu/intel.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/cpu/intel.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/cpu/intel.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/cpu/intel.c	2021-06-17 20:45:39.000000000 +0200
@@ -356,9 +356,6 @@
 	    (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47))
 		__set_bit(X86_FEATURE_CLFLUSH_MONITOR, c->x86_capability);
 
-	if (cpu_has_tsx_force_abort && opt_rtm_abort)
-		wrmsrl(MSR_TSX_FORCE_ABORT, TSX_FORCE_ABORT_RTM);
-
 	probe_c3_errata(c);
 }
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/cpu/microcode/amd.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/cpu/microcode/amd.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/cpu/microcode/amd.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/cpu/microcode/amd.c	2021-06-17 20:45:39.000000000 +0200
@@ -111,7 +111,7 @@
 #define F15H_MPB_MAX_SIZE 4096
 #define F16H_MPB_MAX_SIZE 3458
 #define F17H_MPB_MAX_SIZE 3200
-#define F19H_MPB_MAX_SIZE 4800
+#define F19H_MPB_MAX_SIZE 5568
 
     switch (boot_cpu_data.x86)
     {
@@ -346,6 +346,7 @@
             if ( size < sizeof(*mc) ||
                  (mc = buf)->type != UCODE_UCODE_TYPE ||
                  size - sizeof(*mc) < mc->len ||
+                 mc->len < sizeof(struct microcode_patch) ||
                  (!skip_ucode && !verify_patch_size(mc->len)) )
             {
                 printk(XENLOG_ERR "microcode: Bad microcode data\n");
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/cpu/vpmu.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/cpu/vpmu.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/cpu/vpmu.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/cpu/vpmu.c	2021-06-17 20:45:39.000000000 +0200
@@ -47,7 +47,6 @@
 static unsigned int __read_mostly opt_vpmu_enabled;
 unsigned int __read_mostly vpmu_mode = XENPMU_MODE_OFF;
 unsigned int __read_mostly vpmu_features = 0;
-bool __read_mostly opt_rtm_abort;
 
 static DEFINE_SPINLOCK(vpmu_lock);
 static unsigned vpmu_count;
@@ -77,7 +76,8 @@
         else if ( !cmdline_strcmp(s, "arch") )
             vpmu_features |= XENPMU_FEATURE_ARCH_ONLY;
         else if ( (val = parse_boolean("rtm-abort", s, ss)) >= 0 )
-            opt_rtm_abort = val;
+            printk(XENLOG_WARNING
+                   "'rtm-abort=<bool>' superseded.  Use 'tsx=<bool>' instead\n");
         else
             rc = -EINVAL;
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/cpuid.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/cpuid.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/cpuid.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/cpuid.c	2021-06-17 20:45:39.000000000 +0200
@@ -357,6 +357,16 @@
          boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x3a &&
          cpu_has_rdrand && !is_forced_cpu_cap(X86_FEATURE_RDRAND) )
         __clear_bit(X86_FEATURE_RDRAND, fs);
+
+    /*
+     * On certain hardware, speculative or errata workarounds can result in
+     * TSX being placed in "force-abort" mode, where it doesn't actually
+     * function as expected, but is technically compatible with the ISA.
+     *
+     * Do not advertise RTM to guests by default if it won't actually work.
+     */
+    if ( rtm_disabled )
+        __clear_bit(X86_FEATURE_RTM, fs);
 }
 
 static void __init guest_common_feature_adjustments(uint32_t *fs)
@@ -628,20 +638,6 @@
     if ( cpu_has_itsc && (d->disable_migrate || d->arch.vtsc) )
         __set_bit(X86_FEATURE_ITSC, max_fs);
 
-    /*
-     * On hardware with MSR_TSX_CTRL, the admin may have elected to disable
-     * TSX and hide the feature bits.  Migrating-in VMs may have been booted
-     * pre-mitigation when the TSX features were visbile.
-     *
-     * This situation is compatible (albeit with a perf hit to any TSX code in
-     * the guest), so allow the feature bits to remain set.
-     */
-    if ( cpu_has_tsx_ctrl )
-    {
-        __set_bit(X86_FEATURE_HLE, max_fs);
-        __set_bit(X86_FEATURE_RTM, max_fs);
-    }
-
     /* Clamp the toolstacks choices to reality. */
     for ( i = 0; i < ARRAY_SIZE(fs); i++ )
         fs[i] &= max_fs[i];
@@ -652,9 +648,11 @@
     sanitise_featureset(fs);
 
     /* Fold host's FDP_EXCP_ONLY and NO_FPU_SEL into guest's view. */
-    fs[FEATURESET_7b0] &= ~special_features[FEATURESET_7b0];
+    fs[FEATURESET_7b0] &= ~(cpufeat_mask(X86_FEATURE_FDP_EXCP_ONLY) |
+                            cpufeat_mask(X86_FEATURE_NO_FPU_SEL));
     fs[FEATURESET_7b0] |= (host_cpuid_policy.feat._7b0 &
-                           special_features[FEATURESET_7b0]);
+                           (cpufeat_mask(X86_FEATURE_FDP_EXCP_ONLY) |
+                            cpufeat_mask(X86_FEATURE_NO_FPU_SEL)));
 
     cpuid_featureset_to_policy(fs, p);
 
@@ -724,7 +722,7 @@
      * so dom0 can turn off workarounds as appropriate.  Temporary, until the
      * domain policy logic gains a better understanding of MSRs.
      */
-    if ( is_hardware_domain(d) && boot_cpu_has(X86_FEATURE_ARCH_CAPS) )
+    if ( is_hardware_domain(d) && cpu_has_arch_caps )
         p->feat.arch_caps = true;
 
     d->arch.cpuid = p;
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/debug.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/debug.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/debug.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/debug.c	2021-06-17 20:45:39.000000000 +0200
@@ -112,10 +112,11 @@
                                      void * __user buf, unsigned int len,
                                      bool toaddr, uint64_t pgd3)
 {
+    unsigned long addr = (unsigned long)gaddr;
+
     while ( len > 0 )
     {
         char *va;
-        unsigned long addr = (unsigned long)gaddr;
         mfn_t mfn;
         gfn_t gfn = INVALID_GFN;
         unsigned long pagecnt;
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hpet.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hpet.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hpet.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hpet.c	2021-06-17 20:45:39.000000000 +0200
@@ -52,6 +52,8 @@
 DEFINE_PER_CPU(struct hpet_event_channel *, cpu_bc_channel);
 
 unsigned long __initdata hpet_address;
+int8_t __initdata opt_hpet_legacy_replacement = -1;
+static bool __initdata opt_hpet = true;
 u8 __initdata hpet_blockid;
 u8 __initdata hpet_flags;
 
@@ -63,6 +65,32 @@
 static bool __initdata force_hpet_broadcast;
 boolean_param("hpetbroadcast", force_hpet_broadcast);
 
+static int __init parse_hpet_param(const char *s)
+{
+    const char *ss;
+    int val, rc = 0;
+
+    do {
+        ss = strchr(s, ',');
+        if ( !ss )
+            ss = strchr(s, '\0');
+
+        if ( (val = parse_bool(s, ss)) >= 0 )
+            opt_hpet = val;
+        else if ( (val = parse_boolean("broadcast", s, ss)) >= 0 )
+            force_hpet_broadcast = val;
+        else if ( (val = parse_boolean("legacy-replacement", s, ss)) >= 0 )
+            opt_hpet_legacy_replacement = val;
+        else
+            rc = -EINVAL;
+
+        s = ss + 1;
+    } while ( *ss );
+
+    return rc;
+}
+custom_param("hpet", parse_hpet_param);
+
 /*
  * Calculate a multiplication factor for scaled math, which is used to convert
  * nanoseconds based values to clock ticks:
@@ -764,19 +792,100 @@
 }
 
 static u32 *hpet_boot_cfg;
+static uint64_t __initdata hpet_rate;
+static __initdata struct {
+    uint32_t cmp, cfg;
+} pre_legacy_c0;
+
+bool __init hpet_enable_legacy_replacement_mode(void)
+{
+    unsigned int cfg, c0_cfg, ticks, count;
+
+    if ( !hpet_rate ||
+         !(hpet_read32(HPET_ID) & HPET_ID_LEGSUP) ||
+         ((cfg = hpet_read32(HPET_CFG)) & HPET_CFG_LEGACY) )
+        return false;
+
+    /* Stop the main counter. */
+    hpet_write32(cfg & ~HPET_CFG_ENABLE, HPET_CFG);
+
+    /* Stash channel 0's old CFG/CMP incase we need to undo. */
+    pre_legacy_c0.cfg = c0_cfg = hpet_read32(HPET_Tn_CFG(0));
+    pre_legacy_c0.cmp = hpet_read32(HPET_Tn_CMP(0));
+
+    /* Reconfigure channel 0 to be 32bit periodic. */
+    c0_cfg |= (HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
+               HPET_TN_32BIT);
+    hpet_write32(c0_cfg, HPET_Tn_CFG(0));
+
+    /*
+     * The exact period doesn't have to match a legacy PIT.  All we need
+     * is an interrupt queued up via the IO-APIC to check routing.
+     *
+     * Use HZ as the frequency.
+     */
+    ticks = ((SECONDS(1) / HZ) * div_sc(hpet_rate, SECONDS(1), 32)) >> 32;
+
+    count = hpet_read32(HPET_COUNTER);
+
+    /*
+     * HPET_TN_SETVAL above is atrociously documented in the spec.
+     *
+     * Periodic HPET channels have a main comparator register, and
+     * separate "accumulator" register.  Despite being named accumulator
+     * in the spec, this is not an accurate description of its behaviour
+     * or purpose.
+     *
+     * Each time an interrupt is generated, the "accumulator" register is
+     * re-added to the comparator set up the new period.
+     *
+     * Normally, writes to the CMP register update both registers.
+     * However, under these semantics, it is impossible to set up a
+     * periodic timer correctly without the main HPET counter being at 0.
+     *
+     * Instead, HPET_TN_SETVAL is a self-clearing control bit which we can
+     * use for periodic timers to mean that the second write to CMP
+     * updates the accumulator only, and not the absolute comparator
+     * value.
+     *
+     * This lets us set a period when the main counter isn't at 0.
+     */
+    hpet_write32(count + ticks, HPET_Tn_CMP(0));
+    hpet_write32(ticks,         HPET_Tn_CMP(0));
+
+    /* Restart the main counter, and legacy mode. */
+    hpet_write32(cfg | HPET_CFG_ENABLE | HPET_CFG_LEGACY, HPET_CFG);
+
+    return true;
+}
+
+void __init hpet_disable_legacy_replacement_mode(void)
+{
+    unsigned int cfg = hpet_read32(HPET_CFG);
+
+    ASSERT(hpet_rate);
+
+    cfg &= ~(HPET_CFG_LEGACY | HPET_CFG_ENABLE);
+
+    /* Stop the main counter and disable legacy mode. */
+    hpet_write32(cfg, HPET_CFG);
+
+    /* Restore pre-Legacy Replacement Mode settings. */
+    hpet_write32(pre_legacy_c0.cfg, HPET_Tn_CFG(0));
+    hpet_write32(pre_legacy_c0.cmp, HPET_Tn_CMP(0));
+
+    /* Restart the main counter. */
+    hpet_write32(cfg | HPET_CFG_ENABLE, HPET_CFG);
+}
 
 u64 __init hpet_setup(void)
 {
-    static u64 __initdata hpet_rate;
-    u32 hpet_id, hpet_period;
+    unsigned int hpet_id, hpet_period;
     unsigned int last, rem;
 
-    if ( hpet_rate )
+    if ( hpet_rate || !hpet_address || !opt_hpet )
         return hpet_rate;
 
-    if ( hpet_address == 0 )
-        return 0;
-
     set_fixmap_nocache(FIX_HPET_BASE, hpet_address);
 
     hpet_id = hpet_read32(HPET_ID);
@@ -803,6 +912,9 @@
     if ( (rem * 2) > hpet_period )
         hpet_rate++;
 
+    if ( opt_hpet_legacy_replacement > 0 )
+        hpet_enable_legacy_replacement_mode();
+
     return hpet_rate;
 }
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/dm.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/dm.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/dm.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/dm.c	2021-06-17 20:45:39.000000000 +0200
@@ -370,6 +370,7 @@
     if ( rc )
         return rc;
 
+    rc = -EINVAL;
     if ( !is_hvm_domain(d) )
         goto out;
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/hpet.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/hpet.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/hpet.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/hpet.c	2021-06-17 20:45:39.000000000 +0200
@@ -22,6 +22,7 @@
 #include <asm/hvm/trace.h>
 #include <asm/current.h>
 #include <asm/hpet.h>
+#include <asm/mc146818rtc.h>
 #include <xen/sched.h>
 #include <xen/event.h>
 #include <xen/trace.h>
@@ -290,7 +291,7 @@
         /* if LegacyReplacementRoute bit is set, HPET specification requires
            timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
            timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC. */
-        irq = (tn == 0) ? 0 : 8;
+        irq = (tn == 0) ? 0 : RTC_IRQ;
         h->pt[tn].source = PTSRC_isa;
     }
     else
@@ -318,7 +319,8 @@
                          hpet_tick_to_ns(h, diff),
                          oneshot ? 0 : hpet_tick_to_ns(h, h->hpet.period[tn]),
                          irq, timer_level(h, tn) ? hpet_timer_fired : NULL,
-                         (void *)(unsigned long)tn, timer_level(h, tn));
+                         timer_level(h, tn) ? (void *)(unsigned long)tn : NULL,
+                         timer_level(h, tn));
 }
 
 static inline uint64_t hpet_fixup_reg(
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/hvm.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/hvm.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/hvm.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/hvm.c	2021-06-17 20:45:39.000000000 +0200
@@ -714,15 +714,15 @@
  fail1:
     if ( is_hardware_domain(d) )
         xfree(d->arch.hvm.io_bitmap);
-    XFREE(d->arch.hvm.io_handler);
     XFREE(d->arch.hvm.params);
-    XFREE(d->arch.hvm.pl_time);
     XFREE(d->arch.hvm.irq);
  fail0:
     hvm_destroy_cacheattr_region_list(d);
     destroy_perdomain_mapping(d, PERDOMAIN_VIRT_START, 0);
  fail:
     hvm_domain_relinquish_resources(d);
+    XFREE(d->arch.hvm.io_handler);
+    XFREE(d->arch.hvm.pl_time);
     return rc;
 }
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/vioapic.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/vioapic.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/vioapic.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/vioapic.c	2021-06-17 20:45:39.000000000 +0200
@@ -544,7 +544,7 @@
             }
 
             if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
-                 !ent->fields.mask &&
+                 !ent->fields.mask && !ent->fields.remote_irr &&
                  hvm_irq->gsi_assert_count[vioapic->base_gsi + pin] )
             {
                 ent->fields.remote_irr = 1;
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/vmx/vmx.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/vmx/vmx.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/vmx/vmx.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/vmx/vmx.c	2021-06-17 20:45:39.000000000 +0200
@@ -2397,7 +2397,7 @@
     if ( cpu_has_hypervisor )
         return false;
 
-    if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) )
+    if ( cpu_has_arch_caps )
         rdmsrl(MSR_ARCH_CAPABILITIES, caps);
 
     if ( caps & ARCH_CAPS_IF_PSCHANGE_MC_NO )
@@ -2722,14 +2722,16 @@
 }, nh_lbr[] = {
     { MSR_IA32_LASTINTFROMIP,       1 },
     { MSR_IA32_LASTINTTOIP,         1 },
-    { MSR_C2_LASTBRANCH_TOS,        1 },
+    { MSR_NHL_LBR_SELECT,           1 },
+    { MSR_NHL_LASTBRANCH_TOS,       1 },
     { MSR_P4_LASTBRANCH_0_FROM_LIP, NUM_MSR_P4_LASTBRANCH_FROM_TO },
     { MSR_P4_LASTBRANCH_0_TO_LIP,   NUM_MSR_P4_LASTBRANCH_FROM_TO },
     { 0, 0 }
 }, sk_lbr[] = {
     { MSR_IA32_LASTINTFROMIP,       1 },
     { MSR_IA32_LASTINTTOIP,         1 },
-    { MSR_SKL_LASTBRANCH_TOS,       1 },
+    { MSR_NHL_LBR_SELECT,           1 },
+    { MSR_NHL_LASTBRANCH_TOS,       1 },
     { MSR_SKL_LASTBRANCH_0_FROM_IP, NUM_MSR_SKL_LASTBRANCH },
     { MSR_SKL_LASTBRANCH_0_TO_IP,   NUM_MSR_SKL_LASTBRANCH },
     { MSR_SKL_LASTBRANCH_0_INFO,    NUM_MSR_SKL_LASTBRANCH },
@@ -2741,10 +2743,19 @@
     { MSR_C2_LASTBRANCH_0_FROM_IP,  NUM_MSR_ATOM_LASTBRANCH_FROM_TO },
     { MSR_C2_LASTBRANCH_0_TO_IP,    NUM_MSR_ATOM_LASTBRANCH_FROM_TO },
     { 0, 0 }
+}, sm_lbr[] = {
+    { MSR_IA32_LASTINTFROMIP,       1 },
+    { MSR_IA32_LASTINTTOIP,         1 },
+    { MSR_SM_LBR_SELECT,            1 },
+    { MSR_SM_LASTBRANCH_TOS,        1 },
+    { MSR_C2_LASTBRANCH_0_FROM_IP,  NUM_MSR_ATOM_LASTBRANCH_FROM_TO },
+    { MSR_C2_LASTBRANCH_0_TO_IP,    NUM_MSR_ATOM_LASTBRANCH_FROM_TO },
+    { 0, 0 }
 }, gm_lbr[] = {
     { MSR_IA32_LASTINTFROMIP,       1 },
     { MSR_IA32_LASTINTTOIP,         1 },
-    { MSR_GM_LASTBRANCH_TOS,        1 },
+    { MSR_SM_LBR_SELECT,            1 },
+    { MSR_SM_LASTBRANCH_TOS,        1 },
     { MSR_GM_LASTBRANCH_0_FROM_IP,  NUM_MSR_GM_LASTBRANCH_FROM_TO },
     { MSR_GM_LASTBRANCH_0_TO_IP,    NUM_MSR_GM_LASTBRANCH_FROM_TO },
     { 0, 0 }
@@ -2786,7 +2797,9 @@
         /* Goldmont Plus */
         case 0x7a:
         /* Ice Lake */
-        case 0x7d: case 0x7e:
+        case 0x6a: case 0x6c: case 0x7d: case 0x7e:
+        /* Tiger Lake */
+        case 0x8c: case 0x8d:
         /* Tremont */
         case 0x86:
         /* Kaby Lake */
@@ -2796,6 +2809,7 @@
             return sk_lbr;
         /* Atom */
         case 0x1c: case 0x26: case 0x27: case 0x35: case 0x36:
+            return at_lbr;
         /* Silvermont */
         case 0x37: case 0x4a: case 0x4d: case 0x5a: case 0x5d:
         /* Xeon Phi Knights Landing */
@@ -2804,7 +2818,7 @@
         case 0x85:
         /* Airmont */
         case 0x4c:
-            return at_lbr;
+            return sm_lbr;
         /* Goldmont */
         case 0x5c: case 0x5f:
             return gm_lbr;
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/vpt.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/vpt.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/hvm/vpt.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/hvm/vpt.c	2021-06-17 20:45:39.000000000 +0200
@@ -153,32 +153,43 @@
     return 1;
 }
 
+/*
+ * Functions which read (maybe write) all periodic_time instances
+ * attached to a particular vCPU use pt_vcpu_{un}lock locking helpers.
+ *
+ * Such users are explicitly forbidden from changing the value of the
+ * pt->vcpu field, because another thread holding the pt_migrate lock
+ * may already be spinning waiting for your vcpu lock.
+ */
 static void pt_vcpu_lock(struct vcpu *v)
 {
-    read_lock(&v->domain->arch.hvm.pl_time->pt_migrate);
     spin_lock(&v->arch.hvm.tm_lock);
 }
 
 static void pt_vcpu_unlock(struct vcpu *v)
 {
     spin_unlock(&v->arch.hvm.tm_lock);
-    read_unlock(&v->domain->arch.hvm.pl_time->pt_migrate);
 }
 
+/*
+ * Functions which want to modify a particular periodic_time object
+ * use pt_{un}lock locking helpers.
+ *
+ * These users lock whichever vCPU the periodic_time is attached to,
+ * but since the vCPU could be modified without holding any lock, they
+ * need to take an additional lock that protects against pt->vcpu
+ * changing.
+ */
 static void pt_lock(struct periodic_time *pt)
 {
-    /*
-     * We cannot use pt_vcpu_lock here, because we need to acquire the
-     * per-domain lock first and then (re-)fetch the value of pt->vcpu, or
-     * else we might be using a stale value of pt->vcpu.
-     */
     read_lock(&pt->vcpu->domain->arch.hvm.pl_time->pt_migrate);
     spin_lock(&pt->vcpu->arch.hvm.tm_lock);
 }
 
 static void pt_unlock(struct periodic_time *pt)
 {
-    pt_vcpu_unlock(pt->vcpu);
+    spin_unlock(&pt->vcpu->arch.hvm.tm_lock);
+    read_unlock(&pt->vcpu->domain->arch.hvm.pl_time->pt_migrate);
 }
 
 static void pt_process_missed_ticks(struct periodic_time *pt)
@@ -543,8 +554,10 @@
     pt->cb = cb;
     pt->priv = data;
 
+    pt_vcpu_lock(v);
     pt->on_list = 1;
     list_add(&pt->list, &v->arch.hvm.tm_list);
+    pt_vcpu_unlock(v);
 
     init_timer(&pt->timer, pt_timer_fn, pt, v->processor);
     set_timer(&pt->timer, pt->scheduled);
@@ -580,13 +593,26 @@
         return;
 
     write_lock(&pt->vcpu->domain->arch.hvm.pl_time->pt_migrate);
+
+    if ( pt->vcpu == v )
+        goto out;
+
+    pt_vcpu_lock(pt->vcpu);
+    if ( pt->on_list )
+        list_del(&pt->list);
+    pt_vcpu_unlock(pt->vcpu);
+
     pt->vcpu = v;
+
+    pt_vcpu_lock(v);
     if ( pt->on_list )
     {
-        list_del(&pt->list);
         list_add(&pt->list, &v->arch.hvm.tm_list);
         migrate_timer(&pt->timer, v->processor);
     }
+    pt_vcpu_unlock(v);
+
+ out:
     write_unlock(&pt->vcpu->domain->arch.hvm.pl_time->pt_migrate);
 }
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/io_apic.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/io_apic.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/io_apic.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/io_apic.c	2021-06-17 20:45:39.000000000 +0200
@@ -29,6 +29,8 @@
 #include <xen/acpi.h>
 #include <xen/keyhandler.h>
 #include <xen/softirq.h>
+
+#include <asm/hpet.h>
 #include <asm/mc146818rtc.h>
 #include <asm/smp.h>
 #include <asm/desc.h>
@@ -1930,6 +1932,35 @@
             local_irq_restore(flags);
             return;
         }
+
+        /*
+         * Intel chipsets from Skylake/ApolloLake onwards can statically clock
+         * gate the 8254 PIT.  This option is enabled by default in slightly
+         * later systems, as turning the PIT off is a prerequisite to entering
+         * the C11 power saving state.
+         *
+         * Xen currently depends on the legacy timer interrupt being active
+         * while IRQ routing is configured.
+         *
+         * If the user hasn't made an explicit choice, attempt to reconfigure
+         * the HPET into legacy mode to re-establish the timer interrupt.
+         */
+        if ( opt_hpet_legacy_replacement < 0 &&
+             hpet_enable_legacy_replacement_mode() )
+        {
+            printk(XENLOG_ERR "..no 8254 timer found - trying HPET Legacy Replacement Mode\n");
+
+            if ( timer_irq_works() )
+            {
+                local_irq_restore(flags);
+                return;
+            }
+
+            /* Legacy Replacement mode hasn't helped.  Undo it. */
+            printk(XENLOG_ERR "..no HPET timer found - reverting Legacy Replacement Mode\n");
+            hpet_disable_legacy_replacement_mode();
+        }
+
         clear_IO_APIC_pin(apic1, pin1);
         printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to "
                "IO-APIC\n");
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/Makefile xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/Makefile
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/Makefile	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/Makefile	2021-06-17 20:45:39.000000000 +0200
@@ -176,8 +176,13 @@
 # Check if the compiler supports the MS ABI.
 export XEN_BUILD_EFI := $(shell $(CC) $(XEN_CFLAGS) -c efi/check.c -o efi/check.o 2>/dev/null && echo y)
 # Check if the linker supports PE.
-XEN_BUILD_PE := $(if $(XEN_BUILD_EFI),$(shell $(LD) -mi386pep --subsystem=10 -o efi/check.efi efi/check.o 2>/dev/null && echo y))
+XEN_BUILD_PE := $(if $(XEN_BUILD_EFI),$(shell $(LD) $(call EFI_LDFLAGS,0x100000000) -o efi/check.efi efi/check.o 2>/dev/null && echo y))
 CFLAGS-$(XEN_BUILD_EFI) += -DXEN_BUILD_EFI
+# Check if the linker produces fixups in PE by default (we need to disable it doing so for now).
+XEN_NO_PE_FIXUPS := $(if $(XEN_BUILD_EFI), \
+                         $(shell $(LD) $(call EFI_LDFLAGS,0x100000000) --disable-reloc-section -o efi/check.efi efi/check.o 2>/dev/null && \
+                                 echo --disable-reloc-section))
+EFI_LDFLAGS += $(XEN_NO_PE_FIXUPS)
 
 $(TARGET).efi: VIRT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A VIRT_START$$,,p')
 $(TARGET).efi: ALT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A ALT_START$$,,p')
@@ -266,5 +271,5 @@
 # Suppress loading of DEPS files for internal, temporary target files.  This
 # then also suppresses re-generation of the respective .*.d2 files.
 ifeq ($(filter-out .xen%.o,$(notdir $(MAKECMDGOALS))),)
-DEPS:=
+DEPS_INCLUDE:=
 endif
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/mm/shadow/multi.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/mm/shadow/multi.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/mm/shadow/multi.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/mm/shadow/multi.c	2021-06-17 20:45:39.000000000 +0200
@@ -530,7 +530,8 @@
     {
         /* Guest l1e maps emulated MMIO space */
         *sp = sh_l1e_mmio(target_gfn, gflags);
-        d->arch.paging.shadow.has_fast_mmio_entries = true;
+        if ( sh_l1e_is_magic(*sp) )
+            d->arch.paging.shadow.has_fast_mmio_entries = true;
         goto done;
     }
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/mm/shadow/types.h xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/mm/shadow/types.h
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/mm/shadow/types.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/mm/shadow/types.h	2021-06-17 20:45:39.000000000 +0200
@@ -290,24 +290,41 @@
  * pagetables.
  *
  * This is only feasible for PAE and 64bit Xen: 32-bit non-PAE PTEs don't
- * have reserved bits that we can use for this.
+ * have reserved bits that we can use for this.  And even there it can only
+ * be used if we can be certain the processor doesn't use all 52 address bits.
  */
 
 #define SH_L1E_MAGIC 0xffffffff00000001ULL
+
+static inline bool sh_have_pte_rsvd_bits(void)
+{
+    return paddr_bits < PADDR_BITS && !cpu_has_hypervisor;
+}
+
 static inline bool sh_l1e_is_magic(shadow_l1e_t sl1e)
 {
     return (sl1e.l1 & SH_L1E_MAGIC) == SH_L1E_MAGIC;
 }
 
 /* Guest not present: a single magic value */
-static inline shadow_l1e_t sh_l1e_gnp(void)
+static inline shadow_l1e_t sh_l1e_gnp_raw(void)
 {
     return (shadow_l1e_t){ -1ULL };
 }
 
+static inline shadow_l1e_t sh_l1e_gnp(void)
+{
+    /*
+     * On systems with no reserved physical address bits we can't engage the
+     * fast fault path.
+     */
+    return sh_have_pte_rsvd_bits() ? sh_l1e_gnp_raw()
+                                   : shadow_l1e_empty();
+}
+
 static inline bool sh_l1e_is_gnp(shadow_l1e_t sl1e)
 {
-    return sl1e.l1 == sh_l1e_gnp().l1;
+    return sl1e.l1 == sh_l1e_gnp_raw().l1;
 }
 
 /*
@@ -322,9 +339,14 @@
 
 static inline shadow_l1e_t sh_l1e_mmio(gfn_t gfn, u32 gflags)
 {
-    return (shadow_l1e_t) { (SH_L1E_MMIO_MAGIC
-                             | MASK_INSR(gfn_x(gfn), SH_L1E_MMIO_GFN_MASK)
-                             | (gflags & (_PAGE_USER|_PAGE_RW))) };
+    unsigned long gfn_val = MASK_INSR(gfn_x(gfn), SH_L1E_MMIO_GFN_MASK);
+
+    if ( !sh_have_pte_rsvd_bits() ||
+         gfn_x(gfn) != MASK_EXTR(gfn_val, SH_L1E_MMIO_GFN_MASK) )
+        return shadow_l1e_empty();
+
+    return (shadow_l1e_t) { (SH_L1E_MMIO_MAGIC | gfn_val |
+                             (gflags & (_PAGE_USER | _PAGE_RW))) };
 }
 
 static inline bool sh_l1e_is_mmio(shadow_l1e_t sl1e)
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/msr.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/msr.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/msr.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/msr.c	2021-06-17 20:45:39.000000000 +0200
@@ -135,7 +135,7 @@
      * so dom0 can turn off workarounds as appropriate.  Temporary, until the
      * domain policy logic gains a better understanding of MSRs.
      */
-    if ( is_hardware_domain(d) && boot_cpu_has(X86_FEATURE_ARCH_CAPS) )
+    if ( is_hardware_domain(d) && cpu_has_arch_caps )
     {
         uint64_t val;
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/pv/emul-priv-op.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/pv/emul-priv-op.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/pv/emul-priv-op.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/pv/emul-priv-op.c	2021-06-17 20:45:39.000000000 +0200
@@ -138,6 +138,8 @@
     /* Runtime confirmation that we haven't clobbered an adjacent stub. */
     BUG_ON(STUB_BUF_SIZE / 2 < (p - ctxt->io_emul_stub));
 
+    block_speculation(); /* SCSB */
+
     /* Handy function-typed pointer to the stub. */
     return (void *)stub_va;
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/spec_ctrl.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/spec_ctrl.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/spec_ctrl.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/spec_ctrl.c	2021-06-17 20:45:39.000000000 +0200
@@ -885,7 +885,7 @@
     bool cpu_has_bug_taa;
     uint64_t caps = 0;
 
-    if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) )
+    if ( cpu_has_arch_caps )
         rdmsrl(MSR_ARCH_CAPABILITIES, caps);
 
     hw_smt_enabled = check_smt_enabled();
@@ -1158,9 +1158,6 @@
          ((hw_smt_enabled && opt_smt) ||
           !boot_cpu_has(X86_FEATURE_SC_VERW_IDLE)) )
     {
-        setup_clear_cpu_cap(X86_FEATURE_HLE);
-        setup_clear_cpu_cap(X86_FEATURE_RTM);
-
         opt_tsx = 0;
         tsx_init();
     }
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/string.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/string.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/string.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/string.c	2021-06-17 20:45:39.000000000 +0200
@@ -43,7 +43,8 @@
         return dest;
 
     if ( dest < src )
-        return memcpy(dest, src, n);
+        /* Depends on Xen's implementation operating forwards. */
+        return (memcpy)(dest, src, n);
 
     asm volatile (
         "   std         ; "
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/tsx.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/tsx.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/tsx.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/tsx.c	2021-06-17 20:45:39.000000000 +0200
@@ -6,7 +6,9 @@
  * Valid values:
  *   1 => Explicit tsx=1
  *   0 => Explicit tsx=0
- *  -1 => Default, implicit tsx=1, may change to 0 to mitigate TAA
+ *  -1 => Default, altered to 0/1 (if unspecified) by:
+ *                 - TAA heuristics/settings for speculative safety
+ *                 - "TSX vs PCR3" select for TSX memory ordering safety
  *  -3 => Implicit tsx=1 (feed-through from spec-ctrl=0)
  *
  * This is arranged such that the bottom bit encodes whether TSX is actually
@@ -15,6 +17,7 @@
  */
 int8_t __read_mostly opt_tsx = -1;
 int8_t __read_mostly cpu_has_tsx_ctrl = -1;
+bool __read_mostly rtm_disabled;
 
 static int __init parse_tsx(const char *s)
 {
@@ -33,36 +36,176 @@
 {
     /*
      * This function is first called between microcode being loaded, and CPUID
-     * being scanned generally.  Calculate from raw data whether MSR_TSX_CTRL
-     * is available.
+     * being scanned generally.  Read into boot_cpu_data.x86_capability[] for
+     * the cpu_has_* bits we care about using here.
      */
     if ( unlikely(cpu_has_tsx_ctrl < 0) )
     {
         uint64_t caps = 0;
 
-        if ( boot_cpu_data.cpuid_level >= 7 &&
-             (cpuid_count_edx(7, 0) & cpufeat_mask(X86_FEATURE_ARCH_CAPS)) )
+        if ( boot_cpu_data.cpuid_level >= 7 )
+            boot_cpu_data.x86_capability[cpufeat_word(X86_FEATURE_ARCH_CAPS)]
+                = cpuid_count_edx(7, 0);
+
+        if ( cpu_has_arch_caps )
             rdmsrl(MSR_ARCH_CAPABILITIES, caps);
 
         cpu_has_tsx_ctrl = !!(caps & ARCH_CAPS_TSX_CTRL);
+
+        if ( cpu_has_tsx_force_abort )
+        {
+            /*
+             * On an early TSX-enable Skylake part subject to the memory
+             * ordering erratum, with at least the March 2019 microcode.
+             */
+
+            /*
+             * Probe for the June 2021 microcode which de-features TSX on
+             * client parts.  (Note - this is a subset of parts impacted by
+             * the memory ordering errata.)
+             *
+             * RTM_ALWAYS_ABORT enumerates the new functionality, but is also
+             * read as zero if TSX_FORCE_ABORT.ENABLE_RTM has been set before
+             * we run.
+             *
+             * Undo this behaviour in Xen's view of the world.
+             */
+            bool has_rtm_always_abort = cpu_has_rtm_always_abort;
+
+            if ( !has_rtm_always_abort )
+            {
+                uint64_t val;
+
+                rdmsrl(MSR_TSX_FORCE_ABORT, val);
+
+                if ( val & TSX_ENABLE_RTM )
+                    has_rtm_always_abort = true;
+            }
+
+            /*
+             * Always force RTM_ALWAYS_ABORT, even if it currently visible.
+             * If the user explicitly opts to enable TSX, we'll set
+             * TSX_FORCE_ABORT.ENABLE_RTM and cause RTM_ALWAYS_ABORT to be
+             * hidden from the general CPUID scan later.
+             */
+            if ( has_rtm_always_abort )
+                setup_force_cpu_cap(X86_FEATURE_RTM_ALWAYS_ABORT);
+
+            /*
+             * If no explicit tsx= option is provided, pick a default.
+             *
+             * This deliberately overrides the implicit opt_tsx=-3 from
+             * `spec-ctrl=0` because:
+             * - parse_spec_ctrl() ran before any CPU details where know.
+             * - We now know we're running on a CPU not affected by TAA (as
+             *   TSX_FORCE_ABORT is enumerated).
+             * - When RTM_ALWAYS_ABORT is enumerated, TSX malfunctions, so we
+             *   only ever want it enabled by explicit user choice.
+             *
+             * Without RTM_ALWAYS_ABORT, leave TSX active.  In particular,
+             * this includes SKX where TSX is still supported.
+             *
+             * With RTM_ALWAYS_ABORT, disable TSX.
+             */
+            if ( opt_tsx < 0 )
+                opt_tsx = !cpu_has_rtm_always_abort;
+        }
+
+        /*
+         * The TSX features (HLE/RTM) are handled specially.  They both
+         * enumerate features but, on certain parts, have mechanisms to be
+         * hidden without disrupting running software.
+         *
+         * At the moment, we're running in an unknown context (WRT hiding -
+         * particularly if another fully fledged kernel ran before us) and
+         * depending on user settings, may elect to continue hiding them from
+         * native CPUID instructions.
+         *
+         * Xen doesn't use TSX itself, but use cpu_has_{hle,rtm} for various
+         * system reasons, mostly errata detection, so the meaning is more
+         * useful as "TSX infrastructure available", as opposed to "features
+         * advertised and working".
+         *
+         * Force the features to be visible in Xen's view if we see any of the
+         * infrastructure capable of hiding them.
+         */
+        if ( cpu_has_tsx_ctrl || cpu_has_tsx_force_abort )
+        {
+            setup_force_cpu_cap(X86_FEATURE_HLE);
+            setup_force_cpu_cap(X86_FEATURE_RTM);
+        }
     }
 
+    /*
+     * Note: MSR_TSX_CTRL is enumerated on TSX-enabled MDS_NO and later parts.
+     * MSR_TSX_FORCE_ABORT is enumerated on TSX-enabled pre-MDS_NO Skylake
+     * parts only.  The two features are on a disjoint set of CPUs, and not
+     * offered to guests by hypervisors.
+     */
     if ( cpu_has_tsx_ctrl )
     {
-        uint64_t val;
+        uint32_t hi, lo;
 
-        rdmsrl(MSR_TSX_CTRL, val);
+        rdmsr(MSR_TSX_CTRL, lo, hi);
 
-        val &= ~(TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR);
-        /* Check bottom bit only.  Higher bits are various sentinals. */
-        if ( !(opt_tsx & 1) )
-            val |= TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR;
+        /* Check bottom bit only.  Higher bits are various sentinels. */
+        rtm_disabled = !(opt_tsx & 1);
+
+        lo &= ~(TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR);
+        if ( rtm_disabled )
+            lo |= TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR;
+
+        wrmsr(MSR_TSX_CTRL, lo, hi);
+    }
+    else if ( cpu_has_tsx_force_abort )
+    {
+        /*
+         * On an early TSX-enable Skylake part subject to the memory ordering
+         * erratum, with at least the March 2019 microcode.
+         */
+        uint32_t hi, lo;
+
+        rdmsr(MSR_TSX_FORCE_ABORT, lo, hi);
+
+        /* Check bottom bit only.  Higher bits are various sentinels. */
+        rtm_disabled = !(opt_tsx & 1);
+
+        lo &= ~(TSX_FORCE_ABORT_RTM | TSX_CPUID_CLEAR | TSX_ENABLE_RTM);
+
+        if ( cpu_has_rtm_always_abort )
+        {
+            /*
+             * June 2021 microcode, on a client part with TSX de-featured:
+             *  - There are no mitigations for the TSX memory ordering errata.
+             *  - Performance counter 3 works.  (I.e. it isn't being used by
+             *    microcode to work around the memory ordering errata.)
+             *  - TSX_FORCE_ABORT.FORCE_ABORT_RTM is fixed read1/write-discard.
+             *  - TSX_FORCE_ABORT.TSX_CPUID_CLEAR can be used to hide the
+             *    HLE/RTM CPUID bits.
+             *  - TSX_FORCE_ABORT.ENABLE_RTM may be used to opt in to
+             *    re-enabling RTM, at the users own risk.
+             */
+            lo |= rtm_disabled ? TSX_CPUID_CLEAR : TSX_ENABLE_RTM;
+        }
+        else
+        {
+            /*
+             * Either a server part where TSX isn't de-featured, or pre-June
+             * 2021 microcode:
+             *  - By default, the TSX memory ordering errata is worked around
+             *    in microcode at the cost of Performance Counter 3.
+             *  - "Working TSX" vs "Working PCR3" can be selected by way of
+             *    setting TSX_FORCE_ABORT.FORCE_ABORT_RTM.
+             */
+            if ( rtm_disabled )
+                lo |= TSX_FORCE_ABORT_RTM;
+        }
 
-        wrmsrl(MSR_TSX_CTRL, val);
+        wrmsr(MSR_TSX_FORCE_ABORT, lo, hi);
     }
     else if ( opt_tsx >= 0 )
         printk_once(XENLOG_WARNING
-                    "MSR_TSX_CTRL not available - Ignoring tsx= setting\n");
+                    "TSX controls not available - Ignoring tsx= setting\n");
 }
 
 /*
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/x86_emulate/x86_emulate.c xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/x86_emulate/x86_emulate.c
--- xen-4.14.1+11-gb0b734a8b3/xen/arch/x86/x86_emulate/x86_emulate.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/arch/x86/x86_emulate/x86_emulate.c	2021-06-17 20:45:39.000000000 +0200
@@ -725,7 +725,7 @@
 #define copy_VEX(ptr, vex) ({ \
     if ( !mode_64bit() ) \
         (vex).reg |= 8; \
-    (ptr)[0 - PFX_BYTES] = ext < ext_8f08 ? 0xc4 : 0x8f; \
+    gcc11_wrap(ptr)[0 - PFX_BYTES] = ext < ext_8f08 ? 0xc4 : 0x8f; \
     (ptr)[1 - PFX_BYTES] = (vex).raw[0]; \
     (ptr)[2 - PFX_BYTES] = (vex).raw[1]; \
     container_of((ptr) + 1 - PFX_BYTES, typeof(vex), raw[0]); \
@@ -1256,6 +1256,7 @@
 # define invoke_stub(pre, post, constraints...) do {                    \
     stub_exn.info = (union stub_exception_token) { .raw = ~0 };         \
     stub_exn.line = __LINE__; /* Utility outweighs livepatching cost */ \
+    block_speculation(); /* SCSB */                                     \
     asm volatile ( pre "\n\tINDIRECT_CALL %[stub]\n\t" post "\n"        \
                    ".Lret%=:\n\t"                                       \
                    ".pushsection .fixup,\"ax\"\n"                       \
@@ -6124,6 +6125,10 @@
              (rc = ops->write_segment(x86_seg_ss, &sreg, ctxt)) )
             goto done;
 
+        if ( ctxt->lma )
+            /* In particular mode_64bit() needs to return true from here on. */
+            ctxt->addr_size = ctxt->sp_size = 64;
+
         /*
          * SYSCALL (unlike most instructions) evaluates its singlestep action
          * based on the resulting EFLAGS.TF, not the starting EFLAGS.TF.
@@ -6924,6 +6929,10 @@
                                       ctxt)) != X86EMUL_OKAY )
             goto done;
 
+        if ( ctxt->lma )
+            /* In particular mode_64bit() needs to return true from here on. */
+            ctxt->addr_size = ctxt->sp_size = 64;
+
         singlestep = _regs.eflags & X86_EFLAGS_TF;
         break;
 
@@ -12096,8 +12105,12 @@
     unsigned long orig_ip = ctxt->regs->r(ip);
     int rc;
 
+#ifdef __x86_64__
     if ( mode_64bit() )
         ASSERT(ctxt->lma);
+#else
+    ASSERT(!ctxt->lma && !mode_64bit());
+#endif
 
     rc = x86_emulate(ctxt, ops);
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/common/grant_table.c xen-4.14.2+25-gb6a8c4f72d/xen/common/grant_table.c
--- xen-4.14.1+11-gb0b734a8b3/xen/common/grant_table.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/common/grant_table.c	2021-06-17 20:45:39.000000000 +0200
@@ -836,9 +836,10 @@
         mask |= GTF_sub_page;
 
     /* If not already pinned, check the grant domid and type. */
-    if ( !act->pin && ((((scombo.flags & mask) != GTF_permit_access) &&
-                        ((scombo.flags & mask) != GTF_transitive)) ||
-                       (scombo.domid != ldomid)) )
+    if ( !act->pin &&
+         ((((scombo.flags & mask) != GTF_permit_access) &&
+           (mapflag || ((scombo.flags & mask) != GTF_transitive))) ||
+          (scombo.domid != ldomid)) )
         PIN_FAIL(done, GNTST_general_error,
                  "Bad flags (%x) or dom (%d); expected d%d, flags %x\n",
                  scombo.flags, scombo.domid, ldomid, mask);
@@ -864,7 +865,7 @@
     if ( !act->pin )
     {
         if ( (((scombo.flags & mask) != GTF_permit_access) &&
-              ((scombo.flags & mask) != GTF_transitive)) ||
+              (mapflag || ((scombo.flags & mask) != GTF_transitive))) ||
              (scombo.domid != ldomid) ||
              (!readonly && (scombo.flags & GTF_readonly)) )
         {
@@ -1206,7 +1207,14 @@
         goto undo_out;
     }
 
-    need_iommu = gnttab_need_iommu_mapping(ld);
+    /*
+     * This is deliberately not checking the page's owner: get_paged_frame()
+     * explicitly rejects foreign pages, and all success paths above yield
+     * either owner == rd or owner == dom_io (the dom_cow case is irrelevant
+     * as mem-sharing and IOMMU use are incompatible). The dom_io case would
+     * need checking separately if we compared against owner here.
+     */
+    need_iommu = ld != rd && gnttab_need_iommu_mapping(ld);
     if ( need_iommu )
     {
         unsigned int kind;
@@ -1470,7 +1478,8 @@
     if ( put_handle )
         put_maptrack_handle(lgt, op->handle);
 
-    if ( rc == GNTST_okay && gnttab_need_iommu_mapping(ld) )
+    /* See the respective comment in map_grant_ref(). */
+    if ( rc == GNTST_okay && ld != rd && gnttab_need_iommu_mapping(ld) )
     {
         unsigned int kind;
         int err = 0;
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/common/page_alloc.c xen-4.14.2+25-gb6a8c4f72d/xen/common/page_alloc.c
--- xen-4.14.1+11-gb0b734a8b3/xen/common/page_alloc.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/common/page_alloc.c	2021-06-17 20:45:39.000000000 +0200
@@ -1328,9 +1328,11 @@
                      * Scrub a few (8) pages before becoming eligible for
                      * preemption. But also count non-scrubbing loop iterations
                      * so that we don't get stuck here with an almost clean
-                     * heap.
+                     * heap. Consider the CPU no longer being seen as online as
+                     * a request to preempt immediately, to not unduly delay
+                     * its offlining.
                      */
-                    if ( cnt > 800 && softirq_pending(cpu) )
+                    if ( !cpu_online(cpu) || (cnt > 800 && softirq_pending(cpu)) )
                     {
                         preempt = true;
                         break;
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/common/sched/core.c xen-4.14.2+25-gb6a8c4f72d/xen/common/sched/core.c
--- xen-4.14.1+11-gb0b734a8b3/xen/common/sched/core.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/common/sched/core.c	2021-06-17 20:45:39.000000000 +0200
@@ -1360,6 +1360,8 @@
 
     set_bit(_VPF_blocked, &v->pause_flags);
 
+    smp_mb__after_atomic();
+
     arch_vcpu_block(v);
 
     /* Check for events /after/ blocking: avoids wakeup waiting race. */
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/amd/iommu_cmd.c xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/amd/iommu_cmd.c
--- xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/amd/iommu_cmd.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/amd/iommu_cmd.c	2021-06-17 20:45:39.000000000 +0200
@@ -20,49 +20,40 @@
 #include "iommu.h"
 #include "../ats.h"
 
-static int queue_iommu_command(struct amd_iommu *iommu, u32 cmd[])
+static void send_iommu_command(struct amd_iommu *iommu,
+                               const uint32_t cmd[4])
 {
-    uint32_t tail, head;
+    uint32_t tail;
 
-    tail = iommu->cmd_buffer.tail + IOMMU_CMD_BUFFER_ENTRY_SIZE;
+    tail = iommu->cmd_buffer.tail + sizeof(cmd_entry_t);
     if ( tail == iommu->cmd_buffer.size )
         tail = 0;
 
-    head = readl(iommu->mmio_base +
-                 IOMMU_CMD_BUFFER_HEAD_OFFSET) & IOMMU_RING_BUFFER_PTR_MASK;
-    if ( head != tail )
+    while ( tail == (readl(iommu->mmio_base +
+                           IOMMU_CMD_BUFFER_HEAD_OFFSET) &
+                     IOMMU_RING_BUFFER_PTR_MASK) )
     {
-        memcpy(iommu->cmd_buffer.buffer + iommu->cmd_buffer.tail,
-               cmd, IOMMU_CMD_BUFFER_ENTRY_SIZE);
-
-        iommu->cmd_buffer.tail = tail;
-        return 1;
+        printk_once(XENLOG_ERR
+                    "AMD IOMMU %04x:%02x:%02x.%u: no cmd slot available\n",
+                    iommu->seg, PCI_BUS(iommu->bdf),
+                    PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf));
+        cpu_relax();
     }
 
-    return 0;
-}
+    memcpy(iommu->cmd_buffer.buffer + iommu->cmd_buffer.tail,
+           cmd, sizeof(cmd_entry_t));
 
-static void commit_iommu_command_buffer(struct amd_iommu *iommu)
-{
-    writel(iommu->cmd_buffer.tail,
-           iommu->mmio_base + IOMMU_CMD_BUFFER_TAIL_OFFSET);
-}
+    iommu->cmd_buffer.tail = tail;
 
-static int send_iommu_command(struct amd_iommu *iommu, u32 cmd[])
-{
-    if ( queue_iommu_command(iommu, cmd) )
-    {
-        commit_iommu_command_buffer(iommu);
-        return 1;
-    }
-
-    return 0;
+    writel(tail, iommu->mmio_base + IOMMU_CMD_BUFFER_TAIL_OFFSET);
 }
 
-static void flush_command_buffer(struct amd_iommu *iommu)
+static void flush_command_buffer(struct amd_iommu *iommu,
+                                 unsigned int timeout_base)
 {
-    unsigned int cmd[4], status, loop_count;
-    bool comp_wait;
+    uint32_t cmd[4];
+    s_time_t start, timeout;
+    static unsigned int __read_mostly threshold = 1;
 
     /* RW1C 'ComWaitInt' in status register */
     writel(IOMMU_STATUS_COMP_WAIT_INT,
@@ -78,22 +69,31 @@
                          IOMMU_COMP_WAIT_I_FLAG_SHIFT, &cmd[0]);
     send_iommu_command(iommu, cmd);
 
-    /* Make loop_count long enough for polling completion wait bit */
-    loop_count = 1000;
-    do {
-        status = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
-        comp_wait = status & IOMMU_STATUS_COMP_WAIT_INT;
-        --loop_count;
-    } while ( !comp_wait && loop_count );
-
-    if ( comp_wait )
+    start = NOW();
+    timeout = start + (timeout_base ?: 100) * MILLISECS(threshold);
+    while ( !(readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET) &
+              IOMMU_STATUS_COMP_WAIT_INT) )
     {
-        /* RW1C 'ComWaitInt' in status register */
-        writel(IOMMU_STATUS_COMP_WAIT_INT,
-               iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
-        return;
+        if ( timeout && NOW() > timeout )
+        {
+            threshold |= threshold << 1;
+            printk(XENLOG_WARNING
+                   "AMD IOMMU %04x:%02x:%02x.%u: %scompletion wait taking too long\n",
+                   iommu->seg, PCI_BUS(iommu->bdf),
+                   PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf),
+                   timeout_base ? "iotlb " : "");
+            timeout = 0;
+        }
+        cpu_relax();
     }
-    AMD_IOMMU_DEBUG("Warning: ComWaitInt bit did not assert!\n");
+
+    if ( !timeout )
+        printk(XENLOG_WARNING
+               "AMD IOMMU %04x:%02x:%02x.%u: %scompletion wait took %lums\n",
+               iommu->seg, PCI_BUS(iommu->bdf),
+               PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf),
+               timeout_base ? "iotlb " : "",
+               (NOW() - start) / 10000000);
 }
 
 /* Build low level iommu command messages */
@@ -305,7 +305,7 @@
     /* send INVALIDATE_IOTLB_PAGES command */
     spin_lock_irqsave(&iommu->lock, flags);
     invalidate_iotlb_pages(iommu, maxpend, 0, queueid, daddr, req_id, order);
-    flush_command_buffer(iommu);
+    flush_command_buffer(iommu, iommu_dev_iotlb_timeout);
     spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -342,7 +342,7 @@
     {
         spin_lock_irqsave(&iommu->lock, flags);
         invalidate_iommu_pages(iommu, daddr, dom_id, order);
-        flush_command_buffer(iommu);
+        flush_command_buffer(iommu, 0);
         spin_unlock_irqrestore(&iommu->lock, flags);
     }
 
@@ -366,7 +366,7 @@
     ASSERT( spin_is_locked(&iommu->lock) );
 
     invalidate_dev_table_entry(iommu, bdf);
-    flush_command_buffer(iommu);
+    flush_command_buffer(iommu, 0);
 }
 
 void amd_iommu_flush_intremap(struct amd_iommu *iommu, uint16_t bdf)
@@ -374,7 +374,7 @@
     ASSERT( spin_is_locked(&iommu->lock) );
 
     invalidate_interrupt_table(iommu, bdf);
-    flush_command_buffer(iommu);
+    flush_command_buffer(iommu, 0);
 }
 
 void amd_iommu_flush_all_caches(struct amd_iommu *iommu)
@@ -382,7 +382,7 @@
     ASSERT( spin_is_locked(&iommu->lock) );
 
     invalidate_iommu_all(iommu);
-    flush_command_buffer(iommu);
+    flush_command_buffer(iommu, 0);
 }
 
 void amd_iommu_send_guest_cmd(struct amd_iommu *iommu, u32 cmd[])
@@ -392,7 +392,8 @@
     spin_lock_irqsave(&iommu->lock, flags);
 
     send_iommu_command(iommu, cmd);
-    flush_command_buffer(iommu);
+    /* TBD: Timeout selection may require peeking into cmd[]. */
+    flush_command_buffer(iommu, 0);
 
     spin_unlock_irqrestore(&iommu->lock, flags);
 }
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/amd/iommu-defs.h xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/amd/iommu-defs.h
--- xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/amd/iommu-defs.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/amd/iommu-defs.h	2021-06-17 20:45:39.000000000 +0200
@@ -20,9 +20,6 @@
 #ifndef AMD_IOMMU_DEFS_H
 #define AMD_IOMMU_DEFS_H
 
-/* IOMMU Command Buffer entries: in power of 2 increments, minimum of 256 */
-#define IOMMU_CMD_BUFFER_DEFAULT_ENTRIES	512
-
 /* IOMMU Event Log entries: in power of 2 increments, minimum of 256 */
 #define IOMMU_EVENT_LOG_DEFAULT_ENTRIES     512
 
@@ -164,8 +161,8 @@
 #define IOMMU_CMD_BUFFER_LENGTH_MASK		0x0F000000
 #define IOMMU_CMD_BUFFER_LENGTH_SHIFT		24
 
-#define IOMMU_CMD_BUFFER_ENTRY_SIZE			16
-#define IOMMU_CMD_BUFFER_POWER_OF2_ENTRIES_PER_PAGE	8
+#define IOMMU_CMD_BUFFER_ENTRY_ORDER            4
+#define IOMMU_CMD_BUFFER_MAX_ENTRIES            (1u << 15)
 
 #define IOMMU_CMD_OPCODE_MASK			0xF0000000
 #define IOMMU_CMD_OPCODE_SHIFT			28
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/amd/iommu_init.c xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/amd/iommu_init.c
--- xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/amd/iommu_init.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/amd/iommu_init.c	2021-06-17 20:45:39.000000000 +0200
@@ -118,7 +118,7 @@
     writel(entry, iommu->mmio_base + IOMMU_CMD_BUFFER_BASE_LOW_OFFSET);
 
     power_of2_entries = get_order_from_bytes(iommu->cmd_buffer.size) +
-        IOMMU_CMD_BUFFER_POWER_OF2_ENTRIES_PER_PAGE;
+        PAGE_SHIFT - IOMMU_CMD_BUFFER_ENTRY_ORDER;
 
     entry = 0;
     iommu_set_addr_hi_to_reg(&entry, addr_hi);
@@ -1022,9 +1022,31 @@
 static void * __init allocate_cmd_buffer(struct amd_iommu *iommu)
 {
     /* allocate 'command buffer' in power of 2 increments of 4K */
+    static unsigned int __read_mostly nr_ents;
+
+    if ( !nr_ents )
+    {
+        unsigned int order;
+
+        /*
+         * With the present synchronous model, we need two slots for every
+         * operation (the operation itself and a wait command).  There can be
+         * one such pair of requests pending per CPU.  One extra entry is
+         * needed as the ring is considered full when there's only one entry
+         * left.
+         */
+        BUILD_BUG_ON(CONFIG_NR_CPUS * 2 >= IOMMU_CMD_BUFFER_MAX_ENTRIES);
+        order = get_order_from_bytes((num_present_cpus() * 2 + 1) <<
+                                     IOMMU_CMD_BUFFER_ENTRY_ORDER);
+        nr_ents = 1u << (order + PAGE_SHIFT - IOMMU_CMD_BUFFER_ENTRY_ORDER);
+
+        AMD_IOMMU_DEBUG("using %u-entry cmd ring(s)\n", nr_ents);
+    }
+
+    BUILD_BUG_ON(sizeof(cmd_entry_t) != (1u << IOMMU_CMD_BUFFER_ENTRY_ORDER));
+
     return allocate_ring_buffer(&iommu->cmd_buffer, sizeof(cmd_entry_t),
-                                IOMMU_CMD_BUFFER_DEFAULT_ENTRIES,
-                                "Command Buffer", false);
+                                nr_ents, "Command Buffer", false);
 }
 
 static void * __init allocate_event_log(struct amd_iommu *iommu)
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/iommu.c xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/iommu.c
--- xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/iommu.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/iommu.c	2021-06-17 20:45:39.000000000 +0200
@@ -225,6 +225,13 @@
 {
     struct domain_iommu *hd = dom_iommu(d);
 
+    /*
+     * During early domain creation failure, we may reach here with the
+     * ops not yet initialized.
+     */
+    if ( !hd->platform_ops )
+        return;
+
     hd->platform_ops->teardown(d);
     tasklet_schedule(&iommu_pt_cleanup_tasklet);
 }
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/vtd/dmar.h xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/vtd/dmar.h
--- xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/vtd/dmar.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/vtd/dmar.h	2021-06-17 20:45:39.000000000 +0200
@@ -127,6 +127,34 @@
     }                                                           \
 } while (0)
 
+#define IOMMU_FLUSH_WAIT(what, iommu, offset, op, cond, sts)       \
+do {                                                               \
+    static unsigned int __read_mostly threshold = 1;               \
+    s_time_t start = NOW();                                        \
+    s_time_t timeout = start + DMAR_OPERATION_TIMEOUT * threshold; \
+                                                                   \
+    for ( ; ; )                                                    \
+    {                                                              \
+        sts = op(iommu->reg, offset);                              \
+        if ( cond )                                                \
+            break;                                                 \
+        if ( timeout && NOW() > timeout )                          \
+        {                                                          \
+            threshold |= threshold << 1;                           \
+            printk(XENLOG_WARNING VTDPREFIX                        \
+                   " IOMMU#%u: %s flush taking too long\n",        \
+                   iommu->index, what);                            \
+            timeout = 0;                                           \
+        }                                                          \
+        cpu_relax();                                               \
+    }                                                              \
+                                                                   \
+    if ( !timeout )                                                \
+        printk(XENLOG_WARNING VTDPREFIX                            \
+               " IOMMU#%u: %s flush took %lums\n",                 \
+               iommu->index, what, (NOW() - start) / 10000000);    \
+} while ( false )
+
 int vtd_hw_check(void);
 void disable_pmr(struct vtd_iommu *iommu);
 int is_igd_drhd(struct acpi_drhd_unit *drhd);
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/vtd/extern.h xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/vtd/extern.h
--- xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/vtd/extern.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/vtd/extern.h	2021-06-17 20:45:39.000000000 +0200
@@ -50,6 +50,16 @@
 int iommu_flush_iec_index(struct vtd_iommu *iommu, u8 im, u16 iidx);
 void clear_fault_bits(struct vtd_iommu *iommu);
 
+int __must_check vtd_flush_context_reg(struct vtd_iommu *iommu, uint16_t did,
+                                       uint16_t source_id,
+                                       uint8_t function_mask, uint64_t type,
+                                       bool flush_non_present_entry);
+int __must_check vtd_flush_iotlb_reg(struct vtd_iommu *iommu, uint16_t did,
+                                     uint64_t addr, unsigned int size_order,
+                                     uint64_t type,
+                                     bool flush_non_present_entry,
+                                     bool flush_dev_iotlb);
+
 struct vtd_iommu *ioapic_to_iommu(unsigned int apic_id);
 struct vtd_iommu *hpet_to_iommu(unsigned int hpet_id);
 struct acpi_drhd_unit *ioapic_to_drhd(unsigned int apic_id);
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/vtd/iommu.c xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/vtd/iommu.c
--- xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/vtd/iommu.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/vtd/iommu.c	2021-06-17 20:45:39.000000000 +0200
@@ -326,17 +326,16 @@
     dmar_writel(iommu->reg, DMAR_GCMD_REG, val | DMA_GCMD_WBF);
 
     /* Make sure hardware complete it */
-    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
-                  !(val & DMA_GSTS_WBFS), val);
+    IOMMU_FLUSH_WAIT("write buffer", iommu, DMAR_GSTS_REG, dmar_readl,
+                     !(val & DMA_GSTS_WBFS), val);
 
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
 
 /* return value determine if we need a write buffer flush */
-static int __must_check flush_context_reg(struct vtd_iommu *iommu, u16 did,
-                                          u16 source_id, u8 function_mask,
-                                          u64 type,
-                                          bool flush_non_present_entry)
+int vtd_flush_context_reg(struct vtd_iommu *iommu, uint16_t did,
+                          uint16_t source_id, uint8_t function_mask,
+                          uint64_t type, bool flush_non_present_entry)
 {
     u64 val = 0;
     unsigned long flags;
@@ -377,8 +376,8 @@
     dmar_writeq(iommu->reg, DMAR_CCMD_REG, val);
 
     /* Make sure hardware complete it */
-    IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG, dmar_readq,
-                  !(val & DMA_CCMD_ICC), val);
+    IOMMU_FLUSH_WAIT("context", iommu, DMAR_CCMD_REG, dmar_readq,
+                     !(val & DMA_CCMD_ICC), val);
 
     spin_unlock_irqrestore(&iommu->register_lock, flags);
     /* flush context entry will implicitly flush write buffer */
@@ -402,11 +401,9 @@
 }
 
 /* return value determine if we need a write buffer flush */
-static int __must_check flush_iotlb_reg(struct vtd_iommu *iommu, u16 did,
-                                        u64 addr,
-                                        unsigned int size_order, u64 type,
-                                        bool flush_non_present_entry,
-                                        bool flush_dev_iotlb)
+int vtd_flush_iotlb_reg(struct vtd_iommu *iommu, uint16_t did, uint64_t addr,
+                        unsigned int size_order, uint64_t type,
+                        bool flush_non_present_entry, bool flush_dev_iotlb)
 {
     int tlb_offset = ecap_iotlb_offset(iommu->ecap);
     u64 val = 0;
@@ -457,8 +454,8 @@
     dmar_writeq(iommu->reg, tlb_offset + 8, val);
 
     /* Make sure hardware complete it */
-    IOMMU_WAIT_OP(iommu, (tlb_offset + 8), dmar_readq,
-                  !(val & DMA_TLB_IVT), val);
+    IOMMU_FLUSH_WAIT("iotlb", iommu, (tlb_offset + 8), dmar_readq,
+                     !(val & DMA_TLB_IVT), val);
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 
     /* check IOTLB invalidation granularity */
@@ -1163,10 +1160,10 @@
     unsigned long sagaw, nr_dom;
     int agaw;
 
-    if ( nr_iommus > MAX_IOMMUS )
+    if ( nr_iommus >= MAX_IOMMUS )
     {
         dprintk(XENLOG_ERR VTDPREFIX,
-                 "IOMMU: nr_iommus %d > MAX_IOMMUS\n", nr_iommus);
+                "IOMMU: nr_iommus %d > MAX_IOMMUS\n", nr_iommus + 1);
         return -ENOMEM;
     }
 
@@ -1191,6 +1188,14 @@
 
     iommu->cap = dmar_readq(iommu->reg, DMAR_CAP_REG);
     iommu->ecap = dmar_readq(iommu->reg, DMAR_ECAP_REG);
+    iommu->version = dmar_readl(iommu->reg, DMAR_VER_REG);
+
+    if ( !iommu_qinval && !has_register_based_invalidation(iommu) )
+    {
+        printk(XENLOG_WARNING VTDPREFIX "IOMMU %d: cannot disable Queued Invalidation\n",
+               iommu->index);
+        iommu_qinval = true;
+    }
 
     if ( iommu_verbose )
     {
@@ -2112,7 +2117,7 @@
 }
 __initcall(adjust_vtd_irq_affinities);
 
-static int __must_check init_vtd_hw(void)
+static int __must_check init_vtd_hw(bool resume)
 {
     struct acpi_drhd_unit *drhd;
     struct vtd_iommu *iommu;
@@ -2121,7 +2126,7 @@
     u32 sts;
 
     /*
-     * Basic VT-d HW init: set VT-d interrupt, clear VT-d faults.  
+     * Basic VT-d HW init: set VT-d interrupt, clear VT-d faults, etc.
      */
     for_each_drhd_unit ( drhd )
     {
@@ -2131,6 +2136,20 @@
 
         clear_fault_bits(iommu);
 
+        /*
+         * Disable interrupt remapping and queued invalidation if
+         * already enabled by BIOS in case we've not initialized it yet.
+         */
+        if ( !iommu_x2apic_enabled )
+        {
+            disable_intremap(iommu);
+            disable_qinval(iommu);
+        }
+
+        if ( resume )
+            /* FECTL write done by vtd_resume(). */
+            continue;
+
         spin_lock_irqsave(&iommu->register_lock, flags);
         sts = dmar_readl(iommu->reg, DMAR_FECTL_REG);
         sts &= ~DMA_FECTL_IM;
@@ -2150,8 +2169,12 @@
          */
         if ( enable_qinval(iommu) != 0 )
         {
-            iommu->flush.context = flush_context_reg;
-            iommu->flush.iotlb   = flush_iotlb_reg;
+            /* Ensure register-based invalidation is available */
+            if ( !has_register_based_invalidation(iommu) )
+                return -EIO;
+
+            iommu->flush.context = vtd_flush_context_reg;
+            iommu->flush.iotlb   = vtd_flush_iotlb_reg;
         }
     }
 
@@ -2240,6 +2263,7 @@
     struct acpi_drhd_unit *drhd;
     struct vtd_iommu *iommu;
     int ret;
+    bool reg_inval_supported = true;
 
     if ( list_empty(&acpi_drhd_units) )
     {
@@ -2261,8 +2285,8 @@
     }
 
     /* We enable the following features only if they are supported by all VT-d
-     * engines: Snoop Control, DMA passthrough, Queued Invalidation, Interrupt
-     * Remapping, and Posted Interrupt
+     * engines: Snoop Control, DMA passthrough, Register-based Invalidation,
+     * Queued Invalidation, Interrupt Remapping, and Posted Interrupt.
      */
     for_each_drhd_unit ( drhd )
     {
@@ -2284,6 +2308,9 @@
         if ( iommu_qinval && !ecap_queued_inval(iommu->ecap) )
             iommu_qinval = 0;
 
+        if ( !has_register_based_invalidation(iommu) )
+            reg_inval_supported = false;
+
         if ( iommu_intremap && !ecap_intr_remap(iommu->ecap) )
             iommu_intremap = iommu_intremap_off;
 
@@ -2310,6 +2337,13 @@
 
     softirq_tasklet_init(&vtd_fault_tasklet, do_iommu_page_fault, NULL);
 
+    if ( !iommu_qinval && !reg_inval_supported )
+    {
+        dprintk(XENLOG_ERR VTDPREFIX, "No available invalidation interface\n");
+        ret = -ENODEV;
+        goto error;
+    }
+
     if ( !iommu_qinval && iommu_intremap )
     {
         iommu_intremap = iommu_intremap_off;
@@ -2330,7 +2364,7 @@
     P(iommu_hap_pt_share, "Shared EPT tables");
 #undef P
 
-    ret = init_vtd_hw();
+    ret = init_vtd_hw(false);
     if ( ret )
         goto error;
 
@@ -2601,7 +2635,22 @@
     if ( !iommu_enabled )
         return;
 
-    if ( init_vtd_hw() != 0  && force_iommu )
+    for_each_drhd_unit ( drhd )
+    {
+        iommu = drhd->iommu;
+        i = iommu->index;
+
+        spin_lock_irqsave(&iommu->register_lock, flags);
+        dmar_writel(iommu->reg, DMAR_FEDATA_REG,
+                    iommu_state[i][DMAR_FEDATA_REG]);
+        dmar_writel(iommu->reg, DMAR_FEADDR_REG,
+                    iommu_state[i][DMAR_FEADDR_REG]);
+        dmar_writel(iommu->reg, DMAR_FEUADDR_REG,
+                    iommu_state[i][DMAR_FEUADDR_REG]);
+        spin_unlock_irqrestore(&iommu->register_lock, flags);
+    }
+
+    if ( init_vtd_hw(true) != 0 && force_iommu )
          panic("IOMMU setup failed, crash Xen for security purpose\n");
 
     for_each_drhd_unit ( drhd )
@@ -2612,12 +2661,6 @@
         spin_lock_irqsave(&iommu->register_lock, flags);
         dmar_writel(iommu->reg, DMAR_FECTL_REG,
                     (u32) iommu_state[i][DMAR_FECTL_REG]);
-        dmar_writel(iommu->reg, DMAR_FEDATA_REG,
-                    (u32) iommu_state[i][DMAR_FEDATA_REG]);
-        dmar_writel(iommu->reg, DMAR_FEADDR_REG,
-                    (u32) iommu_state[i][DMAR_FEADDR_REG]);
-        dmar_writel(iommu->reg, DMAR_FEUADDR_REG,
-                    (u32) iommu_state[i][DMAR_FEUADDR_REG]);
         spin_unlock_irqrestore(&iommu->register_lock, flags);
 
         iommu_enable_translation(drhd);
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/vtd/iommu.h xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/vtd/iommu.h
--- xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/vtd/iommu.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/vtd/iommu.h	2021-06-17 20:45:39.000000000 +0200
@@ -450,17 +450,9 @@
     }q;
 };
 
-/* Order of queue invalidation pages(max is 8) */
-#define QINVAL_PAGE_ORDER   2
-
-#define QINVAL_ARCH_PAGE_ORDER  (QINVAL_PAGE_ORDER + PAGE_SHIFT_4K - PAGE_SHIFT)
-#define QINVAL_ARCH_PAGE_NR     ( QINVAL_ARCH_PAGE_ORDER < 0 ?  \
-                                1 :                             \
-                                1 << QINVAL_ARCH_PAGE_ORDER )
-
 /* Each entry is 16 bytes, so 2^8 entries per page */
 #define QINVAL_ENTRY_ORDER  ( PAGE_SHIFT - 4 )
-#define QINVAL_ENTRY_NR     (1 << (QINVAL_PAGE_ORDER + 8))
+#define QINVAL_MAX_ENTRY_NR (1u << (7 + QINVAL_ENTRY_ORDER))
 
 /* Status data flag */
 #define QINVAL_STAT_INIT  0
@@ -540,6 +532,7 @@
     struct list_head ats_devices;
     unsigned long *domid_bitmap;  /* domain id bitmap */
     u16 *domid_map;               /* domain id mapping array */
+    uint32_t version;
 };
 
 #define INTEL_IOMMU_DEBUG(fmt, args...) \
@@ -549,4 +542,10 @@
             dprintk(XENLOG_WARNING VTDPREFIX, fmt, ## args);    \
     } while(0)
 
+/* Register-based invalidation isn't supported by VT-d version 6 and beyond. */
+static inline bool has_register_based_invalidation(const struct vtd_iommu *vtd)
+{
+    return VER_MAJOR(vtd->version) < 6;
+}
+
 #endif
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/vtd/qinval.c xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/vtd/qinval.c
--- xen-4.14.1+11-gb0b734a8b3/xen/drivers/passthrough/vtd/qinval.c	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/drivers/passthrough/vtd/qinval.c	2021-06-17 20:45:39.000000000 +0200
@@ -29,7 +29,8 @@
 #include "extern.h"
 #include "../ats.h"
 
-#define VTD_QI_TIMEOUT	1
+static unsigned int __read_mostly qi_pg_order;
+static unsigned int __read_mostly qi_entry_nr;
 
 static int __must_check invalidate_sync(struct vtd_iommu *iommu);
 
@@ -55,9 +56,13 @@
     tail >>= QINVAL_INDEX_SHIFT;
 
     /* (tail+1 == head) indicates a full queue, wait for HW */
-    while ( ( tail + 1 ) % QINVAL_ENTRY_NR ==
+    while ( ((tail + 1) & (qi_entry_nr - 1)) ==
             ( dmar_readq(iommu->reg, DMAR_IQH_REG) >> QINVAL_INDEX_SHIFT ) )
+    {
+        printk_once(XENLOG_ERR VTDPREFIX " IOMMU#%u: no QI slot available\n",
+                    iommu->index);
         cpu_relax();
+    }
 
     return tail;
 }
@@ -68,7 +73,7 @@
 
     /* Need hold register lock when update tail */
     ASSERT( spin_is_locked(&iommu->register_lock) );
-    val = (index + 1) % QINVAL_ENTRY_NR;
+    val = (index + 1) & (qi_entry_nr - 1);
     dmar_writeq(iommu->reg, DMAR_IQT_REG, (val << QINVAL_INDEX_SHIFT));
 }
 
@@ -177,23 +182,32 @@
     /* Now we don't support interrupt method */
     if ( sw )
     {
-        s_time_t timeout;
-
-        /* In case all wait descriptor writes to same addr with same data */
-        timeout = NOW() + MILLISECS(flush_dev_iotlb ?
-                                    iommu_dev_iotlb_timeout : VTD_QI_TIMEOUT);
+        static unsigned int __read_mostly threshold = 1;
+        s_time_t start = NOW();
+        s_time_t timeout = start + (flush_dev_iotlb
+                                    ? iommu_dev_iotlb_timeout
+                                    : 100) * MILLISECS(threshold);
 
         while ( ACCESS_ONCE(*this_poll_slot) != QINVAL_STAT_DONE )
         {
-            if ( NOW() > timeout )
+            if ( timeout && NOW() > timeout )
             {
-                print_qi_regs(iommu);
+                threshold |= threshold << 1;
                 printk(XENLOG_WARNING VTDPREFIX
-                       " Queue invalidate wait descriptor timed out\n");
-                return -ETIMEDOUT;
+                       " IOMMU#%u: QI%s wait descriptor taking too long\n",
+                       iommu->index, flush_dev_iotlb ? " dev" : "");
+                print_qi_regs(iommu);
+                timeout = 0;
             }
             cpu_relax();
         }
+
+        if ( !timeout )
+            printk(XENLOG_WARNING VTDPREFIX
+                   " IOMMU#%u: QI%s wait descriptor took %lums\n",
+                   iommu->index, flush_dev_iotlb ? " dev" : "",
+                   (NOW() - start) / 10000000);
+
         return 0;
     }
 
@@ -403,8 +417,28 @@
 
     if ( iommu->qinval_maddr == 0 )
     {
-        iommu->qinval_maddr = alloc_pgtable_maddr(QINVAL_ARCH_PAGE_NR,
-                                                  iommu->node);
+        if ( !qi_entry_nr )
+        {
+            /*
+             * With the present synchronous model, we need two slots for every
+             * operation (the operation itself and a wait descriptor).  There
+             * can be one such pair of requests pending per CPU.  One extra
+             * entry is needed as the ring is considered full when there's
+             * only one entry left.
+             */
+            BUILD_BUG_ON(CONFIG_NR_CPUS * 2 >= QINVAL_MAX_ENTRY_NR);
+            qi_pg_order = get_order_from_bytes((num_present_cpus() * 2 + 1) <<
+                                               (PAGE_SHIFT -
+                                                QINVAL_ENTRY_ORDER));
+            qi_entry_nr = 1u << (qi_pg_order + QINVAL_ENTRY_ORDER);
+
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "QI: using %u-entry ring(s)\n", qi_entry_nr);
+        }
+
+        iommu->qinval_maddr =
+            alloc_pgtable_maddr(qi_entry_nr >> QINVAL_ENTRY_ORDER,
+                                iommu->node);
         if ( iommu->qinval_maddr == 0 )
         {
             dprintk(XENLOG_WARNING VTDPREFIX,
@@ -418,15 +452,16 @@
 
     spin_lock_irqsave(&iommu->register_lock, flags);
 
-    /* Setup Invalidation Queue Address(IQA) register with the
-     * address of the page we just allocated.  QS field at
-     * bits[2:0] to indicate size of queue is one 4KB page.
-     * That's 256 entries.  Queued Head (IQH) and Queue Tail (IQT)
-     * registers are automatically reset to 0 with write
-     * to IQA register.
+    /*
+     * Setup Invalidation Queue Address (IQA) register with the address of the
+     * pages we just allocated.  The QS field at bits[2:0] indicates the size
+     * (page order) of the queue.
+     *
+     * Queued Head (IQH) and Queue Tail (IQT) registers are automatically
+     * reset to 0 with write to IQA register.
      */
     dmar_writeq(iommu->reg, DMAR_IQA_REG,
-                iommu->qinval_maddr | QINVAL_PAGE_ORDER);
+                iommu->qinval_maddr | qi_pg_order);
 
     dmar_writeq(iommu->reg, DMAR_IQT_REG, 0);
 
@@ -442,6 +477,23 @@
     return 0;
 }
 
+static int vtd_flush_context_noop(struct vtd_iommu *iommu, uint16_t did,
+                                  uint16_t source_id, uint8_t function_mask,
+                                  uint64_t type, bool flush_non_present_entry)
+{
+    WARN();
+    return -EIO;
+}
+
+static int vtd_flush_iotlb_noop(struct vtd_iommu *iommu, uint16_t did,
+                                uint64_t addr, unsigned int size_order,
+                                uint64_t type, bool flush_non_present_entry,
+                                bool flush_dev_iotlb)
+{
+    WARN();
+    return -EIO;
+}
+
 void disable_qinval(struct vtd_iommu *iommu)
 {
     u32 sts;
@@ -462,4 +514,19 @@
                   !(sts & DMA_GSTS_QIES), sts);
 out:
     spin_unlock_irqrestore(&iommu->register_lock, flags);
+
+    /*
+     * Assign callbacks to noop to catch errors if register-based invalidation
+     * isn't supported.
+     */
+    if ( has_register_based_invalidation(iommu) )
+    {
+        iommu->flush.context = vtd_flush_context_reg;
+        iommu->flush.iotlb   = vtd_flush_iotlb_reg;
+    }
+    else
+    {
+        iommu->flush.context = vtd_flush_context_noop;
+        iommu->flush.iotlb   = vtd_flush_iotlb_noop;
+    }
 }
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-arm/cpuerrata.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-arm/cpuerrata.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-arm/cpuerrata.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-arm/cpuerrata.h	2021-06-17 20:45:39.000000000 +0200
@@ -28,6 +28,8 @@
 CHECK_WORKAROUND_HELPER(766422, ARM32_WORKAROUND_766422, CONFIG_ARM_32)
 CHECK_WORKAROUND_HELPER(834220, ARM64_WORKAROUND_834220, CONFIG_ARM_64)
 CHECK_WORKAROUND_HELPER(ssbd, ARM_SSBD, CONFIG_ARM_SSBD)
+CHECK_WORKAROUND_HELPER(858921, ARM_WORKAROUND_858921,
+                        CONFIG_ARM_ERRATUM_858921)
 
 #undef CHECK_WORKAROUND_HELPER
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-arm/cpufeature.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-arm/cpufeature.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-arm/cpufeature.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-arm/cpufeature.h	2021-06-17 20:45:39.000000000 +0200
@@ -45,8 +45,9 @@
 #define ARM_SSBD 7
 #define ARM_SMCCC_1_1 8
 #define ARM64_WORKAROUND_AT_SPECULATE 9
+#define ARM_WORKAROUND_858921 10
 
-#define ARM_NCAPS           10
+#define ARM_NCAPS           11
 
 #ifndef __ASSEMBLY__
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-arm/processor.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-arm/processor.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-arm/processor.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-arm/processor.h	2021-06-17 20:45:39.000000000 +0200
@@ -53,6 +53,7 @@
 #define ARM_CPU_PART_CORTEX_A17     0xC0E
 #define ARM_CPU_PART_CORTEX_A15     0xC0F
 #define ARM_CPU_PART_CORTEX_A53     0xD03
+#define ARM_CPU_PART_CORTEX_A55     0xD05
 #define ARM_CPU_PART_CORTEX_A57     0xD07
 #define ARM_CPU_PART_CORTEX_A72     0xD08
 #define ARM_CPU_PART_CORTEX_A73     0xD09
@@ -64,6 +65,7 @@
 #define MIDR_CORTEX_A17 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A17)
 #define MIDR_CORTEX_A15 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A15)
 #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
+#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
 #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
 #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
 #define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-arm/time.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-arm/time.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-arm/time.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-arm/time.h	2021-06-17 20:45:39.000000000 +0200
@@ -3,6 +3,7 @@
 
 #include <asm/sysregs.h>
 #include <asm/system.h>
+#include <asm/cpuerrata.h>
 
 #define DT_MATCH_TIMER                      \
     DT_MATCH_COMPATIBLE("arm,armv7-timer"), \
@@ -13,7 +14,26 @@
 static inline cycles_t get_cycles (void)
 {
         isb();
-        return READ_SYSREG64(CNTPCT_EL0);
+        /*
+         * ARM_WORKAROUND_858921: Cortex-A73 (all versions) counter read
+         * can return a wrong value when the counter crosses a 32bit boundary.
+         */
+        if ( !check_workaround_858921() )
+            return READ_SYSREG64(CNTPCT_EL0);
+        else
+        {
+            /*
+             * A recommended workaround for erratum 858921 is to:
+             *  1- Read twice CNTPCT.
+             *  2- Compare bit[32] of the two read values.
+             *      - If bit[32] is different, keep the old value.
+             *      - If bit[32] is the same, keep the new value.
+             */
+            cycles_t old, new;
+            old = READ_SYSREG64(CNTPCT_EL0);
+            new = READ_SYSREG64(CNTPCT_EL0);
+            return (((old ^ new) >> 32) & 1) ? old : new;
+        }
 }
 
 /* List of timer's IRQ */
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-arm/vgic.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-arm/vgic.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-arm/vgic.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-arm/vgic.h	2021-06-17 20:45:39.000000000 +0200
@@ -288,6 +288,8 @@
 extern struct vgic_irq_rank *vgic_rank_irq(struct vcpu *v, unsigned int irq);
 extern void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n);
 extern void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n);
+extern void vgic_set_irqs_pending(struct vcpu *v, uint32_t r,
+                                  unsigned int rank);
 extern void register_vgic_ops(struct domain *d, const struct vgic_ops *ops);
 int vgic_v2_init(struct domain *d, int *mmio_count);
 int vgic_v3_init(struct domain *d, int *mmio_count);
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/apic.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/apic.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/apic.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/apic.h	2021-06-17 20:45:39.000000000 +0200
@@ -24,6 +24,7 @@
     APIC_MODE_X2APIC    /* x2APIC mode - common for large MP machines */
 };
 
+extern bool iommu_x2apic_enabled;
 extern u8 apic_verbosity;
 extern bool directed_eoi_enabled;
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/cpufeature.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/cpufeature.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/cpufeature.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/cpufeature.h	2021-06-17 20:45:39.000000000 +0200
@@ -128,8 +128,10 @@
 /* CPUID level 0x00000007:0.edx */
 #define cpu_has_avx512_4vnniw   boot_cpu_has(X86_FEATURE_AVX512_4VNNIW)
 #define cpu_has_avx512_4fmaps   boot_cpu_has(X86_FEATURE_AVX512_4FMAPS)
+#define cpu_has_rtm_always_abort boot_cpu_has(X86_FEATURE_RTM_ALWAYS_ABORT)
 #define cpu_has_tsx_force_abort boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)
 #define cpu_has_serialize       boot_cpu_has(X86_FEATURE_SERIALIZE)
+#define cpu_has_arch_caps       boot_cpu_has(X86_FEATURE_ARCH_CAPS)
 
 /* CPUID level 0x00000007:1.eax */
 #define cpu_has_avx512_bf16     boot_cpu_has(X86_FEATURE_AVX512_BF16)
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/fixmap.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/fixmap.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/fixmap.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/fixmap.h	2021-06-17 20:45:39.000000000 +0200
@@ -79,7 +79,7 @@
 
 #define clear_fixmap(idx) __set_fixmap(idx, 0, 0)
 
-#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __fix_to_virt(x) gcc11_wrap(FIXADDR_TOP - ((x) << PAGE_SHIFT))
 #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
 
 #define fix_to_virt(x)   ((void *)__fix_to_virt(x))
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/hpet.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/hpet.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/hpet.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/hpet.h	2021-06-17 20:45:39.000000000 +0200
@@ -53,6 +53,7 @@
 extern unsigned long hpet_address;
 extern u8 hpet_blockid;
 extern u8 hpet_flags;
+extern int8_t opt_hpet_legacy_replacement;
 
 /*
  * Detect and initialise HPET hardware: return counter update frequency.
@@ -73,6 +74,18 @@
 int hpet_legacy_irq_tick(void);
 
 /*
+ * Try to enable HPET Legacy Replacement mode.  Returns a boolean indicating
+ * whether the HPET configuration was changed.
+ */
+bool hpet_enable_legacy_replacement_mode(void);
+
+/*
+ * Undo the effects of hpet_disable_legacy_replacement_mode().  Must not be
+ * called unless enable() returned true.
+ */
+void hpet_disable_legacy_replacement_mode(void);
+
+/*
  * Temporarily use an HPET event counter for timer interrupt handling,
  * rather than using the LAPIC timer. Used for Cx state entry.
  */
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/hvm/vpt.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/hvm/vpt.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/hvm/vpt.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/hvm/vpt.h	2021-06-17 20:45:39.000000000 +0200
@@ -128,12 +128,18 @@
     struct RTCState  vrtc;
     struct HPETState vhpet;
     struct PMTState  vpmt;
-    /*
-     * rwlock to prevent periodic_time vCPU migration. Take the lock in read
-     * mode in order to prevent the vcpu field of periodic_time from changing.
-     * Lock must be taken in write mode when changes to the vcpu field are
-     * performed, as it allows exclusive access to all the timers of a domain.
-     */
+     /*
+      * Functions which want to modify the vcpu field of the vpt need
+      * to hold the global lock (pt_migrate) in write mode together
+      * with the per-vcpu locks of the lists being modified. Functions
+      * that want to lock a periodic_timer that's possibly on a
+      * different vCPU list need to take the lock in read mode first in
+      * order to prevent the vcpu field of periodic_timer from
+      * changing.
+      *
+      * Note that two vcpu locks cannot be held at the same time to
+      * avoid a deadlock.
+      */
     rwlock_t pt_migrate;
     /* guest_time = Xen sys time + stime_offset */
     int64_t stime_offset;
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/msr-index.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/msr-index.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/msr-index.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/msr-index.h	2021-06-17 20:45:39.000000000 +0200
@@ -61,6 +61,8 @@
 
 #define MSR_TSX_FORCE_ABORT                 0x0000010f
 #define  TSX_FORCE_ABORT_RTM                (_AC(1, ULL) <<  0)
+#define  TSX_CPUID_CLEAR                    (_AC(1, ULL) <<  1)
+#define  TSX_ENABLE_RTM                     (_AC(1, ULL) <<  2)
 
 #define MSR_TSX_CTRL                        0x00000122
 #define  TSX_CTRL_RTM_DISABLE               (_AC(1, ULL) <<  0)
@@ -616,15 +618,21 @@
 #define NUM_MSR_C2_LASTBRANCH_FROM_TO	4
 #define NUM_MSR_ATOM_LASTBRANCH_FROM_TO	8
 
+/* Nehalem (and newer) last-branch recording */
+#define MSR_NHL_LBR_SELECT		0x000001c8
+#define MSR_NHL_LASTBRANCH_TOS		0x000001c9
+
 /* Skylake (and newer) last-branch recording */
-#define MSR_SKL_LASTBRANCH_TOS		0x000001c9
 #define MSR_SKL_LASTBRANCH_0_FROM_IP	0x00000680
 #define MSR_SKL_LASTBRANCH_0_TO_IP	0x000006c0
 #define MSR_SKL_LASTBRANCH_0_INFO	0x00000dc0
 #define NUM_MSR_SKL_LASTBRANCH		32
 
+/* Silvermont (and newer) last-branch recording */
+#define MSR_SM_LBR_SELECT		0x000001c8
+#define MSR_SM_LASTBRANCH_TOS		0x000001c9
+
 /* Goldmont last-branch recording */
-#define MSR_GM_LASTBRANCH_TOS		0x000001c9
 #define MSR_GM_LASTBRANCH_0_FROM_IP	0x00000680
 #define MSR_GM_LASTBRANCH_0_TO_IP	0x000006c0
 #define NUM_MSR_GM_LASTBRANCH_FROM_TO	32
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/processor.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/processor.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/processor.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/processor.h	2021-06-17 20:45:39.000000000 +0200
@@ -629,6 +629,7 @@
 }
 
 extern int8_t opt_tsx, cpu_has_tsx_ctrl;
+extern bool rtm_disabled;
 void tsx_init(void);
 
 #endif /* !__ASSEMBLY__ */
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/vpmu.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/vpmu.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/vpmu.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/vpmu.h	2021-06-17 20:45:39.000000000 +0200
@@ -126,7 +126,6 @@
 
 extern unsigned int vpmu_mode;
 extern unsigned int vpmu_features;
-extern bool opt_rtm_abort;
 
 /* Context switch */
 static inline void vpmu_switch_from(struct vcpu *prev)
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/x86_64/efibind.h xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/x86_64/efibind.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/asm-x86/x86_64/efibind.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/asm-x86/x86_64/efibind.h	2021-06-17 20:45:39.000000000 +0200
@@ -172,7 +172,7 @@
 #ifndef EFIAPI                  // Forces EFI calling conventions reguardless of compiler options
     #ifdef _MSC_EXTENSIONS
         #define EFIAPI __cdecl  // Force C calling convention for Microsoft C compiler
-    #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+    #elif __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
         #define EFIAPI __attribute__((__ms_abi__))  // Force Microsoft ABI
     #else
         #define EFIAPI          // Substitute expresion to force C calling convention
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/crypto/rijndael.h xen-4.14.2+25-gb6a8c4f72d/xen/include/crypto/rijndael.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/crypto/rijndael.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/crypto/rijndael.h	2021-06-17 20:45:39.000000000 +0200
@@ -52,7 +52,7 @@
 
 int	rijndaelKeySetupEnc(unsigned int [], const unsigned char [], int);
 int	rijndaelKeySetupDec(unsigned int [], const unsigned char [], int);
-void	rijndaelEncrypt(const unsigned int [], int, const unsigned char [],
-	    unsigned char []);
+void	rijndaelEncrypt(const unsigned int [], int, const unsigned char [16],
+	    unsigned char [16]);
 
 #endif /* __RIJNDAEL_H */
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/Makefile xen-4.14.2+25-gb6a8c4f72d/xen/include/Makefile
--- xen-4.14.1+11-gb0b734a8b3/xen/include/Makefile	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/Makefile	2021-06-17 20:45:39.000000000 +0200
@@ -89,7 +89,7 @@
 xlat-y := $(shell sed -ne 's,@arch@,$(compat-arch-y),g' -re 's,^[?!][[:blank:]]+[^[:blank:]]+[[:blank:]]+,,p' xlat.lst | uniq)
 xlat-y := $(filter $(patsubst compat/%,%,$(headers-y)),$(xlat-y))
 
-compat/xlat.h: $(addprefix compat/.xlat/,$(xlat-y)) Makefile
+compat/xlat.h: $(addprefix compat/.xlat/,$(xlat-y)) config/auto.conf Makefile
 	cat $(filter %.h,$^) >$@.new
 	mv -f $@.new $@
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/public/arch-x86/cpufeatureset.h xen-4.14.2+25-gb6a8c4f72d/xen/include/public/arch-x86/cpufeatureset.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/public/arch-x86/cpufeatureset.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/public/arch-x86/cpufeatureset.h	2021-06-17 20:45:39.000000000 +0200
@@ -197,14 +197,14 @@
 XEN_CPUFEATURE(TSC_ADJUST,    5*32+ 1) /*S  TSC_ADJUST MSR available */
 XEN_CPUFEATURE(SGX,           5*32+ 2) /*   Software Guard extensions */
 XEN_CPUFEATURE(BMI1,          5*32+ 3) /*A  1st bit manipulation extensions */
-XEN_CPUFEATURE(HLE,           5*32+ 4) /*A  Hardware Lock Elision */
+XEN_CPUFEATURE(HLE,           5*32+ 4) /*!a Hardware Lock Elision */
 XEN_CPUFEATURE(AVX2,          5*32+ 5) /*A  AVX2 instructions */
 XEN_CPUFEATURE(FDP_EXCP_ONLY, 5*32+ 6) /*!  x87 FDP only updated on exception. */
 XEN_CPUFEATURE(SMEP,          5*32+ 7) /*S  Supervisor Mode Execution Protection */
 XEN_CPUFEATURE(BMI2,          5*32+ 8) /*A  2nd bit manipulation extensions */
 XEN_CPUFEATURE(ERMS,          5*32+ 9) /*A  Enhanced REP MOVSB/STOSB */
 XEN_CPUFEATURE(INVPCID,       5*32+10) /*H  Invalidate Process Context ID */
-XEN_CPUFEATURE(RTM,           5*32+11) /*A  Restricted Transactional Memory */
+XEN_CPUFEATURE(RTM,           5*32+11) /*!A Restricted Transactional Memory */
 XEN_CPUFEATURE(PQM,           5*32+12) /*   Platform QoS Monitoring */
 XEN_CPUFEATURE(NO_FPU_SEL,    5*32+13) /*!  FPU CS/DS stored as zero */
 XEN_CPUFEATURE(MPX,           5*32+14) /*s  Memory Protection Extensions */
@@ -261,6 +261,7 @@
 XEN_CPUFEATURE(AVX512_4FMAPS, 9*32+ 3) /*A  AVX512 Multiply Accumulation Single Precision */
 XEN_CPUFEATURE(SRBDS_CTRL,    9*32+ 9) /*   MSR_MCU_OPT_CTRL and RNGDS_MITG_DIS. */
 XEN_CPUFEATURE(MD_CLEAR,      9*32+10) /*A  VERW clears microarchitectural buffers */
+XEN_CPUFEATURE(RTM_ALWAYS_ABORT, 9*32+11) /*! June 2021 TSX defeaturing in microcode. */
 XEN_CPUFEATURE(TSX_FORCE_ABORT, 9*32+13) /* MSR_TSX_FORCE_ABORT.RTM_ABORT */
 XEN_CPUFEATURE(SERIALIZE,     9*32+14) /*a  SERIALIZE insn */
 XEN_CPUFEATURE(CET_IBT,       9*32+20) /*   CET - Indirect Branch Tracking */
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/public/grant_table.h xen-4.14.2+25-gb6a8c4f72d/xen/include/public/grant_table.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/public/grant_table.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/public/grant_table.h	2021-06-17 20:45:39.000000000 +0200
@@ -166,11 +166,13 @@
 #define GTF_type_mask       (3U<<0)
 
 /*
- * Subflags for GTF_permit_access.
+ * Subflags for GTF_permit_access and GTF_transitive.
  *  GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]
  *  GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
  *  GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
- *  GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST]
+ * Further subflags for GTF_permit_access only.
+ *  GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags to be used for
+ *                             mappings of the grant [GST]
  *  GTF_sub_page: Grant access to only a subrange of the page.  @domid
  *                will only be allowed to copy from the grant, and not
  *                map it. [GST]
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/xen/compiler.h xen-4.14.2+25-gb6a8c4f72d/xen/include/xen/compiler.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/xen/compiler.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/xen/compiler.h	2021-06-17 20:45:39.000000000 +0200
@@ -105,6 +105,12 @@
     __asm__ ("" : "=r"(__ptr) : "0"(ptr));      \
     (typeof(ptr)) (__ptr + (off)); })
 
+#if CONFIG_GCC_VERSION >= 110000 /* See gcc bug 100680. */
+# define gcc11_wrap(x) RELOC_HIDE(x, 0)
+#else
+# define gcc11_wrap(x) (x)
+#endif
+
 #ifdef __GCC_ASM_FLAG_OUTPUTS__
 # define ASM_FLAG_OUT(yes, no) yes
 #else
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/xen/cpumask.h xen-4.14.2+25-gb6a8c4f72d/xen/include/xen/cpumask.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/xen/cpumask.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/xen/cpumask.h	2021-06-17 20:45:39.000000000 +0200
@@ -375,7 +375,7 @@
 	     (cpu) = cpumask_next(cpu, mask))
 #else /* NR_CPUS == 1 */
 #define for_each_cpu(cpu, mask)			\
-	for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)(mask))
+	for ((cpu) = 0; (cpu) < cpumask_test_cpu(0, mask); ++(cpu))
 #endif /* NR_CPUS */
 
 /*
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/include/xen/pdx.h xen-4.14.2+25-gb6a8c4f72d/xen/include/xen/pdx.h
--- xen-4.14.1+11-gb0b734a8b3/xen/include/xen/pdx.h	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/include/xen/pdx.h	2021-06-17 20:45:39.000000000 +0200
@@ -19,7 +19,7 @@
 extern void set_pdx_range(unsigned long smfn, unsigned long emfn);
 
 #define page_to_pdx(pg)  ((pg) - frame_table)
-#define pdx_to_page(pdx) (frame_table + (pdx))
+#define pdx_to_page(pdx) gcc11_wrap(frame_table + (pdx))
 
 bool __mfn_valid(unsigned long mfn);
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/Makefile xen-4.14.2+25-gb6a8c4f72d/xen/Makefile
--- xen-4.14.1+11-gb0b734a8b3/xen/Makefile	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/Makefile	2021-06-17 20:45:39.000000000 +0200
@@ -2,7 +2,7 @@
 # All other places this is stored (eg. compile.h) should be autogenerated.
 export XEN_VERSION       = 4
 export XEN_SUBVERSION    = 14
-export XEN_EXTRAVERSION ?= .2-pre$(XEN_VENDORVERSION)
+export XEN_EXTRAVERSION ?= .3-pre$(XEN_VENDORVERSION)
 export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
 -include xen-version
 
diff -Nru xen-4.14.1+11-gb0b734a8b3/xen/scripts/Kbuild.include xen-4.14.2+25-gb6a8c4f72d/xen/scripts/Kbuild.include
--- xen-4.14.1+11-gb0b734a8b3/xen/scripts/Kbuild.include	2021-02-17 01:13:16.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/xen/scripts/Kbuild.include	2021-06-17 20:45:39.000000000 +0200
@@ -43,6 +43,18 @@
     endif
 endef
 
+# $(if-success,<command>,<then>,<else>)
+# Return <then> if <command> exits with 0, <else> otherwise.
+if-success = $(shell { $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)")
+
+# $(success,<command>)
+# Return y if <command> exits with 0, n otherwise
+success = $(call if-success,$(1),y,n)
+
+# $(ld-option,<flag>)
+# Return y if the linker supports <flag>, n otherwise
+ld-option = $(call success,$(LD) -v $(1))
+
 # cc-ifversion
 # Usage:  EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
 cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4))
diff -Nru xen-4.14.2+25-gb6a8c4f72d/debian/changelog xen-4.14.2+25-gb6a8c4f72d/debian/changelog
--- xen-4.14.2+25-gb6a8c4f72d/debian/changelog	2021-07-11 14:29:13.000000000 +0200
+++ xen-4.14.2+25-gb6a8c4f72d/debian/changelog	2021-07-30 16:57:52.000000000 +0200
@@ -1,3 +1,10 @@
+xen (4.14.2+25-gb6a8c4f72d-2) unstable; urgency=medium
+
+  * Add README.Debian.security containing a note about the end of upstream
+    security support for Xen 4.14. Install it into xen-hypervisor-common.
+
+ -- Hans van Kranenburg <hans@knorrie.org>  Fri, 30 Jul 2021 16:57:52 +0200
+
 xen (4.14.2+25-gb6a8c4f72d-1) unstable; urgency=medium
 
   * Update to new upstream version 4.14.2+25-gb6a8c4f72d, which also contains
diff -Nru xen-4.14.2+25-gb6a8c4f72d/debian/README.Debian.security xen-4.14.2+25-gb6a8c4f72d/debian/README.Debian.security
--- xen-4.14.2+25-gb6a8c4f72d/debian/README.Debian.security	1970-01-01 01:00:00.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/README.Debian.security	2021-07-30 16:57:52.000000000 +0200
@@ -0,0 +1,17 @@
+Notes about security support for Xen in Debian
+==============================================
+
+Upstream security support for Xen 4.14 will end on Jul 7, 2023:
+
+---- >8 ----
+Xen-Version: 4.14
+Initial-Release: 2020-07-24
+Supported-Until: 2022-01-24
+Security-Support-Until: 2023-07-24
+---- >8 ----
+
+At the same moment, security support in Debian will also end.
+
+The document containing the above snippet of information can be found in the
+xen-doc package, at /usr/share/doc/xen/html/SUPPORT.html or online at
+https://xenbits.xen.org/docs/4.14-testing/SUPPORT.html#release-support
diff -Nru xen-4.14.2+25-gb6a8c4f72d/debian/xen-hypervisor-common.docs xen-4.14.2+25-gb6a8c4f72d/debian/xen-hypervisor-common.docs
--- xen-4.14.2+25-gb6a8c4f72d/debian/xen-hypervisor-common.docs	1970-01-01 01:00:00.000000000 +0100
+++ xen-4.14.2+25-gb6a8c4f72d/debian/xen-hypervisor-common.docs	2021-07-30 16:57:52.000000000 +0200
@@ -0,0 +1 @@
+debian/README.Debian.security

Reply to: