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

Bug#1063035: marked as done (bookworm-pu: package xen/4.17.3+10-g091466ba55-1~deb12u1)



Your message dated Sat, 10 Feb 2024 13:11:22 +0000
with message-id <E1rYn8c-002ye4-PB@coccia.debian.org>
and subject line Released with 12.5
has caused the Debian Bug report #1063035,
regarding bookworm-pu: package xen/4.17.3+10-g091466ba55-1~deb12u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1063035: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1063035
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: xen@packages.debian.org, maxi@daemonizer.de, hans@knorrie.org, team@security.debian.org
Control: affects -1 + src:xen

This is a Xen stable update. This update could also have been a security
update on its own, but since the changes do not ultimately require a
DSA, we'd like to publish via the point release channel, so that users
get the new Xen and Linux kernel package at exactly the same moment,
reducing reboot stress.

[ Reason ]
Xen in bookworm is currently affected by several CVEs:
- CVE-2023-46837
- CVE-2023-46839
- CVE-2023-46840

[ Impact ]
The above mentioned CVEs are not fixed in bookworm.

[ Tests ]
The Debian package is based only on upstream commits that have passed
the upstream automated tests.
The Debian package has been successfully tested by the xen packaging
team on their test machines.
The same version is also in unstable without any reports.

[ Risks ]
There could be upstream changes unrelated to the above mentioned
security fixes that cause regressions. However upstream has an automated
testing machinery (osstest) that only allows a commit in the upstream
stable branch if all test pass.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

(Note: as can be seen in the source debdiff, inadvertently, we introduced a
typo when including a previous debian/changelog entry. Oops. We decided that
it's not important enough to do another -2 right now.)

[ Changes ]
* Advance the upstream source code to the latest available commit in the
upstream stable Xen 4.17 branch line.
* No packaging changes were made
* Where necessary, patches were as-is rebased against upstream changes.
* Document changes and mention security issues in the changelog in the
usual format.

[ Other info ]
This update, like previous Xen 4.17 updates for Bookworm, is based on
the upstream stable-4.17 branch.

The branch in general only accepts bug fixes and does not allow new
features, so the changes there are mainly security fixes, important bug
fixes and fixes related to hardware errata or hardware support.

The package we have prepared is exactly what we would have done as a
security update in a stable release, what we have historically done
together with the security team and are planning to continue to do.

As upstream does extensive automated testing on their stable branches
chances for unnoticed regressions are low. We believe that by following
the upstream stable release branch line the risk for regressions is
lower than trying to manually pick and adjust (security) patches without
all the deep knowledge that upstream has. This approach is similar to
what the Linux kernel team is doing.
diff -Nru xen-4.17.2+76-ge1f9cb16e2/CHANGELOG.md xen-4.17.3+10-g091466ba55/CHANGELOG.md
--- xen-4.17.2+76-ge1f9cb16e2/CHANGELOG.md	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/CHANGELOG.md	2024-02-02 08:04:33.000000000 +0100
@@ -13,6 +13,8 @@
 ### Added
  - On x86, support for enforcing system-wide operation in Data Operand
    Independent Timing Mode.
+ - On x86, introduce a new x2APIC driver that uses Cluster Logical addressing
+   mode for IPIs and Physical addressing mode for external interrupts.
 
 ## [4.17.0](https://xenbits.xen.org/gitweb/?p=xen.git;a=shortlog;h=RELEASE-4.17.0) - 2022-12-12
 
diff -Nru xen-4.17.2+76-ge1f9cb16e2/.cirrus.yml xen-4.17.3+10-g091466ba55/.cirrus.yml
--- xen-4.17.2+76-ge1f9cb16e2/.cirrus.yml	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/.cirrus.yml	2024-02-02 08:04:33.000000000 +0100
@@ -15,12 +15,6 @@
     - gmake -j`sysctl -n hw.ncpu` clang=y
 
 task:
-  name: 'FreeBSD 12'
-  freebsd_instance:
-    image_family: freebsd-12-4
-  << : *FREEBSD_TEMPLATE
-
-task:
   name: 'FreeBSD 13'
   freebsd_instance:
     image_family: freebsd-13-2
diff -Nru xen-4.17.2+76-ge1f9cb16e2/Config.mk xen-4.17.3+10-g091466ba55/Config.mk
--- xen-4.17.2+76-ge1f9cb16e2/Config.mk	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/Config.mk	2024-02-02 08:04:33.000000000 +0100
@@ -177,8 +177,6 @@
 
 CFLAGS += -Wall -Wstrict-prototypes
 
-$(call cc-option-add,HOSTCFLAGS,HOSTCC,-Wdeclaration-after-statement)
-$(call cc-option-add,CFLAGS,CC,-Wdeclaration-after-statement)
 $(call cc-option-add,CFLAGS,CC,-Wno-unused-but-set-variable)
 $(call cc-option-add,CFLAGS,CC,-Wno-unused-local-typedefs)
 
@@ -233,15 +231,15 @@
 MINIOS_UPSTREAM_URL ?= git://xenbits.xen.org/mini-os.git
 endif
 OVMF_UPSTREAM_REVISION ?= 7b4a99be8a39c12d3a7fc4b8db9f0eab4ac688d5
-QEMU_UPSTREAM_REVISION ?= qemu-xen-4.17.2
-MINIOS_UPSTREAM_REVISION ?= xen-RELEASE-4.17.1
+QEMU_UPSTREAM_REVISION ?= qemu-xen-4.17.3
+MINIOS_UPSTREAM_REVISION ?= xen-RELEASE-4.17.3
 
 SEABIOS_UPSTREAM_REVISION ?= rel-1.16.0
 
 ETHERBOOT_NICS ?= rtl8139 8086100e
 
 
-QEMU_TRADITIONAL_REVISION ?= xen-4.17.1
+QEMU_TRADITIONAL_REVISION ?= xen-4.17.3
 
 # Specify which qemu-dm to use. This may be `ioemu' to use the old
 # Mercurial in-tree version, or a local directory, or a git URL.
diff -Nru xen-4.17.2+76-ge1f9cb16e2/debian/changelog xen-4.17.3+10-g091466ba55/debian/changelog
--- xen-4.17.2+76-ge1f9cb16e2/debian/changelog	2023-12-02 17:58:08.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/debian/changelog	2024-02-04 16:31:59.000000000 +0100
@@ -1,7 +1,32 @@
+xen (4.17.3+10-g091466ba55-1~deb12u1) bookworm; urgency=medium
+
+  * Rebuild 4.17.3+10-g091466ba55-1 for Bookworm to address the security
+    issues since last Debian stable update.
+
+ -- Hans van Kranenburg <hans@knorrie.org>  Sun, 04 Feb 2024 16:31:59 +0100
+
+xen (4.17.3+10-g091466ba55-1) unstable; urgency=medium
+
+  * Update to new upstream version 4.17.3+10-g091466ba55, which also contains
+    security fixes for the following issues:
+    - arm32: The cache may not be properly cleaned/invalidated (take two)
+      XSA-447 CVE-2023-46837
+    - pci: phantom functions assigned to incorrect contexts
+      XSA-449 CVE-2023-46839
+    - VT-d: Failure to quarantine devices in !HVM builds
+      XSA-450 CVE-2023-46840
+  * Note that the following XSA are not listed, because...
+    - XSA-448 has patches for the Linux kernel.
+  * Compilation with Python 3.12 has been fixed in upstream commit 4000522008
+    ("Only compile the hypervisor with -Wdeclaration-after-statement")
+    (Closes: #1062048)
+
+ -- Hans van Kranenburg <hans@knorrie.org>  Sun, 04 Feb 2024 13:45:17 +0100
+
 xen (4.17.2+76-ge1f9cb16e2-1~deb12u1) bookworm; urgency=medium
 
   * Rebuild for bookworm to address the security issues since
-    4.17.1+2-gb773c48e36-1 listed below.
+    4.17.1+2-gb773c48e36-1 listed blow.
   * d/salsa-ci.yml: Set RELEASE variable to bookworm
 
  -- Maximilian Engelhardt <maxi@daemonizer.de>  Sat, 02 Dec 2023 17:58:08 +0100
diff -Nru xen-4.17.2+76-ge1f9cb16e2/debian/.gitignore xen-4.17.3+10-g091466ba55/debian/.gitignore
--- xen-4.17.2+76-ge1f9cb16e2/debian/.gitignore	2023-12-02 17:58:08.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/debian/.gitignore	1970-01-01 01:00:00.000000000 +0100
@@ -1,39 +0,0 @@
-.debhelper
-*.debhelper.*
-*.preinst.debhelper
-*.postinst.debhelper
-*.prerm.debhelper
-*.postrm.debhelper
-*.substvars
-*.stamp
-tmp
-*-[0-9]*.bug-control
-*-[0-9]*.postinst
-*-[0-9]*.postrm
-*.tmp
-files
-xen-doc
-xen-hypervisor-common
-xen-system-amd64
-xen-system-armhf
-xen-system-arm64
-xen-hypervisor-[0-9]*[0-9]
-xen-hypervisor-[0-9]*[0-9].install
-xen-hypervisor-[0-9]*[0-9].lintian-overrides
-xen-utils-[0-9]*[0-9]
-xen-utils-[0-9]*[0-9].install
-xen-utils-[0-9]*[0-9].NEWS
-xen-utils-[0-9]*[0-9].README.Debian
-xen-utils-[0-9]*[0-9].lintian-overrides
-xen-utils-[0-9]*[0-9].prerm
-libxenmisc[0-9]*[0-9].lintian-overrides
-libxenmisc[0-9]*[0-9]
-libxenmisc[0-9]*[0-9].install
-libxenmisc[0-9]*[0-9].lintian-overrides
-libxen-dev
-libxen*[0-9]
-xen-utils-common
-xenstore-utils
-autoreconf.before
-autoreconf.after
-debhelper-build-stamp
diff -Nru xen-4.17.2+76-ge1f9cb16e2/debian/patches/prefix-abiname/config-prefix.diff xen-4.17.3+10-g091466ba55/debian/patches/prefix-abiname/config-prefix.diff
--- xen-4.17.2+76-ge1f9cb16e2/debian/patches/prefix-abiname/config-prefix.diff	2023-12-02 17:58:08.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/debian/patches/prefix-abiname/config-prefix.diff	2024-02-04 16:31:59.000000000 +0100
@@ -9,7 +9,7 @@
  2 files changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/Config.mk b/Config.mk
-index 4864033..2e9b672 100644
+index 8d91e4c..fc90691 100644
 --- a/Config.mk
 +++ b/Config.mk
 @@ -78,7 +78,7 @@ EXTRA_LIB += $(EXTRA_PREFIX)/lib
diff -Nru xen-4.17.2+76-ge1f9cb16e2/docs/misc/xen-command-line.pandoc xen-4.17.3+10-g091466ba55/docs/misc/xen-command-line.pandoc
--- xen-4.17.2+76-ge1f9cb16e2/docs/misc/xen-command-line.pandoc	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/docs/misc/xen-command-line.pandoc	2024-02-02 08:04:33.000000000 +0100
@@ -2758,6 +2758,15 @@
 
 Permit use of x2apic setup for SMP environments.
 
+### x2apic-mode (x86)
+> `= physical | cluster | mixed`
+
+> Default: `physical` if **FADT** mandates physical mode, otherwise set at
+>          build time by CONFIG_X2APIC_{PHYSICAL,LOGICAL,MIXED}.
+
+In the case that x2apic is in use, this option switches between modes to
+address APICs in the system as interrupt destinations.
+
 ### x2apic_phys (x86)
 > `= <boolean>`
 
@@ -2768,6 +2777,9 @@
 clustered mode.  The default, given no hint from the **FADT**, is cluster
 mode.
 
+**WARNING: `x2apic_phys` is deprecated and superseded by `x2apic-mode`.
+The latter takes precedence if both are set.**
+
 ### xenheap_megabytes (arm32)
 > `= <size>`
 
diff -Nru xen-4.17.2+76-ge1f9cb16e2/stubdom/Makefile xen-4.17.3+10-g091466ba55/stubdom/Makefile
--- xen-4.17.2+76-ge1f9cb16e2/stubdom/Makefile	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/stubdom/Makefile	2024-02-02 08:04:33.000000000 +0100
@@ -243,7 +243,7 @@
 	patch -d $@ -p1 < vtpm-command-duration.patch
 	patch -d $@ -p1 < vtpm-tpm_bn_t-addr.patch
 	mkdir $@/build
-	cd $@/build; CC=${CC} $(CMAKE) .. -DCMAKE_C_FLAGS:STRING="-std=c99 -DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-declaration-after-statement"
+	cd $@/build; CC=${CC} $(CMAKE) .. -DCMAKE_C_FLAGS:STRING="-std=c99 -DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS)"
 	touch $@
 
 TPMEMU_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libtpm.a
diff -Nru xen-4.17.2+76-ge1f9cb16e2/stubdom/vtpmmgr/Makefile xen-4.17.3+10-g091466ba55/stubdom/vtpmmgr/Makefile
--- xen-4.17.2+76-ge1f9cb16e2/stubdom/vtpmmgr/Makefile	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/stubdom/vtpmmgr/Makefile	2024-02-02 08:04:33.000000000 +0100
@@ -17,7 +17,7 @@
 OBJS += mgmt_authority.o
 
 CFLAGS+=-Werror -Iutil -Icrypto -Itcs
-CFLAGS+=-Wno-declaration-after-statement -Wno-unused-label
+CFLAGS+=-Wno-unused-label
 
 build: $(TARGET)
 $(TARGET): $(OBJS)
diff -Nru xen-4.17.2+76-ge1f9cb16e2/tools/libs/guest/xg_cpuid_x86.c xen-4.17.3+10-g091466ba55/tools/libs/guest/xg_cpuid_x86.c
--- xen-4.17.2+76-ge1f9cb16e2/tools/libs/guest/xg_cpuid_x86.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/tools/libs/guest/xg_cpuid_x86.c	2024-02-02 08:04:33.000000000 +0100
@@ -136,20 +136,20 @@
     DECLARE_HYPERCALL_BOUNCE(msrs,
                              *nr_msrs * sizeof(*msrs),
                              XC_HYPERCALL_BUFFER_BOUNCE_OUT);
-    int ret;
+    int ret = -1;
 
-    if ( xc_hypercall_bounce_pre(xch, leaves) ||
-         xc_hypercall_bounce_pre(xch, msrs) )
-        return -1;
-
-    sysctl.cmd = XEN_SYSCTL_get_cpu_policy;
-    sysctl.u.cpu_policy.index = index;
-    sysctl.u.cpu_policy.nr_leaves = *nr_leaves;
-    set_xen_guest_handle(sysctl.u.cpu_policy.leaves, leaves);
-    sysctl.u.cpu_policy.nr_msrs = *nr_msrs;
-    set_xen_guest_handle(sysctl.u.cpu_policy.msrs, msrs);
+    if ( !xc_hypercall_bounce_pre(xch, leaves) &&
+         !xc_hypercall_bounce_pre(xch, msrs) )
+    {
+        sysctl.cmd = XEN_SYSCTL_get_cpu_policy;
+        sysctl.u.cpu_policy.index = index;
+        sysctl.u.cpu_policy.nr_leaves = *nr_leaves;
+        set_xen_guest_handle(sysctl.u.cpu_policy.leaves, leaves);
+        sysctl.u.cpu_policy.nr_msrs = *nr_msrs;
+        set_xen_guest_handle(sysctl.u.cpu_policy.msrs, msrs);
 
-    ret = do_sysctl(xch, &sysctl);
+        ret = do_sysctl(xch, &sysctl);
+    }
 
     xc_hypercall_bounce_post(xch, leaves);
     xc_hypercall_bounce_post(xch, msrs);
@@ -174,20 +174,20 @@
     DECLARE_HYPERCALL_BOUNCE(msrs,
                              *nr_msrs * sizeof(*msrs),
                              XC_HYPERCALL_BUFFER_BOUNCE_OUT);
-    int ret;
+    int ret = -1;
 
-    if ( xc_hypercall_bounce_pre(xch, leaves) ||
-         xc_hypercall_bounce_pre(xch, msrs) )
-        return -1;
-
-    domctl.cmd = XEN_DOMCTL_get_cpu_policy;
-    domctl.domain = domid;
-    domctl.u.cpu_policy.nr_leaves = *nr_leaves;
-    set_xen_guest_handle(domctl.u.cpu_policy.leaves, leaves);
-    domctl.u.cpu_policy.nr_msrs = *nr_msrs;
-    set_xen_guest_handle(domctl.u.cpu_policy.msrs, msrs);
+    if ( !xc_hypercall_bounce_pre(xch, leaves) &&
+         !xc_hypercall_bounce_pre(xch, msrs) )
+    {
+        domctl.cmd = XEN_DOMCTL_get_cpu_policy;
+        domctl.domain = domid;
+        domctl.u.cpu_policy.nr_leaves = *nr_leaves;
+        set_xen_guest_handle(domctl.u.cpu_policy.leaves, leaves);
+        domctl.u.cpu_policy.nr_msrs = *nr_msrs;
+        set_xen_guest_handle(domctl.u.cpu_policy.msrs, msrs);
 
-    ret = do_domctl(xch, &domctl);
+        ret = do_domctl(xch, &domctl);
+    }
 
     xc_hypercall_bounce_post(xch, leaves);
     xc_hypercall_bounce_post(xch, msrs);
@@ -214,32 +214,24 @@
     DECLARE_HYPERCALL_BOUNCE(msrs,
                              nr_msrs * sizeof(*msrs),
                              XC_HYPERCALL_BUFFER_BOUNCE_IN);
-    int ret;
+    int ret = -1;
 
-    if ( err_leaf_p )
-        *err_leaf_p = -1;
-    if ( err_subleaf_p )
-        *err_subleaf_p = -1;
-    if ( err_msr_p )
-        *err_msr_p = -1;
-
-    if ( xc_hypercall_bounce_pre(xch, leaves) )
-        return -1;
-
-    if ( xc_hypercall_bounce_pre(xch, msrs) )
-        return -1;
-
-    domctl.cmd = XEN_DOMCTL_set_cpu_policy;
-    domctl.domain = domid;
-    domctl.u.cpu_policy.nr_leaves = nr_leaves;
-    set_xen_guest_handle(domctl.u.cpu_policy.leaves, leaves);
-    domctl.u.cpu_policy.nr_msrs = nr_msrs;
-    set_xen_guest_handle(domctl.u.cpu_policy.msrs, msrs);
     domctl.u.cpu_policy.err_leaf = -1;
     domctl.u.cpu_policy.err_subleaf = -1;
     domctl.u.cpu_policy.err_msr = -1;
 
-    ret = do_domctl(xch, &domctl);
+    if ( !xc_hypercall_bounce_pre(xch, leaves) &&
+         !xc_hypercall_bounce_pre(xch, msrs) )
+    {
+        domctl.cmd = XEN_DOMCTL_set_cpu_policy;
+        domctl.domain = domid;
+        domctl.u.cpu_policy.nr_leaves = nr_leaves;
+        set_xen_guest_handle(domctl.u.cpu_policy.leaves, leaves);
+        domctl.u.cpu_policy.nr_msrs = nr_msrs;
+        set_xen_guest_handle(domctl.u.cpu_policy.msrs, msrs);
+
+        ret = do_domctl(xch, &domctl);
+    }
 
     xc_hypercall_bounce_post(xch, leaves);
     xc_hypercall_bounce_post(xch, msrs);
diff -Nru xen-4.17.2+76-ge1f9cb16e2/tools/libs/light/Makefile xen-4.17.3+10-g091466ba55/tools/libs/light/Makefile
--- xen-4.17.2+76-ge1f9cb16e2/tools/libs/light/Makefile	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/tools/libs/light/Makefile	2024-02-02 08:04:33.000000000 +0100
@@ -38,8 +38,7 @@
 
 OBJS-$(CONFIG_X86) += $(ACPI_OBJS)
 
-CFLAGS += -Wno-format-zero-length -Wmissing-declarations \
-	-Wno-declaration-after-statement -Wformat-nonliteral
+CFLAGS += -Wno-format-zero-length -Wmissing-declarations -Wformat-nonliteral
 
 CFLAGS-$(CONFIG_X86) += -DCONFIG_PCI_SUPP_LEGACY_IRQ
 
diff -Nru xen-4.17.2+76-ge1f9cb16e2/tools/libs/util/Makefile xen-4.17.3+10-g091466ba55/tools/libs/util/Makefile
--- xen-4.17.2+76-ge1f9cb16e2/tools/libs/util/Makefile	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/tools/libs/util/Makefile	2024-02-02 08:04:33.000000000 +0100
@@ -9,8 +9,7 @@
 OBJS-y += libxlu_vif.o
 OBJS-y += libxlu_pci.o
 
-CFLAGS += -Wno-format-zero-length -Wmissing-declarations \
-	-Wno-declaration-after-statement -Wformat-nonliteral
+CFLAGS += -Wno-format-zero-length -Wmissing-declarations -Wformat-nonliteral
 CFLAGS += $(CFLAGS_libxenctrl)
 
 CFLAGS += $(PTHREAD_CFLAGS)
diff -Nru xen-4.17.2+76-ge1f9cb16e2/tools/tests/depriv/Makefile xen-4.17.3+10-g091466ba55/tools/tests/depriv/Makefile
--- xen-4.17.2+76-ge1f9cb16e2/tools/tests/depriv/Makefile	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/tools/tests/depriv/Makefile	2024-02-02 08:04:33.000000000 +0100
@@ -1,8 +1,6 @@
 XEN_ROOT=$(CURDIR)/../../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-CFLAGS += -Wno-declaration-after-statement
-
 CFLAGS += $(CFLAGS_xeninclude)
 CFLAGS += $(CFLAGS_libxenctrl)
 CFLAGS += $(CFLAGS_libxencall)
diff -Nru xen-4.17.2+76-ge1f9cb16e2/tools/xl/Makefile xen-4.17.3+10-g091466ba55/tools/xl/Makefile
--- xen-4.17.2+76-ge1f9cb16e2/tools/xl/Makefile	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/tools/xl/Makefile	2024-02-02 08:04:33.000000000 +0100
@@ -5,8 +5,7 @@
 XEN_ROOT = $(CURDIR)/../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-CFLAGS += -Wno-format-zero-length -Wmissing-declarations \
-	-Wno-declaration-after-statement -Wformat-nonliteral
+CFLAGS += -Wno-format-zero-length -Wmissing-declarations -Wformat-nonliteral
 CFLAGS += -fPIC
 
 CFLAGS += $(PTHREAD_CFLAGS)
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/arm/arm32/livepatch.c xen-4.17.3+10-g091466ba55/xen/arch/arm/arm32/livepatch.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/arm/arm32/livepatch.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/arm/arm32/livepatch.c	2024-02-02 08:04:33.000000000 +0100
@@ -11,23 +11,24 @@
 #include <asm/page.h>
 #include <asm/livepatch.h>
 
-void arch_livepatch_apply(struct livepatch_func *func)
+void arch_livepatch_apply(const struct livepatch_func *func,
+                          struct livepatch_fstate *state)
 {
     uint32_t insn;
     uint32_t *new_ptr;
     unsigned int i, len;
 
-    BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE > sizeof(func->opaque));
+    BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE > sizeof(state->insn_buffer));
     BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE != sizeof(insn));
 
     ASSERT(vmap_of_xen_text);
 
-    len = livepatch_insn_len(func);
+    len = livepatch_insn_len(func, state);
     if ( !len )
         return;
 
     /* Save old ones. */
-    memcpy(func->opaque, func->old_addr, len);
+    memcpy(state->insn_buffer, func->old_addr, len);
 
     if ( func->new_addr )
     {
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/arm/arm64/livepatch.c xen-4.17.3+10-g091466ba55/xen/arch/arm/arm64/livepatch.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/arm/arm64/livepatch.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/arm/arm64/livepatch.c	2024-02-02 08:04:33.000000000 +0100
@@ -15,23 +15,24 @@
 #include <asm/insn.h>
 #include <asm/livepatch.h>
 
-void arch_livepatch_apply(struct livepatch_func *func)
+void arch_livepatch_apply(const struct livepatch_func *func,
+                          struct livepatch_fstate *state)
 {
     uint32_t insn;
     uint32_t *new_ptr;
     unsigned int i, len;
 
-    BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE > sizeof(func->opaque));
+    BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE > sizeof(state->insn_buffer));
     BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE != sizeof(insn));
 
     ASSERT(vmap_of_xen_text);
 
-    len = livepatch_insn_len(func);
+    len = livepatch_insn_len(func, state);
     if ( !len )
         return;
 
     /* Save old ones. */
-    memcpy(func->opaque, func->old_addr, len);
+    memcpy(state->insn_buffer, func->old_addr, len);
 
     if ( func->new_addr )
         insn = aarch64_insn_gen_branch_imm((unsigned long)func->old_addr,
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/arm/include/asm/page.h xen-4.17.3+10-g091466ba55/xen/arch/arm/include/asm/page.h
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/arm/include/asm/page.h	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/arm/include/asm/page.h	2024-02-02 08:04:33.000000000 +0100
@@ -161,6 +161,13 @@
 static inline int invalidate_dcache_va_range(const void *p, unsigned long size)
 {
     size_t cacheline_mask = dcache_line_bytes - 1;
+    unsigned long idx = 0;
+
+    if ( !size )
+        return 0;
+
+    /* Passing a region that wraps around is illegal */
+    ASSERT(((uintptr_t)p + size - 1) >= (uintptr_t)p);
 
     dsb(sy);           /* So the CPU issues all writes to the range */
 
@@ -173,11 +180,11 @@
     }
 
     for ( ; size >= dcache_line_bytes;
-            p += dcache_line_bytes, size -= dcache_line_bytes )
-        asm volatile (__invalidate_dcache_one(0) : : "r" (p));
+            idx += dcache_line_bytes, size -= dcache_line_bytes )
+        asm volatile (__invalidate_dcache_one(0) : : "r" (p + idx));
 
     if ( size > 0 )
-        asm volatile (__clean_and_invalidate_dcache_one(0) : : "r" (p));
+        asm volatile (__clean_and_invalidate_dcache_one(0) : : "r" (p + idx));
 
     dsb(sy);           /* So we know the flushes happen before continuing */
 
@@ -187,14 +194,21 @@
 static inline int clean_dcache_va_range(const void *p, unsigned long size)
 {
     size_t cacheline_mask = dcache_line_bytes - 1;
+    unsigned long idx = 0;
+
+    if ( !size )
+        return 0;
+
+    /* Passing a region that wraps around is illegal */
+    ASSERT(((uintptr_t)p + size - 1) >= (uintptr_t)p);
 
     dsb(sy);           /* So the CPU issues all writes to the range */
     size += (uintptr_t)p & cacheline_mask;
     size = (size + cacheline_mask) & ~cacheline_mask;
     p = (void *)((uintptr_t)p & ~cacheline_mask);
     for ( ; size >= dcache_line_bytes;
-            p += dcache_line_bytes, size -= dcache_line_bytes )
-        asm volatile (__clean_dcache_one(0) : : "r" (p));
+            idx += dcache_line_bytes, size -= dcache_line_bytes )
+        asm volatile (__clean_dcache_one(0) : : "r" (p + idx));
     dsb(sy);           /* So we know the flushes happen before continuing */
     /* ARM callers assume that dcache_* functions cannot fail. */
     return 0;
@@ -204,14 +218,21 @@
     (const void *p, unsigned long size)
 {
     size_t cacheline_mask = dcache_line_bytes - 1;
+    unsigned long idx = 0;
+
+    if ( !size )
+        return 0;
+
+    /* Passing a region that wraps around is illegal */
+    ASSERT(((uintptr_t)p + size - 1) >= (uintptr_t)p);
 
     dsb(sy);         /* So the CPU issues all writes to the range */
     size += (uintptr_t)p & cacheline_mask;
     size = (size + cacheline_mask) & ~cacheline_mask;
     p = (void *)((uintptr_t)p & ~cacheline_mask);
     for ( ; size >= dcache_line_bytes;
-            p += dcache_line_bytes, size -= dcache_line_bytes )
-        asm volatile (__clean_and_invalidate_dcache_one(0) : : "r" (p));
+            idx += dcache_line_bytes, size -= dcache_line_bytes )
+        asm volatile (__clean_and_invalidate_dcache_one(0) : : "r" (p + idx));
     dsb(sy);         /* So we know the flushes happen before continuing */
     /* ARM callers assume that dcache_* functions cannot fail. */
     return 0;
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/arm/livepatch.c xen-4.17.3+10-g091466ba55/xen/arch/arm/livepatch.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/arm/livepatch.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/arm/livepatch.c	2024-02-02 08:04:33.000000000 +0100
@@ -68,7 +68,7 @@
 int arch_livepatch_verify_func(const struct livepatch_func *func)
 {
     /* If NOPing only do up to maximum amount we can put in the ->opaque. */
-    if ( !func->new_addr && (func->new_size > sizeof(func->opaque) ||
+    if ( !func->new_addr && (func->new_size > LIVEPATCH_OPAQUE_SIZE ||
          func->new_size % ARCH_PATCH_INSN_SIZE) )
         return -EOPNOTSUPP;
 
@@ -78,15 +78,16 @@
     return 0;
 }
 
-void arch_livepatch_revert(const struct livepatch_func *func)
+void arch_livepatch_revert(const struct livepatch_func *func,
+                           struct livepatch_fstate *state)
 {
     uint32_t *new_ptr;
     unsigned int len;
 
     new_ptr = func->old_addr - (void *)_start + vmap_of_xen_text;
 
-    len = livepatch_insn_len(func);
-    memcpy(new_ptr, func->opaque, len);
+    len = livepatch_insn_len(func, state);
+    memcpy(new_ptr, state->insn_buffer, len);
 
     clean_and_invalidate_dcache_va_range(new_ptr, len);
 }
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/apic.c xen-4.17.3+10-g091466ba55/xen/arch/x86/apic.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/apic.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/apic.c	2024-02-02 08:04:33.000000000 +0100
@@ -244,11 +244,7 @@
         outb(0x01, 0x23);
     }
 
-    printk("Enabling APIC mode:  %s.  Using %d I/O APICs\n",
-           !INT_DEST_MODE ? "Physical"
-                          : init_apic_ldr == init_apic_ldr_flat ? "Flat"
-                                                                : "Clustered",
-           nr_ioapics);
+    printk("Enabling APIC mode.  Using %d I/O APICs\n", nr_ioapics);
     enable_apic_mode();
 }
 
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/cpu/amd.c xen-4.17.3+10-g091466ba55/xen/arch/x86/cpu/amd.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/cpu/amd.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/cpu/amd.c	2024-02-02 08:04:33.000000000 +0100
@@ -54,7 +54,7 @@
 bool __ro_after_init amd_legacy_ssbd;
 bool __initdata amd_virt_spec_ctrl;
 
-static bool __read_mostly zen2_c6_disabled;
+static bool __read_mostly fam17_c6_disabled;
 
 static inline int rdmsr_amd_safe(unsigned int msr, unsigned int *lo,
 				 unsigned int *hi)
@@ -951,24 +951,24 @@
 		       val & chickenbit ? "chickenbit" : "microcode");
 }
 
-static void cf_check zen2_disable_c6(void *arg)
+static void cf_check fam17_disable_c6(void *arg)
 {
 	/* Disable C6 by clearing the CCR{0,1,2}_CC6EN bits. */
 	const uint64_t mask = ~((1ul << 6) | (1ul << 14) | (1ul << 22));
 	uint64_t val;
 
-	if (!zen2_c6_disabled) {
+	if (!fam17_c6_disabled) {
 		printk(XENLOG_WARNING
     "Disabling C6 after 1000 days apparent uptime due to AMD errata 1474\n");
-		zen2_c6_disabled = true;
+		fam17_c6_disabled = true;
 		/*
 		 * Prevent CPU hotplug so that started CPUs will either see
-		 * zen2_c6_disabled set, or will be handled by
+		 * zen_c6_disabled set, or will be handled by
 		 * smp_call_function().
 		 */
 		while (!get_cpu_maps())
 			process_pending_softirqs();
-		smp_call_function(zen2_disable_c6, NULL, 0);
+		smp_call_function(fam17_disable_c6, NULL, 0);
 		put_cpu_maps();
 	}
 
@@ -1273,8 +1273,8 @@
 	amd_check_zenbleed();
 	amd_check_erratum_1485();
 
-	if (zen2_c6_disabled)
-		zen2_disable_c6(NULL);
+	if (fam17_c6_disabled)
+		fam17_disable_c6(NULL);
 
 	check_syscfg_dram_mod_en();
 
@@ -1286,7 +1286,7 @@
 	.c_init		= init_amd,
 };
 
-static int __init cf_check zen2_c6_errata_check(void)
+static int __init cf_check amd_check_erratum_1474(void)
 {
 	/*
 	 * Errata #1474: A Core May Hang After About 1044 Days
@@ -1294,7 +1294,8 @@
 	 */
 	s_time_t delta;
 
-	if (cpu_has_hypervisor || boot_cpu_data.x86 != 0x17 || !is_zen2_uarch())
+	if (cpu_has_hypervisor ||
+	    (boot_cpu_data.x86 != 0x17 && boot_cpu_data.x86 != 0x18))
 		return 0;
 
 	/*
@@ -1309,10 +1310,10 @@
 	if (delta > 0) {
 		static struct timer errata_c6;
 
-		init_timer(&errata_c6, zen2_disable_c6, NULL, 0);
+		init_timer(&errata_c6, fam17_disable_c6, NULL, 0);
 		set_timer(&errata_c6, NOW() + delta);
 	} else
-		zen2_disable_c6(NULL);
+		fam17_disable_c6(NULL);
 
 	return 0;
 }
@@ -1320,4 +1321,4 @@
  * Must be executed after early_time_init() for tsc_ticks2ns() to have been
  * calibrated.  That prevents us doing the check in init_amd().
  */
-presmp_initcall(zen2_c6_errata_check);
+presmp_initcall(amd_check_erratum_1474);
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/cpu/intel.c xen-4.17.3+10-g091466ba55/xen/arch/x86/cpu/intel.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/cpu/intel.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/cpu/intel.c	2024-02-02 08:04:33.000000000 +0100
@@ -528,9 +528,30 @@
 	init_intel_cacheinfo(c);
 	if (c->cpuid_level > 9) {
 		unsigned eax = cpuid_eax(10);
+		unsigned int cnt = (eax >> 8) & 0xff;
+
 		/* Check for version and the number of counters */
-		if ((eax & 0xff) && (((eax>>8) & 0xff) > 1))
+		if ((eax & 0xff) && (cnt > 1) && (cnt <= 32)) {
+			uint64_t global_ctrl;
+			unsigned int cnt_mask = (1UL << cnt) - 1;
+
+			/*
+			 * On (some?) Sapphire/Emerald Rapids platforms each
+			 * package-BSP starts with all the enable bits for the
+			 * general-purpose PMCs cleared.  Adjust so counters
+			 * can be enabled from EVNTSEL.
+			 */
+			rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, global_ctrl);
+			if ((global_ctrl & cnt_mask) != cnt_mask) {
+				printk("CPU%u: invalid PERF_GLOBAL_CTRL: %#"
+				       PRIx64 " adjusting to %#" PRIx64 "\n",
+				       smp_processor_id(), global_ctrl,
+				       global_ctrl | cnt_mask);
+				wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL,
+				       global_ctrl | cnt_mask);
+			}
 			__set_bit(X86_FEATURE_ARCH_PERFMON, c->x86_capability);
+		}
 	}
 
 	if ( !cpu_has(c, X86_FEATURE_XTOPOLOGY) )
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/genapic/x2apic.c xen-4.17.3+10-g091466ba55/xen/arch/x86/genapic/x2apic.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/genapic/x2apic.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/genapic/x2apic.c	2024-02-02 08:04:33.000000000 +0100
@@ -191,6 +191,36 @@
     .send_IPI_self = send_IPI_self_x2apic
 };
 
+/*
+ * Mixed x2APIC mode: use physical for external (device) interrupts, and
+ * cluster for inter processor interrupts.  Such mode has the benefits of not
+ * sharing the vector space with all CPUs on the cluster, while still allowing
+ * IPIs to be more efficiently delivered by not having to perform an ICR write
+ * for each target CPU.
+ */
+static const struct genapic __initconstrel apic_x2apic_mixed = {
+    APIC_INIT("x2apic_mixed", NULL),
+
+    /*
+     * The following fields are exclusively used by external interrupts and
+     * hence are set to use Physical destination mode handlers.
+     */
+    .int_delivery_mode = dest_Fixed,
+    .int_dest_mode = 0 /* physical delivery */,
+    .vector_allocation_cpumask = vector_allocation_cpumask_phys,
+    .cpu_mask_to_apicid = cpu_mask_to_apicid_phys,
+
+    /*
+     * The following fields are exclusively used by IPIs and hence are set to
+     * use Cluster Logical destination mode handlers.  Note that init_apic_ldr
+     * is not used by IPIs, but the per-CPU fields it initializes are only used
+     * by the IPI hooks.
+     */
+    .init_apic_ldr = init_apic_ldr_x2apic_cluster,
+    .send_IPI_mask = send_IPI_mask_x2apic_cluster,
+    .send_IPI_self = send_IPI_self_x2apic,
+};
+
 static int cf_check update_clusterinfo(
     struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
@@ -231,38 +261,56 @@
 static int8_t __initdata x2apic_phys = -1;
 boolean_param("x2apic_phys", x2apic_phys);
 
+enum {
+   unset, physical, cluster, mixed
+} static __initdata x2apic_mode = unset;
+
+static int __init cf_check parse_x2apic_mode(const char *s)
+{
+    if ( !cmdline_strcmp(s, "physical") )
+        x2apic_mode = physical;
+    else if ( !cmdline_strcmp(s, "cluster") )
+        x2apic_mode = cluster;
+    else if ( !cmdline_strcmp(s, "mixed") )
+        x2apic_mode = mixed;
+    else
+        return -EINVAL;
+
+    return 0;
+}
+custom_param("x2apic-mode", parse_x2apic_mode);
+
 const struct genapic *__init apic_x2apic_probe(void)
 {
-    if ( x2apic_phys < 0 )
+    /* Honour the legacy cmdline setting if it's the only one provided. */
+    if ( x2apic_mode == unset && x2apic_phys >= 0 )
+        x2apic_mode = x2apic_phys ? physical : cluster;
+
+    if ( x2apic_mode == unset )
     {
-        /*
-         * Force physical mode if there's no (full) interrupt remapping support:
-         * The ID in clustered mode requires a 32 bit destination field due to
-         * the usage of the high 16 bits to hold the cluster ID.
-         */
-        x2apic_phys = iommu_intremap != iommu_intremap_full ||
-                      (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) ||
-                      IS_ENABLED(CONFIG_X2APIC_PHYSICAL);
-    }
-    else if ( !x2apic_phys )
-        switch ( iommu_intremap )
+        if ( acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL )
         {
-        case iommu_intremap_off:
-        case iommu_intremap_restricted:
-            printk("WARNING: x2APIC cluster mode is not supported %s interrupt remapping -"
-                   " forcing phys mode\n",
-                   iommu_intremap == iommu_intremap_off ? "without"
-                                                        : "with restricted");
-            x2apic_phys = true;
-            break;
-
-        case iommu_intremap_full:
-            break;
+            printk(XENLOG_INFO "ACPI FADT forcing x2APIC physical mode\n");
+            x2apic_mode = physical;
         }
+        else
+            x2apic_mode = IS_ENABLED(CONFIG_X2APIC_MIXED) ? mixed
+                          : (IS_ENABLED(CONFIG_X2APIC_PHYSICAL) ? physical
+                                                                : cluster);
+    }
 
-    if ( x2apic_phys )
+    if ( x2apic_mode == physical )
         return &apic_x2apic_phys;
 
+    if ( x2apic_mode == cluster && iommu_intremap != iommu_intremap_full )
+    {
+        printk("WARNING: x2APIC cluster mode is not supported %s interrupt remapping -"
+               " forcing mixed mode\n",
+               iommu_intremap == iommu_intremap_off ? "without"
+                                                    : "with restricted");
+        x2apic_mode = mixed;
+    }
+
     if ( !this_cpu(cluster_cpus) )
     {
         update_clusterinfo(NULL, CPU_UP_PREPARE,
@@ -271,7 +319,7 @@
         register_cpu_notifier(&x2apic_cpu_nfb);
     }
 
-    return &apic_x2apic_cluster;
+    return x2apic_mode == cluster ? &apic_x2apic_cluster : &apic_x2apic_mixed;
 }
 
 void __init check_x2apic_preenabled(void)
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/hvm/vlapic.c xen-4.17.3+10-g091466ba55/xen/arch/x86/hvm/vlapic.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/hvm/vlapic.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/hvm/vlapic.c	2024-02-02 08:04:33.000000000 +0100
@@ -1072,13 +1072,26 @@
     .write = vlapic_mmio_write,
 };
 
+static uint32_t x2apic_ldr_from_id(uint32_t id)
+{
+    return ((id & ~0xf) << 12) | (1 << (id & 0xf));
+}
+
 static void set_x2apic_id(struct vlapic *vlapic)
 {
-    u32 id = vlapic_vcpu(vlapic)->vcpu_id;
-    u32 ldr = ((id & ~0xf) << 12) | (1 << (id & 0xf));
+    const struct vcpu *v = vlapic_vcpu(vlapic);
+    uint32_t apic_id = v->vcpu_id * 2;
+    uint32_t apic_ldr = x2apic_ldr_from_id(apic_id);
 
-    vlapic_set_reg(vlapic, APIC_ID, id * 2);
-    vlapic_set_reg(vlapic, APIC_LDR, ldr);
+    /*
+     * Workaround for migrated domains to derive LDRs as the source host
+     * would've.
+     */
+    if ( v->domain->arch.hvm.bug_x2apic_ldr_vcpu_id )
+        apic_ldr = x2apic_ldr_from_id(v->vcpu_id);
+
+    vlapic_set_reg(vlapic, APIC_ID, apic_id);
+    vlapic_set_reg(vlapic, APIC_LDR, apic_ldr);
 }
 
 int guest_wrmsr_apic_base(struct vcpu *v, uint64_t value)
@@ -1509,27 +1522,40 @@
  */
 static void lapic_load_fixup(struct vlapic *vlapic)
 {
-    uint32_t id = vlapic->loaded.id;
+    const struct vcpu *v = vlapic_vcpu(vlapic);
+    uint32_t good_ldr = x2apic_ldr_from_id(vlapic->loaded.id);
 
-    if ( vlapic_x2apic_mode(vlapic) && id && vlapic->loaded.ldr == 1 )
+    /* Skip fixups on xAPIC mode, or if the x2APIC LDR is already correct */
+    if ( !vlapic_x2apic_mode(vlapic) ||
+         (vlapic->loaded.ldr == good_ldr) )
+        return;
+
+    if ( vlapic->loaded.ldr == 1 )
     {
-        /*
-         * This is optional: ID != 0 contradicts LDR == 1. It's being added
-         * to aid in eventual debugging of issues arising from the fixup done
-         * here, but can be dropped as soon as it is found to conflict with
-         * other (future) changes.
-         */
-        if ( GET_xAPIC_ID(id) != vlapic_vcpu(vlapic)->vcpu_id * 2 ||
-             id != SET_xAPIC_ID(GET_xAPIC_ID(id)) )
-            printk(XENLOG_G_WARNING "%pv: bogus APIC ID %#x loaded\n",
-                   vlapic_vcpu(vlapic), id);
+       /*
+        * Xen <= 4.4 may have a bug by which all the APICs configured in
+        * x2APIC mode got LDR = 1, which is inconsistent on every vCPU
+        * except for the one with ID = 0. We'll fix the bug now and assign
+        * an LDR value consistent with the APIC ID.
+        */
         set_x2apic_id(vlapic);
     }
-    else /* Undo an eventual earlier fixup. */
+    else if ( vlapic->loaded.ldr == x2apic_ldr_from_id(v->vcpu_id) )
     {
-        vlapic_set_reg(vlapic, APIC_ID, id);
-        vlapic_set_reg(vlapic, APIC_LDR, vlapic->loaded.ldr);
+        /*
+         * Migrations from Xen 4.4 to date (4.19 dev window, Nov 2023) may
+         * have LDR drived from the vCPU ID, not the APIC ID. We must preserve
+         * LDRs so new vCPUs use consistent derivations and existing guests,
+         * which may have already read the LDR at the source host, aren't
+         * surprised when interrupts stop working the way they did at the
+         * other end.
+         */
+        v->domain->arch.hvm.bug_x2apic_ldr_vcpu_id = true;
     }
+    else
+        printk(XENLOG_G_WARNING
+               "%pv: bogus x2APIC record: ID %#x, LDR %#x, expected LDR %#x\n",
+               v, vlapic->loaded.id, vlapic->loaded.ldr, good_ldr);
 }
 
 static int cf_check lapic_load_hidden(struct domain *d, hvm_domain_context_t *h)
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/hvm/vmx/vmx.c xen-4.17.3+10-g091466ba55/xen/arch/x86/hvm/vmx/vmx.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/hvm/vmx/vmx.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/hvm/vmx/vmx.c	2024-02-02 08:04:33.000000000 +0100
@@ -1499,7 +1499,13 @@
 {
     vmx_vmcs_enter(v);
 
-    __vmwrite(GUEST_ACTIVITY_STATE, nrs->vmx.activity_state);
+    if ( nrs->vmx.activity_state )
+    {
+        printk("Attempt to set %pv activity_state %#lx\n",
+               v, nrs->vmx.activity_state);
+        domain_crash(v->domain);
+    }
+
     __vmwrite(GUEST_INTERRUPTIBILITY_INFO, nrs->vmx.interruptibility_info);
     __vmwrite(GUEST_PENDING_DBG_EXCEPTIONS, nrs->vmx.pending_dbg);
 
@@ -4037,7 +4043,7 @@
 
     case EXIT_REASON_INIT:
         printk(XENLOG_ERR "Error: INIT received - ignoring\n");
-        return; /* Renter the guest without further processing */
+        break;
     }
 
     /* Now enable interrupts so it's safe to take locks. */
@@ -4323,6 +4329,7 @@
         break;
     }
     case EXIT_REASON_EXTERNAL_INTERRUPT:
+    case EXIT_REASON_INIT:
         /* Already handled above. */
         break;
     case EXIT_REASON_TRIPLE_FAULT:
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/hvm/vmx/vvmx.c xen-4.17.3+10-g091466ba55/xen/arch/x86/hvm/vmx/vvmx.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/hvm/vmx/vvmx.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/hvm/vmx/vvmx.c	2024-02-02 08:04:33.000000000 +0100
@@ -910,7 +910,10 @@
     GUEST_LDTR_AR_BYTES,
     GUEST_TR_AR_BYTES,
     GUEST_INTERRUPTIBILITY_INFO,
+    /*
+     * ACTIVITY_STATE is handled specially.
     GUEST_ACTIVITY_STATE,
+     */
     GUEST_SYSENTER_CS,
     GUEST_PREEMPTION_TIMER,
     /* natural */
@@ -1211,6 +1214,8 @@
     nvcpu->nv_vmentry_pending = 0;
     nvcpu->nv_vmswitch_in_progress = 1;
 
+    /* TODO: Fail VMentry for GUEST_ACTIVITY_STATE != 0 */
+
     /*
      * EFER handling:
      * hvm_set_efer won't work if CR0.PG = 1, so we change the value
@@ -2327,8 +2332,8 @@
         data = hvm_cr4_guest_valid_bits(d);
         break;
     case MSR_IA32_VMX_MISC:
-        /* Do not support CR3-target feature now */
-        data = host_data & ~VMX_MISC_CR3_TARGET;
+        /* Do not support CR3-targets or activity states. */
+        data = host_data & ~(VMX_MISC_CR3_TARGET | VMX_MISC_ACTIVITY_MASK);
         break;
     case MSR_IA32_VMX_EPT_VPID_CAP:
         data = nept_get_ept_vpid_cap();
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/include/asm/hvm/domain.h xen-4.17.3+10-g091466ba55/xen/arch/x86/include/asm/hvm/domain.h
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/include/asm/hvm/domain.h	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/include/asm/hvm/domain.h	2024-02-02 08:04:33.000000000 +0100
@@ -117,6 +117,9 @@
 
     bool                   is_s3_suspended;
 
+    /* Compatibility setting for a bug in x2APIC LDR */
+    bool bug_x2apic_ldr_vcpu_id;
+
     /* hypervisor intercepted msix table */
     struct list_head       msixtbl_list;
 
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/include/asm/hvm/vmx/vmcs.h xen-4.17.3+10-g091466ba55/xen/arch/x86/include/asm/hvm/vmx/vmcs.h
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/include/asm/hvm/vmx/vmcs.h	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/include/asm/hvm/vmx/vmcs.h	2024-02-02 08:04:33.000000000 +0100
@@ -288,6 +288,7 @@
 #define VMX_VPID_INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL 0x80000000000ULL
 extern u64 vmx_ept_vpid_cap;
 
+#define VMX_MISC_ACTIVITY_MASK                  0x000001c0
 #define VMX_MISC_PROC_TRACE                     0x00004000
 #define VMX_MISC_CR3_TARGET                     0x01ff0000
 #define VMX_MISC_VMWRITE_ALL                    0x20000000
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/include/asm/p2m.h xen-4.17.3+10-g091466ba55/xen/arch/x86/include/asm/p2m.h
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/include/asm/p2m.h	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/include/asm/p2m.h	2024-02-02 08:04:33.000000000 +0100
@@ -447,7 +447,14 @@
     return p2m->p2m_class == p2m_alternate;
 }
 
-#define p2m_get_pagetable(p2m)  ((p2m)->phys_table)
+#ifdef CONFIG_HVM
+static inline pagetable_t p2m_get_pagetable(const struct p2m_domain *p2m)
+{
+    return p2m->phys_table;
+}
+#else
+pagetable_t p2m_get_pagetable(const struct p2m_domain *p2m);
+#endif
 
 /*
  * Ensure any deferred p2m TLB flush has been completed on all VCPUs.
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/Kconfig xen-4.17.3+10-g091466ba55/xen/arch/x86/Kconfig
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/Kconfig	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/Kconfig	2024-02-02 08:04:33.000000000 +0100
@@ -228,11 +228,18 @@
 
 endchoice
 
-config X2APIC_PHYSICAL
-	bool "x2APIC Physical Destination mode"
+choice
+	prompt "x2APIC Driver default"
+	default X2APIC_MIXED
 	help
-	  Use x2APIC Physical Destination mode by default when available.
+	  Select APIC addressing when x2APIC is enabled.
+
+	  The default mode is mixed which should provide the best aspects
+	  of both physical and cluster modes.
 
+config X2APIC_PHYSICAL
+	bool "Physical Destination mode"
+	help
 	  When using this mode APICs are addressed using the Physical
 	  Destination mode, which allows using all dynamic vectors on each
 	  CPU independently.
@@ -242,9 +249,27 @@
 	  destination inter processor interrupts (IPIs) slightly slower than
 	  Logical Destination mode.
 
-	  The mode when this option is not selected is Logical Destination.
+config X2APIC_CLUSTER
+	bool "Cluster Destination mode"
+	help
+	  When using this mode APICs are addressed using the Cluster Logical
+	  Destination mode.
+
+	  Cluster Destination has the benefit of sending IPIs faster since
+	  multiple APICs can be targeted as destinations of a single IPI.
+	  However the vector space is shared between all CPUs on the cluster,
+	  and hence using this mode reduces the number of available vectors
+	  when compared to Physical mode.
+
+config X2APIC_MIXED
+	bool "Mixed Destination mode"
+	help
+	  When using this mode APICs are addressed using the Cluster Logical
+	  Destination mode for IPIs and Physical mode for external interrupts.
 
-	  If unsure, say N.
+	  Should provide the best of both modes.
+
+endchoice
 
 config GUEST
 	bool
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/livepatch.c xen-4.17.3+10-g091466ba55/xen/arch/x86/livepatch.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/livepatch.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/livepatch.c	2024-02-02 08:04:33.000000000 +0100
@@ -95,7 +95,7 @@
     if ( !func->new_addr )
     {
         /* Only do up to maximum amount we can put in the ->opaque. */
-        if ( func->new_size > sizeof(func->opaque) )
+        if ( func->new_size > LIVEPATCH_OPAQUE_SIZE )
             return -EOPNOTSUPP;
 
         if ( func->old_size < func->new_size )
@@ -123,13 +123,14 @@
  * "noinline" to cause control flow change and thus invalidate I$ and
  * cause refetch after modification.
  */
-void noinline arch_livepatch_apply(struct livepatch_func *func)
+void noinline arch_livepatch_apply(const struct livepatch_func *func,
+                                   struct livepatch_fstate *state)
 {
     uint8_t *old_ptr;
-    uint8_t insn[sizeof(func->opaque)];
+    uint8_t insn[sizeof(state->insn_buffer)];
     unsigned int len;
 
-    func->patch_offset = 0;
+    state->patch_offset = 0;
     old_ptr = func->old_addr;
 
     /*
@@ -141,14 +142,14 @@
      * ENDBR64 or similar instructions).
      */
     if ( is_endbr64(old_ptr) || is_endbr64_poison(func->old_addr) )
-        func->patch_offset += ENDBR64_LEN;
+        state->patch_offset += ENDBR64_LEN;
 
     /* This call must be done with ->patch_offset already set. */
-    len = livepatch_insn_len(func);
+    len = livepatch_insn_len(func, state);
     if ( !len )
         return;
 
-    memcpy(func->opaque, old_ptr + func->patch_offset, len);
+    memcpy(state->insn_buffer, old_ptr + state->patch_offset, len);
     if ( func->new_addr )
     {
         int32_t val;
@@ -156,7 +157,7 @@
         BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE != (1 + sizeof(val)));
 
         insn[0] = 0xe9; /* Relative jump. */
-        val = func->new_addr - (func->old_addr + func->patch_offset +
+        val = func->new_addr - (func->old_addr + state->patch_offset +
                                 ARCH_PATCH_INSN_SIZE);
 
         memcpy(&insn[1], &val, sizeof(val));
@@ -164,17 +165,18 @@
     else
         add_nops(insn, len);
 
-    memcpy(old_ptr + func->patch_offset, insn, len);
+    memcpy(old_ptr + state->patch_offset, insn, len);
 }
 
 /*
  * "noinline" to cause control flow change and thus invalidate I$ and
  * cause refetch after modification.
  */
-void noinline arch_livepatch_revert(const struct livepatch_func *func)
+void noinline arch_livepatch_revert(const struct livepatch_func *func,
+                                    struct livepatch_fstate *state)
 {
-    memcpy(func->old_addr + func->patch_offset, func->opaque,
-           livepatch_insn_len(func));
+    memcpy(func->old_addr + state->patch_offset, state->insn_buffer,
+           livepatch_insn_len(func, state));
 }
 
 /*
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/mm/mem_sharing.c xen-4.17.3+10-g091466ba55/xen/arch/x86/mm/mem_sharing.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/mm/mem_sharing.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/mm/mem_sharing.c	2024-02-02 08:04:33.000000000 +0100
@@ -2018,7 +2018,7 @@
 
     if ( !mem_sharing_enabled(d) &&
          (rc = mem_sharing_control(d, true, 0)) )
-        return rc;
+        goto out;
 
     switch ( mso.op )
     {
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/mm/p2m-pt.c xen-4.17.3+10-g091466ba55/xen/arch/x86/mm/p2m-pt.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/mm/p2m-pt.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/mm/p2m-pt.c	2024-02-02 08:04:33.000000000 +0100
@@ -564,7 +564,7 @@
     if ( new == p2m_mmio_direct )
         ASSERT(!mfn_eq(mfn, INVALID_MFN) &&
                !rangeset_overlaps_range(mmio_ro_ranges, mfn_x(mfn),
-                                        mfn_x(mfn) + (1ul << order)));
+                                        mfn_x(mfn) + (1UL << order) - 1));
     else if ( p2m_allows_invalid_mfn(new) || new == p2m_invalid ||
               new == p2m_mmio_dm )
         ASSERT(mfn_valid(mfn) || mfn_eq(mfn, INVALID_MFN));
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/x86_emulate/x86_emulate.c xen-4.17.3+10-g091466ba55/xen/arch/x86/x86_emulate/x86_emulate.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/arch/x86/x86_emulate/x86_emulate.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/arch/x86/x86_emulate/x86_emulate.c	2024-02-02 08:04:33.000000000 +0100
@@ -2476,10 +2476,18 @@
                            const struct x86_emulate_ops *ops)
 {
     uint64_t debugctl;
+    int rc = X86EMUL_UNHANDLEABLE;
 
-    return ops->read_msr &&
-           ops->read_msr(MSR_IA32_DEBUGCTLMSR, &debugctl, ctxt) == X86EMUL_OKAY &&
-           (debugctl & IA32_DEBUGCTLMSR_BTF);
+    if ( !ops->read_msr ||
+         (rc = ops->read_msr(MSR_IA32_DEBUGCTLMSR, &debugctl,
+                             ctxt)) != X86EMUL_OKAY )
+    {
+        if ( rc == X86EMUL_EXCEPTION )
+            x86_emul_reset_event(ctxt);
+        debugctl = 0;
+    }
+
+    return debugctl & IA32_DEBUGCTLMSR_BTF;
 }
 
 static bool umip_active(struct x86_emulate_ctxt *ctxt,
@@ -2504,13 +2512,21 @@
 
     if ( !ops->read_xcr || ops->read_xcr(0, &xcr0, ctxt) != X86EMUL_OKAY ||
          !(xcr0 & X86_XCR0_BNDREGS) || !(xcr0 & X86_XCR0_BNDCSR) )
+    {
+        ASSERT(!ctxt->event_pending);
         return;
+    }
 
     if ( !mode_ring0() )
         bndcfg = read_bndcfgu();
     else if ( !ops->read_msr ||
-              ops->read_msr(MSR_IA32_BNDCFGS, &bndcfg, ctxt) != X86EMUL_OKAY )
+              (rc = ops->read_msr(MSR_IA32_BNDCFGS, &bndcfg,
+                                  ctxt)) != X86EMUL_OKAY )
+    {
+        if ( rc == X86EMUL_EXCEPTION )
+            x86_emul_reset_event(ctxt);
         return;
+    }
     if ( (bndcfg & IA32_BNDCFGS_ENABLE) && !(bndcfg & IA32_BNDCFGS_PRESERVE) )
     {
         /*
@@ -5868,8 +5884,10 @@
             if ( (rc = ops->write_segment(x86_seg_gs, &sreg,
                                           ctxt)) != X86EMUL_OKAY )
             {
-                /* Best effort unwind (i.e. no error checking). */
-                ops->write_msr(MSR_SHADOW_GS_BASE, msr_val, ctxt);
+                /* Best effort unwind (i.e. no real error checking). */
+                if ( ops->write_msr(MSR_SHADOW_GS_BASE, msr_val,
+                                    ctxt) == X86EMUL_EXCEPTION )
+                    x86_emul_reset_event(ctxt);
                 goto done;
             }
             break;
@@ -8250,7 +8268,10 @@
                     cr4 = X86_CR4_OSFXSR;
                 if ( !ops->read_msr ||
                      ops->read_msr(MSR_EFER, &msr_val, ctxt) != X86EMUL_OKAY )
+                {
+                    x86_emul_reset_event(ctxt);
                     msr_val = 0;
+                }
                 if ( !(cr4 & X86_CR4_OSFXSR) ||
                      (mode_64bit() && mode_ring0() && (msr_val & EFER_FFXSE)) )
                     op_bytes = offsetof(struct x86_fxsr, xmm[0]);
@@ -12215,7 +12236,9 @@
      * An event being pending should exactly match returning
      * X86EMUL_EXCEPTION.  (If this trips, the chances are a codepath has
      * called hvm_inject_hw_exception() rather than using
-     * x86_emul_hw_exception().)
+     * x86_emul_hw_exception(), or the invocation of a hook has caused an
+     * exception to be raised, while the caller was only checking for
+     * success/failure.)
      */
     ASSERT(ctxt->event_pending == (rc == X86EMUL_EXCEPTION));
 
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/common/domain.c xen-4.17.3+10-g091466ba55/xen/common/domain.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/common/domain.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/common/domain.c	2024-02-02 08:04:33.000000000 +0100
@@ -674,6 +674,7 @@
         watchdog_domain_init(d);
         init_status |= INIT_watchdog;
 
+        err = -ENOMEM;
         d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
         d->irq_caps   = rangeset_new(d, "Interrupts", 0);
         if ( !d->iomem_caps || !d->irq_caps )
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/common/libelf/Makefile xen-4.17.3+10-g091466ba55/xen/common/libelf/Makefile
--- xen-4.17.2+76-ge1f9cb16e2/xen/common/libelf/Makefile	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/common/libelf/Makefile	2024-02-02 08:04:33.000000000 +0100
@@ -13,4 +13,4 @@
 $(obj)/libelf-temp.o: $(addprefix $(obj)/,$(libelf-objs)) FORCE
 	$(call if_changed,ld)
 
-extra-y += libelf-temp.o $(libelf-objs)
+targets += libelf-temp.o $(libelf-objs)
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/common/libfdt/Makefile xen-4.17.3+10-g091466ba55/xen/common/libfdt/Makefile
--- xen-4.17.2+76-ge1f9cb16e2/xen/common/libfdt/Makefile	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/common/libfdt/Makefile	2024-02-02 08:04:33.000000000 +0100
@@ -2,9 +2,9 @@
 
 SECTIONS := text data $(SPECIAL_DATA_SECTIONS)
 OBJCOPYFLAGS := $(foreach s,$(SECTIONS),--rename-section .$(s)=.init.$(s))
+nocov-y += libfdt.o
 
 obj-y += libfdt.o
-nocov-y += libfdt.o
 
 CFLAGS-y += -I$(srctree)/include/xen/libfdt/
 
@@ -14,4 +14,4 @@
 $(obj)/libfdt-temp.o: $(addprefix $(obj)/,$(LIBFDT_OBJS)) FORCE
 	$(call if_changed,ld)
 
-extra-y += libfdt-temp.o $(LIBFDT_OBJS)
+targets += libfdt-temp.o $(LIBFDT_OBJS)
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/common/livepatch.c xen-4.17.3+10-g091466ba55/xen/common/livepatch.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/common/livepatch.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/common/livepatch.c	2024-02-02 08:04:33.000000000 +0100
@@ -260,6 +260,9 @@
     vfree((void *)payload->text_addr);
 
     payload->pages = 0;
+
+    /* fstate gets allocated strictly after move_payload. */
+    XFREE(payload->fstate);
 }
 
 /*
@@ -656,6 +659,7 @@
 {
     const struct livepatch_elf_sec *sec;
     unsigned int i;
+    struct livepatch_func *funcs;
     struct livepatch_func *f;
     struct virtual_region *region;
     const Elf_Note *n;
@@ -666,14 +670,19 @@
         if ( !section_ok(elf, sec, sizeof(*payload->funcs)) )
             return -EINVAL;
 
-        payload->funcs = sec->load_addr;
+        payload->funcs = funcs = sec->load_addr;
         payload->nfuncs = sec->sec->sh_size / sizeof(*payload->funcs);
 
+        payload->fstate = xzalloc_array(typeof(*payload->fstate),
+                                        payload->nfuncs);
+        if ( !payload->fstate )
+            return -ENOMEM;
+
         for ( i = 0; i < payload->nfuncs; i++ )
         {
             int rc;
 
-            f = &(payload->funcs[i]);
+            f = &(funcs[i]);
 
             if ( f->version != LIVEPATCH_PAYLOAD_VERSION )
             {
@@ -1305,7 +1314,7 @@
     ASSERT(!local_irq_is_enabled());
 
     for ( i = 0; i < data->nfuncs; i++ )
-        common_livepatch_apply(&data->funcs[i]);
+        common_livepatch_apply(&data->funcs[i], &data->fstate[i]);
 
     arch_livepatch_revive();
 
@@ -1341,7 +1350,7 @@
     }
 
     for ( i = 0; i < data->nfuncs; i++ )
-        common_livepatch_revert(&data->funcs[i]);
+        common_livepatch_revert(&data->funcs[i], &data->fstate[i]);
 
     /*
      * Since we are running with IRQs disabled and the hooks may call common
@@ -1382,9 +1391,10 @@
 
     for ( i = 0; i < data->nfuncs; i++ )
     {
-        struct livepatch_func *f = &(data->funcs[i]);
+        const struct livepatch_func *f = &(data->funcs[i]);
+        const struct livepatch_fstate *s = &(data->fstate[i]);
 
-        if ( f->applied != expected_state )
+        if ( s->applied != expected_state )
         {
             printk(XENLOG_ERR LIVEPATCH "%s: Payload has a function: '%s' with inconsistent applied state.\n",
                    data->name, f->name ?: "noname");
@@ -2101,7 +2111,8 @@
 
         for ( i = 0; i < data->nfuncs; i++ )
         {
-            struct livepatch_func *f = &(data->funcs[i]);
+            const struct livepatch_func *f = &(data->funcs[i]);
+
             printk("    %s patch %p(%u) with %p (%u)\n",
                    f->name, f->old_addr, f->old_size, f->new_addr, f->new_size);
 
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/common/sched/core.c xen-4.17.3+10-g091466ba55/xen/common/sched/core.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/common/sched/core.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/common/sched/core.c	2024-02-02 08:04:33.000000000 +0100
@@ -647,6 +647,24 @@
         vcpu_move_irqs(v);
 }
 
+static void sched_move_domain_cleanup(const struct scheduler *ops,
+                                      struct sched_unit *units,
+                                      void *domdata)
+{
+    struct sched_unit *unit, *old_unit;
+
+    for ( unit = units; unit; )
+    {
+        if ( unit->priv )
+            sched_free_udata(ops, unit->priv);
+        old_unit = unit;
+        unit = unit->next_in_list;
+        xfree(old_unit);
+    }
+
+    sched_free_domdata(ops, domdata);
+}
+
 /*
  * Move a domain from one cpupool to another.
  *
@@ -686,7 +704,6 @@
     void *old_domdata;
     unsigned int gran = cpupool_get_granularity(c);
     unsigned int n_units = d->vcpu[0] ? DIV_ROUND_UP(d->max_vcpus, gran) : 0;
-    int ret = 0;
 
     for_each_vcpu ( d, v )
     {
@@ -699,8 +716,9 @@
     domdata = sched_alloc_domdata(c->sched, d);
     if ( IS_ERR(domdata) )
     {
-        ret = PTR_ERR(domdata);
-        goto out;
+        rcu_read_unlock(&sched_res_rculock);
+
+        return PTR_ERR(domdata);
     }
 
     for ( unit_idx = 0; unit_idx < n_units; unit_idx++ )
@@ -718,10 +736,10 @@
 
         if ( !unit || !unit->priv )
         {
-            old_units = new_units;
-            old_domdata = domdata;
-            ret = -ENOMEM;
-            goto out_free;
+            sched_move_domain_cleanup(c->sched, new_units, domdata);
+            rcu_read_unlock(&sched_res_rculock);
+
+            return -ENOMEM;
         }
 
         unit_ptr = &unit->next_in_list;
@@ -808,22 +826,11 @@
 
     domain_unpause(d);
 
- out_free:
-    for ( unit = old_units; unit; )
-    {
-        if ( unit->priv )
-            sched_free_udata(c->sched, unit->priv);
-        old_unit = unit;
-        unit = unit->next_in_list;
-        xfree(old_unit);
-    }
-
-    sched_free_domdata(old_ops, old_domdata);
+    sched_move_domain_cleanup(old_ops, old_units, old_domdata);
 
- out:
     rcu_read_unlock(&sched_res_rculock);
 
-    return ret;
+    return 0;
 }
 
 void sched_destroy_vcpu(struct vcpu *v)
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/common/sched/cpupool.c xen-4.17.3+10-g091466ba55/xen/common/sched/cpupool.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/common/sched/cpupool.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/common/sched/cpupool.c	2024-02-02 08:04:33.000000000 +0100
@@ -892,6 +892,8 @@
         if ( cpu >= nr_cpu_ids )
             goto addcpu_out;
         ret = -ENODEV;
+        if ( !cpu_online(cpu) )
+            goto addcpu_out;
         cpus = sched_get_opt_cpumask(c->gran, cpu);
         if ( !cpumask_subset(cpus, &cpupool_free_cpus) ||
              cpumask_intersects(cpus, &cpupool_locked_cpus) )
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/drivers/passthrough/pci.c xen-4.17.3+10-g091466ba55/xen/drivers/passthrough/pci.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/drivers/passthrough/pci.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/drivers/passthrough/pci.c	2024-02-02 08:04:33.000000000 +0100
@@ -1444,11 +1444,10 @@
 
     pdev->fault.count = 0;
 
-    if ( (rc = iommu_call(hd->platform_ops, assign_device, d, devfn,
-                          pci_to_dev(pdev), flag)) )
-        goto done;
+    rc = iommu_call(hd->platform_ops, assign_device, d, devfn, pci_to_dev(pdev),
+                    flag);
 
-    for ( ; pdev->phantom_stride; rc = 0 )
+    while ( pdev->phantom_stride && !rc )
     {
         devfn += pdev->phantom_stride;
         if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
@@ -1459,8 +1458,24 @@
 
  done:
     if ( rc )
-        printk(XENLOG_G_WARNING "%pd: assign (%pp) failed (%d)\n",
-               d, &PCI_SBDF(seg, bus, devfn), rc);
+    {
+        printk(XENLOG_G_WARNING "%pd: assign %s(%pp) failed (%d)\n",
+               d, devfn != pdev->devfn ? "phantom function " : "",
+               &PCI_SBDF(seg, bus, devfn), rc);
+
+        if ( devfn != pdev->devfn && deassign_device(d, seg, bus, pdev->devfn) )
+        {
+            /*
+             * Device with phantom functions that failed to both assign and
+             * rollback.  Mark the device as broken and crash the target domain,
+             * as the state of the functions at this point is unknown and Xen
+             * has no way to assert consistent context assignment among them.
+             */
+            pdev->broken = true;
+            if ( !is_hardware_domain(d) && d != dom_io )
+                domain_crash(d);
+        }
+    }
     /* The device is assigned to dom_io so mark it as quarantined */
     else if ( d == dom_io )
         pdev->quarantine = true;
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/drivers/passthrough/vtd/iommu.c xen-4.17.3+10-g091466ba55/xen/drivers/passthrough/vtd/iommu.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/drivers/passthrough/vtd/iommu.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/drivers/passthrough/vtd/iommu.c	2024-02-02 08:04:33.000000000 +0100
@@ -441,15 +441,13 @@
 
     if ( pgd_maddr )
         /* nothing */;
-#ifdef CONFIG_HVM
-    else if ( iommu_use_hap_pt(d) )
+    else if ( IS_ENABLED(CONFIG_HVM) && iommu_use_hap_pt(d) )
     {
         pagetable_t pgt = p2m_get_pagetable(p2m_get_hostp2m(d));
 
         pgd_maddr = pagetable_get_paddr(pgt);
     }
     else
-#endif
     {
         if ( !hd->arch.vtd.pgd_maddr )
         {
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/include/public/sysctl.h xen-4.17.3+10-g091466ba55/xen/include/public/sysctl.h
--- xen-4.17.2+76-ge1f9cb16e2/xen/include/public/sysctl.h	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/include/public/sysctl.h	2024-02-02 08:04:33.000000000 +0100
@@ -861,10 +861,7 @@
     uint32_t new_size;
     uint32_t old_size;
     uint8_t version;        /* MUST be LIVEPATCH_PAYLOAD_VERSION. */
-    uint8_t opaque[LIVEPATCH_OPAQUE_SIZE];
-    uint8_t applied;
-    uint8_t patch_offset;
-    uint8_t _pad[6];
+    uint8_t _pad[39];
     livepatch_expectation_t expect;
 };
 typedef struct livepatch_func livepatch_func_t;
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/include/xen/livepatch.h xen-4.17.3+10-g091466ba55/xen/include/xen/livepatch.h
--- xen-4.17.2+76-ge1f9cb16e2/xen/include/xen/livepatch.h	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/include/xen/livepatch.h	2024-02-02 08:04:33.000000000 +0100
@@ -13,6 +13,9 @@
 
 #include <xen/elfstructs.h>
 #include <xen/errno.h> /* For -ENOSYS or -EOVERFLOW */
+
+#include <public/sysctl.h> /* For LIVEPATCH_OPAQUE_SIZE */
+
 #ifdef CONFIG_LIVEPATCH
 
 /*
@@ -51,6 +54,12 @@
     bool_t new_symbol;
 };
 
+struct livepatch_fstate {
+    unsigned int patch_offset;
+    enum livepatch_func_state applied;
+    uint8_t insn_buffer[LIVEPATCH_OPAQUE_SIZE];
+};
+
 int livepatch_op(struct xen_sysctl_livepatch_op *);
 void check_for_livepatch_work(void);
 unsigned long livepatch_symbols_lookup_by_name(const char *symname);
@@ -87,10 +96,11 @@
 int arch_livepatch_verify_func(const struct livepatch_func *func);
 
 static inline
-unsigned int livepatch_insn_len(const struct livepatch_func *func)
+unsigned int livepatch_insn_len(const struct livepatch_func *func,
+                                const struct livepatch_fstate *state)
 {
     if ( !func->new_addr )
-        return func->new_size - func->patch_offset;
+        return func->new_size - state->patch_offset;
 
     return ARCH_PATCH_INSN_SIZE;
 }
@@ -117,39 +127,43 @@
 int arch_livepatch_quiesce(void);
 void arch_livepatch_revive(void);
 
-void arch_livepatch_apply(struct livepatch_func *func);
-void arch_livepatch_revert(const struct livepatch_func *func);
+void arch_livepatch_apply(const struct livepatch_func *func,
+                          struct livepatch_fstate *state);
+void arch_livepatch_revert(const struct livepatch_func *func,
+                           struct livepatch_fstate *state);
 void arch_livepatch_post_action(void);
 
 void arch_livepatch_mask(void);
 void arch_livepatch_unmask(void);
 
-static inline void common_livepatch_apply(struct livepatch_func *func)
+static inline void common_livepatch_apply(const struct livepatch_func *func,
+                                          struct livepatch_fstate *state)
 {
     /* If the action has been already executed on this function, do nothing. */
-    if ( func->applied == LIVEPATCH_FUNC_APPLIED )
+    if ( state->applied == LIVEPATCH_FUNC_APPLIED )
     {
         printk(XENLOG_WARNING LIVEPATCH "%s: %s has been already applied before\n",
                 __func__, func->name);
         return;
     }
 
-    arch_livepatch_apply(func);
-    func->applied = LIVEPATCH_FUNC_APPLIED;
+    arch_livepatch_apply(func, state);
+    state->applied = LIVEPATCH_FUNC_APPLIED;
 }
 
-static inline void common_livepatch_revert(struct livepatch_func *func)
+static inline void common_livepatch_revert(const struct livepatch_func *func,
+                                           struct livepatch_fstate *state)
 {
     /* If the apply action hasn't been executed on this function, do nothing. */
-    if ( !func->old_addr || func->applied == LIVEPATCH_FUNC_NOT_APPLIED )
+    if ( !func->old_addr || state->applied == LIVEPATCH_FUNC_NOT_APPLIED )
     {
         printk(XENLOG_WARNING LIVEPATCH "%s: %s has not been applied before\n",
                 __func__, func->name);
         return;
     }
 
-    arch_livepatch_revert(func);
-    func->applied = LIVEPATCH_FUNC_NOT_APPLIED;
+    arch_livepatch_revert(func, state);
+    state->applied = LIVEPATCH_FUNC_NOT_APPLIED;
 }
 #else
 
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/include/xen/livepatch_payload.h xen-4.17.3+10-g091466ba55/xen/include/xen/livepatch_payload.h
--- xen-4.17.2+76-ge1f9cb16e2/xen/include/xen/livepatch_payload.h	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/include/xen/livepatch_payload.h	2024-02-02 08:04:33.000000000 +0100
@@ -52,7 +52,8 @@
     size_t ro_size;                      /* .. and its size (if any). */
     unsigned int pages;                  /* Total pages for [text,rw,ro]_addr */
     struct list_head applied_list;       /* Linked to 'applied_list'. */
-    struct livepatch_func *funcs;        /* The array of functions to patch. */
+    const struct livepatch_func *funcs;  /* The array of functions to patch. */
+    struct livepatch_fstate *fstate;     /* State of patched functions. */
     unsigned int nfuncs;                 /* Nr of functions to patch. */
     const struct livepatch_symbol *symtab; /* All symbols. */
     const char *strtab;                  /* Pointer to .strtab. */
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/Makefile xen-4.17.3+10-g091466ba55/xen/Makefile
--- xen-4.17.2+76-ge1f9cb16e2/xen/Makefile	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/Makefile	2024-02-02 08:04:33.000000000 +0100
@@ -6,7 +6,7 @@
 # All other places this is stored (eg. compile.h) should be autogenerated.
 export XEN_VERSION       = 4
 export XEN_SUBVERSION    = 17
-export XEN_EXTRAVERSION ?= .3-pre$(XEN_VENDORVERSION)
+export XEN_EXTRAVERSION ?= .4-pre$(XEN_VENDORVERSION)
 export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
 -include xen-version
 
@@ -392,6 +392,7 @@
 
 CFLAGS += -nostdinc -fno-builtin -fno-common
 CFLAGS += -Werror -Wredundant-decls -Wno-pointer-arith
+CFLAGS += -Wdeclaration-after-statement
 $(call cc-option-add,CFLAGS,CC,-Wvla)
 CFLAGS += -pipe -D__XEN__ -include $(srctree)/include/xen/config.h
 CFLAGS-$(CONFIG_DEBUG_INFO) += -g
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_action_hooks.c xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_action_hooks.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_action_hooks.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_action_hooks.c	2024-02-02 08:04:33.000000000 +0100
@@ -26,9 +26,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        func->applied = LIVEPATCH_FUNC_APPLIED;
+        fstate->applied = LIVEPATCH_FUNC_APPLIED;
         apply_cnt++;
 
         printk(KERN_DEBUG "%s: applying: %s\n", __func__, func->name);
@@ -47,9 +48,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        func->applied = LIVEPATCH_FUNC_NOT_APPLIED;
+        fstate->applied = LIVEPATCH_FUNC_NOT_APPLIED;
         revert_cnt++;
 
         printk(KERN_DEBUG "%s: reverting: %s\n", __func__, func->name);
@@ -68,7 +70,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         printk(KERN_DEBUG "%s: reverted: %s\n", __func__, func->name);
     }
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_action_hooks_marker.c xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_action_hooks_marker.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_action_hooks_marker.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_action_hooks_marker.c	2024-02-02 08:04:33.000000000 +0100
@@ -23,9 +23,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied == LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: pre applied: %s\n", __func__, func->name);
     }
 
@@ -42,9 +43,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        BUG_ON(func->applied != LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied != LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: post applied: %s\n", __func__, func->name);
     }
 
@@ -59,9 +61,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        BUG_ON(func->applied != LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied != LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: pre reverted: %s\n", __func__, func->name);
     }
 
@@ -78,9 +81,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied == LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: post reverted: %s\n", __func__, func->name);
     }
 
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_action_hooks_noapply.c xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_action_hooks_noapply.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_action_hooks_noapply.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_action_hooks_noapply.c	2024-02-02 08:04:33.000000000 +0100
@@ -25,9 +25,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied == LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: pre applied: %s\n", __func__, func->name);
     }
 
@@ -44,7 +45,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         apply_cnt++;
         printk(KERN_DEBUG "%s: applying: %s\n", __func__, func->name);
@@ -63,10 +64,11 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
         BUG_ON(apply_cnt != 1);
-        BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied == LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: post applied: %s\n", __func__, func->name);
     }
 
@@ -81,9 +83,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied == LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: pre reverted: %s\n", __func__, func->name);
     }
 
@@ -100,9 +103,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied == LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: post reverted: %s\n", __func__, func->name);
     }
 
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_action_hooks_nofunc.c xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_action_hooks_nofunc.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_action_hooks_nofunc.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_action_hooks_nofunc.c	2024-02-02 08:04:33.000000000 +0100
@@ -23,7 +23,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         apply_cnt++;
         printk(KERN_DEBUG "%s: applying: %s\n", __func__, func->name);
@@ -42,7 +42,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         revert_cnt++;
         printk(KERN_DEBUG "%s: reverting: %s\n", __func__, func->name);
@@ -61,7 +61,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         printk(KERN_DEBUG "%s: reverted: %s\n", __func__, func->name);
     }
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_action_hooks_norevert.c xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_action_hooks_norevert.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_action_hooks_norevert.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_action_hooks_norevert.c	2024-02-02 08:04:33.000000000 +0100
@@ -25,9 +25,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied == LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: pre applied: %s\n", __func__, func->name);
     }
 
@@ -44,9 +45,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        BUG_ON(func->applied != LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied != LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: post applied: %s\n", __func__, func->name);
     }
 
@@ -61,9 +63,10 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
-        BUG_ON(func->applied != LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied != LIVEPATCH_FUNC_APPLIED);
         printk(KERN_DEBUG "%s: pre reverted: %s\n", __func__, func->name);
     }
 
@@ -80,7 +83,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         revert_cnt++;
         printk(KERN_DEBUG "%s: reverting: %s\n", __func__, func->name);
@@ -99,16 +102,17 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
+        struct livepatch_fstate *fstate = &payload->fstate[i];
 
         BUG_ON(revert_cnt != 1);
-        BUG_ON(func->applied != LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied != LIVEPATCH_FUNC_APPLIED);
 
         /* Outside of quiesce zone: MAY TRIGGER HOST CRASH/UNDEFINED BEHAVIOR */
         arch_livepatch_quiesce();
         common_livepatch_revert(payload);
         arch_livepatch_revive();
-        BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
+        BUG_ON(fstate->applied == LIVEPATCH_FUNC_APPLIED);
 
         printk(KERN_DEBUG "%s: post reverted: %s\n", __func__, func->name);
     }
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_prepost_hooks.c xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_prepost_hooks.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_prepost_hooks.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_prepost_hooks.c	2024-02-02 08:04:33.000000000 +0100
@@ -30,7 +30,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         pre_apply_cnt++;
         printk(KERN_DEBUG "%s: applying: %s\n", __func__, func->name);
@@ -49,7 +49,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         post_apply_cnt++;
         printk(KERN_DEBUG "%s: applied: %s\n", __func__, func->name);
@@ -66,7 +66,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         pre_revert_cnt++;
         printk(KERN_DEBUG "%s: reverting: %s\n", __func__, func->name);
@@ -86,7 +86,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         post_revert_cnt++;
         printk(KERN_DEBUG "%s: reverted: %s\n", __func__, func->name);
diff -Nru xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_prepost_hooks_fail.c xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_prepost_hooks_fail.c
--- xen-4.17.2+76-ge1f9cb16e2/xen/test/livepatch/xen_prepost_hooks_fail.c	2023-11-23 12:24:12.000000000 +0100
+++ xen-4.17.3+10-g091466ba55/xen/test/livepatch/xen_prepost_hooks_fail.c	2024-02-02 08:04:33.000000000 +0100
@@ -24,7 +24,7 @@
 
     for (i = 0; i < payload->nfuncs; i++)
     {
-        struct livepatch_func *func = &payload->funcs[i];
+        const struct livepatch_func *func = &payload->funcs[i];
 
         printk(KERN_DEBUG "%s: pre applying: %s\n", __func__, func->name);
     }

Attachment: signature.asc
Description: This is a digitally signed message part.


--- End Message ---
--- Begin Message ---
Version: 12.5

The upload requested in this bug has been released as part of 12.5.

--- End Message ---

Reply to: