Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package xen for openSUSE:Factory checked in at 2025-01-07 20:50:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/xen (Old) and /work/SRC/openSUSE:Factory/.xen.new.1881 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "xen" Tue Jan 7 20:50:13 2025 rev:354 rq:1235233 version:4.20.0_02 Changes: -------- --- /work/SRC/openSUSE:Factory/xen/xen.changes 2024-12-05 17:05:59.954956164 +0100 +++ /work/SRC/openSUSE:Factory/.xen.new.1881/xen.changes 2025-01-07 20:50:26.633530530 +0100 @@ -1,0 +2,44 @@ +Mon Jan 6 06:01:11 MST 2025 - carnold@suse.com + +- Update to Xen 4.20.0 pre-release (jsc#PED-8907) + xen-4.20.0-testing-src.tar.bz2 +- New Features + * On Arm: + - Experimental support for Armv8-R. + - Support for NXP S32G3 Processors Family and NXP LINFlexD UART driver. + - Basic handling for SCMI requests over SMC using Shared Memory, by allowing + forwarding the calls to EL3 FW if coming from hwdom. + - Support for LLC (Last Level Cache) coloring. + * On x86: + - xl suspend/resume subcommands. + - Support for SRSO_U/S_NO and SRSO_MSR_FIX +- Changed Features + * Fixed blkif protocol specification for sector sizes different than 512b. + * The dombuilder in libxenguest no longer un-gzips secondary modules, instead + leaving this to the guest kernel to do in guest context. + * On x86: + - Prefer ACPI reboot over UEFI ResetSystem() run time service call. + - Switched the xAPIC flat driver to use physical destination mode for external + interrupts instead of logical destination mode. +- Removed Features + * On x86: + - Support for running on Xeon Phi processors. + - Removed the `ucode=allow-same` command line option. + - Removed x2APIC Cluster Mode for external interrupts. x2APIC Physical and + Mixed Modes are still available. +- Dropped patches + xsa466.patch + +------------------------------------------------------------------- +Wed Dec 11 11:11:11 UTC 2024 - ohering@suse.de + +- Move /etc/bash_completion.d/xl back to %_datadir/bash-completion/completions + +------------------------------------------------------------------- +Mon Dec 9 10:13:51 MST 2024 - carnold@suse.com + +- bsc#1234282 - VUL-0: xen: XSA-466: Xen hypercall page unsafe + against speculative attacks + xsa466.patch + +------------------------------------------------------------------- Old: ---- xen-4.19.1-testing-src.tar.bz2 New: ---- xen-4.20.0-testing-src.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ xen.spec ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:31.053713332 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:31.085714656 +0100 @@ -1,7 +1,7 @@ # # spec file for package xen # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -30,7 +30,7 @@ Name: xen ExclusiveArch: %ix86 x86_64 aarch64 -%define xen_build_dir xen-4.19.1-testing +%define xen_build_dir xen-4.20.0-testing # %define with_gdbsx 0 %define with_dom0_support 0 @@ -124,12 +124,12 @@ BuildRequires: python-rpm-macros Provides: installhint(reboot-needed) -Version: 4.19.1_02 +Version: 4.20.0_02 Release: 0 Summary: Xen Virtualization: Hypervisor (aka VMM aka Microkernel) License: GPL-2.0-only Group: System/Kernel -Source0: xen-4.19.1-testing-src.tar.bz2 +Source0: xen-4.20.0-testing-src.tar.bz2 Source1: stubdom.tar.bz2 Source2: mini-os.tar.bz2 Source9: xen.changes @@ -512,6 +512,7 @@ DESTDIR=%{buildroot} \ SYSCONFIG_DIR=%{_fillupdir} \ PKG_INSTALLDIR=%{_libdir}/pkgconfig \ + BASH_COMPLETION_DIR=%{_datadir}/bash-completion/completions \ %{?_smp_mflags} \ install find %{buildroot} -ls @@ -940,7 +941,7 @@ rm -rf %{buildroot}/usr/sbin rm -rf %{buildroot}/etc/xen rm -rf %{buildroot}/var -rm -f %{buildroot}/%{_sysconfdir}/bash_completion.d/xl +rm -f %{buildroot}/%{_datadir}/bash-completion/completions/xl rm -f %{buildroot}/%{_sysconfdir}/init.d/xen* rm -f %{buildroot}/%{_bindir}/*trace* rm -f %{buildroot}/%{_bindir}/vchan-socket-proxy @@ -1076,7 +1077,7 @@ %exclude %{_unitdir}/%{name}-vcpu-watch.service %exclude %{_unitdir}/xendomains-wait-disks.service %config %{with_systemd_modules_load} -/etc/bash_completion.d/xl +%{_datadir}/bash-completion/completions/xl %dir %{_libdir}/python%{pyver}/site-packages/grub %dir %{_libdir}/python%{pyver}/site-packages/xen %dir %{_libdir}/python%{pyver}/site-packages/xen/lowlevel ++++++ build-python3-conversion.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:32.193760480 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:32.229761969 +0100 @@ -136,54 +136,4 @@ import re,sys -Index: xen-4.19.0-testing/tools/misc/xensymoops -=================================================================== ---- xen-4.19.0-testing.orig/tools/misc/xensymoops -+++ xen-4.19.0-testing/tools/misc/xensymoops -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/python3 - - # An oops analyser for Xen - # Usage: xensymoops path-to-xen.s < oops-message -@@ -43,12 +43,12 @@ def read_oops(): - return (eip_addr, stack_addresses) - - def usage(): -- print >> sys.stderr, """Usage: %s path-to-asm < oops-msg -+ print("""Usage: %s path-to-asm < oops-msg - The oops message should be fed to the standard input. The - command-line argument specifies the path to the Xen assembly dump - produced by \"make debug\". The location of EIP and the backtrace - will be output to standard output. -- """ % sys.argv[0] -+ """ % sys.argv[0], file=sys.stderr) - sys.exit() - - ##### main -@@ -99,7 +99,7 @@ while True: - - # if this address was seen as a potential code address in the backtrace then - # record it in the backtrace list -- if stk_addrs.has_key(address): -+ if address in stk_addrs: - backtrace.append((stk_addrs[address], address, func)) - - # if this was the address that EIP... -@@ -107,12 +107,12 @@ while True: - eip_func = func - - --print "EIP %s in function %s" % (eip_addr, eip_func) --print "Backtrace:" -+print("EIP %s in function %s" % (eip_addr, eip_func)) -+print("Backtrace:") - - # sorting will order primarily by the first element of each tuple, - # i.e. the order in the original oops - backtrace.sort() - - for (i, a, f) in backtrace: -- print "%s in function %s" % ( a, f ) -+ print("%s in function %s" % ( a, f )) ++++++ libxc-sr-LIBXL_HAVE_DOMAIN_SUSPEND_PROPS.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:32.553775369 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:32.585776693 +0100 @@ -20,7 +20,7 @@ --- a/tools/include/libxl.h +++ b/tools/include/libxl.h -@@ -1850,13 +1850,28 @@ static inline int libxl_retrieve_domain_ +@@ -1855,13 +1855,28 @@ static inline int libxl_retrieve_domain_ libxl_retrieve_domain_configuration_0x041200 #endif ++++++ libxc-sr-abort_if_busy.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:32.725782483 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:32.761783972 +0100 @@ -53,7 +53,7 @@ =item B<remus> [I<OPTIONS>] I<domain-id> I<host> --- a/tools/include/libxl.h +++ b/tools/include/libxl.h -@@ -1863,6 +1863,7 @@ typedef struct { +@@ -1868,6 +1868,7 @@ typedef struct { } libxl_domain_suspend_suse_properties; #define LIBXL_SUSPEND_DEBUG 1 #define LIBXL_SUSPEND_LIVE 2 ++++++ libxc-sr-max_iters.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:32.913790258 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:32.957792078 +0100 @@ -46,7 +46,7 @@ =item B<remus> [I<OPTIONS>] I<domain-id> I<host> --- a/tools/include/libxl.h +++ b/tools/include/libxl.h -@@ -1858,6 +1858,7 @@ static inline int libxl_retrieve_domain_ +@@ -1863,6 +1863,7 @@ static inline int libxl_retrieve_domain_ typedef struct { uint32_t flags; /* LIBXL_SUSPEND_* */ ++++++ libxc-sr-min_remaining.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:33.077797041 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:33.113798530 +0100 @@ -51,7 +51,7 @@ =item B<remus> [I<OPTIONS>] I<domain-id> I<host> --- a/tools/include/libxl.h +++ b/tools/include/libxl.h -@@ -1859,6 +1859,7 @@ static inline int libxl_retrieve_domain_ +@@ -1864,6 +1864,7 @@ static inline int libxl_retrieve_domain_ typedef struct { uint32_t flags; /* LIBXL_SUSPEND_* */ uint32_t max_iters; ++++++ libxc-sr-readv_exact.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:33.333807629 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:33.389809945 +0100 @@ -19,7 +19,7 @@ --- a/tools/libs/ctrl/xc_private.c +++ b/tools/libs/ctrl/xc_private.c -@@ -699,8 +699,23 @@ int write_exact(int fd, const void *data +@@ -633,8 +633,23 @@ int write_exact(int fd, const void *data #if defined(__MINIOS__) /* @@ -44,7 +44,7 @@ int writev_exact(int fd, const struct iovec *iov, int iovcnt) { int rc, i; -@@ -715,6 +730,46 @@ int writev_exact(int fd, const struct io +@@ -649,6 +664,46 @@ int writev_exact(int fd, const struct io return 0; } #else @@ -93,7 +93,7 @@ struct iovec *local_iov = NULL; --- a/tools/libs/ctrl/xc_private.h +++ b/tools/libs/ctrl/xc_private.h -@@ -389,6 +389,7 @@ int xc_flush_mmu_updates(xc_interface *x +@@ -382,6 +382,7 @@ int xc_flush_mmu_updates(xc_interface *x /* Return 0 on success; -1 on error setting errno. */ int read_exact(int fd, void *data, size_t size); /* EOF => -1, errno=0 */ ++++++ libxl.LIBXL_HOTPLUG_TIMEOUT.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:33.609819044 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:33.633820036 +0100 @@ -85,7 +85,7 @@ --- a/tools/libs/light/libxl_create.c +++ b/tools/libs/light/libxl_create.c -@@ -1345,6 +1345,7 @@ static void initiate_domain_create(libxl +@@ -1363,6 +1363,7 @@ static void initiate_domain_create(libxl * build info around just to know if the domain has a device model or not. */ store_libxl_entry(gc, domid, &d_config->b_info); @@ -294,7 +294,7 @@ /* private */ libxl__ev_time time; libxl__ev_child child; -@@ -4892,6 +4895,9 @@ _hidden int userlookup_helper_getpwuid(l +@@ -4899,6 +4902,9 @@ _hidden int userlookup_helper_getpwuid(l #endif ++++++ libxl.add-option-to-disable-disk-cache-flushes-in-qdisk.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:33.725823841 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:33.749824833 +0100 @@ -7,10 +7,10 @@ tools/libxl/libxlu_disk_l.l | 1 + 5 files changed, 18 insertions(+), 1 deletion(-) -Index: xen-4.19.0-testing/docs/man/xl-disk-configuration.5.pod.in +Index: xen-4.20.0-testing/docs/man/xl-disk-configuration.5.pod.in =================================================================== ---- xen-4.19.0-testing.orig/docs/man/xl-disk-configuration.5.pod.in -+++ xen-4.19.0-testing/docs/man/xl-disk-configuration.5.pod.in +--- xen-4.20.0-testing.orig/docs/man/xl-disk-configuration.5.pod.in ++++ xen-4.20.0-testing/docs/man/xl-disk-configuration.5.pod.in @@ -339,6 +339,32 @@ No discard @@ -44,10 +44,10 @@ =back An advisory setting for the backend driver, specifying whether to -Index: xen-4.19.0-testing/tools/include/libxl.h +Index: xen-4.20.0-testing/tools/include/libxl.h =================================================================== ---- xen-4.19.0-testing.orig/tools/include/libxl.h -+++ xen-4.19.0-testing/tools/include/libxl.h +--- xen-4.20.0-testing.orig/tools/include/libxl.h ++++ xen-4.20.0-testing/tools/include/libxl.h @@ -603,6 +603,21 @@ #define LIBXL_HAVE_P9_ADD 1 @@ -70,10 +70,10 @@ * libxl ABI compatibility * * The only guarantee which libxl makes regarding ABI compatibility -Index: xen-4.19.0-testing/tools/libs/light/libxl_disk.c +Index: xen-4.20.0-testing/tools/libs/light/libxl_disk.c =================================================================== ---- xen-4.19.0-testing.orig/tools/libs/light/libxl_disk.c -+++ xen-4.19.0-testing/tools/libs/light/libxl_disk.c +--- xen-4.20.0-testing.orig/tools/libs/light/libxl_disk.c ++++ xen-4.20.0-testing/tools/libs/light/libxl_disk.c @@ -464,6 +464,8 @@ static void device_disk_add(libxl__egc * flexarray_append_pair(back, "discard-enable", libxl_defbool_val(disk->discard_enable) ? @@ -83,10 +83,10 @@ flexarray_append(back, "specification"); flexarray_append(back, libxl__device_disk_string_of_specification(disk->specification)); if (disk->specification == LIBXL_DISK_SPECIFICATION_VIRTIO) { -Index: xen-4.19.0-testing/tools/libs/light/libxl_dm.c +Index: xen-4.20.0-testing/tools/libs/light/libxl_dm.c =================================================================== ---- xen-4.19.0-testing.orig/tools/libs/light/libxl_dm.c -+++ xen-4.19.0-testing/tools/libs/light/libxl_dm.c +--- xen-4.20.0-testing.orig/tools/libs/light/libxl_dm.c ++++ xen-4.20.0-testing/tools/libs/light/libxl_dm.c @@ -1019,14 +1019,27 @@ enum { LIBXL__COLO_SECONDARY, }; @@ -164,7 +164,7 @@ break; default: abort(); -@@ -1997,8 +2012,8 @@ static int libxl__build_device_model_arg +@@ -2003,8 +2018,8 @@ static int libxl__build_device_model_arg return ERROR_INVAL; } flexarray_vappend(dm_args, "-drive", @@ -175,10 +175,10 @@ "-device", GCSPRINTF("ide-hd,bus=ahci0.%d,unit=0,drive=ahcidisk-%d", disk, disk), NULL); continue; -Index: xen-4.19.0-testing/tools/libs/util/libxlu_disk.c +Index: xen-4.20.0-testing/tools/libs/util/libxlu_disk.c =================================================================== ---- xen-4.19.0-testing.orig/tools/libs/util/libxlu_disk.c -+++ xen-4.19.0-testing/tools/libs/util/libxlu_disk.c +--- xen-4.20.0-testing.orig/tools/libs/util/libxlu_disk.c ++++ xen-4.20.0-testing/tools/libs/util/libxlu_disk.c @@ -78,6 +78,8 @@ int xlu_disk_parse(XLU_Config *cfg, if (!disk->pdev_path || !strcmp(disk->pdev_path, "")) disk->format = LIBXL_DISK_FORMAT_EMPTY; @@ -188,10 +188,10 @@ if (!disk->vdev) { xlu__disk_err(&dpc,0, "no vdev specified"); -Index: xen-4.19.0-testing/tools/libs/util/libxlu_disk_i.h +Index: xen-4.20.0-testing/tools/libs/util/libxlu_disk_i.h =================================================================== ---- xen-4.19.0-testing.orig/tools/libs/util/libxlu_disk_i.h -+++ xen-4.19.0-testing/tools/libs/util/libxlu_disk_i.h +--- xen-4.20.0-testing.orig/tools/libs/util/libxlu_disk_i.h ++++ xen-4.20.0-testing/tools/libs/util/libxlu_disk_i.h @@ -10,7 +10,7 @@ typedef struct { void *scanner; YY_BUFFER_STATE buf; @@ -201,10 +201,10 @@ const char *spec; } DiskParseContext; -Index: xen-4.19.0-testing/tools/libs/util/libxlu_disk_l.l +Index: xen-4.20.0-testing/tools/libs/util/libxlu_disk_l.l =================================================================== ---- xen-4.19.0-testing.orig/tools/libs/util/libxlu_disk_l.l -+++ xen-4.19.0-testing/tools/libs/util/libxlu_disk_l.l +--- xen-4.20.0-testing.orig/tools/libs/util/libxlu_disk_l.l ++++ xen-4.20.0-testing/tools/libs/util/libxlu_disk_l.l @@ -216,6 +216,7 @@ colo-port=[^,]*,? { STRIP(','); setcolop colo-export=[^,]*,? { STRIP(','); SAVESTRING("colo-export", colo_export, FROMEQUALS); } active-disk=[^,]*,? { STRIP(','); SAVESTRING("active-disk", active_disk, FROMEQUALS); } ++++++ mini-os.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extras/mini-os-remote/Config.mk new/extras/mini-os-remote/Config.mk --- old/extras/mini-os-remote/Config.mk 2024-12-04 16:30:52.000000000 +0100 +++ new/extras/mini-os-remote/Config.mk 2025-01-06 14:00:36.000000000 +0100 @@ -193,6 +193,15 @@ CONFIG-n += CONFIG_TPM_TIS CONFIG-n += CONFIG_TPMBACK CONFIG-n += CONFIG_BALLOON +CONFIG-n += CONFIG_LIBXENCALL +CONFIG-n += CONFIG_LIBXENCTRL +CONFIG-n += CONFIG_LIBXENDEVICEMODEL +CONFIG-n += CONFIG_LIBXENEVTCHN +CONFIG-n += CONFIG_LIBXENFOREIGNMEMORY +CONFIG-n += CONFIG_LIBXENGNTTAB +CONFIG-n += CONFIG_LIBXENGUEST +CONFIG-n += CONFIG_LIBXENTOOLCORE +CONFIG-n += CONFIG_LIBXENTOOLLOG # Setting CONFIG_USE_XEN_CONSOLE copies all print output to the Xen emergency # console apart of standard dom0 handled console. CONFIG-n += CONFIG_USE_XEN_CONSOLE @@ -201,8 +210,6 @@ else CONFIG-n += CONFIG_PARAVIRT endif -# Support legacy CONFIG_XC value -CONFIG_XC ?= $(libc) CONFIG-$(lwip) += CONFIG_LWIP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extras/mini-os-remote/Makefile new/extras/mini-os-remote/Makefile --- old/extras/mini-os-remote/Makefile 2024-12-04 16:30:52.000000000 +0100 +++ new/extras/mini-os-remote/Makefile 2025-01-06 14:00:36.000000000 +0100 @@ -123,23 +123,39 @@ OBJS := $(filter-out $(OBJ_DIR)/lwip%.o $(LWO), $(OBJS)) ifeq ($(libc),y) -ifeq ($(CONFIG_XC),y) +ifeq ($(CONFIG_LIBXENTOOLCORE),y) APP_LDLIBS += -L$(TOOLCORE_PATH) -whole-archive -lxentoolcore -no-whole-archive LIBS += $(TOOLCORE_PATH)/libxentoolcore.a +endif +ifeq ($(CONFIG_LIBXENTOOLLOG),y) APP_LDLIBS += -L$(TOOLLOG_PATH) -whole-archive -lxentoollog -no-whole-archive LIBS += $(TOOLLOG_PATH)/libxentoollog.a +endif +ifeq ($(CONFIG_LIBXENEVTCHN),y) APP_LDLIBS += -L$(EVTCHN_PATH) -whole-archive -lxenevtchn -no-whole-archive LIBS += $(EVTCHN_PATH)/libxenevtchn.a +endif +ifeq ($(CONFIG_LIBXENGNTTAB),y) APP_LDLIBS += -L$(GNTTAB_PATH) -whole-archive -lxengnttab -no-whole-archive LIBS += $(GNTTAB_PATH)/libxengnttab.a +endif +ifeq ($(CONFIG_LIBXENCALL),y) APP_LDLIBS += -L$(CALL_PATH) -whole-archive -lxencall -no-whole-archive LIBS += $(CALL_PATH)/libxencall.a +endif +ifeq ($(CONFIG_LIBXENFOREIGNMEMORY),y) APP_LDLIBS += -L$(FOREIGNMEMORY_PATH) -whole-archive -lxenforeignmemory -no-whole-archive LIBS += $(FOREIGNMEMORY_PATH)/libxenforeignmemory.a +endif +ifeq ($(CONFIG_LIBXENDEVICEMODEL),y) APP_LDLIBS += -L$(DEVICEMODEL_PATH) -whole-archive -lxendevicemodel -no-whole-archive LIBS += $(DEVICEMODEL_PATH)/libxendevicemodel.a +endif +ifeq ($(CONFIG_LIBXENGUEST),y) APP_LDLIBS += -L$(GUEST_PATH) -whole-archive -lxenguest -no-whole-archive LIBS += $(GUEST_PATH)/libxenguest.a +endif +ifeq ($(CONFIG_LIBXENCTRL),y) APP_LDLIBS += -L$(CTRL_PATH) -whole-archive -lxenctrl -no-whole-archive LIBS += $(CTRL_PATH)/libxenctrl.a endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extras/mini-os-remote/arch/x86/mm.c new/extras/mini-os-remote/arch/x86/mm.c --- old/extras/mini-os-remote/arch/x86/mm.c 2024-12-04 16:30:52.000000000 +0100 +++ new/extras/mini-os-remote/arch/x86/mm.c 2025-01-06 14:00:36.000000000 +0100 @@ -126,20 +126,30 @@ } #endif +static const struct { + unsigned int shift; + unsigned int entries; + pgentry_t prot; +} ptdata[PAGETABLE_LEVELS + 1] = { + { 0, 0, 0 }, + { L1_PAGETABLE_SHIFT, L1_PAGETABLE_ENTRIES, L1_PROT }, + { L2_PAGETABLE_SHIFT, L2_PAGETABLE_ENTRIES, L2_PROT }, + { L3_PAGETABLE_SHIFT, L3_PAGETABLE_ENTRIES, L3_PROT }, +#if defined(__x86_64__) + { L4_PAGETABLE_SHIFT, L4_PAGETABLE_ENTRIES, L4_PROT }, +#endif +}; + +static inline unsigned int idx_from_va_lvl(unsigned long va, unsigned int lvl) +{ + return (va >> ptdata[lvl].shift) & (ptdata[lvl].entries - 1); +} + /* * Make pt_pfn a new 'level' page table frame and hook it into the page * table at offset in previous level MFN (pref_l_mfn). pt_pfn is a guest * PFN. */ -static pgentry_t pt_prot[PAGETABLE_LEVELS] = { - L1_PROT, - L2_PROT, - L3_PROT, -#if defined(__x86_64__) - L4_PROT, -#endif -}; - static void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn, unsigned long offset, unsigned long level) { @@ -171,7 +181,7 @@ mmu_updates[0].ptr = (tab[l2_table_offset(pt_page)] & PAGE_MASK) + sizeof(pgentry_t) * l1_table_offset(pt_page); mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | - (pt_prot[level - 1] & ~_PAGE_RW); + (ptdata[level].prot & ~_PAGE_RW); if ( (rc = HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF)) < 0 ) { @@ -184,7 +194,7 @@ mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset; mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | - pt_prot[level]; + ptdata[level + 1].prot; if ( (rc = HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF)) < 0 ) { @@ -193,12 +203,92 @@ } #else tab = mfn_to_virt(prev_l_mfn); - tab[offset] = (*pt_pfn << PAGE_SHIFT) | pt_prot[level]; + tab[offset] = (*pt_pfn << PAGE_SHIFT) | ptdata[level + 1].prot; #endif *pt_pfn += 1; } +#ifdef CONFIG_PARAVIRT +static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1]; +#endif + +/* + * Walk recursively through all PTEs calling a specified function. The function + * is allowed to change the PTE, the walker will follow the new value. + * The walk will cover the virtual address range [from_va .. to_va]. + * The supplied function will be called with the following parameters: + * va: base virtual address of the area covered by the current PTE + * lvl: page table level of the PTE (1 = lowest level, PAGETABLE_LEVELS = + * PTE in page table addressed by %cr3) + * is_leaf: true if PTE doesn't address another page table (it is either at + * level 1, or invalid, or has its PSE bit set) + * pte: address of the PTE + * par: parameter, passed to walk_pt() by caller + * Return value of func() being non-zero will terminate walk_pt(), walk_pt() + * will return that value in this case, zero else. + */ +static int walk_pt(unsigned long from_va, unsigned long to_va, + int (func)(unsigned long va, unsigned int lvl, + bool is_leaf, pgentry_t *pte, void *par), + void *par) +{ + unsigned int lvl = PAGETABLE_LEVELS; + unsigned int ptindex[PAGETABLE_LEVELS + 1]; + unsigned long va = round_pgdown(from_va); + unsigned long va_lvl; + pgentry_t *tab[PAGETABLE_LEVELS + 1]; + pgentry_t *pte; + bool is_leaf; + int ret; + + /* Start at top level page table. */ + tab[lvl] = pt_base; + ptindex[lvl] = idx_from_va_lvl(va, lvl); + + while ( va < (to_va | (PAGE_SIZE - 1)) ) + { + pte = tab[lvl] + ptindex[lvl]; + is_leaf = (lvl == L1_FRAME) || (*pte & _PAGE_PSE) || + !(*pte & _PAGE_PRESENT); + va_lvl = va & ~((1UL << ptdata[lvl].shift) - 1); + ret = func(va_lvl, lvl, is_leaf, pte, par); + if ( ret ) + return ret; + + /* PTE might have been modified by func(), reevaluate leaf state. */ + is_leaf = (lvl == L1_FRAME) || (*pte & _PAGE_PSE) || + !(*pte & _PAGE_PRESENT); + + if ( is_leaf ) + { + /* Reached a leaf PTE. Advance to next page. */ + va += 1UL << ptdata[lvl].shift; + ptindex[lvl]++; + + /* Check for the need to traverse up again. */ + while ( ptindex[lvl] == ptdata[lvl].entries ) + { + /* End of virtual address space? */ + if ( lvl == PAGETABLE_LEVELS ) + return 0; + /* Reached end of current page table, one level up. */ + lvl++; + ptindex[lvl]++; + } + } + else + { + /* Not a leaf, walk one level down. */ + lvl--; + tab[lvl] = mfn_to_virt(pte_to_mfn(*pte)); + ptindex[lvl] = idx_from_va_lvl(va, lvl); + } + } + + return 0; +} + /* * Build the initial pagetable. */ @@ -210,7 +300,6 @@ unsigned long pt_mfn = pfn_to_mfn(virt_to_pfn(pt_base)); unsigned long offset; #ifdef CONFIG_PARAVIRT - static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1]; int count = 0; int rc; #endif @@ -314,128 +403,108 @@ * Mark portion of the address space read only. */ extern struct shared_info shared_info; -static void set_readonly(void *text, void *etext) -{ - unsigned long start_address = - ((unsigned long) text + PAGE_SIZE - 1) & PAGE_MASK; - unsigned long end_address = (unsigned long) etext; - pgentry_t *tab = pt_base, page; - unsigned long mfn = pfn_to_mfn(virt_to_pfn(pt_base)); - unsigned long offset; - unsigned long page_size = PAGE_SIZE; + +struct set_readonly_par { + unsigned long etext; #ifdef CONFIG_PARAVIRT - static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1]; - int count = 0; - int rc; + unsigned int count; #endif +}; - printk("setting %p-%p readonly\n", text, etext); +static int set_readonly_func(unsigned long va, unsigned int lvl, bool is_leaf, + pgentry_t *pte, void *par) +{ + struct set_readonly_par *ro = par; - while ( start_address + page_size <= end_address ) - { - tab = pt_base; - mfn = pfn_to_mfn(virt_to_pfn(pt_base)); + if ( !is_leaf ) + return 0; -#if defined(__x86_64__) - offset = l4_table_offset(start_address); - page = tab[offset]; - mfn = pte_to_mfn(page); - tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT); -#endif - offset = l3_table_offset(start_address); - page = tab[offset]; - mfn = pte_to_mfn(page); - tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT); - offset = l2_table_offset(start_address); - if ( !(tab[offset] & _PAGE_PSE) ) - { - page = tab[offset]; - mfn = pte_to_mfn(page); - tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT); + if ( va + (1UL << ptdata[lvl].shift) > ro->etext ) + return 1; - offset = l1_table_offset(start_address); - } + if ( va == (unsigned long)&shared_info ) + { + printk("skipped %lx\n", va); + return 0; + } - if ( start_address != (unsigned long)&shared_info ) - { #ifdef CONFIG_PARAVIRT - mmu_updates[count].ptr = - ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset; - mmu_updates[count].val = tab[offset] & ~_PAGE_RW; - count++; + mmu_updates[ro->count].ptr = virt_to_mach(pte); + mmu_updates[ro->count].val = *pte & ~_PAGE_RW; + ro->count++; + + if ( ro->count == L1_PAGETABLE_ENTRIES ) + { + if ( HYPERVISOR_mmu_update(mmu_updates, ro->count, NULL, + DOMID_SELF) < 0 ) + BUG(); + ro->count = 0; + } #else - tab[offset] &= ~_PAGE_RW; + *pte &= ~_PAGE_RW; #endif - } - else - printk("skipped %lx\n", start_address); - start_address += page_size; + return 0; +} #ifdef CONFIG_PARAVIRT - if ( count == L1_PAGETABLE_ENTRIES || - start_address + page_size > end_address ) - { - rc = HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF); - if ( rc < 0 ) - { - printk("ERROR: set_readonly(): PTE could not be updated\n"); - do_exit(); - } - count = 0; - } +static void tlb_flush(void) +{ + mmuext_op_t op = { .cmd = MMUEXT_TLB_FLUSH_ALL }; + int count; + + HYPERVISOR_mmuext_op(&op, 1, &count, DOMID_SELF); +} #else - if ( start_address == (1UL << L2_PAGETABLE_SHIFT) ) - page_size = 1UL << L2_PAGETABLE_SHIFT; +static void tlb_flush(void) +{ + write_cr3((unsigned long)pt_base); +} #endif - } + +static void set_readonly(void *text, void *etext) +{ + struct set_readonly_par setro = { .etext = (unsigned long)etext }; + unsigned long start_address = PAGE_ALIGN((unsigned long)text); + + printk("setting %p-%p readonly\n", text, etext); + walk_pt(start_address, setro.etext, set_readonly_func, &setro); #ifdef CONFIG_PARAVIRT - { - mmuext_op_t op = { - .cmd = MMUEXT_TLB_FLUSH_ALL, - }; - int count; - HYPERVISOR_mmuext_op(&op, 1, &count, DOMID_SELF); - } -#else - write_cr3((unsigned long)pt_base); + if ( setro.count && + HYPERVISOR_mmu_update(mmu_updates, setro.count, NULL, DOMID_SELF) < 0) + BUG(); #endif + + tlb_flush(); } /* * get the PTE for virtual address va if it exists. Otherwise NULL. */ -static pgentry_t *get_pgt(unsigned long va) +static int get_pgt_func(unsigned long va, unsigned int lvl, bool is_leaf, + pgentry_t *pte, void *par) { - unsigned long mfn; - pgentry_t *tab; - unsigned offset; + pgentry_t **result; - tab = pt_base; - mfn = virt_to_mfn(pt_base); + if ( !(*pte & _PAGE_PRESENT) && lvl > L1_FRAME ) + return -1; -#if defined(__x86_64__) - offset = l4_table_offset(va); - if ( !(tab[offset] & _PAGE_PRESENT) ) - return NULL; - mfn = pte_to_mfn(tab[offset]); - tab = mfn_to_virt(mfn); -#endif - offset = l3_table_offset(va); - if ( !(tab[offset] & _PAGE_PRESENT) ) - return NULL; - mfn = pte_to_mfn(tab[offset]); - tab = mfn_to_virt(mfn); - offset = l2_table_offset(va); - if ( !(tab[offset] & _PAGE_PRESENT) ) - return NULL; - if ( tab[offset] & _PAGE_PSE ) - return &tab[offset]; - mfn = pte_to_mfn(tab[offset]); - tab = mfn_to_virt(mfn); - offset = l1_table_offset(va); - return &tab[offset]; + if ( lvl > L1_FRAME && !(*pte & _PAGE_PSE) ) + return 0; + + result = par; + *result = pte; + + return 0; +} + +static pgentry_t *get_pgt(unsigned long va) +{ + pgentry_t *tab = NULL; + + walk_pt(va, va, get_pgt_func, &tab); + return tab; } @@ -443,57 +512,45 @@ * return a valid PTE for a given virtual address. If PTE does not exist, * allocate page-table pages. */ -pgentry_t *need_pgt(unsigned long va) +static int need_pgt_func(unsigned long va, unsigned int lvl, bool is_leaf, + pgentry_t *pte, void *par) { + pgentry_t **result = par; unsigned long pt_mfn; - pgentry_t *tab; unsigned long pt_pfn; - unsigned offset; + unsigned int idx; - tab = pt_base; - pt_mfn = virt_to_mfn(pt_base); + if ( !is_leaf ) + return 0; -#if defined(__x86_64__) - offset = l4_table_offset(va); - if ( !(tab[offset] & _PAGE_PRESENT) ) - { - pt_pfn = virt_to_pfn(alloc_page()); - if ( !pt_pfn ) - return NULL; - new_pt_frame(&pt_pfn, pt_mfn, offset, L3_FRAME); - } - ASSERT(tab[offset] & _PAGE_PRESENT); - pt_mfn = pte_to_mfn(tab[offset]); - tab = mfn_to_virt(pt_mfn); -#endif - offset = l3_table_offset(va); - if ( !(tab[offset] & _PAGE_PRESENT) ) + if ( lvl == L1_FRAME || (*pte & _PAGE_PRESENT) ) { - pt_pfn = virt_to_pfn(alloc_page()); - if ( !pt_pfn ) - return NULL; - new_pt_frame(&pt_pfn, pt_mfn, offset, L2_FRAME); + /* + * The PTE is not addressing a page table (is_leaf is true). If we are + * either at the lowest level or we have a valid large page, we don't + * need to allocate a page table. + */ + ASSERT(lvl == L1_FRAME || (*pte & _PAGE_PSE)); + *result = pte; + return 1; } - ASSERT(tab[offset] & _PAGE_PRESENT); - pt_mfn = pte_to_mfn(tab[offset]); - tab = mfn_to_virt(pt_mfn); - offset = l2_table_offset(va); - if ( !(tab[offset] & _PAGE_PRESENT) ) - { - pt_pfn = virt_to_pfn(alloc_page()); - if ( !pt_pfn ) - return NULL; - new_pt_frame(&pt_pfn, pt_mfn, offset, L1_FRAME); - } - ASSERT(tab[offset] & _PAGE_PRESENT); - if ( tab[offset] & _PAGE_PSE ) - return &tab[offset]; - pt_mfn = pte_to_mfn(tab[offset]); - tab = mfn_to_virt(pt_mfn); + pt_mfn = virt_to_mfn(pte); + pt_pfn = virt_to_pfn(alloc_page()); + if ( !pt_pfn ) + return -1; + idx = idx_from_va_lvl(va, lvl); + new_pt_frame(&pt_pfn, pt_mfn, idx, lvl - 1); + + return 0; +} + +pgentry_t *need_pgt(unsigned long va) +{ + pgentry_t *tab = NULL; - offset = l1_table_offset(va); - return &tab[offset]; + walk_pt(va, va, need_pgt_func, &tab); + return tab; } EXPORT_SYMBOL(need_pgt); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extras/mini-os-remote/arch/x86/sched.c new/extras/mini-os-remote/arch/x86/sched.c --- old/extras/mini-os-remote/arch/x86/sched.c 2024-12-04 16:30:52.000000000 +0100 +++ new/extras/mini-os-remote/arch/x86/sched.c 2025-01-06 14:00:36.000000000 +0100 @@ -60,16 +60,10 @@ unsigned long *bottom = (unsigned long *)(thread->stack + STACK_SIZE); unsigned long *pointer = (unsigned long *)thread->sp; int count; - if(thread == current) - { -#ifdef __i386__ - asm("movl %%esp,%0" - : "=r"(pointer)); -#else - asm("movq %%rsp,%0" - : "=r"(pointer)); -#endif - } + + if ( thread == current ) + asm ( "mov %%"ASM_SP",%0" : "=r" (pointer) ); + printk("The stack for \"%s\"\n", thread->name); for(count = 0; count < 25 && pointer < bottom; count ++) { @@ -119,20 +113,12 @@ void run_idle_thread(void) { - /* Switch stacks and run the thread */ -#if defined(__i386__) - __asm__ __volatile__("mov %0,%%esp\n\t" - "push %1\n\t" - "ret" - :"=m" (idle_thread->sp) - :"m" (idle_thread->ip)); -#elif defined(__x86_64__) - __asm__ __volatile__("mov %0,%%rsp\n\t" - "push %1\n\t" - "ret" - :"=m" (idle_thread->sp) - :"m" (idle_thread->ip)); -#endif + /* Switch stacks and run the thread */ + asm volatile ( "mov %[sp], %%"ASM_SP"\n\t" + "jmp *%[ip]\n\t" + : + : [sp] "m" (idle_thread->sp), + [ip] "m" (idle_thread->ip) ); } unsigned long __local_irq_save(void) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extras/mini-os-remote/arch/x86/time.c new/extras/mini-os-remote/arch/x86/time.c --- old/extras/mini-os-remote/arch/x86/time.c 2024-12-04 16:30:52.000000000 +0100 +++ new/extras/mini-os-remote/arch/x86/time.c 2025-01-06 14:00:36.000000000 +0100 @@ -1,7 +1,7 @@ /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- **************************************************************************** * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge - * (C) 2002-2003 - Keir Fraser - University of Cambridge + * (C) 2002-2003 - Keir Fraser - University of Cambridge * (C) 2005 - Grzegorz Milos - Intel Research Cambridge * (C) 2006 - Robert Kaiser - FH Wiesbaden **************************************************************************** @@ -18,20 +18,19 @@ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ - #include <mini-os/os.h> #include <mini-os/traps.h> #include <mini-os/types.h> @@ -45,45 +44,16 @@ *************************************************************************/ /* These are peridically updated in shared_info, and then copied here. */ -struct shadow_time_info { - uint64_t tsc_timestamp; /* TSC at last update of time vals. */ - uint64_t system_timestamp; /* Time, in nanosecs, since boot. */ - uint32_t tsc_to_nsec_mul; - uint32_t tsc_to_usec_mul; - int tsc_shift; - uint32_t version; -}; static struct timespec shadow_ts; static uint32_t shadow_ts_version; -static struct shadow_time_info shadow; - - -#ifndef rmb -#define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") -#endif - -#define HANDLE_USEC_OVERFLOW(_tv) \ - do { \ - while ( (_tv)->tv_usec >= 1000000 ) \ - { \ - (_tv)->tv_usec -= 1000000; \ - (_tv)->tv_sec++; \ - } \ - } while ( 0 ) - -static inline int time_values_up_to_date(void) -{ - struct vcpu_time_info *src = &HYPERVISOR_shared_info->vcpu_info[0].time; - - return (shadow.version == src->version); -} +static struct vcpu_time_info shadow; static inline int wc_values_up_to_date(void) { - shared_info_t *s= HYPERVISOR_shared_info; + shared_info_t *s = HYPERVISOR_shared_info; - return (shadow_ts_version == s->wc_version); + return shadow_ts_version == s->wc_version; } /* @@ -92,109 +62,90 @@ */ static inline uint64_t scale_delta(uint64_t delta, uint32_t mul_frac, int shift) { - uint64_t product; + uint64_t product; #ifdef __i386__ - uint32_t tmp1, tmp2; + uint32_t tmp1, tmp2; #endif - if ( shift < 0 ) - delta >>= -shift; - else - delta <<= shift; + if ( shift < 0 ) + delta >>= -shift; + else + delta <<= shift; #ifdef __i386__ - __asm__ ( - "mul %5 ; " - "mov %4,%%eax ; " - "mov %%edx,%4 ; " - "mul %5 ; " - "add %4,%%eax ; " - "xor %5,%5 ; " - "adc %5,%%edx ; " - : "=A" (product), "=r" (tmp1), "=r" (tmp2) - : "a" ((uint32_t)delta), "1" ((uint32_t)(delta >> 32)), "2" (mul_frac) ); + __asm__ ( + "mul %5 ; " + "mov %4,%%eax ; " + "mov %%edx,%4 ; " + "mul %5 ; " + "add %4,%%eax ; " + "xor %5,%5 ; " + "adc %5,%%edx ; " + : "=A" (product), "=r" (tmp1), "=r" (tmp2) + : "a" ((uint32_t)delta), "1" ((uint32_t)(delta >> 32)), "2" (mul_frac) ); #else - __asm__ ( - "mul %%rdx ; shrd $32,%%rdx,%%rax" - : "=a" (product) : "0" (delta), "d" ((uint64_t)mul_frac) ); + __asm__ ( + "mul %%rdx ; shrd $32,%%rdx,%%rax" + : "=a" (product) : "0" (delta), "d" ((uint64_t)mul_frac) ); #endif - return product; + return product; } - static unsigned long get_nsec_offset(void) { - uint64_t now, delta; - rdtscll(now); - delta = now - shadow.tsc_timestamp; - return scale_delta(delta, shadow.tsc_to_nsec_mul, shadow.tsc_shift); -} - - -static void get_time_values_from_xen(void) -{ - struct vcpu_time_info *src = &HYPERVISOR_shared_info->vcpu_info[0].time; + uint64_t now, delta; - do { - shadow.version = src->version; - rmb(); - shadow.tsc_timestamp = src->tsc_timestamp; - shadow.system_timestamp = src->system_time; - shadow.tsc_to_nsec_mul = src->tsc_to_system_mul; - shadow.tsc_shift = src->tsc_shift; - rmb(); - } - while ((src->version & 1) | (shadow.version ^ src->version)); + rdtscll(now); + delta = now - shadow.tsc_timestamp; - shadow.tsc_to_usec_mul = shadow.tsc_to_nsec_mul / 1000; + return scale_delta(delta, shadow.tsc_to_system_mul, shadow.tsc_shift); } - - - -/* monotonic_clock(): returns # of nanoseconds passed since time_init() - * Note: This function is required to return accurate - * time even in the absence of multiple timer ticks. +/* + * monotonic_clock(): returns # of nanoseconds passed since time_init() + * Note: This function is required to return accurate + * time even in the absence of multiple timer ticks. */ uint64_t monotonic_clock(void) { - uint64_t time; - uint32_t local_time_version; + struct vcpu_time_info *src = &HYPERVISOR_shared_info->vcpu_info[0].time; - do { - local_time_version = shadow.version; - rmb(); - time = shadow.system_timestamp + get_nsec_offset(); - if (!time_values_up_to_date()) - get_time_values_from_xen(); - rmb(); - } while (local_time_version != shadow.version); + if ( shadow.version != src->version ) + { + do { + shadow.version = src->version; + rmb(); + shadow.tsc_timestamp = src->tsc_timestamp; + shadow.system_time = src->system_time; + shadow.tsc_to_system_mul = src->tsc_to_system_mul; + shadow.tsc_shift = src->tsc_shift; + rmb(); + } while ( (src->version & 1) || (shadow.version != src->version) ); + } - return time; + return shadow.system_time + get_nsec_offset(); } static void update_wallclock(void) { - shared_info_t *s = HYPERVISOR_shared_info; + shared_info_t *s = HYPERVISOR_shared_info; - do { - shadow_ts_version = s->wc_version; - rmb(); - shadow_ts.tv_sec = s->wc_sec; - shadow_ts.tv_nsec = s->wc_nsec; - rmb(); - } - while ((s->wc_version & 1) | (shadow_ts_version ^ s->wc_version)); + do { + shadow_ts_version = s->wc_version; + rmb(); + shadow_ts.tv_sec = s->wc_sec; + shadow_ts.tv_nsec = s->wc_nsec; + rmb(); + } while ( (s->wc_version & 1) | (shadow_ts_version ^ s->wc_version) ); } - int gettimeofday(struct timeval *tv, void *tz) { uint64_t nsec = monotonic_clock(); - if (!wc_values_up_to_date()) - update_wallclock(); + if ( !wc_values_up_to_date() ) + update_wallclock(); nsec += shadow_ts.tv_nsec; @@ -209,7 +160,7 @@ void block_domain(s_time_t until) { ASSERT(irqs_disabled()); - if(monotonic_clock() < until) + if ( monotonic_clock() < until ) { HYPERVISOR_set_timer_op(until); #ifdef CONFIG_PARAVIRT @@ -228,9 +179,8 @@ HYPERVISOR_set_timer_op(monotonic_clock() + MILLISECS(1)); } - - static evtchn_port_t port; + void init_time(void) { port = bind_virq(VIRQ_TIMER, &timer_handler, NULL); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extras/mini-os-remote/include/lib.h new/extras/mini-os-remote/include/lib.h --- old/extras/mini-os-remote/include/lib.h 2024-12-04 16:30:52.000000000 +0100 +++ new/extras/mini-os-remote/include/lib.h 2025-01-06 14:00:36.000000000 +0100 @@ -152,8 +152,10 @@ #define BUG_ON(x) ASSERT(!(x)) +#ifdef CONFIG_TEST /* Consistency check as much as possible. */ void sanity_check(void); +#endif /* Get own domid. */ domid_t get_domid(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extras/mini-os-remote/include/x86/os.h new/extras/mini-os-remote/include/x86/os.h --- old/extras/mini-os-remote/include/x86/os.h 2024-12-04 16:30:52.000000000 +0100 +++ new/extras/mini-os-remote/include/x86/os.h 2025-01-06 14:00:36.000000000 +0100 @@ -61,6 +61,16 @@ #define TRAP_deferred_nmi 31 #define TRAP_xen_callback 32 +#if defined(__i386__) +#define __SZ "l" +#define __REG "e" +#else +#define __SZ "q" +#define __REG "r" +#endif + +#define ASM_SP __REG"sp" + /* Everything below this point is not included by assembler (.S) files. */ #ifndef __ASSEMBLY__ @@ -141,14 +151,6 @@ #else -#if defined(__i386__) -#define __SZ "l" -#define __REG "e" -#else -#define __SZ "q" -#define __REG "r" -#endif - #define __cli() asm volatile ( "cli" : : : "memory" ) #define __sti() asm volatile ( "sti" : : : "memory" ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extras/mini-os-remote/mm.c new/extras/mini-os-remote/mm.c --- old/extras/mini-os-remote/mm.c 2024-12-04 16:30:52.000000000 +0100 +++ new/extras/mini-os-remote/mm.c 2025-01-06 14:00:36.000000000 +0100 @@ -1,4 +1,4 @@ -/* +/* **************************************************************************** * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge * (C) 2005 - Grzegorz Milos - Intel Research Cambridge @@ -7,9 +7,9 @@ * File: mm.c * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk) * Changes: Grzegorz Milos - * + * * Date: Aug 2003, chages Aug 2005 - * + * * Environment: Xen Minimal OS * Description: memory management related functions * contains buddy page allocator from Xen. @@ -21,16 +21,16 @@ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ @@ -45,7 +45,7 @@ #include <mini-os/xmalloc.h> #include <mini-os/e820.h> -/********************* +/* * ALLOCATION BITMAP * One bit per page of memory. Bit set => page is allocated. */ @@ -55,7 +55,7 @@ #define PAGES_PER_MAPWORD (sizeof(unsigned long) * 8) -#define allocated_in_map(_pn) \ +#define allocated_in_map(_pn) \ (mm_alloc_bitmap[(_pn) / PAGES_PER_MAPWORD] & \ (1UL << ((_pn) & (PAGES_PER_MAPWORD - 1)))) @@ -63,8 +63,8 @@ /* * Hint regarding bitwise arithmetic in map_{alloc,free}: - * -(1<<n) sets all bits >= n. - * (1<<n)-1 sets all bits < n. + * -(1 << n) sets all bits >= n. + * (1 << n) - 1 sets all bits < n. * Variable names in map_{alloc,free}: * *_idx == Index into `mm_alloc_bitmap' array. * *_off == Bit offset within an element of the `mm_alloc_bitmap' array. @@ -75,72 +75,80 @@ unsigned long start_off, end_off, curr_idx, end_idx; curr_idx = first_page / PAGES_PER_MAPWORD; - start_off = first_page & (PAGES_PER_MAPWORD-1); + start_off = first_page & (PAGES_PER_MAPWORD - 1); end_idx = (first_page + nr_pages) / PAGES_PER_MAPWORD; - end_off = (first_page + nr_pages) & (PAGES_PER_MAPWORD-1); + end_off = (first_page + nr_pages) & (PAGES_PER_MAPWORD - 1); if ( curr_idx == end_idx ) { - mm_alloc_bitmap[curr_idx] |= ((1UL<<end_off)-1) & -(1UL<<start_off); + mm_alloc_bitmap[curr_idx] |= ((1UL << end_off) - 1) & + -(1UL << start_off); } - else + else { - mm_alloc_bitmap[curr_idx] |= -(1UL<<start_off); - while ( ++curr_idx < end_idx ) mm_alloc_bitmap[curr_idx] = ~0UL; - mm_alloc_bitmap[curr_idx] |= (1UL<<end_off)-1; + mm_alloc_bitmap[curr_idx] |= -(1UL << start_off); + while ( ++curr_idx < end_idx ) + mm_alloc_bitmap[curr_idx] = ~0UL; + mm_alloc_bitmap[curr_idx] |= (1UL << end_off) - 1; } nr_free_pages -= nr_pages; } - static void map_free(unsigned long first_page, unsigned long nr_pages) { unsigned long start_off, end_off, curr_idx, end_idx; curr_idx = first_page / PAGES_PER_MAPWORD; - start_off = first_page & (PAGES_PER_MAPWORD-1); + start_off = first_page & (PAGES_PER_MAPWORD - 1); end_idx = (first_page + nr_pages) / PAGES_PER_MAPWORD; - end_off = (first_page + nr_pages) & (PAGES_PER_MAPWORD-1); + end_off = (first_page + nr_pages) & (PAGES_PER_MAPWORD - 1); nr_free_pages += nr_pages; if ( curr_idx == end_idx ) { - mm_alloc_bitmap[curr_idx] &= -(1UL<<end_off) | ((1UL<<start_off)-1); + mm_alloc_bitmap[curr_idx] &= -(1UL << end_off) | + ((1UL << start_off) - 1); } - else + else { - mm_alloc_bitmap[curr_idx] &= (1UL<<start_off)-1; - while ( ++curr_idx != end_idx ) mm_alloc_bitmap[curr_idx] = 0; - mm_alloc_bitmap[curr_idx] &= -(1UL<<end_off); + mm_alloc_bitmap[curr_idx] &= (1UL << start_off) - 1; + while ( ++curr_idx != end_idx ) + mm_alloc_bitmap[curr_idx] = 0; + mm_alloc_bitmap[curr_idx] &= -(1UL << end_off); } } - - -/************************* - * BINARY BUDDY ALLOCATOR - */ +/* BINARY BUDDY ALLOCATOR */ typedef struct chunk_head_st chunk_head_t; -typedef struct chunk_tail_st chunk_tail_t; struct chunk_head_st { - chunk_head_t *next; - chunk_head_t **pprev; - int level; -}; - -struct chunk_tail_st { - int level; + chunk_head_t *next; + chunk_head_t *prev; + unsigned int level; }; /* Linked lists of free chunks of different powers-of-two in size. */ -#define FREELIST_SIZE ((sizeof(void*)<<3)-PAGE_SHIFT) -static chunk_head_t *free_head[FREELIST_SIZE]; -static chunk_head_t free_tail[FREELIST_SIZE]; -#define FREELIST_EMPTY(_l) ((_l)->next == NULL) +#define FREELIST_SIZE ((sizeof(void *) << 3) - PAGE_SHIFT) +static chunk_head_t free_list[FREELIST_SIZE]; +#define FREELIST_EMPTY(_l) ((_l)->level == FREELIST_SIZE) + +static void enqueue_elem(chunk_head_t *elem, unsigned int level) +{ + elem->level = level; + elem->next = free_list[level].next; + elem->prev = &free_list[level]; + elem->next->prev = elem; + free_list[level].next = elem; +} + +static void dequeue_elem(chunk_head_t *elem) +{ + elem->prev->next = elem->next; + elem->next->prev = elem->prev; +} /* * Initialise allocator, placing addresses [@min,@max] in free pool. @@ -152,25 +160,24 @@ unsigned long range; unsigned long r_min, r_max; chunk_head_t *ch; - chunk_tail_t *ct; printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n", (u_long)to_virt(min), min, (u_long)to_virt(max), max); for ( i = 0; i < FREELIST_SIZE; i++ ) { - free_head[i] = &free_tail[i]; - free_tail[i].pprev = &free_head[i]; - free_tail[i].next = NULL; + free_list[i].next = &free_list[i]; + free_list[i].prev = &free_list[i]; + free_list[i].level = FREELIST_SIZE; } - min = round_pgup (min); + min = round_pgup(min); max = round_pgdown(max); /* Allocate space for the allocation bitmap. */ - mm_alloc_bitmap_size = (max + 1) >> (PAGE_SHIFT + 3); - mm_alloc_bitmap_size = round_pgup(mm_alloc_bitmap_size); + mm_alloc_bitmap_size = (max + 1) >> (PAGE_SHIFT + 3); + mm_alloc_bitmap_size = round_pgup(mm_alloc_bitmap_size); mm_alloc_bitmap = (unsigned long *)to_virt(min); - min += mm_alloc_bitmap_size; + min += mm_alloc_bitmap_size; /* All allocated by default. */ memset(mm_alloc_bitmap, ~0, mm_alloc_bitmap_size); @@ -208,74 +215,61 @@ * must not be bigger than remaining range. */ for ( i = PAGE_SHIFT; (1UL << (i + 1)) <= range; i++ ) - if ( r_min & (1UL << i) ) break; + { + if ( r_min & (1UL << i) ) + break; + } ch = (chunk_head_t *)r_min; r_min += 1UL << i; range -= 1UL << i; - ct = (chunk_tail_t *)r_min - 1; - i -= PAGE_SHIFT; - ch->level = i; - ch->next = free_head[i]; - ch->pprev = &free_head[i]; - ch->next->pprev = &ch->next; - free_head[i] = ch; - ct->level = i; + enqueue_elem(ch, i - PAGE_SHIFT); } } mm_alloc_bitmap_remap(); } - /* Allocate 2^@order contiguous pages. Returns a VIRTUAL address. */ unsigned long alloc_pages(int order) { int i; chunk_head_t *alloc_ch, *spare_ch; - chunk_tail_t *spare_ct; if ( !chk_free_pages(1UL << order) ) goto no_memory; /* Find smallest order which can satisfy the request. */ - for ( i = order; i < FREELIST_SIZE; i++ ) { - if ( !FREELIST_EMPTY(free_head[i]) ) - break; + for ( i = order; i < FREELIST_SIZE; i++ ) + { + if ( !FREELIST_EMPTY(free_list[i].next) ) + break; } - if ( i == FREELIST_SIZE ) goto no_memory; - + if ( i >= FREELIST_SIZE ) + goto no_memory; + /* Unlink a chunk. */ - alloc_ch = free_head[i]; - free_head[i] = alloc_ch->next; - alloc_ch->next->pprev = alloc_ch->pprev; + alloc_ch = free_list[i].next; + dequeue_elem(alloc_ch); /* We may have to break the chunk a number of times. */ while ( i != order ) { /* Split into two equal parts. */ i--; - spare_ch = (chunk_head_t *)((char *)alloc_ch + (1UL<<(i+PAGE_SHIFT))); - spare_ct = (chunk_tail_t *)((char *)spare_ch + (1UL<<(i+PAGE_SHIFT)))-1; + spare_ch = (chunk_head_t *)((char *)alloc_ch + + (1UL << (i + PAGE_SHIFT))); /* Create new header for spare chunk. */ - spare_ch->level = i; - spare_ch->next = free_head[i]; - spare_ch->pprev = &free_head[i]; - spare_ct->level = i; - - /* Link in the spare chunk. */ - spare_ch->next->pprev = &spare_ch->next; - free_head[i] = spare_ch; + enqueue_elem(spare_ch, i); } - - map_alloc(PHYS_PFN(to_phys(alloc_ch)), 1UL<<order); - return((unsigned long)alloc_ch); + map_alloc(PHYS_PFN(to_phys(alloc_ch)), 1UL << order); - no_memory: + return (unsigned long)alloc_ch; + no_memory: printk("Cannot handle page request order %d!\n", order); return 0; @@ -285,57 +279,45 @@ void free_pages(void *pointer, int order) { chunk_head_t *freed_ch, *to_merge_ch; - chunk_tail_t *freed_ct; unsigned long mask; - + /* First free the chunk */ map_free(virt_to_pfn(pointer), 1UL << order); - + /* Create free chunk */ freed_ch = (chunk_head_t *)pointer; - freed_ct = (chunk_tail_t *)((char *)pointer + (1UL<<(order + PAGE_SHIFT)))-1; - + /* Now, possibly we can conseal chunks together */ - while(order < FREELIST_SIZE) + while ( order < FREELIST_SIZE ) { mask = 1UL << (order + PAGE_SHIFT); - if((unsigned long)freed_ch & mask) + if ( (unsigned long)freed_ch & mask ) { to_merge_ch = (chunk_head_t *)((char *)freed_ch - mask); - if(allocated_in_map(virt_to_pfn(to_merge_ch)) || - to_merge_ch->level != order) + if ( allocated_in_map(virt_to_pfn(to_merge_ch)) || + to_merge_ch->level != order ) break; - + /* Merge with predecessor */ - freed_ch = to_merge_ch; + freed_ch = to_merge_ch; } - else + else { to_merge_ch = (chunk_head_t *)((char *)freed_ch + mask); - if(allocated_in_map(virt_to_pfn(to_merge_ch)) || - to_merge_ch->level != order) + if ( allocated_in_map(virt_to_pfn(to_merge_ch)) || + to_merge_ch->level != order ) break; - - /* Merge with successor */ - freed_ct = (chunk_tail_t *)((char *)to_merge_ch + mask) - 1; } - - /* We are commited to merging, unlink the chunk */ - *(to_merge_ch->pprev) = to_merge_ch->next; - to_merge_ch->next->pprev = to_merge_ch->pprev; - + + /* We are committed to merging, unlink the chunk */ + dequeue_elem(to_merge_ch); + order++; } /* Link the new chunk */ - freed_ch->level = order; - freed_ch->next = free_head[order]; - freed_ch->pprev = &free_head[order]; - freed_ct->level = order; - - freed_ch->next->pprev = &freed_ch->next; - free_head[order] = freed_ch; - + enqueue_elem(freed_ch, order); + } EXPORT_SYMBOL(free_pages); @@ -347,6 +329,7 @@ reservation.nr_extents = n; reservation.extent_order = 0; reservation.domid = DOMID_SELF; + return HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); } @@ -362,16 +345,15 @@ unsigned long old_brk = brk; unsigned long new_brk = old_brk + increment; - if (new_brk > heap_end) { - printk("Heap exhausted: %lx + %lx = %p > %p\n", - old_brk, - (unsigned long) increment, - (void *) new_brk, - (void *) heap_end); - return NULL; + if ( new_brk > heap_end ) + { + printk("Heap exhausted: %lx + %lx = %p > %p\n", old_brk, + (unsigned long) increment, (void *)new_brk, (void *)heap_end); + return NULL; } - - if (new_brk > heap_mapped) { + + if ( new_brk > heap_mapped ) + { unsigned long n = (new_brk - heap_mapped + PAGE_SIZE - 1) / PAGE_SIZE; if ( !chk_free_pages(n) ) @@ -386,16 +368,13 @@ brk = new_brk; - return (void *) old_brk; + return (void *)old_brk; } EXPORT_SYMBOL(sbrk); #endif - - void init_mm(void) { - unsigned long start_pfn, max_pfn; printk("MM: Init\n"); @@ -403,14 +382,12 @@ arch_init_mm(&start_pfn, &max_pfn); get_max_pages(); - /* - * now we can initialise the page allocator - */ + /* Now we can initialise the page allocator. */ init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn)); printk("MM: done\n"); arch_init_p2m(max_pfn); - + arch_init_demand_mapping_area(); } @@ -418,19 +395,20 @@ { } +#ifdef CONFIG_TEST void sanity_check(void) { int x; chunk_head_t *head; - for (x = 0; x < FREELIST_SIZE; x++) { - for (head = free_head[x]; !FREELIST_EMPTY(head); head = head->next) { + for ( x = 0; x < FREELIST_SIZE; x++ ) + { + for ( head = free_list[x].next; !FREELIST_EMPTY(head); + head = head->next ) + { ASSERT(!allocated_in_map(virt_to_pfn(head))); - if (head->next) - ASSERT(head->next->pprev == &head->next); - } - if (free_head[x]) { - ASSERT(free_head[x]->pprev == &free_head[x]); + ASSERT(head->next->prev == head); } } } +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extras/mini-os-remote/test.c new/extras/mini-os-remote/test.c --- old/extras/mini-os-remote/test.c 2024-12-04 16:30:52.000000000 +0100 +++ new/extras/mini-os-remote/test.c 2025-01-06 14:00:36.000000000 +0100 @@ -185,6 +185,7 @@ { gettimeofday(&tv, NULL); printk("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec); + sanity_check(); msleep(1000); } } ++++++ stubdom.tar.bz2 ++++++ /work/SRC/openSUSE:Factory/xen/stubdom.tar.bz2 /work/SRC/openSUSE:Factory/.xen.new.1881/stubdom.tar.bz2 differ: char 11, line 1 ++++++ x86-ioapic-ack-default.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:34.949874463 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:34.973875456 +0100 @@ -2,7 +2,7 @@ --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c -@@ -2136,7 +2136,10 @@ void __init setup_IO_APIC(void) +@@ -2152,7 +2152,10 @@ void __init setup_IO_APIC(void) io_apic_irqs = ~PIC_IRQS; printk("ENABLING IO-APIC IRQs\n"); ++++++ xen-4.19.1-testing-src.tar.bz2 -> xen-4.20.0-testing-src.tar.bz2 ++++++ ++++ 58754 lines of diff (skipped) ++++++ xen-arch-kconfig-nr_cpus.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:37.745990100 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:37.749990266 +0100 @@ -1,14 +1,14 @@ -Index: xen-4.19.0-testing/xen/arch/Kconfig +Index: xen-4.20.0-testing/xen/arch/Kconfig =================================================================== ---- xen-4.19.0-testing.orig/xen/arch/Kconfig -+++ xen-4.19.0-testing/xen/arch/Kconfig -@@ -7,7 +7,7 @@ config PHYS_ADDR_T_32 - config NR_CPUS +--- xen-4.20.0-testing.orig/xen/arch/Kconfig ++++ xen-4.20.0-testing/xen/arch/Kconfig +@@ -8,7 +8,7 @@ config NR_CPUS int "Maximum number of CPUs" + range 1 1 if ARM && MPU range 1 16383 - default "256" if X86 + default "1024" if X86 + default "1" if ARM && MPU default "8" if ARM && RCAR3 default "4" if ARM && QEMU - default "4" if ARM && MPSOC ++++++ xen.bug1026236.suse_vtsc_tolerance.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:37.785991754 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:37.789991920 +0100 @@ -20,7 +20,7 @@ unsigned long __read_mostly cpu_khz; /* CPU clock frequency in kHz. */ DEFINE_SPINLOCK(rtc_lock); unsigned long pit0_ticks; -@@ -2797,6 +2800,8 @@ int tsc_set_info(struct domain *d, +@@ -2887,6 +2890,8 @@ int tsc_set_info(struct domain *d, switch ( tsc_mode ) { @@ -29,7 +29,7 @@ case XEN_CPUID_TSC_MODE_DEFAULT: case XEN_CPUID_TSC_MODE_ALWAYS_EMULATE: d->arch.vtsc_offset = get_s_time() - elapsed_nsec; -@@ -2810,8 +2815,25 @@ int tsc_set_info(struct domain *d, +@@ -2900,8 +2905,25 @@ int tsc_set_info(struct domain *d, * When a guest is created, gtsc_khz is passed in as zero, making * d->arch.tsc_khz == cpu_khz. Thus no need to check incarnation. */ ++++++ xen.libxl.dmmd.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:37.801992416 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:37.805992582 +0100 @@ -72,9 +72,9 @@ +} + static int libxl__build_device_model_args_new(libxl__gc *gc, - const char *dm, int guest_domid, - const libxl_domain_config *guest_config, -@@ -1885,9 +1909,11 @@ static int libxl__build_device_model_arg + const char *dm, int guest_domid, + const libxl_domain_config *guest_config, +@@ -1891,9 +1915,11 @@ static int libxl__build_device_model_arg libxl__device_disk_dev_number(disks[i].vdev, &disk, &part); const char *format; char *drive; ++++++ xl-save-pc.patch ++++++ --- /var/tmp/diff_new_pack.gLbPbJ/_old 2025-01-07 20:50:37.933997875 +0100 +++ /var/tmp/diff_new_pack.gLbPbJ/_new 2025-01-07 20:50:37.937998041 +0100 @@ -40,8 +40,8 @@ install: all --- a/tools/xl/xl.h +++ b/tools/xl/xl.h -@@ -303,6 +303,7 @@ typedef enum { - DOMAIN_RESTART_SOFT_RESET, /* Soft reset should be performed */ +@@ -306,6 +306,7 @@ typedef enum { + DOMAIN_RESTART_SUSPENDED, /* Domain suspended - keep looping */ } domain_restart_type; +#define XL_SAVE_PAUSE_CHECKPOINT "suse-xl-save-pc" @@ -102,7 +102,7 @@ #include <libxl.h> #include <libxl_utils.h> #include <libxlutil.h> -@@ -668,6 +669,10 @@ int create_domain(struct domain_create * +@@ -706,6 +707,10 @@ int create_domain(struct domain_create * int migrate_fd = dom_info->migrate_fd; bool config_in_json; @@ -113,7 +113,7 @@ int i; int need_daemon = daemonize; int ret, rc; -@@ -1034,6 +1039,24 @@ start: +@@ -1073,6 +1078,24 @@ start: ret = domain_wait_event(domid, &event); if (ret) goto out; @@ -138,7 +138,7 @@ switch (event->type) { case LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN: -@@ -1095,14 +1118,39 @@ start: +@@ -1134,10 +1157,34 @@ start: goto start; case DOMAIN_RESTART_NONE: @@ -171,11 +171,6 @@ goto out; + } - default: - abort(); - } -+ break; - - case LIBXL_EVENT_TYPE_DOMAIN_DEATH: - LOG("Domain %u has been destroyed.", domid); + case DOMAIN_RESTART_SUSPENDED: + LOG("Continue waiting for domain %u", domid);