public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/xen] f44: update to xen 4.21.2
@ 2026-07-30 15:02 Michael Young
  0 siblings, 0 replies; only message in thread
From: Michael Young @ 2026-07-30 15:02 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/xen
            Branch : f44
            Commit : bbef6d9f4f233ed7e1f60af2f35e8ab59d530474
            Author : Michael Young <m.a.young@durham.ac.uk>
            Date   : 2026-07-30T15:57:36+01:00
            Stats  : +24/-4532 in 35 file(s)
            URL    : https://src.fedoraproject.org/rpms/xen/c/bbef6d9f4f233ed7e1f60af2f35e8ab59d530474?branch=f44

            Log:
            update to xen 4.21.2

includes multiple security fixes

---
diff --git a/.gitignore b/.gitignore
index 6b74118..a99a4eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,4 @@ pciutils-2.2.9.tar.bz2
 zlib-1.2.3.tar.gz
 polarssl-1.1.4-gpl.tgz
 /mini-os-4.21.0.tar.xz
-/xen-4.21.1.tar.xz
+/xen-4.21.2.tar.xz

diff --git a/sources b/sources
index 4b30fea..8fc67c3 100644
--- a/sources
+++ b/sources
@@ -5,4 +5,4 @@ SHA512 (zlib-1.2.3.tar.gz) = 021b958fcd0d346c4ba761bcf0cc40f3522de6186cf5a0a6ea3
 SHA512 (polarssl-1.1.4-gpl.tgz) = 88da614e4d3f4409c4fd3bb3e44c7587ba051e3fed4e33d526069a67e8180212e1ea22da984656f50e290049f60ddca65383e5983c0f8884f648d71f698303ad
 SHA512 (pciutils-2.2.9.tar.bz2) = 2b3d98d027e46d8c08037366dde6f0781ca03c610ef2b380984639e4ef39899ed8d8b8e4cd9c9dc54df101279b95879bd66bfd4d04ad07fef41e847ea7ae32b5
 SHA512 (mini-os-4.21.0.tar.xz) = 7543774d15da84476d93d04154990923c82209cb3fa125574c0383652c5a310957200f54b63b34502161f9c3afce4907e0060d9036f3eaf3a7cb6b1b3119b546
-SHA512 (xen-4.21.1.tar.xz) = 8dfe65255e202b3dacf9d0d7265636bc1f97627c11b08babc13a5b8e74c7c65e7e2c6a1513e28b3c713fe512edb6702a73b2bf667e2a8f2ce825b196a2cd5aab
+SHA512 (xen-4.21.2.tar.xz) = 78de26ab01f06024890e867c0b4a38d4a590ecffebc18f8dafa842baeb144b0f0463f2cf241eb3b081179b357ddf5ee389d883ca23a12a2be51ba3161fb8c0fd

diff --git a/xen.git-90b20547b756a5cf9b0fec9fb0de5b361e8bf4c3.patch b/xen.git-90b20547b756a5cf9b0fec9fb0de5b361e8bf4c3.patch
deleted file mode 100644
index a5e65ba..0000000
--- a/xen.git-90b20547b756a5cf9b0fec9fb0de5b361e8bf4c3.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 90b20547b756a5cf9b0fec9fb0de5b361e8bf4c3 Mon Sep 17 00:00:00 2001
-From: Andrew Cooper <andrew.cooper3@citrix.com>
-Date: Fri, 10 Apr 2026 21:55:46 +0100
-Subject: [PATCH] x86/amd: Mitigate AMD-SN-7053 / FP-DSS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=utf8
-Content-Transfer-Encoding: 8bit
-
-This is XSA-488 / CVE-2025-54505
-
-Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-(cherry picked from commit 99912d346009fda1e7fb1510c9501fbab17e92a0)
----
- xen/arch/x86/cpu/amd.c               | 37 ++++++++++++++++++++++++++++
- xen/arch/x86/include/asm/msr-index.h |  1 +
- 2 files changed, 38 insertions(+)
-
-diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
-index 8c55d233f3..1bb0766ebf 100644
---- a/xen/arch/x86/cpu/amd.c
-+++ b/xen/arch/x86/cpu/amd.c
-@@ -1048,6 +1048,42 @@ void amd_init_de_cfg(const struct cpuinfo_x86 *c)
-     wrmsrl(MSR_AMD64_DE_CFG, val | new);
- }
- 
-+static void amd_init_fp_cfg(const struct cpuinfo_x86 *c)
-+{
-+    uint64_t val, new = 0;
-+
-+    /* If virtualised, we won't have mutable access even if we can read it. */
-+    if ( cpu_has_hypervisor )
-+        return;
-+
-+    /*
-+     * On Zen1, mitigate SB-7053 / FP-DSS Floating Point Divider State
-+     * Sampling by setting bit 9 as instructed.
-+     */
-+    if ( c->family == 0x17 && is_zen1_uarch() )
-+        new |= 1 << 9;
-+
-+    /*
-+     * Avoid reading FP_CFG if we don't intend to change anything.  The
-+     * register doesn't exist on all families.
-+     */
-+    if ( !new )
-+        return;
-+
-+    val = rdmsr(MSR_AMD64_FP_CFG);
-+
-+    if ( (val & new) == new )
-+        return;
-+
-+    /*
-+     * FP_CFG is a Core-scoped MSR, and this write is racy.  However, both
-+     * threads calculate the new value from state which expected to be
-+     * consistent across CPUs and unrelated to the old value, so the result
-+     * should be consistent.
-+     */
-+    wrmsr(MSR_AMD64_FP_CFG, val | new);
-+}
-+
- void __init amd_init_lfence_dispatch(void)
- {
-     struct cpuinfo_x86 *c = &boot_cpu_data;
-@@ -1120,6 +1156,7 @@ static void cf_check init_amd(struct cpuinfo_x86 *c)
- 	uint64_t value;
- 
- 	amd_init_de_cfg(c);
-+	amd_init_fp_cfg(c);
- 
- 	if (c == &boot_cpu_data)
- 		amd_init_lfence_dispatch(); /* Needs amd_init_de_cfg() */
-diff --git a/xen/arch/x86/include/asm/msr-index.h b/xen/arch/x86/include/asm/msr-index.h
-index df52587c85..6c5b2569e1 100644
---- a/xen/arch/x86/include/asm/msr-index.h
-+++ b/xen/arch/x86/include/asm/msr-index.h
-@@ -428,6 +428,7 @@
- #define MSR_AMD64_LS_CFG		0xc0011020U
- #define MSR_AMD64_IC_CFG		0xc0011021U
- #define MSR_AMD64_DC_CFG		0xc0011022U
-+#define MSR_AMD64_FP_CFG		0xc0011028U
- #define MSR_AMD64_DE_CFG		0xc0011029U
- #define AMD64_DE_CFG_LFENCE_SERIALISE	(_AC(1, ULL) << 1)
- #define MSR_AMD64_EX_CFG		0xc001102cU
--- 
-2.39.5
-

diff --git a/xen.json.nocpuid.patch b/xen.json.nocpuid.patch
deleted file mode 100644
index f701f0d..0000000
--- a/xen.json.nocpuid.patch
+++ /dev/null
@@ -1,27 +0,0 @@
---- xen-4.21.0/tools/libs/light/libxl_nocpuid.c.orig	2025-11-18 18:02:13.000000000 +0000
-+++ xen-4.21.0/tools/libs/light/libxl_nocpuid.c	2025-11-20 09:03:56.517804514 +0000
-@@ -40,11 +40,24 @@
-     return 0;
- }
- 
-+#ifdef HAVE_LIBJSONC
-+#ifndef _hidden
-+#define _hidden
-+#endif
-+_hidden int libxl_cpuid_policy_list_gen_jso(json_object **jso_r,
-+                                libxl_cpuid_policy_list *pcpuid)
-+{
-+    return 0;
-+}
-+#endif
-+
-+#if defined(HAVE_LIBYAJL)
- yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
-                                 libxl_cpuid_policy_list *pcpuid)
- {
-     return 0;
- }
-+#endif
- 
- int libxl__cpuid_policy_list_parse_json(libxl__gc *gc,
-                                         const libxl__json_object *o,

diff --git a/xen.spec b/xen.spec
index 7656e6b..27c1305 100644
--- a/xen.spec
+++ b/xen.spec
@@ -50,8 +50,8 @@
 
 Summary: Xen is a virtual machine monitor
 Name:    xen
-Version: 4.21.1
-Release: 4%{?dist}
+Version: 4.21.2
+Release: 1%{?dist}
 # Automatically converted from old format: GPLv2+ and LGPLv2+ and BSD - review is highly recommended.
 License: GPL-2.0-or-later AND LicenseRef-Callaway-LGPLv2+ AND LicenseRef-Callaway-BSD
 URL:     http://xen.org/
@@ -78,38 +78,6 @@ Patch6: xen.gcc11.fixes.patch
 Patch7: xen.gcc12.fixes.patch
 Patch8: xen.efi.build.patch
 Patch9: xen.python3.12.patch
-Patch11: xen.json.nocpuid.patch
-Patch12: xsa483.patch
-Patch13: xsa484.patch
-Patch14: xsa486.patch
-Patch15: xen.git-90b20547b756a5cf9b0fec9fb0de5b361e8bf4c3.patch
-Patch16: xsa490-4.21.patch
-Patch17: xsa491-4.21.patch
-Patch18: xsa492-4.21-01.patch
-Patch19: xsa492-4.21-02.patch
-Patch20: xsa492-4.21-03.patch
-Patch21: xsa492-4.21-04.patch
-Patch22: xsa492-4.21-05.patch
-Patch23: xsa492-4.21-06.patch
-Patch24: xsa492-4.21-07.patch
-Patch25: xsa492-4.21-08.patch
-Patch26: xsa492-4.21-09.patch
-Patch27: xsa492-4.21-10.patch
-Patch28: xsa492-4.21-11.patch
-Patch29: xsa492-4.21-12.patch
-Patch30: xsa492-4.21-13.patch
-Patch31: xsa492-4.21-14.patch
-Patch32: xsa492-4.21-15.patch
-Patch33: xsa492-4.21-16.patch
-Patch34: xsa492-4.21-17.patch
-Patch35: xsa492-4.21-18.patch
-Patch36: xsa492-4.21-19.patch
-Patch37: xsa492-4.21-20.patch
-Patch38: xsa493-4.21-01.patch
-Patch39: xsa493-4.21-02.patch
-Patch40: xsa493-4.21-03.patch
-Patch41: xsa493-4.21-04.patch
-Patch42: xsa494-4.21.patch
 
 
 # build using Fedora seabios and ipxe packages for roms
@@ -295,38 +263,6 @@ This package contains files used in testing the xen builds
 %patch 7 -p1
 %patch 8 -p1
 %patch 9 -p1
-%patch 11 -p1
-%patch 12 -p1
-%patch 13 -p1
-%patch 14 -p1
-%patch 15 -p1
-%patch 16 -p1
-%patch 17 -p1
-%patch 18 -p1
-%patch 19 -p1
-%patch 20 -p1
-%patch 21 -p1
-%patch 22 -p1
-%patch 23 -p1
-%patch 24 -p1
-%patch 25 -p1
-%patch 26 -p1
-%patch 27 -p1
-%patch 28 -p1
-%patch 29 -p1
-%patch 30 -p1
-%patch 31 -p1
-%patch 32 -p1
-%patch 33 -p1
-%patch 34 -p1
-%patch 35 -p1
-%patch 36 -p1
-%patch 37 -p1
-%patch 38 -p1
-%patch 39 -p1
-%patch 40 -p1
-%patch 41 -p1
-%patch 42 -p1
 
 # stubdom sources
 cp -v %{SOURCE10} %{SOURCE11} %{SOURCE12} %{SOURCE13} %{SOURCE14} %{SOURCE15} stubdom
@@ -882,6 +818,26 @@ fi
 %{_libexecdir}/xen/tests/*
 
 %changelog
+* Thu Jul 30 2026 Michael Young <m.a.young@durham.ac.uk> - 4.21.2-1
+- update to xen 4.21.2
+- includes security fixes
+  x86 shadow paging is deprecated [XSA-495, CVE-2026-42493]
+  vIRQ event channel binding may break Xenstore [XSA-496, CVE-2026-42492]
+  buffer overruns in libfsimage iso9660 handling [XSA-497, CVE-2026-42494,
+	CVE-2026-42495, CVE-2026-62423, CVE-2026-62424, CVE-2026-62425]
+  sysctl and platform-op locks open to abuse [XSA-499, CVE-2026-62426,
+	CVE-2026-62427]
+  grant-table: type confusion in grant-copy [XSA-500, CVE-2026-62428]
+  grant-table: version change racing with other operations [XSA-501,
+	CVE-2026-62435, CVE-2026-62436]
+  vNUMA domain cleanup may race other operations [XSA-502, CVE-2026-62429]
+  x86: Out-of-bounds read in vRTC emulation [XSA-503, CVE-2026-62430]
+  Viridian STIMER division by zero [XSA-504, CVE-2026-62431]
+  evtchn: Race between FIFO expand and reset [XSA-505, CVE-2026-62432]
+  correct buffer checks for DM_OP hypercalls [XSA-506, CVE-2026-62433]
+  PoD: Don't try to reclaim special pages [XSA-507, CVE-2026-62434]
+  pygrub is only supported in de-privileged mode [XSA-508]
+
 * Fri Jun 12 2026 Michael Young <m.a.young@durham.ac.uk> - 4.21.1-4
 - x86 HVM I/O port list traversal [XSA-491, CVE-2026-42487]
 - domctl lock open to abuse [XSA-492, CVE-2026-42489, CVE-2026-42490]

diff --git a/xsa483.patch b/xsa483.patch
deleted file mode 100644
index 8ecb2e9..0000000
--- a/xsa483.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: Andrii Sultanov <andriy.sultanov@vates.tech>
-Subject: tools/oxenstored: Reset quota when resetting permissions
-
-The quota object contains both limits and the current node usage counts.
-
-When a domain is torn down, the node data itself is cleaned up but the node
-usage counts are not.  A later domain reusing the same domid can create fewer
-nodes before being deemed to be over quota.
-
-Reset the count when the node permissions are cleaned up.
-
-This is XSA-483 / CVE-2026-23556.
-
-Signed-off-by: Andrii Sultanov <andriy.sultanov@vates.tech>
-Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
-
-diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
-index 9b8dd2812df0..aa9204ead3ec 100644
---- a/tools/ocaml/xenstored/store.ml
-+++ b/tools/ocaml/xenstored/store.ml
-@@ -465,7 +465,8 @@ let reset_permissions store domid =
-         if perms <> node.perms then
-           Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
-         Some { node with Node.perms }
--    ) store.root
-+    ) store.root;
-+  store.quota <- Quota.del store.quota domid
- 
- type ops = {
-   store: t;

diff --git a/xsa484.patch b/xsa484.patch
deleted file mode 100644
index 522549e..0000000
--- a/xsa484.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From 3d0d19ad17f29c64dde4a7baf392da4fd58f3654 Mon Sep 17 00:00:00 2001
-From: Juergen Gross <jgross@suse.com>
-Date: Mon, 16 Mar 2026 15:06:11 +0100
-Subject: [PATCH] tools/xenstored: make conn_delete_all_transactions()
- idempotent
-
-conn_delete_all_transactions() should be callable in any context,
-resetting ALL transaction related data.
-
-This includes number of active transactions and the transaction
-pointer in struct connection.
-
-So reset conn->trans to NULL in conn_delete_all_transactions() and
-do the cleanup for each transaction in destroy_transaction().
-
-This avoids triggering the assert() in conn_delete_all_transactions()
-in case e.g. ignore_connection() was called while an operation inside
-a transaction was performed, or XS_RESET_WATCHES was called in a
-transaction.
-
-This is XSA-484 / CVE-2026-23557.
-
-Reported-by: Andrii Sultanov <andriy.sultanov@vates.tech>
-Fixes: 1f9d04fb021c ("xenstored: allow guest to shutdown all its watches/transactions")
-Signed-off-by: Juergen Gross <jgross@suse.com>
----
- tools/xenstored/transaction.c | 20 +++++++++-----------
- 1 file changed, 9 insertions(+), 11 deletions(-)
-
-diff --git a/tools/xenstored/transaction.c b/tools/xenstored/transaction.c
-index 167cd597fd..0825c48859 100644
---- a/tools/xenstored/transaction.c
-+++ b/tools/xenstored/transaction.c
-@@ -432,17 +432,23 @@ static int finalize_transaction(struct connection *conn,
- static int destroy_transaction(void *_transaction)
- {
- 	struct transaction *trans = _transaction;
-+	struct connection *conn = trans->conn;
- 	struct accessed_node *i;
- 
- 	wrl_ntransactions--;
- 	trace_destroy(trans, "transaction");
- 	while ((i = list_top(&trans->accessed, struct accessed_node, list))) {
- 		if (i->ta_node)
--			db_delete(trans->conn, i->trans_name, NULL);
-+			db_delete(conn, i->trans_name, NULL);
- 		list_del(&i->list);
- 		talloc_free(i);
- 	}
- 
-+	list_del(&trans->list);
-+	domain_transaction_dec(conn);
-+	if (list_empty(&conn->transaction_list))
-+		conn->ta_start_time = 0;
-+
- 	return 0;
- }
- 
-@@ -523,10 +529,6 @@ int do_transaction_end(const void *ctx, struct connection *conn,
- 		return ENOENT;
- 
- 	conn->transaction = NULL;
--	list_del(&trans->list);
--	domain_transaction_dec(conn);
--	if (list_empty(&conn->transaction_list))
--		conn->ta_start_time = 0;
- 
- 	chk_quota = trans->node_created && domain_is_unprivileged(conn);
- 
-@@ -572,14 +574,10 @@ void conn_delete_all_transactions(struct connection *conn)
- 	struct transaction *trans;
- 
- 	while ((trans = list_top(&conn->transaction_list,
--				 struct transaction, list))) {
--		list_del(&trans->list);
-+				 struct transaction, list)))
- 		talloc_free(trans);
--	}
--
--	assert(conn->transaction == NULL);
- 
--	conn->ta_start_time = 0;
-+	conn->transaction = NULL;
- }
- 
- int check_transactions(struct hashtable *hash)
--- 
-2.53.0
-

diff --git a/xsa486.patch b/xsa486.patch
deleted file mode 100644
index 654e957..0000000
--- a/xsa486.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: gnttab: split gnttab_map_frame()
-
-If a domain tries to map status frames in parallel to switching grant
-table version from 2 to 1, the mapping operation may put in place P2M
-entries referencing MFNs which gnttab_unpopulate_status_frames() is in the
-process of freeing.
-
-Ideally we would refcount pages when entered into P2M tables, but that's a
-significant change. Extend the grant-table-locked region instead in
-xenmem_add_to_physmap_one() (being the sole caller of gnttab_map_frame()),
-such that a race with gnttab_unpopulate_status_frames() is no longer
-possible.
-
-This is XSA-486 / CVE-2026-23558.
-
-Fixes: 5ce8fafa947c ("Dynamic grant-table sizing")
-Fixes: a98dc13703e0 ("Introduce a grant_entry_v2 structure")
-Reported-by: Rafal Wojtczuk <rafal.wojtczuk@7bulls.com>
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/arch/arm/mm.c
-+++ b/xen/arch/arm/mm.c
-@@ -174,12 +174,10 @@ int xenmem_add_to_physmap_one(
-     switch ( space )
-     {
-     case XENMAPSPACE_grant_table:
--        rc = gnttab_map_frame(d, idx, gfn, &mfn);
-+        rc = gnttab_map_frame_begin(d, idx, gfn, &mfn);
-         if ( rc )
-             return rc;
- 
--        /* Need to take care of the reference obtained in gnttab_map_frame(). */
--        page = mfn_to_page(mfn);
-         t = p2m_ram_rw;
- 
-         break;
-@@ -281,10 +279,23 @@ int xenmem_add_to_physmap_one(
-      * to drop the reference we took earlier. In all other cases we need to
-      * drop any reference we took earlier (perhaps indirectly).
-      */
--    if ( space == XENMAPSPACE_gmfn_foreign ? rc : page != NULL )
-+    switch ( space )
-     {
-+    default:
-+        if ( page )
-+            put_page(page);
-+        break;
-+
-+    case XENMAPSPACE_grant_table:
-+        gnttab_map_frame_end(d, mfn);
-+        break;
-+
-+    case XENMAPSPACE_gmfn_foreign:
-+        if ( !rc )
-+            break;
-         ASSERT(page != NULL);
-         put_page(page);
-+        break;
-     }
- 
-     return rc;
---- a/xen/arch/x86/mm/p2m.c
-+++ b/xen/arch/x86/mm/p2m.c
-@@ -2009,11 +2009,9 @@ int xenmem_add_to_physmap_one(
-         break;
- 
-     case XENMAPSPACE_grant_table:
--        rc = gnttab_map_frame(d, idx, gfn, &mfn);
-+        rc = gnttab_map_frame_begin(d, idx, gfn, &mfn);
-         if ( rc )
-             return rc;
--        /* Need to take care of the reference obtained in gnttab_map_frame(). */
--        page = mfn_to_page(mfn);
-         break;
- 
-     case XENMAPSPACE_gmfn:
-@@ -2095,19 +2093,28 @@ int xenmem_add_to_physmap_one(
-     put_gfn(d, gfn_x(gfn));
- 
-  put_both:
--    /*
--     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
--     * We also may need to transfer ownership of the page reference to our
--     * caller.
--     */
--    if ( space == XENMAPSPACE_gmfn )
-+    switch ( space )
-     {
-+    case XENMAPSPACE_gmfn:
-+        /*
-+         * We took a ref of the gfn at the top.  We also may need to transfer
-+         * ownership of the page reference to our caller.
-+         */
-         put_gfn(d, gmfn);
-         if ( !rc && extra.ppage )
-         {
-             *extra.ppage = page;
-             page = NULL;
-         }
-+        break;
-+
-+    case XENMAPSPACE_grant_table:
-+        /*
-+         * We (gnttab_map_frame_begin()) acquired a lock and took a ref of the
-+         * page underlying the MFN at the top.
-+         */
-+        gnttab_map_frame_end(d, mfn);
-+        break;
-     }
- 
-     if ( page )
---- a/xen/common/grant_table.c
-+++ b/xen/common/grant_table.c
-@@ -4250,7 +4250,8 @@ int gnttab_acquire_resource(
-     return rc;
- }
- 
--int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, mfn_t *mfn)
-+int gnttab_map_frame_begin(
-+    struct domain *d, unsigned long idx, gfn_t gfn, mfn_t *mfn)
- {
-     int rc = 0;
-     struct grant_table *gt = d->grant_table;
-@@ -4288,11 +4289,19 @@ int gnttab_map_frame(struct domain *d, u
-             put_page(pg);
-     }
- 
--    grant_write_unlock(gt);
-+    if ( rc )
-+        grant_write_unlock(d->grant_table);
- 
-     return rc;
- }
- 
-+void gnttab_map_frame_end(struct domain *d, mfn_t mfn)
-+{
-+    put_page(mfn_to_page(mfn));
-+
-+    grant_write_unlock(d->grant_table);
-+}
-+
- static void gnttab_usage_print(struct domain *rd)
- {
-     int first = 1;
---- a/xen/include/xen/grant_table.h
-+++ b/xen/include/xen/grant_table.h
-@@ -60,8 +60,13 @@ int gnttab_release_mappings(struct domai
- int mem_sharing_gref_to_gfn(struct grant_table *gt, grant_ref_t ref,
-                             gfn_t *gfn, uint16_t *status);
- 
--int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn,
--                     mfn_t *mfn);
-+/*
-+ * These need to be used as a pair, as the first (in the success case) returns
-+ * with a lock and page reference held which the second needs to drop.
-+ */
-+int gnttab_map_frame_begin(struct domain *d, unsigned long idx, gfn_t gfn,
-+                           mfn_t *mfn);
-+void gnttab_map_frame_end(struct domain *d, mfn_t mfn);
- 
- unsigned int gnttab_resource_max_frames(const struct domain *d, unsigned int id);
- 
-@@ -100,12 +105,14 @@ static inline int mem_sharing_gref_to_gf
-     return -EINVAL;
- }
- 
--static inline int gnttab_map_frame(struct domain *d, unsigned long idx,
--                                   gfn_t gfn, mfn_t *mfn)
-+static inline int gnttab_map_frame_begin(struct domain *d, unsigned long idx,
-+                                         gfn_t gfn, mfn_t *mfn)
- {
-     return -EINVAL;
- }
- 
-+static inline void gnttab_map_frame_end(struct domain *d, mfn_t mfn) {}
-+
- static inline unsigned int gnttab_resource_max_frames(
-     const struct domain *d, unsigned int id)
- {

diff --git a/xsa490-4.21.patch b/xsa490-4.21.patch
deleted file mode 100644
index 5a560cb..0000000
--- a/xsa490-4.21.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From: Andrew Cooper <andrew.cooper3@citrix.com>
-Subject: x86/amd: Mitigate AMD-SN-7052
-
-This is XSA-490 / CVE-2025-54518.
-
-Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
-diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
-index 1bb0766ebf13..b5bf2b732e8f 100644
---- a/xen/arch/x86/cpu/amd.c
-+++ b/xen/arch/x86/cpu/amd.c
-@@ -1116,11 +1116,25 @@ static void amd_check_bp_cfg(void)
- {
- 	uint64_t val, new = 0;
- 
--	/*
--	 * AMD Erratum #1485.  Set bit 5, as instructed.
--	 */
--	if (!cpu_has_hypervisor && boot_cpu_data.x86 == 0x19 && is_zen4_uarch())
--		new |= (1 << 5);
-+	if (!cpu_has_hypervisor) {
-+		/*
-+		 * AMD Erratum #1485.  If SMT is enabled and STIBP disabled,
-+		 * the CPU may fetch incorrect instruction bytes.
-+		 *
-+		 * Set bit 5, as instructed.
-+		 */
-+		if (boot_cpu_data.x86 == 0x19 && is_zen4_uarch())
-+			new |= (1 << 5);
-+
-+		/*
-+		 * AMD SB-7052.  CPU OP Cache corruption, causing instructions
-+		 * to be executed at a higher privilege.
-+		 *
-+		 * Set bit 33, as instructed.
-+		 */
-+		if (boot_cpu_data.x86 == 0x17 && is_zen2_uarch())
-+			new |= (1UL << 33);
-+	}
- 
- 	/*
- 	 * On hardware supporting SRSO_MSR_FIX, activate BP_SPEC_REDUCE by

diff --git a/xsa491-4.21.patch b/xsa491-4.21.patch
deleted file mode 100644
index d1ebc1a..0000000
--- a/xsa491-4.21.patch
+++ /dev/null
@@ -1,211 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: x86/HVM: add locking to I/O port translation list traversal
-
-XEN_DOMCTL_ioport_mapping is usable by DM stubdoms, and hence we can't
-assume the list to be left unaltered while the guest (really: the
-hypervisor on behalf of the guest) is accessing it.
-
-This is XSA-491 / CVE-2026-42487.
-
-Fixes: 192c4dabc344 ("domctl and p2m changes for PCI passthru")
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/arch/x86/domctl.c
-+++ b/xen/arch/x86/domctl.c
-@@ -663,6 +663,7 @@ long arch_do_domctl(
-                    "ioport_map:add: dom%d gport=%x mport=%x nr=%x\n",
-                    d->domain_id, fgp, fmp, np);
- 
-+            write_lock(&hvm->g2m_ioport_lock);
-             list_for_each_entry(g2m_ioport, &hvm->g2m_ioport_list, list)
-                 if (g2m_ioport->mport == fmp )
-                 {
-@@ -684,11 +685,14 @@ long arch_do_domctl(
-                 g2m_ioport->np = np;
-                 list_add_tail(&g2m_ioport->list, &hvm->g2m_ioport_list);
-             }
-+            write_unlock(&hvm->g2m_ioport_lock);
-             if ( !ret )
-                 ret = ioports_permit_access(d, fmp, fmp + np - 1);
-             if ( ret && !found && g2m_ioport )
-             {
-+                write_lock(&hvm->g2m_ioport_lock);
-                 list_del(&g2m_ioport->list);
-+                write_unlock(&hvm->g2m_ioport_lock);
-                 xfree(g2m_ioport);
-             }
-         }
-@@ -697,6 +701,8 @@ long arch_do_domctl(
-             printk(XENLOG_G_INFO
-                    "ioport_map:remove: dom%d gport=%x mport=%x nr=%x\n",
-                    d->domain_id, fgp, fmp, np);
-+
-+            write_lock(&hvm->g2m_ioport_lock);
-             list_for_each_entry(g2m_ioport, &hvm->g2m_ioport_list, list)
-                 if ( g2m_ioport->mport == fmp )
-                 {
-@@ -704,6 +710,8 @@ long arch_do_domctl(
-                     xfree(g2m_ioport);
-                     break;
-                 }
-+            write_unlock(&hvm->g2m_ioport_lock);
-+
-             ret = ioports_deny_access(d, fmp, fmp + np - 1);
-             if ( ret && is_hardware_domain(currd) )
-                 printk(XENLOG_ERR
---- a/xen/arch/x86/hvm/emulate.c
-+++ b/xen/arch/x86/hvm/emulate.c
-@@ -160,7 +160,6 @@ void hvmemul_cancel(struct vcpu *v)
-     hvio->mmio_insn_bytes = 0;
-     hvio->mmio_access = (struct npfec){};
-     hvio->mmio_retry = false;
--    hvio->g2m_ioport = NULL;
- 
-     hvmemul_cache_disable(v);
- }
---- a/xen/arch/x86/hvm/hvm.c
-+++ b/xen/arch/x86/hvm/hvm.c
-@@ -610,6 +610,7 @@ int hvm_domain_initialise(struct domain
-     spin_lock_init(&d->arch.hvm.irq_lock);
-     spin_lock_init(&d->arch.hvm.uc_lock);
-     spin_lock_init(&d->arch.hvm.write_map.lock);
-+    rwlock_init(&d->arch.hvm.g2m_ioport_lock);
-     rwlock_init(&d->arch.hvm.mmcfg_lock);
-     INIT_LIST_HEAD(&d->arch.hvm.write_map.list);
-     INIT_LIST_HEAD(&d->arch.hvm.g2m_ioport_list);
---- a/xen/arch/x86/hvm/io.c
-+++ b/xen/arch/x86/hvm/io.c
-@@ -143,36 +143,56 @@ bool handle_pio(uint16_t port, unsigned
-     return true;
- }
- 
--static bool cf_check g2m_portio_accept(
--    const struct hvm_io_handler *handler, const ioreq_t *p)
-+/* NB: Returns with the lock held in the success case. */
-+static const struct g2m_ioport *g2m_portio_find_and_lock(struct hvm_domain *hvm,
-+                                                         uint64_t addr,
-+                                                         uint32_t size)
- {
--    struct vcpu *curr = current;
--    const struct hvm_domain *hvm = &curr->domain->arch.hvm;
--    struct hvm_vcpu_io *hvio = &curr->arch.hvm.hvm_io;
--    struct g2m_ioport *g2m_ioport;
--    unsigned int start, end;
-+    const struct g2m_ioport *g2m_ioport;
-+
-+    read_lock(&hvm->g2m_ioport_lock);
- 
-     list_for_each_entry( g2m_ioport, &hvm->g2m_ioport_list, list )
-     {
--        start = g2m_ioport->gport;
--        end = start + g2m_ioport->np;
--        if ( (p->addr >= start) && (p->addr + p->size <= end) )
--        {
--            hvio->g2m_ioport = g2m_ioport;
--            return 1;
--        }
-+        unsigned int start = g2m_ioport->gport;
-+
-+        if ( addr >= start && addr + size <= start + g2m_ioport->np )
-+            return g2m_ioport;
-     }
- 
--    return 0;
-+    read_unlock(&hvm->g2m_ioport_lock);
-+
-+    return NULL;
-+}
-+
-+static bool cf_check g2m_portio_accept(
-+    const struct hvm_io_handler *handler, const ioreq_t *p)
-+{
-+    struct hvm_domain *hvm = &current->domain->arch.hvm;
-+    const struct g2m_ioport *g2m_ioport =
-+        g2m_portio_find_and_lock(hvm, p->addr, p->size);
-+
-+    if ( !g2m_ioport )
-+        return false;
-+
-+    read_unlock(&hvm->g2m_ioport_lock);
-+
-+    return true;
- }
- 
- static int cf_check g2m_portio_read(
-     const struct hvm_io_handler *handler, uint64_t addr, uint32_t size,
-     uint64_t *data)
- {
--    struct hvm_vcpu_io *hvio = &current->arch.hvm.hvm_io;
--    const struct g2m_ioport *g2m_ioport = hvio->g2m_ioport;
--    unsigned int mport = (addr - g2m_ioport->gport) + g2m_ioport->mport;
-+    struct hvm_domain *hvm = &current->domain->arch.hvm;
-+    const struct g2m_ioport *g2m_ioport =
-+        g2m_portio_find_and_lock(hvm, addr, size);
-+    unsigned int mport;
-+
-+    if ( !g2m_ioport )
-+        return X86EMUL_RETRY;
-+
-+    mport = addr - g2m_ioport->gport + g2m_ioport->mport;
- 
-     switch ( size )
-     {
-@@ -189,6 +209,8 @@ static int cf_check g2m_portio_read(
-         BUG();
-     }
- 
-+    read_unlock(&hvm->g2m_ioport_lock);
-+
-     return X86EMUL_OKAY;
- }
- 
-@@ -196,9 +218,15 @@ static int cf_check g2m_portio_write(
-     const struct hvm_io_handler *handler, uint64_t addr, uint32_t size,
-     uint64_t data)
- {
--    struct hvm_vcpu_io *hvio = &current->arch.hvm.hvm_io;
--    const struct g2m_ioport *g2m_ioport = hvio->g2m_ioport;
--    unsigned int mport = (addr - g2m_ioport->gport) + g2m_ioport->mport;
-+    struct hvm_domain *hvm = &current->domain->arch.hvm;
-+    const struct g2m_ioport *g2m_ioport =
-+        g2m_portio_find_and_lock(hvm, addr, size);
-+    unsigned int mport;
-+
-+    if ( !g2m_ioport )
-+        return X86EMUL_RETRY;
-+
-+    mport = addr - g2m_ioport->gport + g2m_ioport->mport;
- 
-     switch ( size )
-     {
-@@ -215,6 +243,8 @@ static int cf_check g2m_portio_write(
-         BUG();
-     }
- 
-+    read_unlock(&hvm->g2m_ioport_lock);
-+
-     return X86EMUL_OKAY;
- }
- 
---- a/xen/arch/x86/include/asm/hvm/domain.h
-+++ b/xen/arch/x86/include/asm/hvm/domain.h
-@@ -125,6 +125,7 @@ struct hvm_domain {
- 
-     /* List of guest to machine IO ports mapping. */
-     struct list_head g2m_ioport_list;
-+    rwlock_t g2m_ioport_lock;
- 
-     /* List of MMCFG regions trapped by Xen. */
-     struct list_head mmcfg_regions;
---- a/xen/arch/x86/include/asm/hvm/vcpu.h
-+++ b/xen/arch/x86/include/asm/hvm/vcpu.h
-@@ -54,8 +54,6 @@ struct hvm_vcpu_io {
-     unsigned long msix_unmask_address;
-     unsigned long msix_snoop_address;
-     unsigned long msix_snoop_gpa;
--
--    const struct g2m_ioport *g2m_ioport;
- };
- 
- struct nestedvcpu {

diff --git a/xsa492-4.21-01.patch b/xsa492-4.21-01.patch
deleted file mode 100644
index 7244ebd..0000000
--- a/xsa492-4.21-01.patch
+++ /dev/null
@@ -1,264 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: sched: use sequence counter to enlighten vcpu_runstate_get()
-
-Subsequently XEN_DOMCTL_getdomaininfo will want to invoke the function
-without holding a lock, thus allowing parallel execution of potentially
-many instances. As was learned from 228ab9992ffb ("domctl: improve
-locking during domain destruction"), reverted by d0887cc6b16e, such
-parallelism can result in severe lock contention on any (previously)
-inner lock. To avoid taking that risk replace the use of the scheduler
-lock in vcpu_runstate_get() by a newly introduced sequence counter.
-Convert the "no lock if current" property to "use a local counter
-instance", thus guaranteeing the loop to exit after the first iteration.
-
-Skeleton and commentary of the seqcount implementation based on /
-derived from Linux 6.11-rc.
-
-To have runstate_seq placed next to runstate in struct vcpu, without
-introducing a new obvious padding hole, yet while keeping the latter
-adjacent to runstate_guest{,_area} as well, move runstate down a little.
-
-This is part of XSA-492.
-
-Requested-by: Andrew Cooper <andrew.cooper3@citrix.com>
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-Reviewed-by: Juergen Gross <jgross@suse.com>
-
---- a/xen/common/sched/core.c
-+++ b/xen/common/sched/core.c
-@@ -281,13 +281,18 @@ static inline void vcpu_runstate_change(
-     }
- 
-     delta = new_entry_time - v->runstate.state_entry_time;
--    if ( delta > 0 )
-+
-+    /* Serialization: ->schedule_lock (see ASSERT() above). */
-+    with_seq_write(&v->runstate_seq)
-     {
--        v->runstate.time[v->runstate.state] += delta;
--        v->runstate.state_entry_time = new_entry_time;
--    }
-+        if ( delta > 0 )
-+        {
-+            v->runstate.time[v->runstate.state] += delta;
-+            v->runstate.state_entry_time = new_entry_time;
-+        }
- 
--    v->runstate.state = new_state;
-+        v->runstate.state = new_state;
-+    }
- }
- 
- void sched_guest_idle(void (*idle) (void), unsigned int cpu)
-@@ -307,30 +312,18 @@ void sched_guest_idle(void (*idle) (void
- void vcpu_runstate_get(const struct vcpu *v,
-                        struct vcpu_runstate_info *runstate)
- {
--    spinlock_t *lock;
--    s_time_t delta;
--    struct sched_unit *unit;
-+    struct seqcount seq = SEQCNT_ZERO();
-+    const struct seqcount *s = likely(v == current) ? &seq : &v->runstate_seq;
- 
--    rcu_read_lock(&sched_res_rculock);
--
--    /*
--     * Be careful in case of an idle vcpu: the assignment to a unit might
--     * change even with the scheduling lock held, so be sure to use the
--     * correct unit for locking in order to avoid triggering an ASSERT() in
--     * the unlock function.
--     */
--    unit = is_idle_vcpu(v) ? get_sched_res(v->processor)->sched_unit_idle
--                           : v->sched_unit;
--    lock = likely(v == current) ? NULL : unit_schedule_lock_irq(unit);
--    memcpy(runstate, &v->runstate, sizeof(*runstate));
--    delta = NOW() - runstate->state_entry_time;
--    if ( delta > 0 )
--        runstate->time[runstate->state] += delta;
--
--    if ( unlikely(lock != NULL) )
--        unit_schedule_unlock_irq(lock, unit);
-+    until_seq_read(s)
-+    {
-+        s_time_t delta;
- 
--    rcu_read_unlock(&sched_res_rculock);
-+        *runstate = v->runstate;
-+        delta = NOW() - runstate->state_entry_time;
-+        if ( delta > 0 )
-+            runstate->time[runstate->state] += delta;
-+    }
- }
- 
- uint64_t get_cpu_idle_time(unsigned int cpu)
---- a/xen/include/xen/sched.h
-+++ b/xen/include/xen/sched.h
-@@ -16,6 +16,7 @@
- #include <xen/radix-tree.h>
- #include <xen/multicall.h>
- #include <xen/nospec.h>
-+#include <xen/seqcount.h>
- #include <xen/tasklet.h>
- #include <xen/mm.h>
- #include <xen/smp.h>
-@@ -198,7 +199,6 @@ struct vcpu
- 
-     struct sched_unit *sched_unit;
- 
--    struct vcpu_runstate_info runstate;
- #ifndef CONFIG_COMPAT
- # define runstate_guest(v) ((v)->runstate_guest)
-     XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */
-@@ -210,6 +210,8 @@ struct vcpu
-     } runstate_guest; /* guest address */
- #endif
-     struct guest_area runstate_guest_area;
-+    struct vcpu_runstate_info runstate;
-+    struct seqcount  runstate_seq;
-     unsigned int     new_state;
- 
-     /* Has the FPU been initialised? */
---- /dev/null
-+++ b/xen/include/xen/seqcount.h
-@@ -0,0 +1,139 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+#ifndef XEN_SEQCOUNT_H
-+#define XEN_SEQCOUNT_H
-+
-+#include <xen/lib.h>
-+#include <xen/nospec.h>
-+
-+#include <asm/atomic.h>
-+#include <asm/system.h>
-+
-+/*
-+ * Sequence counters (seqcount_t)
-+ *
-+ * This is the raw counting mechanism, without any writer protection.
-+ *
-+ * Write side critical sections must be serialized (and non-preemptible).
-+ *
-+ * If readers can be invoked from interrupt contexts, interrupts must also
-+ * be respectively disabled before entering the write section.
-+ *
-+ * This mechanism can't be used if the protected data contains pointers,
-+ * as the writer can invalidate a pointer that a reader is following.
-+ */
-+struct seqcount {
-+    unsigned int sequence;
-+};
-+
-+/*
-+ * SEQCNT_ZERO() - initializer for seqcount_t
-+ * @name: Name of the struct seqcount instance
-+ */
-+#define SEQCNT_ZERO() { .sequence = 0 }
-+
-+static inline unsigned int seqprop_sequence(const struct seqcount *s)
-+{
-+    return ACCESS_ONCE(s->sequence);
-+}
-+
-+/*
-+ * read_seqcount_begin() - begin a seqcount read critical section
-+ * @s: Pointer to struct seqcount
-+ *
-+ * Return: count to be passed to read_seqcount_retry()
-+ */
-+static inline unsigned int _read_seqcount_begin(const struct seqcount *s)
-+{
-+    unsigned int seq;
-+
-+    while ((seq = seqprop_sequence(s)) & 1)
-+        cpu_relax();
-+
-+    smp_rmb();
-+
-+    return seq;
-+}
-+
-+static always_inline unsigned int read_seqcount_begin(const struct seqcount *s)
-+{
-+    unsigned int seq = _read_seqcount_begin(s);
-+
-+    block_lock_speculation();
-+
-+    return seq;
-+}
-+
-+/*
-+ * read_seqcount_retry() - end a seqcount read critical section
-+ * @s: Pointer to struct seqcount
-+ * @start: count, from read_seqcount_begin()
-+ *
-+ * read_seqcount_retry closes the read critical section of given struct
-+ * seqcount.  If the critical section was invalid, it must be ignored
-+ * (and typically retried).
-+ *
-+ * Return: true if a read section retry is required, else false
-+ */
-+static inline bool _read_seqcount_retry(const struct seqcount *s,
-+                                        unsigned int start)
-+{
-+    smp_rmb();
-+    return unlikely(seqprop_sequence(s) != start);
-+}
-+
-+static always_inline bool read_seqcount_retry(const struct seqcount *s,
-+                                              unsigned int start)
-+{
-+    return lock_evaluate_nospec(_read_seqcount_retry(s, start));
-+}
-+
-+/* Loops until a consistent count has been observed across the loop body. */
-+#define until_seq_read(seq)                                    \
-+    for ( unsigned int retry_ = 1, count_;                     \
-+          retry_ && (count_ = read_seqcount_begin(seq), true); \
-+          retry_ = read_seqcount_retry(seq, count_) )
-+
-+/*
-+ * write_seqcount_begin() - start a struct seqcount write side critical section
-+ * @s: Pointer to struct seqcount
-+ *
-+ * Context: sequence counter write side sections must be serialized.
-+ * If readers can be invoked from interrupt context, interrupts must be
-+ * respectively disabled.
-+ */
-+static inline void write_seqcount_begin(struct seqcount *s)
-+{
-+    add_sized(&s->sequence, 1);
-+    smp_wmb();
-+}
-+
-+/*
-+ * write_seqcount_end() - end a struct seqcount write side critical section
-+ * @s: Pointer to seqcount
-+ */
-+static inline void write_seqcount_end(struct seqcount *s)
-+{
-+    smp_wmb();
-+    add_sized(&s->sequence, 1);
-+}
-+
-+/*
-+ * Not really a loop, but we need write_seqcount_{begin,end}() in the correct
-+ * position.
-+ */
-+#define with_seq_write(seq)                           \
-+    for ( bool once_ = true;                          \
-+          once_ && (write_seqcount_begin(seq), true); \
-+          (write_seqcount_end(seq), once_ = false) )
-+
-+#endif /* XEN_SEQCOUNT_H */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-file-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */

diff --git a/xsa492-4.21-02.patch b/xsa492-4.21-02.patch
deleted file mode 100644
index 75ca8ca..0000000
--- a/xsa492-4.21-02.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl: handle XEN_DOMCTL_getdomaininfo without acquiring domctl lock
-
-getdomaininfo() is not called under consistently the same lock. Thus,
-with caller side locking irrelevant, it can as well be called with the
-domctl lock not held. (Callers not pausing the domain they want to
-retrieve information for already need to be aware that not all of the
-data returned can be relied on as being consistent; most data will also
-be stale by the time the caller gets to look at it.)
-
-Move the handling not only ahead of acquiring the lock, but also ahead
-of the XSM check, leveraging that the sub-op has its own hook.
-
-While moving, convert an assignment to an assertion: The domain in
-question was determined from the field which previously was "updated".
-
-This is part of XSA-492.
-
-Fixes: 5513bd0b4675 ("add xenstore domain flag to hypervisor")
-Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -318,6 +318,26 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         break;
-     }
- 
-+    /* Handle sub-ops not requiring the domctl lock. */
-+    switch ( op->cmd )
-+    {
-+    case XEN_DOMCTL_getdomaininfo:
-+        ret = xsm_getdomaininfo(XSM_XS_PRIV, d);
-+        if ( !ret )
-+        {
-+            getdomaininfo(d, &op->u.getdomaininfo);
-+
-+            ASSERT(op->domain == op->u.getdomaininfo.domain);
-+            copyback = true;
-+        }
-+
-+        goto domctl_out_unlock_domonly;
-+
-+    default:
-+        /* Everything else handled further down. */
-+        break;
-+    }
-+
-     ret = xsm_domctl(XSM_OTHER, d, op->cmd,
-                      /* SSIDRef only applicable for cmd == createdomain */
-                      op->u.createdomain.ssidref);
-@@ -516,17 +536,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         copyback = 1;
-         break;
- 
--    case XEN_DOMCTL_getdomaininfo:
--        ret = xsm_getdomaininfo(XSM_XS_PRIV, d);
--        if ( ret )
--            break;
--
--        getdomaininfo(d, &op->u.getdomaininfo);
--
--        op->domain = op->u.getdomaininfo.domain;
--        copyback = 1;
--        break;
--
-     case XEN_DOMCTL_getvcpucontext:
-     {
-         vcpu_guest_context_u c = { .nat = NULL };
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -172,9 +172,13 @@ static XSM_INLINE int cf_check xsm_domct
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_unbind_pt_irq:
-         return xsm_default_action(XSM_DM_PRIV, current->domain, d);
--    case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-         return xsm_default_action(XSM_XS_PRIV, current->domain, d);
-+
-+    case XEN_DOMCTL_getdomaininfo:
-+        ASSERT_UNREACHABLE();
-+        return -EILSEQ;
-+
-     default:
-         return xsm_default_action(XSM_PRIV, current->domain, d);
-     }
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -682,8 +682,12 @@ static int cf_check flask_domctl(struct
-          */
-         return avc_current_has_perm(ssidref, SECCLASS_DOMAIN, DOMAIN__CREATE, NULL);
- 
--    /* These have individual XSM hooks (common/domctl.c) */
-+    /* These have individual XSM hooks and don't make it here. */
-     case XEN_DOMCTL_getdomaininfo:
-+        ASSERT_UNREACHABLE();
-+        return -EILSEQ;
-+
-+    /* These have individual XSM hooks (common/domctl.c) */
-     case XEN_DOMCTL_scheduler_op:
-     case XEN_DOMCTL_irq_permission:
-     case XEN_DOMCTL_iomem_permission:

diff --git a/xsa492-4.21-03.patch b/xsa492-4.21-03.patch
deleted file mode 100644
index 5a0db22..0000000
--- a/xsa492-4.21-03.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From: Daniel P. Smith <dpsmith@apertussolutions.com>
-Subject: domctl: protect locking for get_domain_state
-
-When DOMID_INVALID is passed, the dom exec handler lock is being taken
-without any check that the domain is even allowed to take the lock. This
-allows for an unauthorized domain to DoS the get_domain_state domctl op.
-Move to consider the op effectively being called against the hypervisor.
-Thus it is the target of the call being invoked to identify the last
-domain with a state change. The subsequent check of whether the source
-domain is allowed the state of the last domain to change state is still
-relevant.
-
-This is part of XSA-492.
-
-Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/tools/flask/policy/modules/xenstore.te
-+++ b/tools/flask/policy/modules/xenstore.te
-@@ -14,6 +14,7 @@ allow xenstore_t xen_t:xen writeconsole;
- # Xenstore queries domaininfo on all domains
- allow xenstore_t domain_type:domain getdomaininfo;
- allow xenstore_t domain_type:domain2 get_domain_state;
-+allow xenstore_t domxen_t:domain2 get_domain_state;
- 
- # As a shortcut, the following 3 rules are used instead of adding a domain_comms
- # rule between xenstore_t and every domain type that talks to xenstore
---- a/xen/common/domain.c
-+++ b/xen/common/domain.c
-@@ -216,12 +216,8 @@ int get_domain_state(struct xen_domctl_g
-     if ( info->pad0 )
-         return -EINVAL;
- 
--    if ( d )
-+    if ( d != dom_xen )
-     {
--        rc = xsm_get_domain_state(XSM_XS_PRIV, d);
--        if ( rc )
--            return rc;
--
-         set_domain_state_info(info, d);
- 
-         return 0;
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -304,13 +304,19 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         fallthrough;
-     case XEN_DOMCTL_test_assign_device:
-     case XEN_DOMCTL_vm_event_op:
--    case XEN_DOMCTL_get_domain_state:
-         if ( op->domain == DOMID_INVALID )
-         {
-             d = NULL;
-             break;
-         }
-         fallthrough;
-+    case XEN_DOMCTL_get_domain_state:
-+        if ( op->domain == DOMID_INVALID )
-+        {
-+            d = dom_xen;
-+            break;
-+        }
-+        fallthrough;
-     default:
-         d = rcu_lock_domain_by_id(op->domain);
-         if ( !d )
-@@ -863,7 +869,9 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         break;
- 
-     case XEN_DOMCTL_get_domain_state:
--        ret = get_domain_state(&op->u.get_domain_state, d, &op->domain);
-+        ret = xsm_get_domain_state(XSM_XS_PRIV, d);
-+        if ( !ret )
-+            ret = get_domain_state(&op->u.get_domain_state, d, &op->domain);
-         if ( !ret )
-             copyback = true;
-         break;
-@@ -876,7 +884,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-     domctl_lock_release();
- 
-  domctl_out_unlock_domonly:
--    if ( d && d != dom_io )
-+    if ( d && !is_system_domain(d) )
-         rcu_unlock_domain(d);
- 
-     if ( copyback && __copy_to_guest(u_domctl, op, 1) )

diff --git a/xsa492-4.21-04.patch b/xsa492-4.21-04.patch
deleted file mode 100644
index 481ff5d..0000000
--- a/xsa492-4.21-04.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl: handle XEN_DOMCTL_get_domain_state without acquiring domctl lock
-
-get_domain_state() uses its own locking. Thus, with caller side locking
-irrelevant, it can as well be called with the domctl lock not held.
-
-Move the handling not only ahead of acquiring the lock, but also ahead
-of the XSM check, leveraging that the sub-op has its own hook.
-
-This is part of XSA-492.
-
-Fixes: 3ad3df1bd0aa ("xen: add new domctl get_domain_state")
-Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -339,6 +339,14 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
- 
-         goto domctl_out_unlock_domonly;
- 
-+    case XEN_DOMCTL_get_domain_state:
-+        ret = xsm_get_domain_state(XSM_XS_PRIV, d);
-+        if ( !ret )
-+            ret = get_domain_state(&op->u.get_domain_state, d, &op->domain);
-+        if ( !ret )
-+            copyback = true;
-+        goto domctl_out_unlock_domonly;
-+
-     default:
-         /* Everything else handled further down. */
-         break;
-@@ -868,14 +876,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-             ret = -EOPNOTSUPP;
-         break;
- 
--    case XEN_DOMCTL_get_domain_state:
--        ret = xsm_get_domain_state(XSM_XS_PRIV, d);
--        if ( !ret )
--            ret = get_domain_state(&op->u.get_domain_state, d, &op->domain);
--        if ( !ret )
--            copyback = true;
--        break;
--
-     default:
-         ret = arch_do_domctl(op, d, u_domctl);
-         break;
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -172,10 +172,9 @@ static XSM_INLINE int cf_check xsm_domct
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_unbind_pt_irq:
-         return xsm_default_action(XSM_DM_PRIV, current->domain, d);
--    case XEN_DOMCTL_get_domain_state:
--        return xsm_default_action(XSM_XS_PRIV, current->domain, d);
- 
-     case XEN_DOMCTL_getdomaininfo:
-+    case XEN_DOMCTL_get_domain_state:
-         ASSERT_UNREACHABLE();
-         return -EILSEQ;
- 
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -684,6 +684,7 @@ static int cf_check flask_domctl(struct
- 
-     /* These have individual XSM hooks and don't make it here. */
-     case XEN_DOMCTL_getdomaininfo:
-+    case XEN_DOMCTL_get_domain_state:
-         ASSERT_UNREACHABLE();
-         return -EILSEQ;
- 
-@@ -694,7 +695,6 @@ static int cf_check flask_domctl(struct
-     case XEN_DOMCTL_memory_mapping:
-     case XEN_DOMCTL_set_target:
-     case XEN_DOMCTL_vm_event_op:
--    case XEN_DOMCTL_get_domain_state:
- 
-     /* These have individual XSM hooks (arch/../domctl.c) */
-     case XEN_DOMCTL_bind_pt_irq:

diff --git a/xsa492-4.21-05.patch b/xsa492-4.21-05.patch
deleted file mode 100644
index cb7beaa..0000000
--- a/xsa492-4.21-05.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domain: locking for iomem_caps accesses
-
-In order to be able to pull at least the XEN_DOMCTL_iomem_mapping handling
-out of the domctl-locked region, a separate (per-domain) lock is needed to
-synchronize in particular with XEN_DOMCTL_iomem_permission.
-
-Locking is added only as far as domctl-s are affected. Uses presently
-outside of the domctl lock may want dealing with subsequently (perhaps
-limited to non-__init code).
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/common/domain.c
-+++ b/xen/common/domain.c
-@@ -518,10 +518,15 @@ static int late_hwdom_init(struct domain
-      * may be modified after this hypercall returns if a more complex
-      * device model is desired.
-      */
-+    write_lock(&dom0->caps_lock);
-     rangeset_swap(d->irq_caps, dom0->irq_caps);
-     rangeset_swap(d->iomem_caps, dom0->iomem_caps);
- #ifdef CONFIG_X86
-     rangeset_swap(d->arch.ioport_caps, dom0->arch.ioport_caps);
-+#endif
-+    write_unlock(&dom0->caps_lock);
-+
-+#ifdef CONFIG_X86
-     setup_io_bitmap(d);
-     setup_io_bitmap(dom0);
- #endif
-@@ -873,6 +878,7 @@ struct domain *domain_create(domid_t dom
-     rspin_lock_init_prof(d, domain_lock);
-     rspin_lock_init_prof(d, page_alloc_lock);
-     spin_lock_init(&d->hypercall_deadlock_mutex);
-+    rwlock_init(&d->caps_lock);
-     INIT_PAGE_LIST_HEAD(&d->page_list);
-     INIT_PAGE_LIST_HEAD(&d->extra_page_list);
-     INIT_PAGE_LIST_HEAD(&d->xenpage_list);
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -267,6 +267,35 @@ static struct vnuma_info *vnuma_init(con
-     return ERR_PTR(ret);
- }
- 
-+void iocaps_double_lock(struct domain *d, bool write)
-+{
-+    struct domain *currd = current->domain;
-+
-+    if ( d->domain_id > currd->domain_id )
-+        read_lock(&currd->caps_lock);
-+
-+    if ( write )
-+        write_lock(&d->caps_lock);
-+    else
-+        read_lock(&d->caps_lock);
-+
-+    if ( d->domain_id < currd->domain_id )
-+        read_lock(&currd->caps_lock);
-+}
-+
-+void iocaps_double_unlock(struct domain *d, bool write)
-+{
-+    struct domain *currd = current->domain;
-+
-+    if ( d != currd )
-+        read_unlock(&currd->caps_lock);
-+
-+    if ( write )
-+        write_unlock(&d->caps_lock);
-+    else
-+        read_unlock(&d->caps_lock);
-+}
-+
- static bool is_stable_domctl(uint32_t cmd)
- {
-     return cmd == XEN_DOMCTL_get_domain_state;
-@@ -687,6 +716,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         if ( (mfn + nr_mfns - 1) < mfn ) /* wrap? */
-             break;
- 
-+        iocaps_double_lock(d, true);
-+
-         if ( !iomem_access_permitted(current->domain,
-                                      mfn, mfn + nr_mfns - 1) ||
-              xsm_iomem_permission(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, allow) )
-@@ -695,6 +726,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-             ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
-         else
-             ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
-+
-+        iocaps_double_unlock(d, true);
-         break;
-     }
- 
-@@ -719,19 +752,15 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-             break;
- #endif
- 
-+        iocaps_double_lock(d, false);
-+
-         ret = -EPERM;
-         if ( !iomem_access_permitted(current->domain, mfn, mfn_end) ||
--             !iomem_access_permitted(d, mfn, mfn_end) )
--            break;
--
--        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
--        if ( ret )
--            break;
--
--        if ( !paging_mode_translate(d) )
--            break;
--
--        if ( add )
-+             !iomem_access_permitted(d, mfn, mfn_end) ||
-+             (ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add)) ||
-+             !paging_mode_translate(d) )
-+            /* Nothing. */;
-+        else if ( add )
-         {
-             printk(XENLOG_G_DEBUG
-                    "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
-@@ -755,6 +784,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-                        "memory_map: error %ld removing dom%d access to [%lx,%lx]\n",
-                        ret, d->domain_id, mfn, mfn_end);
-         }
-+
-+        iocaps_double_unlock(d, false);
-         break;
-     }
- 
---- a/xen/include/xen/iocap.h
-+++ b/xen/include/xen/iocap.h
-@@ -12,6 +12,9 @@
- #include <asm/iocap.h>
- #include <asm/p2m.h>
- 
-+void iocaps_double_lock(struct domain *d, bool write);
-+void iocaps_double_unlock(struct domain *d, bool write);
-+
- static inline int iomem_permit_access(struct domain *d, unsigned long s,
-                                       unsigned long e)
- {
---- a/xen/include/xen/sched.h
-+++ b/xen/include/xen/sched.h
-@@ -536,6 +536,7 @@ struct domain
- #endif
- 
-     /* I/O capabilities (access to IRQs and memory-mapped I/O). */
-+    rwlock_t         caps_lock;
-     struct rangeset *iomem_caps;
-     struct rangeset *irq_caps;
- 

diff --git a/xsa492-4.21-06.patch b/xsa492-4.21-06.patch
deleted file mode 100644
index c9e0061..0000000
--- a/xsa492-4.21-06.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: x86/domain: locking for ioport_caps accesses
-
-In order to be able to pull at least the XEN_DOMCTL_ioport_mapping
-handling out of the domctl-locked region, the new separate (per-domain)
-lock is used to synchronize in particular with
-XEN_DOMCTL_ioport_permission.
-
-Locking is added only as far as domctl-s are affected. Uses presently
-outside of the domctl lock may want dealing with subsequently (perhaps
-limited to non-__init code).
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/arch/x86/domctl.c
-+++ b/xen/arch/x86/domctl.c
-@@ -233,6 +233,8 @@ long arch_do_domctl(
-         unsigned int np = domctl->u.ioport_permission.nr_ports;
-         int allow = domctl->u.ioport_permission.allow_access;
- 
-+        iocaps_double_lock(d, true);
-+
-         if ( (fp + np) <= fp || (fp + np) > MAX_IOPORTS )
-             ret = -EINVAL;
-         else if ( !ioports_access_permitted(currd, fp, fp + np - 1) ||
-@@ -242,6 +244,8 @@ long arch_do_domctl(
-             ret = ioports_permit_access(d, fp, fp + np - 1);
-         else
-             ret = ioports_deny_access(d, fp, fp + np - 1);
-+
-+        iocaps_double_unlock(d, true);
-         break;
-     }
- 
-@@ -648,16 +652,13 @@ long arch_do_domctl(
-             break;
-         }
- 
--        ret = -EPERM;
--        if ( !ioports_access_permitted(currd, fmp, fmp + np - 1) )
--            break;
--
--        ret = xsm_ioport_mapping(XSM_HOOK, d, fmp, fmp + np - 1, add);
--        if ( ret )
--            break;
--
-         hvm = &d->arch.hvm;
--        if ( add )
-+        iocaps_double_lock(d, true);
-+
-+        if ( !ioports_access_permitted(currd, fmp, fmp + np - 1) ||
-+             (ret = xsm_ioport_mapping(XSM_HOOK, d, fmp, fmp + np - 1, add)) )
-+            ret = ret ?: -EPERM;
-+        else if ( add )
-         {
-             printk(XENLOG_G_INFO
-                    "ioport_map:add: dom%d gport=%x mport=%x nr=%x\n",
-@@ -718,6 +720,8 @@ long arch_do_domctl(
-                        "ioport_map: error %ld denying dom%d access to [%x,%x]\n",
-                        ret, d->domain_id, fmp, fmp + np - 1);
-         }
-+
-+        iocaps_double_unlock(d, true);
-         break;
-     }
- 
---- a/xen/arch/x86/setup.c
-+++ b/xen/arch/x86/setup.c
-@@ -2339,9 +2339,12 @@ void __hwdom_init setup_io_bitmap(struct
-         return;
- 
-     bitmap_fill(d->arch.hvm.io_bitmap, 0x10000);
-+
-+    read_lock(&d->caps_lock);
-     if ( rangeset_report_ranges(d->arch.ioport_caps, 0, 0x10000,
-                                 io_bitmap_cb, d) )
-         BUG();
-+    read_unlock(&d->caps_lock);
- 
-     /*
-      * We need to trap 4-byte accesses to 0xcf8 (see admin_io_okay(),

diff --git a/xsa492-4.21-07.patch b/xsa492-4.21-07.patch
deleted file mode 100644
index e343773..0000000
--- a/xsa492-4.21-07.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domain: locking for irq_caps accesses
-
-In order to be able to pull at least the XEN_DOMCTL_{,un}bind_pt_irq
-handling out of the domctl-locked region, a separate (per-domain) lock is
-needed to synchronize in particular with XEN_DOMCTL_{irq,gsi}_permission.
-
-Locking is added only as far as domctl-s are affected. Uses presently
-outside of the domctl lock may want dealing with subsequently (perhaps
-limited to non-__init code).
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-Reviewed-by: Julien Grall <julien@xen.org>
-
---- a/xen/arch/arm/domctl.c
-+++ b/xen/arch/arm/domctl.c
-@@ -76,6 +76,7 @@ long arch_do_domctl(struct xen_domctl *d
-     case XEN_DOMCTL_bind_pt_irq:
-     {
-         int rc;
-+        struct domain *currd = current->domain;
-         struct xen_domctl_bind_pt_irq *bind = &domctl->u.bind_pt_irq;
-         uint32_t irq = bind->u.spi.spi;
-         uint32_t virq = bind->machine_irq;
-@@ -107,21 +108,26 @@ long arch_do_domctl(struct xen_domctl *d
-         if ( rc )
-             return rc;
- 
--        if ( !irq_access_permitted(current->domain, irq) )
--            return -EPERM;
-+        read_lock(&currd->caps_lock);
- 
--        if ( !vgic_reserve_virq(d, virq) )
--            return -EBUSY;
--
--        rc = route_irq_to_guest(d, virq, irq, "routed IRQ");
--        if ( rc )
--            vgic_free_virq(d, virq);
-+        if ( !irq_access_permitted(currd, irq) )
-+            rc = -EPERM;
-+        else if ( !vgic_reserve_virq(d, virq) )
-+            rc = -EBUSY;
-+        else
-+        {
-+            rc = route_irq_to_guest(d, virq, irq, "routed IRQ");
-+            if ( rc )
-+                vgic_free_virq(d, virq);
-+        }
- 
-+        read_unlock(&currd->caps_lock);
-         return rc;
-     }
-     case XEN_DOMCTL_unbind_pt_irq:
-     {
-         int rc;
-+        struct domain *currd = current->domain;
-         struct xen_domctl_bind_pt_irq *bind = &domctl->u.bind_pt_irq;
-         uint32_t irq = bind->u.spi.spi;
-         uint32_t virq = bind->machine_irq;
-@@ -138,16 +144,15 @@ long arch_do_domctl(struct xen_domctl *d
-         if ( rc )
-             return rc;
- 
--        if ( !irq_access_permitted(current->domain, irq) )
--            return -EPERM;
--
--        rc = release_guest_irq(d, virq);
--        if ( rc )
--            return rc;
-+        read_lock(&currd->caps_lock);
- 
--        vgic_free_virq(d, virq);
-+        if ( !irq_access_permitted(currd, irq) )
-+            rc = -EPERM;
-+        else if ( !(rc = release_guest_irq(d, virq)) )
-+            vgic_free_virq(d, virq);
- 
--        return 0;
-+        read_unlock(&currd->caps_lock);
-+        return rc;
-     }
- 
-     case XEN_DOMCTL_vuart_op:
---- a/xen/arch/x86/domctl.c
-+++ b/xen/arch/x86/domctl.c
-@@ -267,16 +267,17 @@ long arch_do_domctl(
-             break;
-         }
- 
--        ret = -EPERM;
-+        iocaps_double_lock(d, true);
-+
-         if ( !irq_access_permitted(currd, irq) ||
-              xsm_irq_permission(XSM_HOOK, d, irq, flags) )
--            break;
--
--        if ( flags )
-+            ret = -EPERM;
-+        else if ( flags )
-             ret = irq_permit_access(d, irq);
-         else
-             ret = irq_deny_access(d, irq);
- 
-+        iocaps_double_unlock(d, true);
-         break;
-     }
- 
-@@ -579,20 +580,27 @@ long arch_do_domctl(
-             break;
- 
-         irq = domain_pirq_to_irq(d, bind->machine_irq);
--        ret = -EPERM;
--        if ( irq <= 0 || !irq_access_permitted(currd, irq) )
--            break;
-+        if ( irq <= 0 )
-+            ret = -EPERM;
- 
--        ret = -ESRCH;
--        if ( is_iommu_enabled(d) )
-+        read_lock(&currd->caps_lock);
-+
-+        if ( !irq_access_permitted(currd, irq) )
-+            ret = -EPERM;
-+        else if ( is_iommu_enabled(d) )
-         {
-             pcidevs_lock();
-             ret = pt_irq_create_bind(d, bind);
-             pcidevs_unlock();
-+
-+            if ( ret < 0 )
-+                printk(XENLOG_G_ERR "pt_irq_create_bind failed (%ld) for %pd\n",
-+                       ret, d);
-         }
--        if ( ret < 0 )
--            printk(XENLOG_G_ERR "pt_irq_create_bind failed (%ld) for dom%d\n",
--                   ret, d->domain_id);
-+        else
-+            ret = -ESRCH;
-+
-+        read_unlock(&currd->caps_lock);
-         break;
-     }
- 
-@@ -605,23 +613,26 @@ long arch_do_domctl(
-         if ( !is_hvm_domain(d) )
-             break;
- 
--        ret = -EPERM;
--        if ( irq <= 0 || !irq_access_permitted(currd, irq) )
--            break;
--
-         ret = xsm_unbind_pt_irq(XSM_HOOK, d, bind);
-         if ( ret )
-             break;
- 
--        if ( is_iommu_enabled(d) )
-+        read_lock(&currd->caps_lock);
-+
-+        if ( !irq_access_permitted(currd, irq) )
-+            ret = -EPERM;
-+        else if ( is_iommu_enabled(d) )
-         {
-             pcidevs_lock();
-             ret = pt_irq_destroy_bind(d, bind);
-             pcidevs_unlock();
-+
-+            if ( ret < 0 )
-+                printk(XENLOG_G_ERR "pt_irq_destroy_bind failed (%ld) for %pd\n",
-+                       ret, d);
-         }
--        if ( ret < 0 )
--            printk(XENLOG_G_ERR "pt_irq_destroy_bind failed (%ld) for dom%d\n",
--                   ret, d->domain_id);
-+
-+        read_unlock(&currd->caps_lock);
-         break;
-     }
- 
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -695,6 +695,9 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-             ret = -EINVAL;
-             break;
-         }
-+
-+        iocaps_double_lock(d, true);
-+
-         irq = pirq_access_permitted(current->domain, pirq);
-         if ( !irq || xsm_irq_permission(XSM_HOOK, d, irq, allow) )
-             ret = -EPERM;
-@@ -702,6 +705,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-             ret = irq_permit_access(d, irq);
-         else
-             ret = irq_deny_access(d, irq);
-+
-+        iocaps_double_unlock(d, true);
-         break;
-     }
- #endif

diff --git a/xsa492-4.21-08.patch b/xsa492-4.21-08.patch
deleted file mode 100644
index 4aefbf4..0000000
--- a/xsa492-4.21-08.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: XSM/Flask: split the .iomem_mapping() hook
-
-It's used twice in entirely different situations. The use in do_domctl()
-wants to become an ordinary XSM_DM_PRIV invocation, while the one in vPCI
-code need to remain XSM_HOOK (it may plausibly become XSM_TARGET). For
-Flask, the same backing function will continue to be used for the time
-being.
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-
---- a/xen/drivers/vpci/header.c
-+++ b/xen/drivers/vpci/header.c
-@@ -67,7 +67,7 @@ static int cf_check map_range(
-             return -EPERM;
-         }
- 
--        rc = xsm_iomem_mapping(XSM_HOOK, map->d, map_mfn, m_end, map->map);
-+        rc = xsm_iomem_mapping_vpci(XSM_HOOK, map->d, map_mfn, m_end, map->map);
-         if ( rc )
-         {
-             printk(XENLOG_G_WARNING
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -580,6 +580,13 @@ static XSM_INLINE int cf_check xsm_iomem
-     return xsm_default_action(action, current->domain, d);
- }
- 
-+static XSM_INLINE int cf_check xsm_iomem_mapping_vpci(
-+    XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow)
-+{
-+    XSM_ASSERT_ACTION(XSM_HOOK);
-+    return xsm_default_action(action, current->domain, d);
-+}
-+
- static XSM_INLINE int cf_check xsm_pci_config_permission(
-     XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf, uint16_t start,
-     uint16_t end, uint8_t access)
---- a/xen/include/xsm/xsm.h
-+++ b/xen/include/xsm/xsm.h
-@@ -118,6 +118,8 @@ struct xsm_ops {
-                             uint8_t allow);
-     int (*iomem_mapping)(struct domain *d, uint64_t s, uint64_t e,
-                          uint8_t allow);
-+    int (*iomem_mapping_vpci)(struct domain *d, uint64_t s, uint64_t e,
-+                              uint8_t allow);
-     int (*pci_config_permission)(struct domain *d, uint32_t machine_bdf,
-                                  uint16_t start, uint16_t end, uint8_t access);
- 
-@@ -523,6 +525,12 @@ static inline int xsm_iomem_mapping(
-     return alternative_call(xsm_ops.iomem_mapping, d, s, e, allow);
- }
- 
-+static inline int xsm_iomem_mapping_vpci(
-+    xsm_default_t def, struct domain *d, uint64_t s, uint64_t e, uint8_t allow)
-+{
-+    return alternative_call(xsm_ops.iomem_mapping_vpci, d, s, e, allow);
-+}
-+
- static inline int xsm_pci_config_permission(
-     xsm_default_t def, struct domain *d, uint32_t machine_bdf, uint16_t start,
-     uint16_t end, uint8_t access)
---- a/xen/xsm/dummy.c
-+++ b/xen/xsm/dummy.c
-@@ -76,6 +76,7 @@ static const struct xsm_ops __initconst_
-     .irq_permission                = xsm_irq_permission,
-     .iomem_permission              = xsm_iomem_permission,
-     .iomem_mapping                 = xsm_iomem_mapping,
-+    .iomem_mapping_vpci            = xsm_iomem_mapping_vpci,
-     .pci_config_permission         = xsm_pci_config_permission,
-     .get_vnumainfo                 = xsm_get_vnumainfo,
- 
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -1950,6 +1950,7 @@ static const struct xsm_ops __initconst_
-     .irq_permission = flask_irq_permission,
-     .iomem_permission = flask_iomem_permission,
-     .iomem_mapping = flask_iomem_mapping,
-+    .iomem_mapping_vpci = flask_iomem_mapping,
-     .pci_config_permission = flask_pci_config_permission,
- 
-     .resource_plug_core = flask_resource_plug_core,

diff --git a/xsa492-4.21-09.patch b/xsa492-4.21-09.patch
deleted file mode 100644
index 96e9403..0000000
--- a/xsa492-4.21-09.patch
+++ /dev/null
@@ -1,194 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl: handle XEN_DOMCTL_memory_mapping without acquiring domctl lock
-
-With dedicated locking added, the domctl lock isn't required here anymore.
-Move the re-purposed dedicated XSM check as early as possible.
-
-Minimal "modernization": Switch "add" to bool and use %pd in log messages.
-
-This is part of XSA-492.
-
-Fixes: fda49f9b3fbb ("Add build option to allow more hypercalls from stubdoms")
-Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -376,6 +376,66 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-             copyback = true;
-         goto domctl_out_unlock_domonly;
- 
-+    case XEN_DOMCTL_memory_mapping:
-+    {
-+        unsigned long gfn = op->u.memory_mapping.first_gfn;
-+        unsigned long mfn = op->u.memory_mapping.first_mfn;
-+        unsigned long nr_mfns = op->u.memory_mapping.nr_mfns;
-+        unsigned long mfn_end = mfn + nr_mfns - 1;
-+        bool add = op->u.memory_mapping.add_mapping;
-+
-+        ret = -EINVAL;
-+        if ( mfn_end < mfn || /* Wrap? */
-+             ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
-+             (gfn + nr_mfns - 1) < gfn ) /* Wrap? */
-+            goto domctl_out_unlock_domonly;
-+
-+        ret = xsm_iomem_mapping(XSM_DM_PRIV, d, mfn, mfn_end, add);
-+        if ( ret || !paging_mode_translate(d) )
-+            goto domctl_out_unlock_domonly;
-+
-+#ifndef CONFIG_X86 /* XXX ARM!? */
-+        ret = -E2BIG;
-+        /* Must break hypercall up as this could take a while. */
-+        if ( nr_mfns > 64 )
-+            goto domctl_out_unlock_domonly;
-+#endif
-+
-+        iocaps_double_lock(d, false);
-+
-+        ret = -EPERM;
-+        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) ||
-+             !iomem_access_permitted(d, mfn, mfn_end) )
-+            /* Nothing. */;
-+        else if ( add )
-+        {
-+            printk(XENLOG_G_DEBUG
-+                   "memory_map:add: %pd gfn=%lx mfn=%lx nr=%lx\n",
-+                   d, gfn, mfn, nr_mfns);
-+
-+            ret = map_mmio_regions(d, _gfn(gfn), nr_mfns, _mfn(mfn));
-+            if ( ret < 0 )
-+                printk(XENLOG_G_WARNING
-+                       "memory_map:fail: %pd gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
-+                       d, gfn, mfn, nr_mfns, ret);
-+        }
-+        else
-+        {
-+            printk(XENLOG_G_DEBUG
-+                   "memory_map:remove: %pd gfn=%lx mfn=%lx nr=%lx\n",
-+                   d, gfn, mfn, nr_mfns);
-+
-+            ret = unmap_mmio_regions(d, _gfn(gfn), nr_mfns, _mfn(mfn));
-+            if ( ret < 0 && is_hardware_domain(current->domain) )
-+                printk(XENLOG_ERR
-+                       "memory_map: error %ld removing %pd access to [%lx,%lx]\n",
-+                       ret, d, mfn, mfn_end);
-+        }
-+
-+        iocaps_double_unlock(d, false);
-+        goto domctl_out_unlock_domonly;
-+    }
-+
-     default:
-         /* Everything else handled further down. */
-         break;
-@@ -736,64 +796,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         break;
-     }
- 
--    case XEN_DOMCTL_memory_mapping:
--    {
--        unsigned long gfn = op->u.memory_mapping.first_gfn;
--        unsigned long mfn = op->u.memory_mapping.first_mfn;
--        unsigned long nr_mfns = op->u.memory_mapping.nr_mfns;
--        unsigned long mfn_end = mfn + nr_mfns - 1;
--        int add = op->u.memory_mapping.add_mapping;
--
--        ret = -EINVAL;
--        if ( mfn_end < mfn || /* wrap? */
--             ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
--             (gfn + nr_mfns - 1) < gfn ) /* wrap? */
--            break;
--
--#ifndef CONFIG_X86 /* XXX ARM!? */
--        ret = -E2BIG;
--        /* Must break hypercall up as this could take a while. */
--        if ( nr_mfns > 64 )
--            break;
--#endif
--
--        iocaps_double_lock(d, false);
--
--        ret = -EPERM;
--        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) ||
--             !iomem_access_permitted(d, mfn, mfn_end) ||
--             (ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add)) ||
--             !paging_mode_translate(d) )
--            /* Nothing. */;
--        else if ( add )
--        {
--            printk(XENLOG_G_DEBUG
--                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
--                   d->domain_id, gfn, mfn, nr_mfns);
--
--            ret = map_mmio_regions(d, _gfn(gfn), nr_mfns, _mfn(mfn));
--            if ( ret < 0 )
--                printk(XENLOG_G_WARNING
--                       "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
--                       d->domain_id, gfn, mfn, nr_mfns, ret);
--        }
--        else
--        {
--            printk(XENLOG_G_DEBUG
--                   "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
--                   d->domain_id, gfn, mfn, nr_mfns);
--
--            ret = unmap_mmio_regions(d, _gfn(gfn), nr_mfns, _mfn(mfn));
--            if ( ret < 0 && is_hardware_domain(current->domain) )
--                printk(XENLOG_ERR
--                       "memory_map: error %ld removing dom%d access to [%lx,%lx]\n",
--                       ret, d->domain_id, mfn, mfn_end);
--        }
--
--        iocaps_double_unlock(d, false);
--        break;
--    }
--
-     case XEN_DOMCTL_settimeoffset:
-         domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
-         break;
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -168,13 +168,13 @@ static XSM_INLINE int cf_check xsm_domct
-     switch ( cmd )
-     {
-     case XEN_DOMCTL_ioport_mapping:
--    case XEN_DOMCTL_memory_mapping:
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_unbind_pt_irq:
-         return xsm_default_action(XSM_DM_PRIV, current->domain, d);
- 
-     case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-+    case XEN_DOMCTL_memory_mapping:
-         ASSERT_UNREACHABLE();
-         return -EILSEQ;
- 
-@@ -576,7 +576,7 @@ static XSM_INLINE int cf_check xsm_iomem
- static XSM_INLINE int cf_check xsm_iomem_mapping(
-     XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow)
- {
--    XSM_ASSERT_ACTION(XSM_HOOK);
-+    XSM_ASSERT_ACTION(XSM_DM_PRIV);
-     return xsm_default_action(action, current->domain, d);
- }
- 
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -685,6 +685,7 @@ static int cf_check flask_domctl(struct
-     /* These have individual XSM hooks and don't make it here. */
-     case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-+    case XEN_DOMCTL_memory_mapping:
-         ASSERT_UNREACHABLE();
-         return -EILSEQ;
- 
-@@ -692,7 +693,6 @@ static int cf_check flask_domctl(struct
-     case XEN_DOMCTL_scheduler_op:
-     case XEN_DOMCTL_irq_permission:
-     case XEN_DOMCTL_iomem_permission:
--    case XEN_DOMCTL_memory_mapping:
-     case XEN_DOMCTL_set_target:
-     case XEN_DOMCTL_vm_event_op:
- 

diff --git a/xsa492-4.21-10.patch b/xsa492-4.21-10.patch
deleted file mode 100644
index 6406a19..0000000
--- a/xsa492-4.21-10.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl: handle XEN_DOMCTL_ioport_mapping without acquiring domctl lock
-
-With dedicated locking added, the domctl lock isn't required here anymore.
-As the handling is in arch-specific code (x86 only), almost no code is
-being moved, but a 2nd (extensible to other sub-ops) invocation of
-arch_do_domctl() is being added. Move just the re-purposed dedicated XSM
-check as early as possible.
-
-In flask_domctl() don't put #ifdef around the moved case label.
-
-This is part of XSA-492.
-
-Fixes: fda49f9b3fbb ("Add build option to allow more hypercalls from stubdoms")
-Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-
---- a/xen/arch/x86/domctl.c
-+++ b/xen/arch/x86/domctl.c
-@@ -663,12 +663,15 @@ long arch_do_domctl(
-             break;
-         }
- 
-+        ret = xsm_ioport_mapping(XSM_DM_PRIV, d, fmp, fmp + np - 1, add);
-+        if ( ret )
-+            break;
-+
-         hvm = &d->arch.hvm;
-         iocaps_double_lock(d, true);
- 
--        if ( !ioports_access_permitted(currd, fmp, fmp + np - 1) ||
--             (ret = xsm_ioport_mapping(XSM_HOOK, d, fmp, fmp + np - 1, add)) )
--            ret = ret ?: -EPERM;
-+        if ( !ioports_access_permitted(currd, fmp, fmp + np - 1) )
-+            ret = -EPERM;
-         else if ( add )
-         {
-             printk(XENLOG_G_INFO
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -436,6 +436,10 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         goto domctl_out_unlock_domonly;
-     }
- 
-+    case XEN_DOMCTL_ioport_mapping:
-+        ret = arch_do_domctl(op, d, u_domctl);
-+        goto domctl_out_unlock_domonly;
-+
-     default:
-         /* Everything else handled further down. */
-         break;
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -167,13 +167,13 @@ static XSM_INLINE int cf_check xsm_domct
-     XSM_ASSERT_ACTION(XSM_OTHER);
-     switch ( cmd )
-     {
--    case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_unbind_pt_irq:
-         return xsm_default_action(XSM_DM_PRIV, current->domain, d);
- 
-     case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-+    case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_memory_mapping:
-         ASSERT_UNREACHABLE();
-         return -EILSEQ;
-@@ -772,7 +772,7 @@ static XSM_INLINE int cf_check xsm_iopor
- static XSM_INLINE int cf_check xsm_ioport_mapping(
-     XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow)
- {
--    XSM_ASSERT_ACTION(XSM_HOOK);
-+    XSM_ASSERT_ACTION(XSM_DM_PRIV);
-     return xsm_default_action(action, current->domain, d);
- }
- 
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -685,6 +685,7 @@ static int cf_check flask_domctl(struct
-     /* These have individual XSM hooks and don't make it here. */
-     case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-+    case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_memory_mapping:
-         ASSERT_UNREACHABLE();
-         return -EILSEQ;
-@@ -703,7 +704,6 @@ static int cf_check flask_domctl(struct
-     /* These have individual XSM hooks (arch/x86/domctl.c) */
-     case XEN_DOMCTL_shadow_op:
-     case XEN_DOMCTL_ioport_permission:
--    case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_gsi_permission:
- #endif
- #ifdef CONFIG_HAS_PASSTHROUGH

diff --git a/xsa492-4.21-11.patch b/xsa492-4.21-11.patch
deleted file mode 100644
index 647fd5a..0000000
--- a/xsa492-4.21-11.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl: handle XEN_DOMCTL_{,un}bind_pt_irq without acquiring domctl lock
-
-With dedicated locking added, the domctl lock isn't required here anymore.
-(It also already isn't used when pt_irq_{create,destroy}_bind() are
-invoked for PVH Dom0.) As the handling is in arch-specific code, no code
-is being moved, but the 2nd (extensible to other sub-ops like the ones
-here) invocation of arch_do_domctl() is being re-used.
-
-This is part of XSA-492.
-
-Fixes: fda49f9b3fbb ("Add build option to allow more hypercalls from stubdoms")
-Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-Acked-by: Julien Grall <julien@xen.org>
-
---- a/xen/arch/arm/domctl.c
-+++ b/xen/arch/arm/domctl.c
-@@ -104,7 +104,7 @@ long arch_do_domctl(struct xen_domctl *d
-         if ( rc )
-             return rc;
- 
--        rc = xsm_bind_pt_irq(XSM_HOOK, d, bind);
-+        rc = xsm_bind_pt_irq(XSM_DM_PRIV, d, bind);
-         if ( rc )
-             return rc;
- 
-@@ -140,7 +140,7 @@ long arch_do_domctl(struct xen_domctl *d
-         if ( irq != virq )
-             return -EINVAL;
- 
--        rc = xsm_unbind_pt_irq(XSM_HOOK, d, bind);
-+        rc = xsm_unbind_pt_irq(XSM_DM_PRIV, d, bind);
-         if ( rc )
-             return rc;
- 
---- a/xen/arch/x86/domctl.c
-+++ b/xen/arch/x86/domctl.c
-@@ -575,7 +575,7 @@ long arch_do_domctl(
-         if ( !is_hvm_domain(d) )
-             break;
- 
--        ret = xsm_bind_pt_irq(XSM_HOOK, d, bind);
-+        ret = xsm_bind_pt_irq(XSM_DM_PRIV, d, bind);
-         if ( ret )
-             break;
- 
-@@ -613,7 +613,7 @@ long arch_do_domctl(
-         if ( !is_hvm_domain(d) )
-             break;
- 
--        ret = xsm_unbind_pt_irq(XSM_HOOK, d, bind);
-+        ret = xsm_unbind_pt_irq(XSM_DM_PRIV, d, bind);
-         if ( ret )
-             break;
- 
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -437,6 +437,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-     }
- 
-     case XEN_DOMCTL_ioport_mapping:
-+    case XEN_DOMCTL_bind_pt_irq:
-+    case XEN_DOMCTL_unbind_pt_irq:
-         ret = arch_do_domctl(op, d, u_domctl);
-         goto domctl_out_unlock_domonly;
- 
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -168,13 +168,11 @@ static XSM_INLINE int cf_check xsm_domct
-     switch ( cmd )
-     {
-     case XEN_DOMCTL_bind_pt_irq:
--    case XEN_DOMCTL_unbind_pt_irq:
--        return xsm_default_action(XSM_DM_PRIV, current->domain, d);
--
-     case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-     case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_memory_mapping:
-+    case XEN_DOMCTL_unbind_pt_irq:
-         ASSERT_UNREACHABLE();
-         return -EILSEQ;
- 
-@@ -541,14 +539,14 @@ static XSM_INLINE int cf_check xsm_unmap
- static XSM_INLINE int cf_check xsm_bind_pt_irq(
-     XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind)
- {
--    XSM_ASSERT_ACTION(XSM_HOOK);
-+    XSM_ASSERT_ACTION(XSM_DM_PRIV);
-     return xsm_default_action(action, current->domain, d);
- }
- 
- static XSM_INLINE int cf_check xsm_unbind_pt_irq(
-     XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind)
- {
--    XSM_ASSERT_ACTION(XSM_HOOK);
-+    XSM_ASSERT_ACTION(XSM_DM_PRIV);
-     return xsm_default_action(action, current->domain, d);
- }
- 
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -683,10 +683,12 @@ static int cf_check flask_domctl(struct
-         return avc_current_has_perm(ssidref, SECCLASS_DOMAIN, DOMAIN__CREATE, NULL);
- 
-     /* These have individual XSM hooks and don't make it here. */
-+    case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-     case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_memory_mapping:
-+    case XEN_DOMCTL_unbind_pt_irq:
-         ASSERT_UNREACHABLE();
-         return -EILSEQ;
- 
-@@ -697,9 +699,6 @@ static int cf_check flask_domctl(struct
-     case XEN_DOMCTL_set_target:
-     case XEN_DOMCTL_vm_event_op:
- 
--    /* These have individual XSM hooks (arch/../domctl.c) */
--    case XEN_DOMCTL_bind_pt_irq:
--    case XEN_DOMCTL_unbind_pt_irq:
- #ifdef CONFIG_X86
-     /* These have individual XSM hooks (arch/x86/domctl.c) */
-     case XEN_DOMCTL_shadow_op:

diff --git a/xsa492-4.21-12.patch b/xsa492-4.21-12.patch
deleted file mode 100644
index c19d1e1..0000000
--- a/xsa492-4.21-12.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl: handle XEN_DOMCTL_io{mem,port}_permission without acquiring domctl lock
-
-With dedicated locking added, the domctl lock isn't required here anymore.
-As the I/O port handling is in arch-specific code (x86 only), no code is
-being moved, but the 2nd invocation of arch_do_domctl() is re-used. Move
-the re-purposed dedicated XSM checks as early as possible.
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-
---- a/xen/arch/x86/domctl.c
-+++ b/xen/arch/x86/domctl.c
-@@ -233,12 +233,17 @@ long arch_do_domctl(
-         unsigned int np = domctl->u.ioport_permission.nr_ports;
-         int allow = domctl->u.ioport_permission.allow_access;
- 
-+        ret = -EINVAL;
-+        if ( (fp + np) <= fp || (fp + np) > MAX_IOPORTS )
-+            break;
-+
-+        ret = xsm_ioport_permission(XSM_PRIV, d, fp, fp + np - 1, allow);
-+        if ( ret )
-+            break;
-+
-         iocaps_double_lock(d, true);
- 
--        if ( (fp + np) <= fp || (fp + np) > MAX_IOPORTS )
--            ret = -EINVAL;
--        else if ( !ioports_access_permitted(currd, fp, fp + np - 1) ||
--                  xsm_ioport_permission(XSM_HOOK, d, fp, fp + np - 1, allow) )
-+        if ( !ioports_access_permitted(currd, fp, fp + np - 1) )
-             ret = -EPERM;
-         else if ( allow )
-             ret = ioports_permit_access(d, fp, fp + np - 1);
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -376,6 +376,34 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-             copyback = true;
-         goto domctl_out_unlock_domonly;
- 
-+    case XEN_DOMCTL_iomem_permission:
-+    {
-+        unsigned long mfn = op->u.iomem_permission.first_mfn;
-+        unsigned long nr_mfns = op->u.iomem_permission.nr_mfns;
-+        bool allow = op->u.iomem_permission.allow_access;
-+
-+        ret = -EINVAL;
-+        if ( (mfn + nr_mfns - 1) < mfn ) /* Wrap? */
-+            goto domctl_out_unlock_domonly;
-+
-+        ret = xsm_iomem_permission(XSM_PRIV, d, mfn, mfn + nr_mfns - 1, allow);
-+        if ( ret )
-+            goto domctl_out_unlock_domonly;
-+
-+        iocaps_double_lock(d, true);
-+
-+        if ( !iomem_access_permitted(current->domain,
-+                                     mfn, mfn + nr_mfns - 1) )
-+            ret = -EPERM;
-+        else if ( allow )
-+            ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
-+        else
-+            ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
-+
-+        iocaps_double_unlock(d, true);
-+        goto domctl_out_unlock_domonly;
-+    }
-+
-     case XEN_DOMCTL_memory_mapping:
-     {
-         unsigned long gfn = op->u.memory_mapping.first_gfn;
-@@ -436,6 +464,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         goto domctl_out_unlock_domonly;
-     }
- 
-+    case XEN_DOMCTL_ioport_permission:
-     case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_unbind_pt_irq:
-@@ -777,31 +806,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-     }
- #endif
- 
--    case XEN_DOMCTL_iomem_permission:
--    {
--        unsigned long mfn = op->u.iomem_permission.first_mfn;
--        unsigned long nr_mfns = op->u.iomem_permission.nr_mfns;
--        int allow = op->u.iomem_permission.allow_access;
--
--        ret = -EINVAL;
--        if ( (mfn + nr_mfns - 1) < mfn ) /* wrap? */
--            break;
--
--        iocaps_double_lock(d, true);
--
--        if ( !iomem_access_permitted(current->domain,
--                                     mfn, mfn + nr_mfns - 1) ||
--             xsm_iomem_permission(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, allow) )
--            ret = -EPERM;
--        else if ( allow )
--            ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
--        else
--            ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
--
--        iocaps_double_unlock(d, true);
--        break;
--    }
--
-     case XEN_DOMCTL_settimeoffset:
-         domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
-         break;
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -170,7 +170,9 @@ static XSM_INLINE int cf_check xsm_domct
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-+    case XEN_DOMCTL_iomem_permission:
-     case XEN_DOMCTL_ioport_mapping:
-+    case XEN_DOMCTL_ioport_permission:
-     case XEN_DOMCTL_memory_mapping:
-     case XEN_DOMCTL_unbind_pt_irq:
-         ASSERT_UNREACHABLE();
-@@ -567,7 +569,7 @@ static XSM_INLINE int cf_check xsm_irq_p
- static XSM_INLINE int cf_check xsm_iomem_permission(
-     XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow)
- {
--    XSM_ASSERT_ACTION(XSM_HOOK);
-+    XSM_ASSERT_ACTION(XSM_PRIV);
-     return xsm_default_action(action, current->domain, d);
- }
- 
-@@ -763,7 +765,7 @@ static XSM_INLINE int cf_check xsm_priv_
- static XSM_INLINE int cf_check xsm_ioport_permission(
-     XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow)
- {
--    XSM_ASSERT_ACTION(XSM_HOOK);
-+    XSM_ASSERT_ACTION(XSM_PRIV);
-     return xsm_default_action(action, current->domain, d);
- }
- 
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -686,7 +686,9 @@ static int cf_check flask_domctl(struct
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-+    case XEN_DOMCTL_iomem_permission:
-     case XEN_DOMCTL_ioport_mapping:
-+    case XEN_DOMCTL_ioport_permission:
-     case XEN_DOMCTL_memory_mapping:
-     case XEN_DOMCTL_unbind_pt_irq:
-         ASSERT_UNREACHABLE();
-@@ -695,14 +697,12 @@ static int cf_check flask_domctl(struct
-     /* These have individual XSM hooks (common/domctl.c) */
-     case XEN_DOMCTL_scheduler_op:
-     case XEN_DOMCTL_irq_permission:
--    case XEN_DOMCTL_iomem_permission:
-     case XEN_DOMCTL_set_target:
-     case XEN_DOMCTL_vm_event_op:
- 
- #ifdef CONFIG_X86
-     /* These have individual XSM hooks (arch/x86/domctl.c) */
-     case XEN_DOMCTL_shadow_op:
--    case XEN_DOMCTL_ioport_permission:
-     case XEN_DOMCTL_gsi_permission:
- #endif
- #ifdef CONFIG_HAS_PASSTHROUGH

diff --git a/xsa492-4.21-13.patch b/xsa492-4.21-13.patch
deleted file mode 100644
index 91ce1ae..0000000
--- a/xsa492-4.21-13.patch
+++ /dev/null
@@ -1,163 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl: handle XEN_DOMCTL_{irq,gsi}_permission without acquiring domctl lock
-
-With dedicated locking added, the domctl lock isn't required here anymore.
-As the GSI handling is in arch-specific code (x86 only), no code is being
-moved there; the 2nd invocation of arch_do_domctl() is re-used. Move the
-re-purposed (XSM_HOOK -> XSM_PRIV, as xsm_domctl() is now bypassed)
-dedicated XSM checks as early as possible.
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/arch/x86/domctl.c
-+++ b/xen/arch/x86/domctl.c
-@@ -272,10 +272,13 @@ long arch_do_domctl(
-             break;
-         }
- 
-+        ret = xsm_irq_permission(XSM_PRIV, d, irq, flags);
-+        if ( ret )
-+            break;
-+
-         iocaps_double_lock(d, true);
- 
--        if ( !irq_access_permitted(currd, irq) ||
--             xsm_irq_permission(XSM_HOOK, d, irq, flags) )
-+        if ( !irq_access_permitted(currd, irq) )
-             ret = -EPERM;
-         else if ( flags )
-             ret = irq_permit_access(d, irq);
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -464,8 +464,41 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         goto domctl_out_unlock_domonly;
-     }
- 
-+#ifdef CONFIG_HAS_PIRQ
-+    case XEN_DOMCTL_irq_permission:
-+    {
-+        unsigned int pirq = op->u.irq_permission.pirq, irq;
-+        bool allow = op->u.irq_permission.allow_access;
-+
-+        ret = -EINVAL;
-+        if ( pirq >= current->domain->nr_pirqs )
-+            goto domctl_out_unlock_domonly;
-+
-+        irq = domain_pirq_to_irq(current->domain, pirq);
-+
-+        ret = -EPERM;
-+        if ( irq )
-+            ret = xsm_irq_permission(XSM_PRIV, d, irq, allow);
-+        if ( ret )
-+            goto domctl_out_unlock_domonly;
-+
-+        iocaps_double_lock(d, true);
-+
-+        if ( !irq_access_permitted(current->domain, irq) )
-+            ret = -EPERM;
-+        else if ( allow )
-+            ret = irq_permit_access(d, irq);
-+        else
-+            ret = irq_deny_access(d, irq);
-+
-+        iocaps_double_unlock(d, true);
-+        goto domctl_out_unlock_domonly;
-+    }
-+#endif
-+
-     case XEN_DOMCTL_ioport_permission:
-     case XEN_DOMCTL_ioport_mapping:
-+    case XEN_DOMCTL_gsi_permission:
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_unbind_pt_irq:
-         ret = arch_do_domctl(op, d, u_domctl);
-@@ -779,33 +812,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         }
-         break;
- 
--#ifdef CONFIG_HAS_PIRQ
--    case XEN_DOMCTL_irq_permission:
--    {
--        unsigned int pirq = op->u.irq_permission.pirq, irq;
--        int allow = op->u.irq_permission.allow_access;
--
--        if ( pirq >= current->domain->nr_pirqs )
--        {
--            ret = -EINVAL;
--            break;
--        }
--
--        iocaps_double_lock(d, true);
--
--        irq = pirq_access_permitted(current->domain, pirq);
--        if ( !irq || xsm_irq_permission(XSM_HOOK, d, irq, allow) )
--            ret = -EPERM;
--        else if ( allow )
--            ret = irq_permit_access(d, irq);
--        else
--            ret = irq_deny_access(d, irq);
--
--        iocaps_double_unlock(d, true);
--        break;
--    }
--#endif
--
-     case XEN_DOMCTL_settimeoffset:
-         domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
-         break;
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -170,9 +170,11 @@ static XSM_INLINE int cf_check xsm_domct
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-+    case XEN_DOMCTL_gsi_permission:
-     case XEN_DOMCTL_iomem_permission:
-     case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_ioport_permission:
-+    case XEN_DOMCTL_irq_permission:
-     case XEN_DOMCTL_memory_mapping:
-     case XEN_DOMCTL_unbind_pt_irq:
-         ASSERT_UNREACHABLE();
-@@ -562,7 +564,7 @@ static XSM_INLINE int cf_check xsm_unmap
- static XSM_INLINE int cf_check xsm_irq_permission(
-     XSM_DEFAULT_ARG struct domain *d, int pirq, uint8_t allow)
- {
--    XSM_ASSERT_ACTION(XSM_HOOK);
-+    XSM_ASSERT_ACTION(XSM_PRIV);
-     return xsm_default_action(action, current->domain, d);
- }
- 
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -686,9 +686,11 @@ static int cf_check flask_domctl(struct
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_getdomaininfo:
-     case XEN_DOMCTL_get_domain_state:
-+    case XEN_DOMCTL_gsi_permission:
-     case XEN_DOMCTL_iomem_permission:
-     case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_ioport_permission:
-+    case XEN_DOMCTL_irq_permission:
-     case XEN_DOMCTL_memory_mapping:
-     case XEN_DOMCTL_unbind_pt_irq:
-         ASSERT_UNREACHABLE();
-@@ -696,14 +698,12 @@ static int cf_check flask_domctl(struct
- 
-     /* These have individual XSM hooks (common/domctl.c) */
-     case XEN_DOMCTL_scheduler_op:
--    case XEN_DOMCTL_irq_permission:
-     case XEN_DOMCTL_set_target:
-     case XEN_DOMCTL_vm_event_op:
- 
- #ifdef CONFIG_X86
-     /* These have individual XSM hooks (arch/x86/domctl.c) */
-     case XEN_DOMCTL_shadow_op:
--    case XEN_DOMCTL_gsi_permission:
- #endif
- #ifdef CONFIG_HAS_PASSTHROUGH
-     /*

diff --git a/xsa492-4.21-14.patch b/xsa492-4.21-14.patch
deleted file mode 100644
index 2b13377..0000000
--- a/xsa492-4.21-14.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl/XSM: drop vm_event_control hook
-
-Integrate the checking with xsm_domctl(). Care needs to be taken with the
-GET_VERSION sub-op, which may be invoked with DOMID_INVALID, and which has
-been (and continues to be) bypassing XSM checking.
-
-Since the latter two parameters were unused, monitor_domctl() invoking the
-hook was actually redundant with the earlier xsm_domctl() (as can be seen
-nicely from the hunks changing xsm/flask/hooks.c).
-
-As a positive side effect, permissions are then checked at the same early
-point with and without Flask.
-
-While folding XEN_DOMCTL_monitor_op and XEN_DOMCTL_vm_event_op in
-flask_domctl(), also fold in XEN_DOMCTL_set_access_required.
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -496,6 +496,23 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-     }
- #endif
- 
-+    case XEN_DOMCTL_vm_event_op:
-+        if ( op->u.vm_event_op.op == XEN_VM_EVENT_GET_VERSION )
-+        {
-+            /* No XSM check (and potentially d == NULL) here. */
-+            ret = vm_event_domctl(d, &op->u.vm_event_op);
-+            if ( !ret )
-+                copyback = true;
-+            goto domctl_out_unlock_domonly;
-+        }
-+        if ( !d )
-+        {
-+            ret = -ESRCH;
-+            goto domctl_out_unlock_domonly;
-+        }
-+        /* Other sub-ops handled further down. */
-+        break;
-+
-     case XEN_DOMCTL_ioport_permission:
-     case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_gsi_permission:
---- a/xen/common/monitor.c
-+++ b/xen/common/monitor.c
-@@ -30,16 +30,11 @@
- 
- int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop)
- {
--    int rc;
-     bool requested_status = false;
- 
-     if ( unlikely(current->domain == d) ) /* no domain_pause() */
-         return -EPERM;
- 
--    rc = xsm_vm_event_control(XSM_PRIV, d, mop->op, mop->event);
--    if ( unlikely(rc) )
--        return rc;
--
-     switch ( mop->op )
-     {
-     case XEN_DOMCTL_MONITOR_OP_ENABLE:
---- a/xen/common/vm_event.c
-+++ b/xen/common/vm_event.c
-@@ -603,11 +603,10 @@ int vm_event_domctl(struct domain *d, st
- 
-     /* All other subops need to target a real domain. */
-     if ( unlikely(d == NULL) )
--        return -ESRCH;
--
--    rc = xsm_vm_event_control(XSM_PRIV, d, vec->mode, vec->op);
--    if ( rc )
--        return rc;
-+    {
-+        ASSERT_UNREACHABLE();
-+        return -EILSEQ;
-+    }
- 
-     if ( unlikely(d == current->domain) ) /* no domain_pause() */
-     {
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -652,13 +652,6 @@ static XSM_INLINE int cf_check xsm_hvm_a
-     }
- }
- 
--static XSM_INLINE int cf_check xsm_vm_event_control(
--    XSM_DEFAULT_ARG struct domain *d, int mode, int op)
--{
--    XSM_ASSERT_ACTION(XSM_PRIV);
--    return xsm_default_action(action, current->domain, d);
--}
--
- #ifdef CONFIG_VM_EVENT
- static XSM_INLINE int cf_check xsm_mem_access(XSM_DEFAULT_ARG struct domain *d)
- {
---- a/xen/include/xsm/xsm.h
-+++ b/xen/include/xsm/xsm.h
-@@ -157,8 +157,6 @@ struct xsm_ops {
-     int (*hvm_altp2mhvm_op)(struct domain *d, uint64_t mode, uint32_t op);
-     int (*get_vnumainfo)(struct domain *d);
- 
--    int (*vm_event_control)(struct domain *d, int mode, int op);
--
- #ifdef CONFIG_VM_EVENT
-     int (*mem_access)(struct domain *d);
- #endif
-@@ -657,12 +655,6 @@ static inline int xsm_get_vnumainfo(xsm_
-     return alternative_call(xsm_ops.get_vnumainfo, d);
- }
- 
--static inline int xsm_vm_event_control(
--    xsm_default_t def, struct domain *d, int mode, int op)
--{
--    return alternative_call(xsm_ops.vm_event_control, d, mode, op);
--}
--
- #ifdef CONFIG_VM_EVENT
- static inline int xsm_mem_access(xsm_default_t def, struct domain *d)
- {
---- a/xen/xsm/dummy.c
-+++ b/xen/xsm/dummy.c
-@@ -116,8 +116,6 @@ static const struct xsm_ops __initconst_
-     .remove_from_physmap           = xsm_remove_from_physmap,
-     .map_gmfn_foreign              = xsm_map_gmfn_foreign,
- 
--    .vm_event_control              = xsm_vm_event_control,
--
- #ifdef CONFIG_VM_EVENT
-     .mem_access                    = xsm_mem_access,
- #endif
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -699,7 +699,6 @@ static int cf_check flask_domctl(struct
-     /* These have individual XSM hooks (common/domctl.c) */
-     case XEN_DOMCTL_scheduler_op:
-     case XEN_DOMCTL_set_target:
--    case XEN_DOMCTL_vm_event_op:
- 
- #ifdef CONFIG_X86
-     /* These have individual XSM hooks (arch/x86/domctl.c) */
-@@ -793,9 +792,8 @@ static int cf_check flask_domctl(struct
-         return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__TRIGGER);
- 
-     case XEN_DOMCTL_set_access_required:
--        return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__VM_EVENT);
--
-     case XEN_DOMCTL_monitor_op:
-+    case XEN_DOMCTL_vm_event_op:
-         return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__VM_EVENT);
- 
-     case XEN_DOMCTL_debug_op:
-@@ -1368,11 +1366,6 @@ static int cf_check flask_hvm_altp2mhvm_
-     return current_has_perm(d, SECCLASS_HVM, HVM__ALTP2MHVM_OP);
- }
- 
--static int cf_check flask_vm_event_control(struct domain *d, int mode, int op)
--{
--    return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__VM_EVENT);
--}
--
- #ifdef CONFIG_VM_EVENT
- static int cf_check flask_mem_access(struct domain *d)
- {
-@@ -1971,8 +1964,6 @@ static const struct xsm_ops __initconst_
-     .do_xsm_op = do_flask_op,
-     .get_vnumainfo = flask_get_vnumainfo,
- 
--    .vm_event_control = flask_vm_event_control,
--
- #ifdef CONFIG_VM_EVENT
-     .mem_access = flask_mem_access,
- #endif

diff --git a/xsa492-4.21-15.patch b/xsa492-4.21-15.patch
deleted file mode 100644
index ac87f3b..0000000
--- a/xsa492-4.21-15.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl/XSM: pass full struct xen_domctl to xsm_domctl()
-
-Subsequently some sub-ops will want to inspect their sub-sub-ops. Plus
-this way we don't need to pass SSIDref separately anymore for
-domain_create.
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-
---- a/xen/arch/x86/mm/paging.c
-+++ b/xen/arch/x86/mm/paging.c
-@@ -735,7 +735,7 @@ long do_paging_domctl_cont(
-     if ( d == NULL )
-         return -ESRCH;
- 
--    ret = xsm_domctl(XSM_OTHER, d, op.cmd, 0 /* SSIDref not applicable */);
-+    ret = xsm_domctl(XSM_OTHER, d, &op);
-     if ( !ret )
-     {
-         if ( domctl_lock_acquire() )
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -526,9 +526,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         break;
-     }
- 
--    ret = xsm_domctl(XSM_OTHER, d, op->cmd,
--                     /* SSIDRef only applicable for cmd == createdomain */
--                     op->u.createdomain.ssidref);
-+    ret = xsm_domctl(XSM_OTHER, d, op);
-     if ( ret )
-         goto domctl_out_unlock_domonly;
- 
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -162,10 +162,10 @@ static XSM_INLINE int cf_check xsm_set_t
- }
- 
- static XSM_INLINE int cf_check xsm_domctl(
--    XSM_DEFAULT_ARG struct domain *d, unsigned int cmd, uint32_t ssidref)
-+    XSM_DEFAULT_ARG struct domain *d, struct xen_domctl *op)
- {
-     XSM_ASSERT_ACTION(XSM_OTHER);
--    switch ( cmd )
-+    switch ( op->cmd )
-     {
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_getdomaininfo:
---- a/xen/include/xsm/xsm.h
-+++ b/xen/include/xsm/xsm.h
-@@ -61,7 +61,7 @@ struct xsm_ops {
-     int (*sysctl_scheduler_op)(int op);
- #endif
-     int (*set_target)(struct domain *d, struct domain *e);
--    int (*domctl)(struct domain *d, unsigned int cmd, uint32_t ssidref);
-+    int (*domctl)(struct domain *d, struct xen_domctl *op);
-     int (*sysctl)(int cmd);
-     int (*readconsole)(uint32_t clear);
- 
-@@ -260,9 +260,9 @@ static inline int xsm_set_target(
- }
- 
- static inline int xsm_domctl(xsm_default_t def, struct domain *d,
--                             unsigned int cmd, uint32_t ssidref)
-+                             struct xen_domctl *op)
- {
--    return alternative_call(xsm_ops.domctl, d, cmd, ssidref);
-+    return alternative_call(xsm_ops.domctl, d, op);
- }
- 
- static inline int xsm_sysctl(xsm_default_t def, int cmd)
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -667,10 +667,9 @@ static int cf_check flask_set_target(str
-     return rc;
- }
- 
--static int cf_check flask_domctl(struct domain *d, unsigned int cmd,
--                                 uint32_t ssidref)
-+static int cf_check flask_domctl(struct domain *d, struct xen_domctl *op)
- {
--    switch ( cmd )
-+    switch ( op->cmd )
-     {
-     case XEN_DOMCTL_createdomain:
-         /*
-@@ -680,7 +679,8 @@ static int cf_check flask_domctl(struct
-          * Note that d is NULL because we haven't even allocated memory for it
-          * this early in XEN_DOMCTL_createdomain.
-          */
--        return avc_current_has_perm(ssidref, SECCLASS_DOMAIN, DOMAIN__CREATE, NULL);
-+        return avc_current_has_perm(op->u.createdomain.ssidref, SECCLASS_DOMAIN,
-+                                    DOMAIN__CREATE, NULL);
- 
-     /* These have individual XSM hooks and don't make it here. */
-     case XEN_DOMCTL_bind_pt_irq:
-@@ -855,7 +855,7 @@ static int cf_check flask_domctl(struct
-         return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SET_LLC_COLORS);
- 
-     default:
--        return avc_unknown_permission("domctl", cmd);
-+        return avc_unknown_permission("domctl", op->cmd);
-     }
- }
- 

diff --git a/xsa492-4.21-16.patch b/xsa492-4.21-16.patch
deleted file mode 100644
index 2cb8619..0000000
--- a/xsa492-4.21-16.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl/XSM: drop scheduler_op hook
-
-Integrate the checking with xsm_domctl(), now that it has the full op
-struct passed. As a positive side effect, permissions are then checked at
-the same early point with and without Flask.
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-Reviewed-by: Juergen Gross <jgross@suse.com>
-
---- a/xen/common/sched/core.c
-+++ b/xen/common/sched/core.c
-@@ -2074,10 +2074,6 @@ long sched_adjust(struct domain *d, stru
- {
-     long ret;
- 
--    ret = xsm_domctl_scheduler_op(XSM_HOOK, d, op->cmd);
--    if ( ret )
--        return ret;
--
-     if ( op->sched_id != dom_scheduler(d)->sched_id )
-         return -EINVAL;
- 
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -141,13 +141,6 @@ static XSM_INLINE int cf_check xsm_getdo
-     return xsm_default_action(action, current->domain, d);
- }
- 
--static XSM_INLINE int cf_check xsm_domctl_scheduler_op(
--    XSM_DEFAULT_ARG struct domain *d, int cmd)
--{
--    XSM_ASSERT_ACTION(XSM_HOOK);
--    return xsm_default_action(action, current->domain, d);
--}
--
- static XSM_INLINE int cf_check xsm_sysctl_scheduler_op(XSM_DEFAULT_ARG int cmd)
- {
-     XSM_ASSERT_ACTION(XSM_HOOK);
---- a/xen/include/xsm/xsm.h
-+++ b/xen/include/xsm/xsm.h
-@@ -56,7 +56,6 @@ struct xsm_ops {
-                                 struct xen_domctl_getdomaininfo *info);
-     int (*domain_create)(struct domain *d, uint32_t ssidref);
-     int (*getdomaininfo)(struct domain *d);
--    int (*domctl_scheduler_op)(struct domain *d, int op);
- #ifdef CONFIG_SYSCTL
-     int (*sysctl_scheduler_op)(int op);
- #endif
-@@ -240,12 +239,6 @@ static inline int xsm_get_domain_state(x
-     return alternative_call(xsm_ops.get_domain_state, d);
- }
- 
--static inline int xsm_domctl_scheduler_op(
--    xsm_default_t def, struct domain *d, int cmd)
--{
--    return alternative_call(xsm_ops.domctl_scheduler_op, d, cmd);
--}
--
- #ifdef CONFIG_SYSCTL
- static inline int xsm_sysctl_scheduler_op(xsm_default_t def, int cmd)
- {
---- a/xen/xsm/dummy.c
-+++ b/xen/xsm/dummy.c
-@@ -18,7 +18,6 @@ static const struct xsm_ops __initconst_
-     .security_domaininfo           = xsm_security_domaininfo,
-     .domain_create                 = xsm_domain_create,
-     .getdomaininfo                 = xsm_getdomaininfo,
--    .domctl_scheduler_op           = xsm_domctl_scheduler_op,
- #ifdef CONFIG_SYSCTL
-     .sysctl_scheduler_op           = xsm_sysctl_scheduler_op,
- #endif
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -609,7 +609,7 @@ static int cf_check flask_getdomaininfo(
-     return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETDOMAININFO);
- }
- 
--static int cf_check flask_domctl_scheduler_op(struct domain *d, int op)
-+static int flask_domctl_scheduler_op(struct domain *d, int op)
- {
-     switch ( op )
-     {
-@@ -697,7 +697,6 @@ static int cf_check flask_domctl(struct
-         return -EILSEQ;
- 
-     /* These have individual XSM hooks (common/domctl.c) */
--    case XEN_DOMCTL_scheduler_op:
-     case XEN_DOMCTL_set_target:
- 
- #ifdef CONFIG_X86
-@@ -745,6 +744,9 @@ static int cf_check flask_domctl(struct
-     case XEN_DOMCTL_setdomainhandle:
-         return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINHANDLE);
- 
-+    case XEN_DOMCTL_scheduler_op:
-+        return flask_domctl_scheduler_op(d, op->u.scheduler_op.cmd);
-+
-     case XEN_DOMCTL_set_ext_vcpucontext:
-     case XEN_DOMCTL_set_vcpu_msrs:
-     case XEN_DOMCTL_setvcpucontext:
-@@ -1884,7 +1886,6 @@ static const struct xsm_ops __initconst_
-     .security_domaininfo = flask_security_domaininfo,
-     .domain_create = flask_domain_create,
-     .getdomaininfo = flask_getdomaininfo,
--    .domctl_scheduler_op = flask_domctl_scheduler_op,
- #ifdef CONFIG_SYSCTL
-     .sysctl_scheduler_op = flask_sysctl_scheduler_op,
- #endif

diff --git a/xsa492-4.21-17.patch b/xsa492-4.21-17.patch
deleted file mode 100644
index 99542df..0000000
--- a/xsa492-4.21-17.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl/XSM: drop shadow_control_op hook
-
-Integrate the checking with xsm_domctl(), now that it has the full op
-struct passed. As a positive side effect, permissions are then checked at
-the same early point with and without Flask.
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-
---- a/xen/arch/x86/mm/paging.c
-+++ b/xen/arch/x86/mm/paging.c
-@@ -677,10 +677,6 @@ int paging_domctl(struct domain *d, stru
-         return -EBUSY;
-     }
- 
--    rc = xsm_shadow_control(XSM_HOOK, d, sc->op);
--    if ( rc )
--        return rc;
--
-     /* Code to handle log-dirty. Note that some log dirty operations
-      * piggy-back on shadow operations. For example, when
-      * XEN_DOMCTL_SHADOW_OP_OFF is called, it first checks whether log dirty
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -682,13 +682,6 @@ static XSM_INLINE int cf_check xsm_do_mc
-     return xsm_default_action(action, current->domain, NULL);
- }
- 
--static XSM_INLINE int cf_check xsm_shadow_control(
--    XSM_DEFAULT_ARG struct domain *d, uint32_t op)
--{
--    XSM_ASSERT_ACTION(XSM_HOOK);
--    return xsm_default_action(action, current->domain, d);
--}
--
- static XSM_INLINE int cf_check xsm_mem_sharing_op(
-     XSM_DEFAULT_ARG struct domain *d, struct domain *cd, int op)
- {
---- a/xen/include/xsm/xsm.h
-+++ b/xen/include/xsm/xsm.h
-@@ -172,7 +172,6 @@ struct xsm_ops {
- 
- #ifdef CONFIG_X86
-     int (*do_mca)(void);
--    int (*shadow_control)(struct domain *d, uint32_t op);
-     int (*mem_sharing_op)(struct domain *d, struct domain *cd, int op);
-     int (*apic)(struct domain *d, int cmd);
-     int (*machine_memory_map)(void);
-@@ -680,12 +679,6 @@ static inline int xsm_do_mca(xsm_default
-     return alternative_call(xsm_ops.do_mca);
- }
- 
--static inline int xsm_shadow_control(
--    xsm_default_t def, struct domain *d, uint32_t op)
--{
--    return alternative_call(xsm_ops.shadow_control, d, op);
--}
--
- static inline int xsm_mem_sharing_op(
-     xsm_default_t def, struct domain *d, struct domain *cd, int op)
- {
---- a/xen/xsm/dummy.c
-+++ b/xen/xsm/dummy.c
-@@ -130,7 +130,6 @@ static const struct xsm_ops __initconst_
-     .platform_op                   = xsm_platform_op,
- #ifdef CONFIG_X86
-     .do_mca                        = xsm_do_mca,
--    .shadow_control                = xsm_shadow_control,
-     .mem_sharing_op                = xsm_mem_sharing_op,
-     .apic                          = xsm_apic,
-     .machine_memory_map            = xsm_machine_memory_map,
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -40,6 +40,7 @@
- 
- #ifdef CONFIG_X86
- #include <asm/pv/shim.h>
-+static int flask_shadow_control(struct domain *d, unsigned int op);
- #else
- #define pv_shim false
- #endif
-@@ -699,10 +700,6 @@ static int cf_check flask_domctl(struct
-     /* These have individual XSM hooks (common/domctl.c) */
-     case XEN_DOMCTL_set_target:
- 
--#ifdef CONFIG_X86
--    /* These have individual XSM hooks (arch/x86/domctl.c) */
--    case XEN_DOMCTL_shadow_op:
--#endif
- #ifdef CONFIG_HAS_PASSTHROUGH
-     /*
-      * These have individual XSM hooks
-@@ -787,6 +784,11 @@ static int cf_check flask_domctl(struct
-     case XEN_DOMCTL_get_address_size:
-         return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETADDRSIZE);
- 
-+#ifdef CONFIG_X86
-+    case XEN_DOMCTL_shadow_op:
-+        return flask_shadow_control(d, op->u.shadow_op.op);
-+#endif
-+
-     case XEN_DOMCTL_mem_sharing_op:
-         return current_has_perm(d, SECCLASS_HVM, HVM__MEM_SHARING);
- 
-@@ -1603,7 +1605,7 @@ static int cf_check flask_do_mca(void)
-     return domain_has_xen(current->domain, XEN__MCA_OP);
- }
- 
--static int cf_check flask_shadow_control(struct domain *d, uint32_t op)
-+static int flask_shadow_control(struct domain *d, unsigned int op)
- {
-     uint32_t perm;
- 
-@@ -1999,7 +2001,6 @@ static const struct xsm_ops __initconst_
-     .platform_op = flask_platform_op,
- #ifdef CONFIG_X86
-     .do_mca = flask_do_mca,
--    .shadow_control = flask_shadow_control,
-     .mem_sharing_op = flask_mem_sharing_op,
-     .apic = flask_apic,
-     .machine_memory_map = flask_machine_memory_map,

diff --git a/xsa492-4.21-18.patch b/xsa492-4.21-18.patch
deleted file mode 100644
index 1d82124..0000000
--- a/xsa492-4.21-18.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl: handle XEN_DOMCTL_get_device_group without acquiring domctl lock
-
-iommu_get_device_group() uses its own locking. Thus, with caller side
-locking irrelevant, it can as well be called with the domctl lock not
-held.
-
-Move the handling not only ahead of acquiring the lock, but also ahead
-of the XSM check, leveraging that the sub-op has its own hook.
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -513,6 +513,10 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         /* Other sub-ops handled further down. */
-         break;
- 
-+    case XEN_DOMCTL_get_device_group:
-+        ret = iommu_do_domctl(op, d, u_domctl);
-+        goto domctl_out_unlock_domonly;
-+
-     case XEN_DOMCTL_ioport_permission:
-     case XEN_DOMCTL_ioport_mapping:
-     case XEN_DOMCTL_gsi_permission:
-@@ -918,7 +922,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-     case XEN_DOMCTL_assign_device:
-     case XEN_DOMCTL_test_assign_device:
-     case XEN_DOMCTL_deassign_device:
--    case XEN_DOMCTL_get_device_group:
-         ret = iommu_do_domctl(op, d, u_domctl);
-         break;
- 
---- a/xen/drivers/passthrough/pci.c
-+++ b/xen/drivers/passthrough/pci.c
-@@ -1620,7 +1620,7 @@ static int iommu_get_device_group(
-         if ( (pdev->seg != seg) || ((b == bus) && (df == devfn)) )
-             continue;
- 
--        if ( xsm_get_device_group(XSM_HOOK, (seg << 16) | (b << 8) | df) )
-+        if ( xsm_get_device_group(XSM_PRIV, (seg << 16) | (b << 8) | df) )
-             continue;
- 
-         sdev_id = iommu_call(ops, get_device_group_id, seg, b, df);
-@@ -1690,7 +1690,7 @@ int iommu_do_pci_domctl(
-         u32 max_sdevs;
-         XEN_GUEST_HANDLE_64(uint32) sdevs;
- 
--        ret = xsm_get_device_group(XSM_HOOK, domctl->u.get_device_group.machine_sbdf);
-+        ret = xsm_get_device_group(XSM_PRIV, domctl->u.get_device_group.machine_sbdf);
-         if ( ret )
-             break;
- 
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -162,6 +162,7 @@ static XSM_INLINE int cf_check xsm_domct
-     {
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_getdomaininfo:
-+    case XEN_DOMCTL_get_device_group:
-     case XEN_DOMCTL_get_domain_state:
-     case XEN_DOMCTL_gsi_permission:
-     case XEN_DOMCTL_iomem_permission:
-@@ -401,7 +402,7 @@ static XSM_INLINE int cf_check xsm_get_v
- static XSM_INLINE int cf_check xsm_get_device_group(
-     XSM_DEFAULT_ARG uint32_t machine_bdf)
- {
--    XSM_ASSERT_ACTION(XSM_HOOK);
-+    XSM_ASSERT_ACTION(XSM_PRIV);
-     return xsm_default_action(action, current->domain, NULL);
- }
- 
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -686,6 +686,7 @@ static int cf_check flask_domctl(struct
-     /* These have individual XSM hooks and don't make it here. */
-     case XEN_DOMCTL_bind_pt_irq:
-     case XEN_DOMCTL_getdomaininfo:
-+    case XEN_DOMCTL_get_device_group:
-     case XEN_DOMCTL_get_domain_state:
-     case XEN_DOMCTL_gsi_permission:
-     case XEN_DOMCTL_iomem_permission:
-@@ -705,7 +706,6 @@ static int cf_check flask_domctl(struct
-      * These have individual XSM hooks
-      * (drivers/passthrough/{pci,device_tree.c)
-      */
--    case XEN_DOMCTL_get_device_group:
-     case XEN_DOMCTL_test_assign_device:
-     case XEN_DOMCTL_assign_device:
-     case XEN_DOMCTL_deassign_device:

diff --git a/xsa492-4.21-19.patch b/xsa492-4.21-19.patch
deleted file mode 100644
index 54a1117..0000000
--- a/xsa492-4.21-19.patch
+++ /dev/null
@@ -1,378 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl/XSM: drop {,de}assign_{,dt}device hooks
-
-Integrate the checking with xsm_domctl(). As a positive side effect,
-permissions are then checked at the same early point with and without
-Flask. As the DT device path needs fetching earlier (but must not be
-double fetched), cache it in a private field of the public interface
-struct.
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -325,6 +325,10 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-     case XEN_DOMCTL_deassign_device:
-         if ( op->domain == DOMID_IO )
-         {
-+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
-+            if ( op->u.assign_device.dev == XEN_DOMCTL_DEV_DT )
-+                op->u.assign_device.u.dt.dev = NULL;
-+#endif
-             d = dom_io;
-             break;
-         }
-@@ -332,6 +336,11 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-             return -ESRCH;
-         fallthrough;
-     case XEN_DOMCTL_test_assign_device:
-+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
-+        if ( op->u.assign_device.dev == XEN_DOMCTL_DEV_DT )
-+            op->u.assign_device.u.dt.dev = NULL;
-+        fallthrough;
-+#endif
-     case XEN_DOMCTL_vm_event_op:
-         if ( op->domain == DOMID_INVALID )
-         {
---- a/xen/drivers/passthrough/device_tree.c
-+++ b/xen/drivers/passthrough/device_tree.c
-@@ -340,15 +340,15 @@ int iommu_do_dt_domctl(struct xen_domctl
-         if ( (d && d->is_dying) || domctl->u.assign_device.flags )
-             break;
- 
--        ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
--                                    domctl->u.assign_device.u.dt.size,
--                                    &dev);
--        if ( ret )
--            break;
--
--        ret = xsm_assign_dtdevice(XSM_HOOK, d, dt_node_full_name(dev));
--        if ( ret )
--            break;
-+        dev = domctl->u.assign_device.u.dt.dev;
-+        if ( !dev )
-+        {
-+            ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
-+                                        domctl->u.assign_device.u.dt.size,
-+                                        &dev);
-+            if ( ret )
-+                break;
-+        }
- 
-         if ( domctl->cmd == XEN_DOMCTL_test_assign_device )
-         {
-@@ -396,15 +396,15 @@ int iommu_do_dt_domctl(struct xen_domctl
-         if ( domctl->u.assign_device.flags )
-             break;
- 
--        ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
--                                    domctl->u.assign_device.u.dt.size,
--                                    &dev);
--        if ( ret )
--            break;
--
--        ret = xsm_deassign_dtdevice(XSM_HOOK, d, dt_node_full_name(dev));
--        if ( ret )
--            break;
-+        dev = domctl->u.assign_device.u.dt.dev;
-+        if ( !dev )
-+        {
-+            ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
-+                                        domctl->u.assign_device.u.dt.size,
-+                                        &dev);
-+            if ( ret )
-+                break;
-+        }
- 
-         if ( d == dom_io )
-         {
---- a/xen/drivers/passthrough/pci.c
-+++ b/xen/drivers/passthrough/pci.c
-@@ -1740,10 +1740,6 @@ int iommu_do_pci_domctl(
- 
-         machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
- 
--        ret = xsm_assign_device(XSM_HOOK, d, machine_sbdf);
--        if ( ret )
--            break;
--
-         seg = machine_sbdf >> 16;
-         bus = PCI_BUS(machine_sbdf);
-         devfn = PCI_DEVFN(machine_sbdf);
-@@ -1785,10 +1781,6 @@ int iommu_do_pci_domctl(
- 
-         machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
- 
--        ret = xsm_deassign_device(XSM_HOOK, d, machine_sbdf);
--        if ( ret )
--            break;
--
-         seg = machine_sbdf >> 16;
-         bus = PCI_BUS(machine_sbdf);
-         devfn = PCI_DEVFN(machine_sbdf);
---- a/xen/include/public/domctl.h
-+++ b/xen/include/public/domctl.h
-@@ -575,7 +575,10 @@ struct xen_domctl_assign_device {
-         } pci;
-         struct {
-             uint32_t size; /* Length of the path */
--            XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */
-+            XEN_GUEST_HANDLE_64(char) path; /* Path to the device tree node */
-+#ifdef __XEN__
-+            struct dt_device_node *dev; /* Resolved device node of the above */
-+#endif
-         } dt;
-     } u;
- };
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -405,40 +405,8 @@ static XSM_INLINE int cf_check xsm_get_d
-     XSM_ASSERT_ACTION(XSM_PRIV);
-     return xsm_default_action(action, current->domain, NULL);
- }
--
--static XSM_INLINE int cf_check xsm_assign_device(
--    XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf)
--{
--    XSM_ASSERT_ACTION(XSM_HOOK);
--    return xsm_default_action(action, current->domain, d);
--}
--
--static XSM_INLINE int cf_check xsm_deassign_device(
--    XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf)
--{
--    XSM_ASSERT_ACTION(XSM_HOOK);
--    return xsm_default_action(action, current->domain, d);
--}
--
- #endif /* HAS_PASSTHROUGH && HAS_PCI */
- 
--#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
--static XSM_INLINE int cf_check xsm_assign_dtdevice(
--    XSM_DEFAULT_ARG struct domain *d, const char *dtpath)
--{
--    XSM_ASSERT_ACTION(XSM_HOOK);
--    return xsm_default_action(action, current->domain, d);
--}
--
--static XSM_INLINE int cf_check xsm_deassign_dtdevice(
--    XSM_DEFAULT_ARG struct domain *d, const char *dtpath)
--{
--    XSM_ASSERT_ACTION(XSM_HOOK);
--    return xsm_default_action(action, current->domain, d);
--}
--
--#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
--
- static XSM_INLINE int cf_check xsm_resource_plug_core(XSM_DEFAULT_VOID)
- {
-     XSM_ASSERT_ACTION(XSM_HOOK);
---- a/xen/include/xsm/xsm.h
-+++ b/xen/include/xsm/xsm.h
-@@ -124,13 +124,6 @@ struct xsm_ops {
- 
- #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_PCI)
-     int (*get_device_group)(uint32_t machine_bdf);
--    int (*assign_device)(struct domain *d, uint32_t machine_bdf);
--    int (*deassign_device)(struct domain *d, uint32_t machine_bdf);
--#endif
--
--#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
--    int (*assign_dtdevice)(struct domain *d, const char *dtpath);
--    int (*deassign_dtdevice)(struct domain *d, const char *dtpath);
- #endif
- 
-     int (*resource_plug_core)(void);
-@@ -533,35 +526,8 @@ static inline int xsm_get_device_group(x
- {
-     return alternative_call(xsm_ops.get_device_group, machine_bdf);
- }
--
--static inline int xsm_assign_device(
--    xsm_default_t def, struct domain *d, uint32_t machine_bdf)
--{
--    return alternative_call(xsm_ops.assign_device, d, machine_bdf);
--}
--
--static inline int xsm_deassign_device(
--    xsm_default_t def, struct domain *d, uint32_t machine_bdf)
--{
--    return alternative_call(xsm_ops.deassign_device, d, machine_bdf);
--}
- #endif /* HAS_PASSTHROUGH && HAS_PCI) */
- 
--#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
--static inline int xsm_assign_dtdevice(
--    xsm_default_t def, struct domain *d, const char *dtpath)
--{
--    return alternative_call(xsm_ops.assign_dtdevice, d, dtpath);
--}
--
--static inline int xsm_deassign_dtdevice(
--    xsm_default_t def, struct domain *d, const char *dtpath)
--{
--    return alternative_call(xsm_ops.deassign_dtdevice, d, dtpath);
--}
--
--#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
--
- static inline int xsm_resource_plug_pci(xsm_default_t def, uint32_t machine_bdf)
- {
-     return alternative_call(xsm_ops.resource_plug_pci, machine_bdf);
---- a/xen/xsm/dummy.c
-+++ b/xen/xsm/dummy.c
-@@ -81,13 +81,6 @@ static const struct xsm_ops __initconst_
- 
- #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_PCI)
-     .get_device_group              = xsm_get_device_group,
--    .assign_device                 = xsm_assign_device,
--    .deassign_device               = xsm_deassign_device,
--#endif
--
--#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
--    .assign_dtdevice               = xsm_assign_dtdevice,
--    .deassign_dtdevice             = xsm_deassign_dtdevice,
- #endif
- 
-     .resource_plug_core            = xsm_resource_plug_core,
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -45,6 +45,17 @@ static int flask_shadow_control(struct d
- #define pv_shim false
- #endif
- 
-+#ifdef CONFIG_HAS_PASSTHROUGH
-+#ifdef CONFIG_HAS_PCI
-+static int flask_assign_device(struct domain *d, unsigned int machine_bdf);
-+static int flask_deassign_device(struct domain *d, unsigned int machine_bdf);
-+#endif
-+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
-+static int flask_assign_dtdevice(struct domain *d, const char *dtpath);
-+static int flask_deassign_dtdevice(struct domain *d, const char *dtpath);
-+#endif
-+#endif /* CONFIG_HAS_PASSTHROUGH */
-+
- static uint32_t domain_sid(const struct domain *dom)
- {
-     struct domain_security_struct *dsec = dom->ssid;
-@@ -700,16 +711,6 @@ static int cf_check flask_domctl(struct
- 
-     /* These have individual XSM hooks (common/domctl.c) */
-     case XEN_DOMCTL_set_target:
--
--#ifdef CONFIG_HAS_PASSTHROUGH
--    /*
--     * These have individual XSM hooks
--     * (drivers/passthrough/{pci,device_tree.c)
--     */
--    case XEN_DOMCTL_test_assign_device:
--    case XEN_DOMCTL_assign_device:
--    case XEN_DOMCTL_deassign_device:
--#endif
-         return 0;
- 
-     case XEN_DOMCTL_destroydomain:
-@@ -789,6 +790,49 @@ static int cf_check flask_domctl(struct
-         return flask_shadow_control(d, op->u.shadow_op.op);
- #endif
- 
-+#ifdef CONFIG_HAS_PASSTHROUGH
-+
-+    case XEN_DOMCTL_test_assign_device:
-+    case XEN_DOMCTL_assign_device:
-+    case XEN_DOMCTL_deassign_device:
-+        switch ( op->u.assign_device.dev )
-+        {
-+#ifdef CONFIG_HAS_PCI
-+        case XEN_DOMCTL_DEV_PCI:
-+            return op->cmd != XEN_DOMCTL_deassign_device
-+                   ? flask_assign_device(
-+                         d, op->u.assign_device.u.pci.machine_sbdf)
-+                   : flask_deassign_device(
-+                         d, op->u.assign_device.u.pci.machine_sbdf);
-+#endif
-+
-+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
-+        case XEN_DOMCTL_DEV_DT:
-+        {
-+            struct dt_device_node *dev;
-+            int ret = dt_find_node_by_gpath(op->u.assign_device.u.dt.path,
-+                                            op->u.assign_device.u.dt.size,
-+                                            &dev);
-+
-+            if ( ret )
-+                return ret;
-+
-+            op->u.assign_device.u.dt.dev = dev;
-+
-+            return op->cmd != XEN_DOMCTL_deassign_device
-+                   ? flask_assign_dtdevice(d, dt_node_full_name(dev))
-+                   : flask_deassign_dtdevice(d, dt_node_full_name(dev));
-+        }
-+#endif
-+
-+        default:
-+            /* Unknown type. */
-+            break;
-+        }
-+        return avc_unknown_permission("assign_device", op->cmd);
-+
-+#endif /* CONFIG_HAS_PASSTHROUGH */
-+
-     case XEN_DOMCTL_mem_sharing_op:
-         return current_has_perm(d, SECCLASS_HVM, HVM__MEM_SHARING);
- 
-@@ -1416,7 +1460,7 @@ static int flask_test_assign_device(uint
-     return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL);
- }
- 
--static int cf_check flask_assign_device(struct domain *d, uint32_t machine_bdf)
-+static int flask_assign_device(struct domain *d, uint32_t machine_bdf)
- {
-     uint32_t dsid, rsid;
-     int rc = -EPERM;
-@@ -1446,7 +1490,7 @@ static int cf_check flask_assign_device(
-     return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, dperm, &ad);
- }
- 
--static int cf_check flask_deassign_device(
-+static int flask_deassign_device(
-     struct domain *d, uint32_t machine_bdf)
- {
-     uint32_t rsid;
-@@ -1478,7 +1522,7 @@ static int flask_test_assign_dtdevice(co
-                                 NULL);
- }
- 
--static int cf_check flask_assign_dtdevice(struct domain *d, const char *dtpath)
-+static int flask_assign_dtdevice(struct domain *d, const char *dtpath)
- {
-     uint32_t dsid, rsid;
-     int rc = -EPERM;
-@@ -1508,7 +1552,7 @@ static int cf_check flask_assign_dtdevic
-     return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, dperm, &ad);
- }
- 
--static int cf_check flask_deassign_dtdevice(
-+static int flask_deassign_dtdevice(
-     struct domain *d, const char *dtpath)
- {
-     uint32_t rsid;
-@@ -1989,13 +2033,6 @@ static const struct xsm_ops __initconst_
- 
- #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_PCI)
-     .get_device_group = flask_get_device_group,
--    .assign_device = flask_assign_device,
--    .deassign_device = flask_deassign_device,
--#endif
--
--#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
--    .assign_dtdevice = flask_assign_dtdevice,
--    .deassign_dtdevice = flask_deassign_dtdevice,
- #endif
- 
-     .platform_op = flask_platform_op,

diff --git a/xsa492-4.21-20.patch b/xsa492-4.21-20.patch
deleted file mode 100644
index bfd10a9..0000000
--- a/xsa492-4.21-20.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: domctl: handle XEN_DOMCTL_set_target without acquiring domctl lock
-
-The only locking required here is that between checking d->target and
-setting it. To avoid the need for an explicit lock, use cmpxchgptr() to
-update d->target.
-
-Move the handling not only ahead of acquiring the lock, but also ahead
-of the XSM check, leveraging that the sub-op has its own hook.
-
-This is part of XSA-492.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-
---- a/xen/common/domctl.c
-+++ b/xen/common/domctl.c
-@@ -505,6 +505,30 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-     }
- #endif
- 
-+    case XEN_DOMCTL_set_target:
-+    {
-+        struct domain *e = get_domain_by_id(op->u.set_target.target);
-+
-+        ret = -ESRCH;
-+        if ( !e )
-+            goto domctl_out_unlock_domonly;
-+
-+        if ( d == e )
-+            ret = -EINVAL;
-+        else if ( !is_hvm_domain(e) )
-+            ret = -EOPNOTSUPP;
-+        else
-+            ret = xsm_set_target(XSM_PRIV, d, e);
-+
-+        /* Hold reference on @e until we destroy @d. */
-+        if ( !ret && cmpxchgptr(&d->target, NULL, e) )
-+            ret = -EINVAL;
-+
-+        if ( ret )
-+            put_domain(e);
-+        goto domctl_out_unlock_domonly;
-+    }
-+
-     case XEN_DOMCTL_vm_event_op:
-         if ( op->u.vm_event_op.op == XEN_VM_EVENT_GET_VERSION )
-         {
-@@ -844,36 +868,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
-         domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
-         break;
- 
--    case XEN_DOMCTL_set_target:
--    {
--        struct domain *e;
--
--        ret = -ESRCH;
--        e = get_domain_by_id(op->u.set_target.target);
--        if ( e == NULL )
--            break;
--
--        ret = -EINVAL;
--        if ( (d == e) || (d->target != NULL) )
--        {
--            put_domain(e);
--            break;
--        }
--
--        ret = -EOPNOTSUPP;
--        if ( is_hvm_domain(e) )
--            ret = xsm_set_target(XSM_HOOK, d, e);
--        if ( ret )
--        {
--            put_domain(e);
--            break;
--        }
--
--        /* Hold reference on @e until we destroy @d. */
--        d->target = e;
--        break;
--    }
--
-     case XEN_DOMCTL_subscribe:
-         d->suspend_evtchn = op->u.subscribe.port;
-         break;
---- a/xen/include/xsm/dummy.h
-+++ b/xen/include/xsm/dummy.h
-@@ -150,7 +150,7 @@ static XSM_INLINE int cf_check xsm_sysct
- static XSM_INLINE int cf_check xsm_set_target(
-     XSM_DEFAULT_ARG struct domain *d, struct domain *e)
- {
--    XSM_ASSERT_ACTION(XSM_HOOK);
-+    XSM_ASSERT_ACTION(XSM_PRIV);
-     return xsm_default_action(action, current->domain, NULL);
- }
- 
-@@ -170,6 +170,7 @@ static XSM_INLINE int cf_check xsm_domct
-     case XEN_DOMCTL_ioport_permission:
-     case XEN_DOMCTL_irq_permission:
-     case XEN_DOMCTL_memory_mapping:
-+    case XEN_DOMCTL_set_target:
-     case XEN_DOMCTL_unbind_pt_irq:
-         ASSERT_UNREACHABLE();
-         return -EILSEQ;
---- a/xen/xsm/flask/hooks.c
-+++ b/xen/xsm/flask/hooks.c
-@@ -705,14 +705,11 @@ static int cf_check flask_domctl(struct
-     case XEN_DOMCTL_ioport_permission:
-     case XEN_DOMCTL_irq_permission:
-     case XEN_DOMCTL_memory_mapping:
-+    case XEN_DOMCTL_set_target:
-     case XEN_DOMCTL_unbind_pt_irq:
-         ASSERT_UNREACHABLE();
-         return -EILSEQ;
- 
--    /* These have individual XSM hooks (common/domctl.c) */
--    case XEN_DOMCTL_set_target:
--        return 0;
--
-     case XEN_DOMCTL_destroydomain:
-         return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__DESTROY);
- 

diff --git a/xsa493-4.21-01.patch b/xsa493-4.21-01.patch
deleted file mode 100644
index c06b9a5..0000000
--- a/xsa493-4.21-01.patch
+++ /dev/null
@@ -1,311 +0,0 @@
-From 2e21b5301765de353c06081eee953255bf327176 Mon Sep 17 00:00:00 2001
-From: Michal Orzel <michal.orzel@amd.com>
-Date: Tue, 14 Apr 2026 10:11:24 +0200
-Subject: xen/arm64: flushtlb: Optimize ARM64_WORKAROUND_REPEAT_TLBI
-
-The ARM64_WORKAROUND_REPEAT_TLBI workaround is used to mitigate several
-errata where broadcast TLBI;DSB sequences don't provide all the
-architecturally required synchronization. The workaround performs more
-work than necessary, and can have significant overhead. This patch
-optimizes the workaround, as explained below.
-
-1. All relevant errata only affect the ordering and/or completion of
-   memory accesses which have been translated by an invalidated TLB
-   entry. The actual invalidation of TLB entries is unaffected.
-
-2. The existing workaround is applied to both broadcast and local TLB
-   invalidation, whereas for all relevant errata it is only necessary to
-   apply a workaround for broadcast invalidation.
-
-3. The existing workaround replaces every TLBI with a TLBI;DSB;TLBI
-   sequence, whereas for all relevant errata it is only necessary to
-   execute a single additional TLBI;DSB sequence after any number of
-   TLBIs are completed by a DSB.
-
-   For example, for a sequence of batched TLBIs:
-
-       TLBI <op1>[, <arg1>]
-       TLBI <op2>[, <arg2>]
-       TLBI <op3>[, <arg3>]
-       DSB ISH
-
-   ... the existing workaround will expand this to:
-
-       TLBI <op1>[, <arg1>]
-       DSB ISH                  // additional
-       TLBI <op1>[, <arg1>]     // additional
-       TLBI <op2>[, <arg2>]
-       DSB ISH                  // additional
-       TLBI <op2>[, <arg2>]     // additional
-       TLBI <op3>[, <arg3>]
-       DSB ISH                  // additional
-       TLBI <op3>[, <arg3>]     // additional
-       DSB ISH
-
-   ... whereas it is sufficient to have:
-
-       TLBI <op1>[, <arg1>]
-       TLBI <op2>[, <arg2>]
-       TLBI <op3>[, <arg3>]
-       DSB ISH
-       TLBI <opX>[, <argX>]     // additional
-       DSB ISH                  // additional
-
-   Using a single additional TLBI and DSB at the end of the sequence can
-   have significantly lower overhead as each DSB which completes a TLBI
-   must synchronize with other PEs in the system, with potential
-   performance effects both locally and system-wide.
-
-4. The existing workaround repeats each specific TLBI operation, whereas
-   for all relevant errata it is sufficient for the additional TLBI to
-   use *any* operation which will be broadcast, regardless of which
-   translation regime or stage of translation the operation applies to.
-
-   For example, for a single TLBI:
-
-       TLBI ALLE2IS
-       DSB ISH
-
-   ... the existing workaround will expand this to:
-
-       TLBI ALLE2IS
-       DSB ISH
-       TLBI ALLE2IS             // additional
-       DSB ISH                  // additional
-
-   ... whereas it is sufficient to have:
-
-       TLBI ALLE2IS
-       DSB ISH
-       TLBI VALE1IS, XZR        // additional
-       DSB ISH                  // additional
-
-   As the additional TLBI doesn't have to match a specific earlier TLBI,
-   the additional TLBI can be implemented in separate code, with no
-   memory of the earlier TLBIs. The additional TLBI can also use a
-   cheaper TLBI operation.
-
-5. The existing workaround is applied to both Stage-1 and Stage-2 TLB
-   invalidation, whereas for all relevant errata it is only necessary to
-   apply a workaround for Stage-1 invalidation.
-
-   Architecturally, TLBI operations which invalidate only Stage-2
-   information (e.g. IPAS2E1IS) are not required to invalidate TLB
-   entries which combine information from Stage-1 and Stage-2
-   translation table entries, and consequently may not complete memory
-   accesses translated by those combined entries. In these cases,
-   completion of memory accesses is only guaranteed after subsequent
-   invalidation of Stage-1 information (e.g. VMALLE1IS).
-
-Rework the workaround logic as follows:
- - add TLB_HELPER_LOCAL() to be used for local TLB ops without a
-   workaround,
- - modify TLB_HELPER() workaround to use tlbi vale2is, xzr as a second
-   TLBI,
- - drop TLB_HELPER_VA(). It's used only by __flush_xen_tlb_one_local
-   which is local and does not need workaround and by
-   __flush_xen_tlb_one. In the latter case, since it's used in a loop,
-   we don't need a workaround in the middle. Add __tlb_repeat_sync with
-   a workaround to be used at the end after DSB and before final ISB,
- - TLBI VALE2IS passing XZR is used as an additional TLBI. While there is
-   an identity mapping there, it's used very rarely. The performance
-   impact is therefore negligible. If things change in the future, we
-   can revisit the decision.
-
-Signed-off-by: Michal Orzel <michal.orzel@amd.com>
-Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
-Reviewed-by: Julien Grall <jgrall@amazon.com>
-(cherry picked from commit 7c502d7591519135765b8041cbd1c70e56e5a0b9)
-
-diff --git a/xen/arch/arm/include/asm/arm32/flushtlb.h b/xen/arch/arm/include/asm/arm32/flushtlb.h
-index 61c25a318998..5483be08fbbe 100644
---- a/xen/arch/arm/include/asm/arm32/flushtlb.h
-+++ b/xen/arch/arm/include/asm/arm32/flushtlb.h
-@@ -57,6 +57,9 @@ static inline void __flush_xen_tlb_one(vaddr_t va)
-     asm volatile(STORE_CP32(0, TLBIMVAHIS) : : "r" (va) : "memory");
- }
- 
-+/* Only for ARM64_WORKAROUND_REPEAT_TLBI */
-+static inline void __tlb_repeat_sync(void) {}
-+
- #endif /* __ASM_ARM_ARM32_FLUSHTLB_H__ */
- /*
-  * Local variables:
-diff --git a/xen/arch/arm/include/asm/arm64/flushtlb.h b/xen/arch/arm/include/asm/arm64/flushtlb.h
-index 3b99c11b50d1..1606b26bf28a 100644
---- a/xen/arch/arm/include/asm/arm64/flushtlb.h
-+++ b/xen/arch/arm/include/asm/arm64/flushtlb.h
-@@ -12,9 +12,14 @@
-  * ARM64_WORKAROUND_REPEAT_TLBI:
-  * Modification of the translation table for a virtual address might lead to
-  * read-after-read ordering violation.
-- * The workaround repeats TLBI+DSB ISH operation for all the TLB flush
-- * operations. While this is strictly not necessary, we don't want to
-- * take any risk.
-+ * The workaround repeats TLBI+DSB ISH operation for broadcast TLB flush
-+ * operations. The workaround is not needed for local operations.
-+ *
-+ * It is sufficient for the additional TLBI to use *any* operation which will
-+ * be broadcast, regardless of which translation regime or stage of translation
-+ * the operation applies to. TLBI VALE2IS is used passing XZR. While there is
-+ * an identity mapping there, it's only used during suspend/resume, CPU on/off,
-+ * so the impact (performance if any) is negligible.
-  *
-  * For Xen page-tables the ISB will discard any instructions fetched
-  * from the old mappings.
-@@ -26,69 +31,90 @@
-  * Note that for local TLB flush, using non-shareable (nsh) is sufficient
-  * (see D5-4929 in ARM DDI 0487H.a). Although, the memory barrier in
-  * for the workaround is left as inner-shareable to match with Linux
-- * v6.1-rc8.
-+ * v6.19.
-  */
--#define TLB_HELPER(name, tlbop, sh)              \
-+#define TLB_HELPER_LOCAL(name, tlbop)            \
- static inline void name(void)                    \
- {                                                \
-     asm_inline volatile (                        \
--        "dsb  "  # sh  "st;"                     \
-+        "dsb  nshst;"                            \
-         "tlbi "  # tlbop  ";"                    \
--        ALTERNATIVE(                             \
--            "nop; nop;",                         \
--            "dsb  ish;"                          \
--            "tlbi "  # tlbop  ";",               \
--            ARM64_WORKAROUND_REPEAT_TLBI,        \
--            CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \
--        "dsb  "  # sh  ";"                       \
-+        "dsb  nsh;"                              \
-         "isb;"                                   \
-         : : : "memory");                         \
- }
- 
--/*
-- * FLush TLB by VA. This will likely be used in a loop, so the caller
-- * is responsible to use the appropriate memory barriers before/after
-- * the sequence.
-- *
-- * See above about the ARM64_WORKAROUND_REPEAT_TLBI sequence.
-- */
--#define TLB_HELPER_VA(name, tlbop)               \
--static inline void name(vaddr_t va)              \
--{                                                \
--    asm_inline volatile (                        \
--        "tlbi "  # tlbop  ", %0;"                \
--        ALTERNATIVE(                             \
--            "nop; nop;",                         \
--            "dsb  ish;"                          \
--            "tlbi "  # tlbop  ", %0;",           \
--            ARM64_WORKAROUND_REPEAT_TLBI,        \
--            CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \
--        : : "r" (va >> PAGE_SHIFT) : "memory");  \
-+#define TLB_HELPER(name, tlbop)                       \
-+static inline void name(void)                         \
-+{                                                     \
-+    asm_inline volatile (                             \
-+        "dsb  ishst;"                                 \
-+        "tlbi "  # tlbop  ";"                         \
-+        ALTERNATIVE(                                  \
-+            "nop; nop;",                              \
-+            "dsb  ish;"                               \
-+            "tlbi vale2is, xzr;",                     \
-+            ARM64_WORKAROUND_REPEAT_TLBI,             \
-+            CONFIG_ARM64_WORKAROUND_REPEAT_TLBI)      \
-+        "dsb  ish;"                                   \
-+        "isb;"                                        \
-+        : : : "memory"); \
- }
- 
- /* Flush local TLBs, current VMID only. */
--TLB_HELPER(flush_guest_tlb_local, vmalls12e1, nsh)
-+TLB_HELPER_LOCAL(flush_guest_tlb_local, vmalls12e1)
- 
- /* Flush innershareable TLBs, current VMID only */
--TLB_HELPER(flush_guest_tlb, vmalls12e1is, ish)
-+TLB_HELPER(flush_guest_tlb, vmalls12e1is)
- 
- /* Flush local TLBs, all VMIDs, non-hypervisor mode */
--TLB_HELPER(flush_all_guests_tlb_local, alle1, nsh)
-+TLB_HELPER_LOCAL(flush_all_guests_tlb_local, alle1)
- 
- /* Flush innershareable TLBs, all VMIDs, non-hypervisor mode */
--TLB_HELPER(flush_all_guests_tlb, alle1is, ish)
-+TLB_HELPER(flush_all_guests_tlb, alle1is)
- 
- /* Flush all hypervisor mappings from the TLB of the local processor. */
--TLB_HELPER(flush_xen_tlb_local, alle2, nsh)
-+TLB_HELPER_LOCAL(flush_xen_tlb_local, alle2)
-+
-+#undef TLB_HELPER_LOCAL
-+#undef TLB_HELPER
-+
-+/*
-+ * FLush TLB by VA. This will likely be used in a loop, so the caller
-+ * is responsible to use the appropriate memory barriers before/after
-+ * the sequence.
-+ */
- 
- /* Flush TLB of local processor for address va. */
--TLB_HELPER_VA(__flush_xen_tlb_one_local, vae2)
-+static inline void __flush_xen_tlb_one_local(vaddr_t va)
-+{
-+    asm_inline volatile (
-+        "tlbi vae2, %0" : : "r" (va >> PAGE_SHIFT) : "memory");
-+}
- 
- /* Flush TLB of all processors in the inner-shareable domain for address va. */
--TLB_HELPER_VA(__flush_xen_tlb_one, vae2is)
-+static inline void __flush_xen_tlb_one(vaddr_t va)
-+{
-+    asm_inline volatile (
-+        "tlbi vae2is, %0" : : "r" (va >> PAGE_SHIFT) : "memory");
-+}
- 
--#undef TLB_HELPER
--#undef TLB_HELPER_VA
-+/*
-+ * ARM64_WORKAROUND_REPEAT_TLBI:
-+ * For all relevant erratas it is only necessary to execute a single
-+ * additional TLBI;DSB sequence after any number of TLBIs are completed by DSB.
-+ */
-+static inline void __tlb_repeat_sync(void)
-+{
-+    asm_inline volatile (
-+        ALTERNATIVE(
-+            "nop; nop;",
-+            "tlbi vale2is, xzr;"
-+            "dsb  ish;",
-+            ARM64_WORKAROUND_REPEAT_TLBI,
-+            CONFIG_ARM64_WORKAROUND_REPEAT_TLBI)
-+        : : : "memory");
-+}
- 
- #endif /* __ASM_ARM_ARM64_FLUSHTLB_H__ */
- /*
-diff --git a/xen/arch/arm/include/asm/flushtlb.h b/xen/arch/arm/include/asm/flushtlb.h
-index e45fb6d97b02..c292c3c00d29 100644
---- a/xen/arch/arm/include/asm/flushtlb.h
-+++ b/xen/arch/arm/include/asm/flushtlb.h
-@@ -65,6 +65,7 @@ static inline void flush_xen_tlb_range_va(vaddr_t va,
-         va += PAGE_SIZE;
-     }
-     dsb(ish); /* Ensure the TLB invalidation has completed */
-+    __tlb_repeat_sync();
-     isb();
- }
- 
-diff --git a/xen/arch/arm/include/asm/mmu/layout.h b/xen/arch/arm/include/asm/mmu/layout.h
-index 19c0ec63a59a..feafc14ebfda 100644
---- a/xen/arch/arm/include/asm/mmu/layout.h
-+++ b/xen/arch/arm/include/asm/mmu/layout.h
-@@ -23,6 +23,10 @@
-  *
-  *  Reserved to identity map Xen
-  *
-+ *  Note: As part of ARM64_WORKAROUND_REPEAT_TLBI, VA 0 is used for an extra
-+ *  TLBI operation given its rare use (only identity mapping) and thus
-+ *  negligible performance impact.
-+ *
-  * 0x00000a0000000000 - 0x00000a7fffffffff (512GB, L0 slot [20])
-  *  (Relative offsets)
-  *   0  -   2M   Unmapped

diff --git a/xsa493-4.21-02.patch b/xsa493-4.21-02.patch
deleted file mode 100644
index f80119c..0000000
--- a/xsa493-4.21-02.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 7e70b87512c966248b1e8453d9ac54c643c06f44 Mon Sep 17 00:00:00 2001
-From: Michal Orzel <michal.orzel@amd.com>
-Date: Fri, 22 May 2026 09:35:55 +0200
-Subject: xen/arm: Sync missing definitions for Arm CPUs with Linux
-
-Synchronize with Linux kernel 7.0 definitions for the following CPUs:
- - Cortex-A76AE,
- - Cortex-A78AE,
- - Cortex-X1C,
- - Cortex-X3,
- - Neoverse-V2,
- - Cortex-X4,
- - Neoverse-V3AE,
- - Neoverse-V3,
- - Cortex-X925.
-
-These will be used for errata detection in subsequent patches.
-
-Signed-off-by: Michal Orzel <michal.orzel@amd.com>
-Reviewed-by: Julien Grall <julien@xen.org>
-
-diff --git a/xen/arch/arm/include/asm/processor.h b/xen/arch/arm/include/asm/processor.h
-index ec23fd098b63..907778683b08 100644
---- a/xen/arch/arm/include/asm/processor.h
-+++ b/xen/arch/arm/include/asm/processor.h
-@@ -89,13 +89,22 @@
- #define ARM_CPU_PART_CORTEX_A76     0xD0B
- #define ARM_CPU_PART_NEOVERSE_N1    0xD0C
- #define ARM_CPU_PART_CORTEX_A77     0xD0D
-+#define ARM_CPU_PART_CORTEX_A76AE   0xD0E
- #define ARM_CPU_PART_NEOVERSE_V1    0xD40
- #define ARM_CPU_PART_CORTEX_A78     0xD41
-+#define ARM_CPU_PART_CORTEX_A78AE   0xD42
- #define ARM_CPU_PART_CORTEX_X1      0xD44
- #define ARM_CPU_PART_CORTEX_A710    0xD47
- #define ARM_CPU_PART_CORTEX_X2      0xD48
- #define ARM_CPU_PART_NEOVERSE_N2    0xD49
- #define ARM_CPU_PART_CORTEX_A78C    0xD4B
-+#define ARM_CPU_PART_CORTEX_X1C     0xD4C
-+#define ARM_CPU_PART_CORTEX_X3      0xD4E
-+#define ARM_CPU_PART_NEOVERSE_V2    0xD4F
-+#define ARM_CPU_PART_CORTEX_X4      0xD82
-+#define ARM_CPU_PART_NEOVERSE_V3AE  0xD83
-+#define ARM_CPU_PART_NEOVERSE_V3    0xD84
-+#define ARM_CPU_PART_CORTEX_X925    0xD85
- 
- #define MIDR_CORTEX_A12 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A12)
- #define MIDR_CORTEX_A17 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A17)
-@@ -110,13 +119,22 @@
- #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
- #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
- #define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
-+#define MIDR_CORTEX_A76AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76AE)
- #define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
- #define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
-+#define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE)
- #define MIDR_CORTEX_X1  MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
- #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
- #define MIDR_CORTEX_X2  MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
- #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
- #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
-+#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C)
-+#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3)
-+#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)
-+#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)
-+#define MIDR_NEOVERSE_V3AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3AE)
-+#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
-+#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
- 
- /* MPIDR Multiprocessor Affinity Register */
- #define _MPIDR_UP           (30)

diff --git a/xsa493-4.21-03.patch b/xsa493-4.21-03.patch
deleted file mode 100644
index 86bae68..0000000
--- a/xsa493-4.21-03.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From c0f7b40fdbb986b3cf470ed51f3878261e33f9cb Mon Sep 17 00:00:00 2001
-From: Michal Orzel <michal.orzel@amd.com>
-Date: Fri, 22 May 2026 09:35:56 +0200
-Subject: xen/arm: Add C1-Ultra definitions
-
-Add processor definitions for C1-Ultra. These will be used for errata
-detection in subsequent patches.
-
-These values can be found in the C1-Ultra TRM:
-
-  https://developer.arm.com/documentation/108014/0100/
-
-... in section A.5.1 ("MIDR_EL1, Main ID Register").
-
-Signed-off-by: Michal Orzel <michal.orzel@amd.com>
-Reviewed-by: Julien Grall <julien@xen.org>
-
-diff --git a/xen/arch/arm/include/asm/processor.h b/xen/arch/arm/include/asm/processor.h
-index 907778683b08..72745cca62bc 100644
---- a/xen/arch/arm/include/asm/processor.h
-+++ b/xen/arch/arm/include/asm/processor.h
-@@ -105,6 +105,7 @@
- #define ARM_CPU_PART_NEOVERSE_V3AE  0xD83
- #define ARM_CPU_PART_NEOVERSE_V3    0xD84
- #define ARM_CPU_PART_CORTEX_X925    0xD85
-+#define ARM_CPU_PART_C1_ULTRA       0xD8C
- 
- #define MIDR_CORTEX_A12 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A12)
- #define MIDR_CORTEX_A17 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A17)
-@@ -135,6 +136,7 @@
- #define MIDR_NEOVERSE_V3AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3AE)
- #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
- #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
-+#define MIDR_C1_ULTRA MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_ULTRA)
- 
- /* MPIDR Multiprocessor Affinity Register */
- #define _MPIDR_UP           (30)

diff --git a/xsa493-4.21-04.patch b/xsa493-4.21-04.patch
deleted file mode 100644
index b59ee74..0000000
--- a/xsa493-4.21-04.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 6af67aeca418bffb807424eb3415fab59e581733 Mon Sep 17 00:00:00 2001
-From: Michal Orzel <michal.orzel@amd.com>
-Date: Fri, 22 May 2026 09:35:57 +0200
-Subject: xen/arm: Add C1-Premium definitions
-
-Add processor definitions for C1-Premium. These will be used for errata
-detection in subsequent patches.
-
-These values can be found in the C1-Premium TRM:
-
-  https://developer.arm.com/documentation/109416/0100/
-
-... in section A.5.1 ("MIDR_EL1, Main ID Register").
-
-Signed-off-by: Michal Orzel <michal.orzel@amd.com>
-Reviewed-by: Julien Grall <julien@xen.org>
-
-diff --git a/xen/arch/arm/include/asm/processor.h b/xen/arch/arm/include/asm/processor.h
-index 72745cca62bc..25c5762c6706 100644
---- a/xen/arch/arm/include/asm/processor.h
-+++ b/xen/arch/arm/include/asm/processor.h
-@@ -106,6 +106,7 @@
- #define ARM_CPU_PART_NEOVERSE_V3    0xD84
- #define ARM_CPU_PART_CORTEX_X925    0xD85
- #define ARM_CPU_PART_C1_ULTRA       0xD8C
-+#define ARM_CPU_PART_C1_PREMIUM     0xD90
- 
- #define MIDR_CORTEX_A12 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A12)
- #define MIDR_CORTEX_A17 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A17)
-@@ -137,6 +138,7 @@
- #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
- #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
- #define MIDR_C1_ULTRA MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_ULTRA)
-+#define MIDR_C1_PREMIUM MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_PREMIUM)
- 
- /* MPIDR Multiprocessor Affinity Register */
- #define _MPIDR_UP           (30)

diff --git a/xsa494-4.21.patch b/xsa494-4.21.patch
deleted file mode 100644
index d52a0f1..0000000
--- a/xsa494-4.21.patch
+++ /dev/null
@@ -1,404 +0,0 @@
-From 579016a359741044c9076bf0884e1dbab00ab080 Mon Sep 17 00:00:00 2001
-From: Roger Pau Monne <roger.pau@citrix.com>
-Date: Mon, 16 Mar 2026 11:03:22 +0100
-Subject: [PATCH] x86/mm: accurately track which vCPU page-tables are loaded
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Neither current nor curr_vcpu per-CPU fields accurately track which
-page-tables are loaded.  There are corner cases when dealing with shadow
-paging failures that switch to the idle vCPU page-tables without changing
-current or curr_vcpu per-CPU fields.
-
-Introduce a new per-CPU field that attempts to track which vCPU page-tables
-are loaded.  Update such tracking when cr3 is changed, and do so in a
-region with interrupts disabled, as to avoid handling interrupts with a
-mismatch between the vCPU tracking field and the loaded page-tables.
-
-As a result of this newly more accurate tracking the mapcache override
-functionality can be removed: the dom0 PV builder was the only user of it,
-and it's updated here to properly signal which vCPU page-tables are loaded
-in the calls to switch_cr3_cr4().
-
-Note the EFI page-tables have the Xen owned L4 slots copied from the idle
-page-tables, so for the effects of the mapcache the EFI page-tables could
-use the idle mapcache if it had one.  Pass the idle vCPU in the
-switch_cr3_cr4() call that switches to the runtime EFI page-tables.
-
-There are known issues with the use of mapcache in NMI context.  This patch
-does not alter the behaviour.
-
-This is CVE-2026-42488 / XSA-494.
-
-Fixes: fb0ff49fe9f7 ("x86/shadow: defer releasing of PV's top-level shadow reference")
-Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
-Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
----
- xen/arch/x86/domain_page.c           | 48 ++++++++++++----------------
- xen/arch/x86/flushtlb.c              |  5 ++-
- xen/arch/x86/include/asm/domain.h    |  1 -
- xen/arch/x86/include/asm/flushtlb.h  |  2 +-
- xen/arch/x86/include/asm/processor.h |  3 ++
- xen/arch/x86/mm.c                    |  4 +--
- xen/arch/x86/pv/dom0_build.c         | 12 +++----
- xen/arch/x86/pv/domain.c             | 13 ++++++--
- xen/arch/x86/smpboot.c               |  1 +
- xen/common/efi/common-stub.c         |  5 ---
- xen/common/efi/runtime.c             | 21 +++++-------
- xen/include/xen/efi.h                |  1 -
- 12 files changed, 54 insertions(+), 62 deletions(-)
-
-diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c
-index eac5e3304fb8..72c00194f315 100644
---- a/xen/arch/x86/domain_page.c
-+++ b/xen/arch/x86/domain_page.c
-@@ -18,48 +18,40 @@
- #include <asm/hardirq.h>
- #include <asm/setup.h>
- 
--static DEFINE_PER_CPU(struct vcpu *, override);
--
- static inline struct vcpu *mapcache_current_vcpu(void)
- {
--    /* In the common case we use the mapcache of the running VCPU. */
--    struct vcpu *v = this_cpu(override) ?: current;
--
--    /*
--     * When current isn't properly set up yet, this is equivalent to
--     * running in an idle vCPU (callers must check for NULL).
--     */
--    if ( !v )
--        return NULL;
-+    struct vcpu *v = this_cpu(pgtable_vcpu);
-+    struct vcpu *curr = current;
- 
-     /*
--     * When using efi runtime page tables, we have the equivalent of the idle
--     * domain's page tables but current may point at another domain's VCPU.
--     * Return NULL as though current is not properly set up yet.
-+     * During early boot pgtable_vcpu is not set, callers must handle NULL.
-+     * Non-PV domains don't have a mapcache, the directmap covers all physical
-+     * address space.
-      */
--    if ( efi_rs_using_pgtables() )
-+    if ( !v || !is_pv_vcpu(v) )
-         return NULL;
- 
-     /*
--     * If guest_table is NULL, and we are running a paravirtualised guest,
--     * then it means we are running on the idle domain's page table and must
--     * therefore use its mapcache.
-+     * If we are in a lazy context-switch state from a PV vCPU do a full switch
-+     * to the idle vCPU now, otherwise an incoming FLUSH_VCPU_STATE IPI would
-+     * change the page tables under our feet an invalidate any in-use mapcache
-+     * entries.
-      */
--    if ( unlikely(pagetable_is_null(v->arch.guest_table)) && is_pv_vcpu(v) )
-+    if ( unlikely(this_cpu(curr_vcpu) != curr) )
-     {
--        /* If we really are idling, perform lazy context switch now. */
--        if ( (v = idle_vcpu[smp_processor_id()]) == current )
--            sync_local_execstate();
-+        ASSERT(curr == idle_vcpu[smp_processor_id()]);
-+        sync_local_execstate();
-         /* We must now be running on the idle page table. */
-         ASSERT(cr3_pa(read_cr3()) == __pa(idle_pg_table));
-     }
- 
--    return v;
--}
--
--void __init mapcache_override_current(struct vcpu *v)
--{
--    this_cpu(override) = v;
-+    /*
-+     * At this point we can guarantee Xen is not in lazy context switch: either
-+     * the code above will have synced the state, or an incoming
-+     * FLUSH_VCPU_STATE IPI has done so behind our back.  Use ACCESS_ONCE to
-+     * ensure the compiler never returns the locally cached pgtable_vcpu value.
-+     */
-+    return ACCESS_ONCE(this_cpu(pgtable_vcpu));
- }
- 
- #define mapcache_l2_entry(e) ((e) >> PAGETABLE_ORDER)
-diff --git a/xen/arch/x86/flushtlb.c b/xen/arch/x86/flushtlb.c
-index 09e676c151fa..928bca66b433 100644
---- a/xen/arch/x86/flushtlb.c
-+++ b/xen/arch/x86/flushtlb.c
-@@ -111,7 +111,9 @@ static void do_tlb_flush(void)
-     local_irq_restore(flags);
- }
- 
--void switch_cr3_cr4(unsigned long cr3, unsigned long cr4)
-+DEFINE_PER_CPU(struct vcpu *, pgtable_vcpu);
-+
-+void switch_cr3_cr4(struct vcpu *v, unsigned long cr3, unsigned long cr4)
- {
-     unsigned long flags, old_cr4;
-     u32 t = 0;
-@@ -155,6 +157,7 @@ void switch_cr3_cr4(unsigned long cr3, unsigned long cr4)
-     if ( (old_cr4 & X86_CR4_PCIDE) > (cr4 & X86_CR4_PCIDE) )
-         cr3 |= X86_CR3_NOFLUSH;
-     write_cr3(cr3);
-+    this_cpu(pgtable_vcpu) = v;
- 
-     if ( old_cr4 != cr4 )
-         write_cr4(cr4);
-diff --git a/xen/arch/x86/include/asm/domain.h b/xen/arch/x86/include/asm/domain.h
-index 828f42c3e448..10d2b9fe2546 100644
---- a/xen/arch/x86/include/asm/domain.h
-+++ b/xen/arch/x86/include/asm/domain.h
-@@ -75,7 +75,6 @@ struct mapcache_domain {
- 
- int mapcache_domain_init(struct domain *d);
- int mapcache_vcpu_init(struct vcpu *v);
--void mapcache_override_current(struct vcpu *v);
- 
- /* x86/64: toggle guest between kernel and user modes. */
- void toggle_guest_mode(struct vcpu *v);
-diff --git a/xen/arch/x86/include/asm/flushtlb.h b/xen/arch/x86/include/asm/flushtlb.h
-index 7bcbca2b7f31..345677eb72ae 100644
---- a/xen/arch/x86/include/asm/flushtlb.h
-+++ b/xen/arch/x86/include/asm/flushtlb.h
-@@ -104,7 +104,7 @@ static inline void invlpg(const void *p)
- }
- 
- /* Write pagetable base and implicitly tick the tlbflush clock. */
--void switch_cr3_cr4(unsigned long cr3, unsigned long cr4);
-+void switch_cr3_cr4(struct vcpu *v, unsigned long cr3, unsigned long cr4);
- 
- /* flush_* flag fields: */
-  /*
-diff --git a/xen/arch/x86/include/asm/processor.h b/xen/arch/x86/include/asm/processor.h
-index 2e087c625770..d2cacdfedb74 100644
---- a/xen/arch/x86/include/asm/processor.h
-+++ b/xen/arch/x86/include/asm/processor.h
-@@ -328,6 +328,9 @@ DECLARE_PER_CPU(struct tss_page, tss_page);
- 
- DECLARE_PER_CPU(root_pgentry_t *, root_pgt);
- 
-+/* vCPU of the currently loaded page-tables. */
-+DECLARE_PER_CPU(struct vcpu *, pgtable_vcpu);
-+
- extern void write_ptbase(struct vcpu *v);
- 
- /* PAUSE (encoding: REP NOP) is a good thing to insert into busy-wait loops. */
-diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
-index 2b23bf2e7a75..d02c9862d387 100644
---- a/xen/arch/x86/mm.c
-+++ b/xen/arch/x86/mm.c
-@@ -535,7 +535,7 @@ void write_ptbase(struct vcpu *v)
-         cpu_info->pv_cr3 = __pa(this_cpu(root_pgt));
-         if ( new_cr4 & X86_CR4_PCIDE )
-             cpu_info->pv_cr3 |= get_pcid_bits(v, true);
--        switch_cr3_cr4(v->arch.cr3, new_cr4);
-+        switch_cr3_cr4(v, v->arch.cr3, new_cr4);
-     }
-     else
-     {
-@@ -543,7 +543,7 @@ void write_ptbase(struct vcpu *v)
-         cpu_info->use_pv_cr3 = false;
-         cpu_info->xen_cr3 = 0;
-         /* switch_cr3_cr4() serializes. */
--        switch_cr3_cr4(v->arch.cr3, new_cr4);
-+        switch_cr3_cr4(v, v->arch.cr3, new_cr4);
-         cpu_info->pv_cr3 = 0;
-     }
- }
-diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c
-index 37729091dfaa..42bc530c0f0d 100644
---- a/xen/arch/x86/pv/dom0_build.c
-+++ b/xen/arch/x86/pv/dom0_build.c
-@@ -828,8 +828,7 @@ static int __init dom0_construct(const struct boot_domain *bd)
-     update_cr3(v);
- 
-     /* We run on dom0's page tables for the final part of the build process. */
--    switch_cr3_cr4(cr3_pa(v->arch.cr3), read_cr4());
--    mapcache_override_current(v);
-+    switch_cr3_cr4(v, cr3_pa(v->arch.cr3), read_cr4());
- 
-     /* Copy the OS image and free temporary buffer. */
-     elf.dest_base = (void*)vkern_start;
-@@ -838,8 +837,7 @@ static int __init dom0_construct(const struct boot_domain *bd)
-     rc = elf_load_binary(&elf);
-     if ( rc < 0 )
-     {
--        mapcache_override_current(NULL);
--        switch_cr3_cr4(current->arch.cr3, read_cr4());
-+        switch_cr3_cr4(current, current->arch.cr3, read_cr4());
-         printk("Failed to load the kernel binary\n");
-         goto out;
-     }
-@@ -850,8 +848,7 @@ static int __init dom0_construct(const struct boot_domain *bd)
-         if ( (parms.virt_hypercall < v_start) ||
-              (parms.virt_hypercall >= v_end) )
-         {
--            mapcache_override_current(NULL);
--            switch_cr3_cr4(current->arch.cr3, read_cr4());
-+            switch_cr3_cr4(current, current->arch.cr3, read_cr4());
-             printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
-             return -EINVAL;
-         }
-@@ -992,8 +989,7 @@ static int __init dom0_construct(const struct boot_domain *bd)
- #endif
- 
-     /* Return to idle domain's page tables. */
--    mapcache_override_current(NULL);
--    switch_cr3_cr4(current->arch.cr3, read_cr4());
-+    switch_cr3_cr4(current, current->arch.cr3, read_cr4());
- 
-     update_domain_wallclock_time(d);
- 
-diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
-index ef4f442e7332..d9e52f5f88f3 100644
---- a/xen/arch/x86/pv/domain.c
-+++ b/xen/arch/x86/pv/domain.c
-@@ -451,6 +451,8 @@ static void _toggle_guest_pt(struct vcpu *v)
-     pagetable_t old_shadow;
-     unsigned long cr3;
- 
-+    ASSERT(local_irq_is_enabled());
-+
-     v->arch.flags ^= TF_kernel_mode;
-     guest_update = v->arch.flags & TF_kernel_mode;
-     old_shadow = update_cr3(v);
-@@ -473,15 +475,22 @@ static void _toggle_guest_pt(struct vcpu *v)
-     {
-         cr3 &= ~X86_CR3_NOFLUSH;
- 
-+        local_irq_disable();
-         if ( unlikely(mfn_eq(pagetable_get_mfn(old_shadow),
-                              maddr_to_mfn(cr3))) )
-         {
--            cr3 = idle_vcpu[v->processor]->arch.cr3;
-             /* Also suppress runstate/time area updates below. */
-             guest_update = false;
-+
-+            cr3 = idle_vcpu[v->processor]->arch.cr3;
-+            this_cpu(pgtable_vcpu) = idle_vcpu[v->processor];
-         }
-+
-+        write_cr3(cr3);
-+        local_irq_enable();
-     }
--    write_cr3(cr3);
-+    else
-+        write_cr3(cr3);
- 
-     if ( !pagetable_is_null(old_shadow) )
-         shadow_put_top_level(v->domain, old_shadow);
-diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
-index 27628800a821..b37feab3bef4 100644
---- a/xen/arch/x86/smpboot.c
-+++ b/xen/arch/x86/smpboot.c
-@@ -1063,6 +1063,7 @@ static int cpu_smpboot_alloc(unsigned int cpu)
- 
-     info->current_vcpu = idle_vcpu[cpu]; /* set_current() */
-     per_cpu(curr_vcpu, cpu) = idle_vcpu[cpu];
-+    per_cpu(pgtable_vcpu, cpu) = idle_vcpu[cpu];
- 
-     gdt = per_cpu(gdt, cpu) ?: alloc_xenheap_pages(0, memflags);
-     if ( gdt == NULL )
-diff --git a/xen/common/efi/common-stub.c b/xen/common/efi/common-stub.c
-index 77f138a6c574..7b12005bea3f 100644
---- a/xen/common/efi/common-stub.c
-+++ b/xen/common/efi/common-stub.c
-@@ -7,11 +7,6 @@ bool efi_enabled(unsigned int feature)
-     return false;
- }
- 
--bool efi_rs_using_pgtables(void)
--{
--    return false;
--}
--
- unsigned long efi_get_time(void)
- {
-     BUG();
-diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c
-index 30d649ca5c1b..feb09acf754c 100644
---- a/xen/common/efi/runtime.c
-+++ b/xen/common/efi/runtime.c
-@@ -49,7 +49,6 @@ const CHAR16 *__read_mostly efi_fw_vendor;
- const EFI_RUNTIME_SERVICES *__read_mostly efi_rs;
- #ifndef CONFIG_ARM /* TODO - disabled until implemented on ARM */
- static DEFINE_SPINLOCK(efi_rs_lock);
--static unsigned int efi_rs_on_cpu = NR_CPUS;
- #endif
- 
- UINTN __read_mostly efi_memmap_size;
-@@ -92,6 +91,11 @@ struct efi_rs_state efi_rs_enter(void)
-     if ( mfn_eq(efi_l4_mfn, INVALID_MFN) )
-         return state;
- 
-+    /*
-+     * If in lazy idle context switch state sync now to avoid an incoming
-+     * FLUSH_VCPU_STATE IPI changing the loaded page-tables.
-+     */
-+    sync_local_execstate();
-     state.cr3 = read_cr3();
-     save_fpu_enable();
-     asm volatile ( "fnclex; fldcw %0" :: "m" (fcw) );
-@@ -99,8 +103,6 @@ struct efi_rs_state efi_rs_enter(void)
- 
-     spin_lock(&efi_rs_lock);
- 
--    efi_rs_on_cpu = smp_processor_id();
--
-     /* prevent fixup_page_fault() from doing anything */
-     irq_enter();
- 
-@@ -115,7 +117,8 @@ struct efi_rs_state efi_rs_enter(void)
-         lgdt(&gdt_desc);
-     }
- 
--    switch_cr3_cr4(mfn_to_maddr(efi_l4_mfn), read_cr4());
-+    switch_cr3_cr4(idle_vcpu[smp_processor_id()], mfn_to_maddr(efi_l4_mfn),
-+                   read_cr4());
- 
-     /*
-      * At the time of writing (2022), no UEFI firwmare is CET-IBT compatible.
-@@ -143,7 +146,7 @@ void efi_rs_leave(struct efi_rs_state *state)
-     if ( state->msr_s_cet )
-         wrmsrl(MSR_S_CET, state->msr_s_cet);
- 
--    switch_cr3_cr4(state->cr3, read_cr4());
-+    switch_cr3_cr4(curr, state->cr3, read_cr4());
-     if ( is_pv_vcpu(curr) && !is_idle_vcpu(curr) )
-     {
-         struct desc_ptr gdt_desc = {
-@@ -154,18 +157,10 @@ void efi_rs_leave(struct efi_rs_state *state)
-         lgdt(&gdt_desc);
-     }
-     irq_exit();
--    efi_rs_on_cpu = NR_CPUS;
-     spin_unlock(&efi_rs_lock);
-     vcpu_restore_fpu_nonlazy(curr, true);
- }
- 
--bool efi_rs_using_pgtables(void)
--{
--    return !mfn_eq(efi_l4_mfn, INVALID_MFN) &&
--           (smp_processor_id() == efi_rs_on_cpu) &&
--           (read_cr3() == mfn_to_maddr(efi_l4_mfn));
--}
--
- unsigned long efi_get_time(void)
- {
-     EFI_TIME time;
-diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h
-index 723cb8085270..9953197ee553 100644
---- a/xen/include/xen/efi.h
-+++ b/xen/include/xen/efi.h
-@@ -40,7 +40,6 @@ extern bool efi_secure_boot;
- 
- void efi_init_memory(void);
- bool efi_boot_mem_unused(unsigned long *start, unsigned long *end);
--bool efi_rs_using_pgtables(void);
- unsigned long efi_get_time(void);
- void efi_halt_system(void);
- void efi_reset_system(bool warm);
--- 
-2.53.0
-

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-07-30 15:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-30 15:02 [rpms/xen] f44: update to xen 4.21.2 Michael Young

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox