* [PATCH v2 1/9] xenstored: use fread() instead of mmap() for reading live update state
2025-07-29 11:01 [PATCH v2 0/9] Enable Xenstore-stubdom Live Update Juergen Gross
@ 2025-07-29 11:01 ` Juergen Gross
2025-07-29 19:21 ` Andrew Cooper
2025-07-29 11:01 ` [PATCH v2 2/9] libevtchn: add O_CLOEXEC support for Mini-OS Juergen Gross
` (7 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Juergen Gross @ 2025-07-29 11:01 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Julien Grall, Anthony PERARD, Jason Andryuk
Mini-OS doesn't support using mmap() for accessing a file. In order
to support reading the live update state from a 9pfs based file, use
fread() instead of mmap().
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
V2:
- move to start of series
---
tools/xenstored/lu.c | 95 +++++++++++++++++++++++++++-----------------
1 file changed, 59 insertions(+), 36 deletions(-)
diff --git a/tools/xenstored/lu.c b/tools/xenstored/lu.c
index 77e0d377c5..f2c8b92d07 100644
--- a/tools/xenstored/lu.c
+++ b/tools/xenstored/lu.c
@@ -27,9 +27,11 @@ struct live_update *lu_status;
struct lu_dump_state {
void *buf;
+ unsigned int buf_size;
unsigned int size;
- int fd;
+ unsigned int offset;
char *filename;
+ FILE *fp;
};
static int lu_destroy(void *data)
@@ -80,9 +82,10 @@ bool lu_is_pending(void)
return lu_status != NULL;
}
-static void lu_get_dump_state(struct lu_dump_state *state)
+static void lu_get_dump_state(void *ctx, struct lu_dump_state *state)
{
struct stat statbuf;
+ int fd;
state->size = 0;
@@ -91,82 +94,107 @@ static void lu_get_dump_state(struct lu_dump_state *state)
if (!state->filename)
barf("Allocation failure");
- state->fd = open(state->filename, O_RDONLY);
- if (state->fd < 0)
- return;
- if (fstat(state->fd, &statbuf) != 0)
- goto out_close;
+ fd = open(state->filename, O_RDONLY);
+ if (fd < 0)
+ barf("No state file found");
+ if (fstat(fd, &statbuf) != 0)
+ barf("Could not fstat state file");
state->size = statbuf.st_size;
- state->buf = mmap(NULL, state->size, PROT_READ, MAP_PRIVATE,
- state->fd, 0);
- if (state->buf == MAP_FAILED) {
- state->size = 0;
- goto out_close;
- }
+ /* Start with a 4k buffer. If needed we'll reallocate a larger one. */
+ state->buf_size = 4096;
+ state->buf = talloc_size(ctx, state->buf_size);
+ if (!state->buf)
+ barf("Allocation failure");
- return;
+ state->fp = fdopen(fd, "r");
+}
- out_close:
- close(state->fd);
+static void lu_dump_close(FILE *fp)
+{
+ fclose(fp);
}
static void lu_close_dump_state(struct lu_dump_state *state)
{
assert(state->filename != NULL);
- munmap(state->buf, state->size);
- close(state->fd);
+ lu_dump_close(state->fp);
unlink(state->filename);
talloc_free(state->filename);
+ talloc_free(state->buf);
+}
+
+static void lu_read_data(void *ctx, struct lu_dump_state *state,
+ unsigned int size)
+{
+ if (state->offset + size > state->size)
+ barf("Inconsistent state data");
+
+ if (size > state->buf_size) {
+ state->buf = talloc_realloc_size(ctx, state->buf, size);
+ if (!state->buf)
+ barf("Allocation failure");
+ state->buf_size = size;
+ }
+
+ if (fread(state->buf, size, 1, state->fp) != 1)
+ barf("State read error");
+
+ state->offset += size;
}
void lu_read_state(void)
{
struct lu_dump_state state = {};
- struct xs_state_record_header *head;
+ struct xs_state_record_header head;
void *ctx = talloc_new(NULL); /* Work context for subfunctions. */
struct xs_state_preamble *pre;
unsigned int version;
syslog(LOG_INFO, "live-update: read state\n");
- lu_get_dump_state(&state);
+ lu_get_dump_state(ctx, &state);
if (state.size == 0)
barf_perror("No state found after live-update");
+ lu_read_data(ctx, &state, sizeof(*pre));
pre = state.buf;
version = be32toh(pre->version);
if (memcmp(pre->ident, XS_STATE_IDENT, sizeof(pre->ident)) ||
!version || version > XS_STATE_VERSION ||
pre->flags != XS_STATE_FLAGS)
barf("Unknown record identifier");
- for (head = state.buf + sizeof(*pre);
- head->type != XS_STATE_TYPE_END &&
- (void *)head - state.buf < state.size;
- head = (void *)head + sizeof(*head) + head->length) {
- switch (head->type) {
+
+ for (;;) {
+ lu_read_data(ctx, &state, sizeof(head));
+ head = *(struct xs_state_record_header *)(state.buf);
+ if (head.type == XS_STATE_TYPE_END)
+ break;
+ lu_read_data(ctx, &state, head.length);
+
+ switch (head.type) {
case XS_STATE_TYPE_GLOBAL:
- read_state_global(ctx, head + 1);
+ read_state_global(ctx, state.buf);
break;
case XS_STATE_TYPE_CONN:
- read_state_connection(ctx, head + 1);
+ read_state_connection(ctx, state.buf);
break;
case XS_STATE_TYPE_WATCH:
- read_state_watch(ctx, head + 1);
+ read_state_watch(ctx, state.buf);
break;
case XS_STATE_TYPE_TA:
xprintf("live-update: ignore transaction record\n");
break;
case XS_STATE_TYPE_NODE:
- read_state_node(ctx, head + 1);
+ read_state_node(ctx, state.buf);
break;
case XS_STATE_TYPE_DOMAIN:
- read_state_domain(ctx, head + 1, version);
+ read_state_domain(ctx, state.buf, version);
break;
default:
xprintf("live-update: unknown state record %08x\n",
- head->type);
+ head.type);
break;
}
}
@@ -271,11 +299,6 @@ static FILE *lu_dump_open(const void *ctx)
return fdopen(fd, "w");
}
-static void lu_dump_close(FILE *fp)
-{
- fclose(fp);
-}
-
static const char *lu_dump_state(const void *ctx, struct connection *conn)
{
FILE *fp;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/9] xenstored: use fread() instead of mmap() for reading live update state
2025-07-29 11:01 ` [PATCH v2 1/9] xenstored: use fread() instead of mmap() for reading live update state Juergen Gross
@ 2025-07-29 19:21 ` Andrew Cooper
2025-07-29 19:25 ` Andrew Cooper
0 siblings, 1 reply; 18+ messages in thread
From: Andrew Cooper @ 2025-07-29 19:21 UTC (permalink / raw)
To: Juergen Gross, xen-devel; +Cc: Julien Grall, Anthony PERARD, Jason Andryuk
On 29/07/2025 12:01 pm, Juergen Gross wrote:
> diff --git a/tools/xenstored/lu.c b/tools/xenstored/lu.c
> index 77e0d377c5..f2c8b92d07 100644
> --- a/tools/xenstored/lu.c
> +++ b/tools/xenstored/lu.c
> @@ -27,9 +27,11 @@ struct live_update *lu_status;
>
> struct lu_dump_state {
> void *buf;
> + unsigned int buf_size;
> unsigned int size;
> - int fd;
> + unsigned int offset;
> char *filename;
> + FILE *fp;
I know there's already one unsigned int size here, but life is too short
to not use size_t from the get-go.
~Andrew
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/9] xenstored: use fread() instead of mmap() for reading live update state
2025-07-29 19:21 ` Andrew Cooper
@ 2025-07-29 19:25 ` Andrew Cooper
2025-07-30 6:18 ` Jürgen Groß
0 siblings, 1 reply; 18+ messages in thread
From: Andrew Cooper @ 2025-07-29 19:25 UTC (permalink / raw)
To: Juergen Gross, xen-devel; +Cc: Julien Grall, Anthony PERARD, Jason Andryuk
On 29/07/2025 8:21 pm, Andrew Cooper wrote:
> On 29/07/2025 12:01 pm, Juergen Gross wrote:
>> diff --git a/tools/xenstored/lu.c b/tools/xenstored/lu.c
>> index 77e0d377c5..f2c8b92d07 100644
>> --- a/tools/xenstored/lu.c
>> +++ b/tools/xenstored/lu.c
>> @@ -27,9 +27,11 @@ struct live_update *lu_status;
>>
>> struct lu_dump_state {
>> void *buf;
>> + unsigned int buf_size;
>> unsigned int size;
>> - int fd;
>> + unsigned int offset;
>> char *filename;
>> + FILE *fp;
> I know there's already one unsigned int size here, but life is too short
> to not use size_t from the get-go.
That said, offset really needs to be an offs64_t if you want 32bit
guests to 9P safely on a modern filesystem.
~Andrew
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/9] xenstored: use fread() instead of mmap() for reading live update state
2025-07-29 19:25 ` Andrew Cooper
@ 2025-07-30 6:18 ` Jürgen Groß
2025-07-30 6:54 ` Juergen Gross
0 siblings, 1 reply; 18+ messages in thread
From: Jürgen Groß @ 2025-07-30 6:18 UTC (permalink / raw)
To: Andrew Cooper, xen-devel; +Cc: Julien Grall, Anthony PERARD, Jason Andryuk
[-- Attachment #1.1.1: Type: text/plain, Size: 1246 bytes --]
On 29.07.25 21:25, Andrew Cooper wrote:
> On 29/07/2025 8:21 pm, Andrew Cooper wrote:
>> On 29/07/2025 12:01 pm, Juergen Gross wrote:
>>> diff --git a/tools/xenstored/lu.c b/tools/xenstored/lu.c
>>> index 77e0d377c5..f2c8b92d07 100644
>>> --- a/tools/xenstored/lu.c
>>> +++ b/tools/xenstored/lu.c
>>> @@ -27,9 +27,11 @@ struct live_update *lu_status;
>>>
>>> struct lu_dump_state {
>>> void *buf;
>>> + unsigned int buf_size;
>>> unsigned int size;
>>> - int fd;
>>> + unsigned int offset;
>>> char *filename;
>>> + FILE *fp;
>> I know there's already one unsigned int size here, but life is too short
>> to not use size_t from the get-go.
>
> That said, offset really needs to be an offs64_t if you want 32bit
> guests to 9P safely on a modern filesystem.
For 32bit guests I don't see a problem here, as this would mean the Xenstore
state would exceed 4GB, which seems unlikely using an in-memory data base in
a system supporting less than 2GB of memory (the Mini-OS limit for 32bit is
1GB, while a 32bit daemon can use max. 2GB of virtual memory).
Using unsigned int is a potential problem in 64bit mode, though. So switching
to size_t for size and off64_t for offset seems sensible.
Juergen
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/9] xenstored: use fread() instead of mmap() for reading live update state
2025-07-30 6:18 ` Jürgen Groß
@ 2025-07-30 6:54 ` Juergen Gross
0 siblings, 0 replies; 18+ messages in thread
From: Juergen Gross @ 2025-07-30 6:54 UTC (permalink / raw)
To: Andrew Cooper, xen-devel; +Cc: Julien Grall, Anthony PERARD, Jason Andryuk
[-- Attachment #1.1.1: Type: text/plain, Size: 1459 bytes --]
On 30.07.25 08:18, Jürgen Groß wrote:
> On 29.07.25 21:25, Andrew Cooper wrote:
>> On 29/07/2025 8:21 pm, Andrew Cooper wrote:
>>> On 29/07/2025 12:01 pm, Juergen Gross wrote:
>>>> diff --git a/tools/xenstored/lu.c b/tools/xenstored/lu.c
>>>> index 77e0d377c5..f2c8b92d07 100644
>>>> --- a/tools/xenstored/lu.c
>>>> +++ b/tools/xenstored/lu.c
>>>> @@ -27,9 +27,11 @@ struct live_update *lu_status;
>>>> struct lu_dump_state {
>>>> void *buf;
>>>> + unsigned int buf_size;
>>>> unsigned int size;
>>>> - int fd;
>>>> + unsigned int offset;
>>>> char *filename;
>>>> + FILE *fp;
>>> I know there's already one unsigned int size here, but life is too short
>>> to not use size_t from the get-go.
>>
>> That said, offset really needs to be an offs64_t if you want 32bit
>> guests to 9P safely on a modern filesystem.
>
> For 32bit guests I don't see a problem here, as this would mean the Xenstore
> state would exceed 4GB, which seems unlikely using an in-memory data base in
> a system supporting less than 2GB of memory (the Mini-OS limit for 32bit is
> 1GB, while a 32bit daemon can use max. 2GB of virtual memory).
>
> Using unsigned int is a potential problem in 64bit mode, though. So switching
> to size_t for size and off64_t for offset seems sensible.
Meh, off64_t seems to be unknown in Mini-OS environment. Will use size_t for
offset, too.
Juergen
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 2/9] libevtchn: add O_CLOEXEC support for Mini-OS
2025-07-29 11:01 [PATCH v2 0/9] Enable Xenstore-stubdom Live Update Juergen Gross
2025-07-29 11:01 ` [PATCH v2 1/9] xenstored: use fread() instead of mmap() for reading live update state Juergen Gross
@ 2025-07-29 11:01 ` Juergen Gross
2025-07-29 16:32 ` Anthony PERARD
2025-07-29 11:01 ` [PATCH v2 3/9] libxengnttab: set the cloexec flag on Mini-OS Juergen Gross
` (6 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Juergen Gross @ 2025-07-29 11:01 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Anthony PERARD, Jason Andryuk
With Mini-OS now supporting O_CLOEXEC for the kexec case, no longer
ignore the XENEVTCHN_NO_CLOEXEC flag in minios.c.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/libs/evtchn/minios.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tools/libs/evtchn/minios.c b/tools/libs/evtchn/minios.c
index 046cd28d37..0d2a201438 100644
--- a/tools/libs/evtchn/minios.c
+++ b/tools/libs/evtchn/minios.c
@@ -114,10 +114,6 @@ static void evtchn_initialize(void)
ftype_evtchn = alloc_file_type(&evtchn_ops);
}
-/*
- * XENEVTCHN_NO_CLOEXEC is being ignored, as there is no exec() call supported
- * in Mini-OS.
- */
int osdep_evtchn_open(xenevtchn_handle *xce, unsigned int flags)
{
int fd;
@@ -137,6 +133,8 @@ int osdep_evtchn_open(xenevtchn_handle *xce, unsigned int flags)
return -1;
}
+ if ( !(flags & XENEVTCHN_NO_CLOEXEC) )
+ file->cloexec = true;
file->dev = ports;
XEN_LIST_INIT(&ports->list);
xce->fd = fd;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 3/9] libxengnttab: set the cloexec flag on Mini-OS
2025-07-29 11:01 [PATCH v2 0/9] Enable Xenstore-stubdom Live Update Juergen Gross
2025-07-29 11:01 ` [PATCH v2 1/9] xenstored: use fread() instead of mmap() for reading live update state Juergen Gross
2025-07-29 11:01 ` [PATCH v2 2/9] libevtchn: add O_CLOEXEC support for Mini-OS Juergen Gross
@ 2025-07-29 11:01 ` Juergen Gross
2025-07-29 16:34 ` Anthony PERARD
2025-07-29 11:01 ` [PATCH v2 4/9] xenstored: don't use xenevtchn_fdopen() in stubdom Juergen Gross
` (5 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Juergen Gross @ 2025-07-29 11:01 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Anthony PERARD, Jason Andryuk
With Mini-OS now supporting the O_CLOEXEC flag for the kexec case,
set the related cloexec flag in minios.c.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/libs/gnttab/minios.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/libs/gnttab/minios.c b/tools/libs/gnttab/minios.c
index cac89f0ba6..63bbdc7719 100644
--- a/tools/libs/gnttab/minios.c
+++ b/tools/libs/gnttab/minios.c
@@ -74,6 +74,7 @@ int osdep_gnttab_open(xengnttab_handle *xgt)
}
file->dev = gntmap;
+ file->cloexec = true;
gntmap_init(gntmap);
xgt->fd = fd;
return 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 4/9] xenstored: don't use xenevtchn_fdopen() in stubdom
2025-07-29 11:01 [PATCH v2 0/9] Enable Xenstore-stubdom Live Update Juergen Gross
` (2 preceding siblings ...)
2025-07-29 11:01 ` [PATCH v2 3/9] libxengnttab: set the cloexec flag on Mini-OS Juergen Gross
@ 2025-07-29 11:01 ` Juergen Gross
2025-07-29 11:01 ` [PATCH v2 5/9] tools/libxenevtchn: add xenevtchn_bind() under Mini-OS Juergen Gross
` (4 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Juergen Gross @ 2025-07-29 11:01 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Julien Grall, Anthony PERARD, Jason Andryuk
When running in a stubdom environment xenevtchn_fdopen() won't work,
as any file descriptor state is lost across kexec().
Use a wrapper to replace the call of xenevtchn_fdopen() with the
really needed xenevtchn_open() when running on top of Mini-OS.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/xenstored/core.h | 3 +++
tools/xenstored/domain.c | 2 +-
tools/xenstored/minios.c | 5 +++++
tools/xenstored/posix.c | 5 +++++
4 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
index 1ba9592d16..bef24a688c 100644
--- a/tools/xenstored/core.h
+++ b/tools/xenstored/core.h
@@ -29,6 +29,7 @@
#include <stdint.h>
#include <time.h>
#include <errno.h>
+#include <xenevtchn.h>
#include "xenstore_lib.h"
#include "xenstore_state.h"
@@ -405,6 +406,8 @@ void handle_special_fds(void);
int get_socket_fd(void);
void set_socket_fd(int fd);
+xenevtchn_handle *evtchn_fdopen(int fd);
+
#ifdef __MINIOS__
void mount_9pfs(void);
#endif
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 2362216a7a..6767d29a19 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -1396,7 +1396,7 @@ void domain_init(int evtfd)
if (evtfd < 0)
xce_handle = xenevtchn_open(NULL, XENEVTCHN_NO_CLOEXEC);
else
- xce_handle = xenevtchn_fdopen(NULL, evtfd, 0);
+ xce_handle = evtchn_fdopen(evtfd);
if (xce_handle == NULL)
barf_perror("Failed to open evtchn device");
diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
index a229954cf4..aa1f03fd6b 100644
--- a/tools/xenstored/minios.c
+++ b/tools/xenstored/minios.c
@@ -85,6 +85,11 @@ void set_socket_fd(int fd)
{
}
+xenevtchn_handle *evtchn_fdopen(int fd)
+{
+ return xenevtchn_open(NULL, XENEVTCHN_NO_CLOEXEC);
+}
+
static void mount_thread(void *p)
{
xenbus_event_queue events = NULL;
diff --git a/tools/xenstored/posix.c b/tools/xenstored/posix.c
index 6037d739d0..ebdec82215 100644
--- a/tools/xenstored/posix.c
+++ b/tools/xenstored/posix.c
@@ -408,6 +408,11 @@ void set_socket_fd(int fd)
sock = fd;
}
+xenevtchn_handle *evtchn_fdopen(int fd)
+{
+ return xenevtchn_fdopen(NULL, fd, 0);
+}
+
const char *xenstore_rundir(void)
{
return xenstore_daemon_rundir();
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 5/9] tools/libxenevtchn: add xenevtchn_bind() under Mini-OS
2025-07-29 11:01 [PATCH v2 0/9] Enable Xenstore-stubdom Live Update Juergen Gross
` (3 preceding siblings ...)
2025-07-29 11:01 ` [PATCH v2 4/9] xenstored: don't use xenevtchn_fdopen() in stubdom Juergen Gross
@ 2025-07-29 11:01 ` Juergen Gross
2025-07-29 17:00 ` Anthony PERARD
2025-07-29 11:01 ` [PATCH v2 6/9] xenstored: rebind event channels after live update in stubdom Juergen Gross
` (3 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Juergen Gross @ 2025-07-29 11:01 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Anthony PERARD, Jason Andryuk
In order to reactivate an event channel after kexec() of Mini-OS,
libxenevtchn needs to allocate the port data for the event channel
and set the handler again. Add a new interface xenevtchn_bind()
for that purpose, available under Mini-OS only.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/include/xenevtchn.h | 11 +++++++++++
tools/libs/evtchn/minios.c | 17 +++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/tools/include/xenevtchn.h b/tools/include/xenevtchn.h
index 1255c85178..113a718d67 100644
--- a/tools/include/xenevtchn.h
+++ b/tools/include/xenevtchn.h
@@ -173,6 +173,17 @@ int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port);
*/
int xenevtchn_restrict(xenevtchn_handle *xce, domid_t domid);
+/**
+ * Bind an event channel under Mini-OS.
+ *
+ * Bind an event channel specified by its known port after a kexec() of
+ * Mini-OS. This function is available under Mini-OS only!
+ *
+ * @parm xce handle to the open evtchn interface
+ * @parm port the event channel to bind again
+ * @return 0 on success, -1 on failure with errno set appropriately.
+ */
+int xenevtchn_bind(xenevtchn_handle *xce, evtchn_port_t port);
#endif
/*
diff --git a/tools/libs/evtchn/minios.c b/tools/libs/evtchn/minios.c
index 0d2a201438..36e4201249 100644
--- a/tools/libs/evtchn/minios.c
+++ b/tools/libs/evtchn/minios.c
@@ -259,6 +259,23 @@ xenevtchn_port_or_error_t xenevtchn_bind_interdomain(xenevtchn_handle *xce,
return local_port;
}
+int xenevtchn_bind(xenevtchn_handle *xce, evtchn_port_t port)
+{
+ struct port_info *port_info;
+ port_info = port_alloc(xce);
+ if ( port_info == NULL )
+ return -1;
+
+ printf("xenevtchn_bind(%"PRId32")\n", port);
+ bind_evtchn(port, evtchn_handler, xce);
+
+ port_info->bound = true;
+ port_info->port = port;
+ unmask_evtchn(port);
+
+ return 0;
+}
+
int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port)
{
int fd = xce->fd;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 5/9] tools/libxenevtchn: add xenevtchn_bind() under Mini-OS
2025-07-29 11:01 ` [PATCH v2 5/9] tools/libxenevtchn: add xenevtchn_bind() under Mini-OS Juergen Gross
@ 2025-07-29 17:00 ` Anthony PERARD
2025-07-30 6:03 ` Jürgen Groß
0 siblings, 1 reply; 18+ messages in thread
From: Anthony PERARD @ 2025-07-29 17:00 UTC (permalink / raw)
To: Juergen Gross; +Cc: xen-devel, Anthony PERARD, Jason Andryuk
On Tue, Jul 29, 2025 at 01:01:41PM +0200, Juergen Gross wrote:
> In order to reactivate an event channel after kexec() of Mini-OS,
> libxenevtchn needs to allocate the port data for the event channel
> and set the handler again. Add a new interface xenevtchn_bind()
> for that purpose, available under Mini-OS only.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>
> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
> ---
> tools/include/xenevtchn.h | 11 +++++++++++
> tools/libs/evtchn/minios.c | 17 +++++++++++++++++
> 2 files changed, 28 insertions(+)
>
> diff --git a/tools/include/xenevtchn.h b/tools/include/xenevtchn.h
> index 1255c85178..113a718d67 100644
> --- a/tools/include/xenevtchn.h
> +++ b/tools/include/xenevtchn.h
> @@ -173,6 +173,17 @@ int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port);
> */
> int xenevtchn_restrict(xenevtchn_handle *xce, domid_t domid);
>
> +/**
> + * Bind an event channel under Mini-OS.
> + *
> + * Bind an event channel specified by its known port after a kexec() of
> + * Mini-OS. This function is available under Mini-OS only!
Would guarding this prototype within "#ifdef __MINIOS__" be useful to
prevent it from been used? That would give an error earlier when
compiling, rather than later when linking a binary.
In anycase: Acked-by: Anthony PERARD <anthony.perard@vates.tech>
> + *
> + * @parm xce handle to the open evtchn interface
> + * @parm port the event channel to bind again
> + * @return 0 on success, -1 on failure with errno set appropriately.
> + */
> +int xenevtchn_bind(xenevtchn_handle *xce, evtchn_port_t port);
> #endif
>
> /*
Thanks,
--
Anthony PERARD
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 5/9] tools/libxenevtchn: add xenevtchn_bind() under Mini-OS
2025-07-29 17:00 ` Anthony PERARD
@ 2025-07-30 6:03 ` Jürgen Groß
0 siblings, 0 replies; 18+ messages in thread
From: Jürgen Groß @ 2025-07-30 6:03 UTC (permalink / raw)
To: Anthony PERARD; +Cc: xen-devel, Anthony PERARD, Jason Andryuk
[-- Attachment #1.1.1: Type: text/plain, Size: 1520 bytes --]
On 29.07.25 19:00, Anthony PERARD wrote:
> On Tue, Jul 29, 2025 at 01:01:41PM +0200, Juergen Gross wrote:
>> In order to reactivate an event channel after kexec() of Mini-OS,
>> libxenevtchn needs to allocate the port data for the event channel
>> and set the handler again. Add a new interface xenevtchn_bind()
>> for that purpose, available under Mini-OS only.
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
>> ---
>> tools/include/xenevtchn.h | 11 +++++++++++
>> tools/libs/evtchn/minios.c | 17 +++++++++++++++++
>> 2 files changed, 28 insertions(+)
>>
>> diff --git a/tools/include/xenevtchn.h b/tools/include/xenevtchn.h
>> index 1255c85178..113a718d67 100644
>> --- a/tools/include/xenevtchn.h
>> +++ b/tools/include/xenevtchn.h
>> @@ -173,6 +173,17 @@ int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port);
>> */
>> int xenevtchn_restrict(xenevtchn_handle *xce, domid_t domid);
>>
>> +/**
>> + * Bind an event channel under Mini-OS.
>> + *
>> + * Bind an event channel specified by its known port after a kexec() of
>> + * Mini-OS. This function is available under Mini-OS only!
>
> Would guarding this prototype within "#ifdef __MINIOS__" be useful to
> prevent it from been used? That would give an error earlier when
> compiling, rather than later when linking a binary.
Yes, I can add that.
>
> In anycase: Acked-by: Anthony PERARD <anthony.perard@vates.tech>
Thanks,
Juergen
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 6/9] xenstored: rebind event channels after live update in stubdom
2025-07-29 11:01 [PATCH v2 0/9] Enable Xenstore-stubdom Live Update Juergen Gross
` (4 preceding siblings ...)
2025-07-29 11:01 ` [PATCH v2 5/9] tools/libxenevtchn: add xenevtchn_bind() under Mini-OS Juergen Gross
@ 2025-07-29 11:01 ` Juergen Gross
2025-07-29 11:01 ` [PATCH v2 7/9] tools/xenstored: make stubdom_init() live update aware Juergen Gross
` (2 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Juergen Gross @ 2025-07-29 11:01 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Julien Grall, Anthony PERARD, Jason Andryuk
After performing a live update in stubdom environment some information
about inter-domain event channels is lost. In order to set this
information again, call xenevtchn_bind() from new_domain() in the
restore case.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/xenstored/core.c | 1 -
tools/xenstored/core.h | 3 +++
tools/xenstored/domain.c | 8 ++++++--
tools/xenstored/minios.c | 5 +++++
tools/xenstored/posix.c | 5 +++++
5 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index 3022efdce1..e3e8607592 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -49,7 +49,6 @@
#include "control.h"
#include "lu.h"
-extern xenevtchn_handle *xce_handle; /* in domain.c */
static int xce_pollfd_idx = -1;
struct pollfd *poll_fds;
static unsigned int current_array_size;
diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
index bef24a688c..3f7426fbe3 100644
--- a/tools/xenstored/core.h
+++ b/tools/xenstored/core.h
@@ -394,6 +394,8 @@ static inline bool domain_is_unprivileged(const struct connection *conn)
return conn && domid_is_unprivileged(conn->id);
}
+extern xenevtchn_handle *xce_handle; /* in domain.c */
+
/* Return the event channel used by xenbus. */
evtchn_port_t get_xenbus_evtchn(void);
void early_init(bool live_update, bool dofork, const char *pidfile);
@@ -407,6 +409,7 @@ int get_socket_fd(void);
void set_socket_fd(int fd);
xenevtchn_handle *evtchn_fdopen(int fd);
+int evtchn_rebind(int port);
#ifdef __MINIOS__
void mount_9pfs(void);
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 6767d29a19..7a6ce5b91b 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -862,9 +862,13 @@ static int new_domain(struct domain *domain, int port, bool restore)
wrl_domain_new(domain);
- if (restore)
+ if (restore) {
+ if (evtchn_rebind(port)) {
+ errno = ENOMEM;
+ return errno;
+ }
domain->port = port;
- else {
+ } else {
/* Tell kernel we're interested in this event. */
rc = xenevtchn_bind_interdomain(xce_handle, domain->domid,
port);
diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
index aa1f03fd6b..ec5faebaf3 100644
--- a/tools/xenstored/minios.c
+++ b/tools/xenstored/minios.c
@@ -90,6 +90,11 @@ xenevtchn_handle *evtchn_fdopen(int fd)
return xenevtchn_open(NULL, XENEVTCHN_NO_CLOEXEC);
}
+int evtchn_rebind(int port)
+{
+ return xenevtchn_bind(xce_handle, port);
+}
+
static void mount_thread(void *p)
{
xenbus_event_queue events = NULL;
diff --git a/tools/xenstored/posix.c b/tools/xenstored/posix.c
index ebdec82215..97561701ae 100644
--- a/tools/xenstored/posix.c
+++ b/tools/xenstored/posix.c
@@ -413,6 +413,11 @@ xenevtchn_handle *evtchn_fdopen(int fd)
return xenevtchn_fdopen(NULL, fd, 0);
}
+int evtchn_rebind(int port)
+{
+ return 0;
+}
+
const char *xenstore_rundir(void)
{
return xenstore_daemon_rundir();
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 7/9] tools/xenstored: make stubdom_init() live update aware
2025-07-29 11:01 [PATCH v2 0/9] Enable Xenstore-stubdom Live Update Juergen Gross
` (5 preceding siblings ...)
2025-07-29 11:01 ` [PATCH v2 6/9] xenstored: rebind event channels after live update in stubdom Juergen Gross
@ 2025-07-29 11:01 ` Juergen Gross
2025-07-29 11:01 ` [PATCH v2 8/9] SUPPORT.md: add xenstorepvh-stubdom live update Juergen Gross
2025-07-29 11:01 ` [PATCH v2 9/9] CHANGELOG.md: " Juergen Gross
8 siblings, 0 replies; 18+ messages in thread
From: Juergen Gross @ 2025-07-29 11:01 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Julien Grall, Anthony PERARD, Jason Andryuk
Pass the live_update bool to stubdom_init() in order to be able to
handle it properly under Mini-OS.
As stubdom_init() will (re-)create the 9pfs device needed for
reading the saved state, call stubdom_init() before lu_read_state().
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/xenstored/core.c | 4 ++--
tools/xenstored/core.h | 2 +-
tools/xenstored/domain.c | 15 +++++++++------
tools/xenstored/domain.h | 2 +-
tools/xenstored/minios.c | 12 +++++++++---
5 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index e3e8607592..5377d72f54 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -2774,14 +2774,14 @@ int main(int argc, char *argv[])
if (tracefile)
tracefile = absolute_filename(NULL, tracefile);
+ stubdom_init(live_update);
+
#ifndef NO_LIVE_UPDATE
/* Read state in case of live update. */
if (live_update)
lu_read_state();
#endif
- stubdom_init();
-
check_store();
/* Get ready to listen to the tools. */
diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
index 3f7426fbe3..5071f1dedd 100644
--- a/tools/xenstored/core.h
+++ b/tools/xenstored/core.h
@@ -412,7 +412,7 @@ xenevtchn_handle *evtchn_fdopen(int fd);
int evtchn_rebind(int port);
#ifdef __MINIOS__
-void mount_9pfs(void);
+void mount_9pfs(bool live_update);
#endif
const char *xenstore_rundir(void);
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 7a6ce5b91b..57ca98ee5b 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -1337,7 +1337,7 @@ void dom0_init(void)
xenevtchn_notify(xce_handle, dom0->port);
}
-void stubdom_init(void)
+void stubdom_init(bool live_update)
{
#ifdef __MINIOS__
struct domain *stubdom;
@@ -1345,13 +1345,16 @@ void stubdom_init(void)
if (stub_domid < 0)
return;
- stubdom = introduce_domain(NULL, stub_domid, xenbus_evtchn, false);
- if (!stubdom)
- barf_perror("Failed to initialize stubdom");
+ if (!live_update) {
+ stubdom = introduce_domain(NULL, stub_domid, xenbus_evtchn,
+ false);
+ if (!stubdom)
+ barf_perror("Failed to initialize stubdom");
- xenevtchn_notify(xce_handle, stubdom->port);
+ xenevtchn_notify(xce_handle, stubdom->port);
+ }
- mount_9pfs();
+ mount_9pfs(live_update);
#endif
}
diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h
index 94481fdcc0..3ca702f56d 100644
--- a/tools/xenstored/domain.h
+++ b/tools/xenstored/domain.h
@@ -93,7 +93,7 @@ int do_set_feature(const void *ctx, struct connection *conn,
void domain_early_init(void);
void domain_init(int evtfd);
void dom0_init(void);
-void stubdom_init(void);
+void stubdom_init(bool live_update);
void domain_deinit(void);
void ignore_connection(struct connection *conn, unsigned int err);
diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
index ec5faebaf3..f04423fe09 100644
--- a/tools/xenstored/minios.c
+++ b/tools/xenstored/minios.c
@@ -131,15 +131,21 @@ static void mount_thread(void *p)
free(err);
}
- p9_device = init_9pfront(0, XENSTORE_LIB_DIR);
+ p9_device = init_9pfront2(0, XENSTORE_LIB_DIR, INIT9P_FLAG_KEXEC);
/* Start logging if selected. */
reopen_log();
}
-void mount_9pfs(void)
+void mount_9pfs(bool live_update)
{
- create_thread("mount-9pfs", mount_thread, NULL);
+ if (!live_update)
+ create_thread("mount-9pfs", mount_thread, NULL);
+ else {
+ p9_device = init_9pfront2(0, XENSTORE_LIB_DIR,
+ INIT9P_FLAG_REINIT);
+ reopen_log();
+ }
}
const char *xenstore_rundir(void)
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 8/9] SUPPORT.md: add xenstorepvh-stubdom live update
2025-07-29 11:01 [PATCH v2 0/9] Enable Xenstore-stubdom Live Update Juergen Gross
` (6 preceding siblings ...)
2025-07-29 11:01 ` [PATCH v2 7/9] tools/xenstored: make stubdom_init() live update aware Juergen Gross
@ 2025-07-29 11:01 ` Juergen Gross
2025-07-29 11:01 ` [PATCH v2 9/9] CHANGELOG.md: " Juergen Gross
8 siblings, 0 replies; 18+ messages in thread
From: Juergen Gross @ 2025-07-29 11:01 UTC (permalink / raw)
To: xen-devel
Cc: Juergen Gross, Andrew Cooper, Anthony PERARD, Michal Orzel,
Jan Beulich, Julien Grall, Roger Pau Monné,
Stefano Stabellini
Live update is now working with the PVH variant of xenstore-stubdom.
Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- new patch
---
SUPPORT.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SUPPORT.md b/SUPPORT.md
index 6a82a92189..eb44ee85fd 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -280,7 +280,7 @@ or itself will not be regarded a security issue.
### C xenstore stubdom PVH
Status: Supported
- Status, Liveupdate: Not implemented
+ Status, Liveupdate: Supported
### OCaml xenstored daemon
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 9/9] CHANGELOG.md: add xenstorepvh-stubdom live update
2025-07-29 11:01 [PATCH v2 0/9] Enable Xenstore-stubdom Live Update Juergen Gross
` (7 preceding siblings ...)
2025-07-29 11:01 ` [PATCH v2 8/9] SUPPORT.md: add xenstorepvh-stubdom live update Juergen Gross
@ 2025-07-29 11:01 ` Juergen Gross
8 siblings, 0 replies; 18+ messages in thread
From: Juergen Gross @ 2025-07-29 11:01 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Oleksii Kurochko, Community Manager
Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- new patch
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5f31ca08fe..d118bb1c8c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Support PCI passthrough for HVM domUs when dom0 is PVH (note SR-IOV
capability usage is not yet supported on PVH dom0).
- Smoke tests for the FreeBSD Xen builds in Cirrus CI.
+ - PVH xenstore-stubdom now supports Live Update.
- On Arm:
- Ability to enable stack protector
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread