public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Michael Young <m.a.young@durham.ac.uk>
To: git-commits@fedoraproject.org
Subject: [rpms/xen] f44: update to xen 4.21.2
Date: Thu, 30 Jul 2026 15:02:02 GMT [thread overview]
Message-ID: <178542372244.1.17663596591177064262.rpms-xen-bbef6d9f4f23@fedoraproject.org> (raw)
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 = ¤t->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 = ¤t->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 = ¤t->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 = ¤t->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 = ¤t->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
-
reply other threads:[~2026-07-30 15:02 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178542372244.1.17663596591177064262.rpms-xen-bbef6d9f4f23@fedoraproject.org \
--to=m.a.young@durham.ac.uk \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox