On 02.07.25 10:12, Juergen Gross wrote:
Especially for support of Xenstore-stubdom live update some memory must
be handed over to the new kernel without moving it around: as the
9pfs device used for storing and retrieving the state of Xenstore
needs to be kept operational across kexec (it can't be reopened due to
Xenstore not being available without access to the device), the ring
pages need to be accessible via active grants by the backend all the
time.

Add the basic support for that by reserving a pre-defined number of
memory pages at the top of the memory. This memory area will be
handed over to the new kernel via specifying it as a module in
struct hvm_start_info.

The contents of the memory area are described via a generic table of
contents in the last page of the memory.

Signed-off-by: Juergen Gross <jgr...@suse.com>
---
  Config.mk             |  2 ++
  arch/x86/kexec.c      | 77 +++++++++++++++++++++++++++++++++++++++++++
  arch/x86/mm.c         | 18 ++++++++++
  arch/x86/setup.c      | 28 ++++++++++++++++
  include/kernel.h      |  1 +
  include/kexec.h       | 45 +++++++++++++++++++++++++
  include/x86/arch_mm.h |  1 +
  kexec.c               |  3 ++
  mm.c                  |  6 ++++
  9 files changed, 181 insertions(+)

diff --git a/Config.mk b/Config.mk
index b9675e61..0e4e86d8 100644
--- a/Config.mk
+++ b/Config.mk
@@ -220,6 +220,8 @@ CONFIG-$(lwip) += CONFIG_LWIP
  $(foreach i,$(CONFIG-y),$(eval $(i) ?= y))
  $(foreach i,$(CONFIG-n),$(eval $(i) ?= n))
+CONFIG-val-$(CONFIG_KEXEC) += CONFIG_KEXEC_MODULE_PAGES
+
  $(foreach i,$(CONFIG-val-y),$(eval $(i) ?= 0))
CONFIG-x += CONFIG_LIBXS
diff --git a/arch/x86/kexec.c b/arch/x86/kexec.c
index 804e7b6d..7fb98473 100644
--- a/arch/x86/kexec.c
+++ b/arch/x86/kexec.c
@@ -201,10 +201,73 @@ static unsigned long kexec_param_loc;
  static unsigned int kexec_param_size;
  static unsigned long kexec_param_mem;
+static struct kexec_module *kexec_check_module(void)
+{
+    unsigned long mod_size;
+    unsigned long mod;
+    struct kexec_module *module_ptr;
+
+    mod = get_module(&mod_size);
+    if ( !mod )
+        return NULL;
+    /* Size must be a multiple of PAGE_SIZE. */
+    if ( mod_size & ~PAGE_MASK )
+        return NULL;
+
+    /* Kxec module description is at start of the last page of the module. */
+    module_ptr = (void *)(mod + mod_size - (unsigned long)PAGE_SIZE);
+
+    /* Check eye catcher. */
+    if ( memcmp(module_ptr->eye_catcher, KEXECMOD_EYECATCHER,
+                sizeof(module_ptr->eye_catcher)) )
+        return NULL;
+    if ( module_ptr->n_pages != (mod_size >> PAGE_SHIFT) - 1 )
+        return NULL;

There is missing:

+    kexec_mod_start = mod;

Otherwise a second live update won't work.

I'll wait for more feedback before sending out V2.


Juergen

Attachment: OpenPGP_0xB0DE9DD628BF132F.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to