From: Paul Durrant <pdurrant@amazon.com>
... and update xen-domctx to dump some information describing the record.
NOTE: Processing of the content during restore is currently limited to
PV domains, and matches processing of the PV-only SHARED_INFO record
done by libxc. All content is, however, saved such that restore
processing can be modified in future without requiring a new record
format.
Signed-off-by: Paul Durrant <pdurrant@amazon.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Ian Jackson <iwj@xenproject.org>
Cc: Wei Liu <wl@xen.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Julien Grall <julien@xen.org>
Cc: Stefano Stabellini <sstabellini@kernel.org>
v10:
- Re-base
- Amend the specification now there is one
- Dropped Jan's R-b as modifications are not completely trivial
v9:
- Use macros to make the code less verbose
- Add missing check for allocation failure
v8:
- Incorporate zero-ing out of shared info fields that would be done in
processing of SHARED_INFO from older stream versions
v7:
- Only restore vcpu_info and arch sub-structures for PV domains, to match
processing of SHARED_INFO in xc_sr_restore_x86_pv.c
- Use additional option to domain_load_end() to ignore the record for
HVM domains
v6:
- Only save compat_shared_info buffer if has_32bit_shinfo is set
- Validate flags field in load handler
v5:
- Addressed comments from Julien
v4:
- Addressed comments from Jan
v3:
- Actually dump some of the content of shared_info
v2:
- Drop the header change to define a 'Xen' page size and instead use a
variable length struct now that the framework makes this is feasible
- Guard use of 'has_32bit_shinfo' in common code with CONFIG_COMPAT
---
docs/specs/domain-context.md | 29 +++++++++
tools/misc/xen-domctx.c | 80 +++++++++++++++++++++++++
xen/common/domain.c | 113 +++++++++++++++++++++++++++++++++++
xen/include/public/save.h | 11 ++++
4 files changed, 233 insertions(+)
diff --git a/docs/specs/domain-context.md b/docs/specs/domain-context.md
index f177cf24b3..95e9f9d1ab 100644
--- a/docs/specs/domain-context.md
+++ b/docs/specs/domain-context.md
@@ -128,6 +128,33 @@ can no longer be safely inferred.
A record of this type terminates the image. No further data from the buffer
should be consumed.
+### SHARED_INFO
+
+```
+ 0 1 2 3 4 5 6 7 octet
++-------+-------+-------+-------+-------+-------+-------+-------+
+| type == 2 | instance == 0 |
++-------------------------------+-------------------------------+
+| length |
++-------------------------------+-------------------------------+
+| flags | buffer
++-------------------------------+
+...
+```
+
+\pagebreak
+The record body contains the following fields:
+
+| Field | Description |
+|-------------|-------------------------------------------------|
+| `flags` | A bit-wise OR of the following: |
+| | |
+| | 0x00000001: The domain has 32-bit (compat) |
+| | shared info |
+| | |
+| `buffer` | The shared info (`length` being architecture |
+| | dependent[4]) |
+
* * *
[1] See https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/designs/non-cooperative-migration.md
@@ -135,3 +162,5 @@ should be consumed.
[2] See https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=xen/include/public/hvm/save.h
[3] See https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/specs/libxc-migration-stream.pandoc
+
+[4] See https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=tools/include/xen-foreign/reference.size
diff --git a/tools/misc/xen-domctx.c b/tools/misc/xen-domctx.c
index ca135b9a28..5ea6de50d1 100644
--- a/tools/misc/xen-domctx.c
+++ b/tools/misc/xen-domctx.c
@@ -57,6 +57,85 @@ static void dump_start(void)
printf(" START: Xen %u.%u\n", s->xen_major, s->xen_minor);
}
+static void print_binary(const char *prefix, const void *val, size_t size,
+ const char *suffix)
+{
+ printf("%s", prefix);
+
+ while ( size-- )
+ {
+ uint8_t octet = *(const uint8_t *)val++;
+ unsigned int i;
+
+ for ( i = 0; i < 8; i++ )
+ {
+ printf("%u", octet & 1);
+ octet >>= 1;
+ }
+ }
+
+ printf("%s", suffix);
+}
+
+static void dump_shared_info(void)
+{
+ struct domain_context_shared_info *s;
+ bool has_32bit_shinfo;
+ shared_info_any_t *info;
+ unsigned int i, n;
+
+ GET_PTR(s);
+ has_32bit_shinfo = s->flags & DOMAIN_CONTEXT_32BIT_SHARED_INFO;
+
+ printf(" SHARED_INFO: has_32bit_shinfo: %s\n",
+ has_32bit_shinfo ? "true" : "false");
+
+ info = (shared_info_any_t *)s->buffer;
+
+#define GET_FIELD_PTR(_f) \
+ (has_32bit_shinfo ? \
+ (const void *)&(info->x32._f) : \
+ (const void *)&(info->x64._f))
+#define GET_FIELD_SIZE(_f) \
+ (has_32bit_shinfo ? sizeof(info->x32._f) : sizeof(info->x64._f))
+#define GET_FIELD(_f) \
+ (has_32bit_shinfo ? info->x32._f : info->x64._f)
+
+ n = has_32bit_shinfo ?
+ ARRAY_SIZE(info->x32.evtchn_pending) :
+ ARRAY_SIZE(info->x64.evtchn_pending);
+
+ for ( i = 0; i < n; i++ )
+ {
+ const char *prefix = !i ?
+ " evtchn_pending: " :
+ " ";
+
+ print_binary(prefix, GET_FIELD_PTR(evtchn_pending[0]),
+ GET_FIELD_SIZE(evtchn_pending[0]), "\n");
+ }
+
+ for ( i = 0; i < n; i++ )
+ {
+ const char *prefix = !i ?
+ " evtchn_mask: " :
+ " ";
+
+ print_binary(prefix, GET_FIELD_PTR(evtchn_mask[0]),
+ GET_FIELD_SIZE(evtchn_mask[0]), "\n");
+ }
+
+ printf(" wc: version: %u sec: %u nsec: %u",
+ GET_FIELD(wc_version), GET_FIELD(wc_sec), GET_FIELD(wc_nsec));
+ if ( !has_32bit_shinfo )
+ printf(" sec_hi: %u", info->x64.xen_wc_sec_hi);
+ printf("\n");
+
+#undef GET_FIELD
+#undef GET_FIELD_SIZE
+#undef GET_FIELD_PTR
+}
+
static void dump_end(void)
{
struct domain_context_end *e;
@@ -145,6 +224,7 @@ int main(int argc, char **argv)
switch (rec->type)
{
case DOMAIN_CONTEXT_START: dump_start(); break;
+ case DOMAIN_CONTEXT_SHARED_INFO: dump_shared_info(); break;
case DOMAIN_CONTEXT_END: dump_end(); break;
default:
printf("Unknown type %u: skipping\n", rec->type);
diff --git a/xen/common/domain.c b/xen/common/domain.c
index f748806a45..6c223dae38 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -33,6 +33,7 @@
#include <xen/xenoprof.h>
#include <xen/irq.h>
#include <xen/argo.h>
+#include <xen/save.h>
#include <asm/debugger.h>
#include <asm/p2m.h>
#include <asm/processor.h>
@@ -1671,6 +1672,118 @@ int continue_hypercall_on_cpu(
return 0;
}
+static int save_shared_info(struct domain *d, struct domain_ctxt_state *c,
+ bool dry_run)
+{
+#ifdef CONFIG_COMPAT
+ struct domain_context_shared_info s = {
+ .flags = has_32bit_shinfo(d) ? DOMAIN_CONTEXT_32BIT_SHARED_INFO : 0,
+ };
+ size_t size = has_32bit_shinfo(d) ?
+ sizeof(struct compat_shared_info) :
+ sizeof(struct shared_info);
+#else
+ struct domain_context_shared_info s = {};
+ size_t size = sizeof(struct shared_info);
+#endif
+ int rc;
+
+ rc = domain_save_ctxt_rec_begin(c, DOMAIN_CONTEXT_SHARED_INFO, 0);
+ if ( rc )
+ return rc;
+
+ rc = domain_save_ctxt_rec_data(c, &s, offsetof(typeof(s), buffer));
+ if ( rc )
+ return rc;
+
+ rc = domain_save_ctxt_rec_data(c, d->shared_info, size);
+ if ( rc )
+ return rc;
+
+ return domain_save_ctxt_rec_end(c);
+}
+
+static int load_shared_info(struct domain *d, struct domain_ctxt_state *c)
+{
+ struct domain_context_shared_info s = {};
+ size_t size;
+ unsigned int i;
+ int rc;
+
+ rc = domain_load_ctxt_rec_begin(c, DOMAIN_CONTEXT_SHARED_INFO, &i);
+ if ( rc )
+ return rc;
+
+ if ( i ) /* expect only a single instance */
+ return -ENXIO;
+
+ rc = domain_load_ctxt_rec_data(c, &s, offsetof(typeof(s), buffer));
+ if ( rc )
+ return rc;
+
+ if ( s.flags & ~DOMAIN_CONTEXT_32BIT_SHARED_INFO )
+ return -EINVAL;
+
+ if ( s.flags & DOMAIN_CONTEXT_32BIT_SHARED_INFO )
+ {
+#ifdef CONFIG_COMPAT
+ d->arch.has_32bit_shinfo = true;
+ size = sizeof(struct compat_shared_info);
+#else
+ return -EINVAL;
+#endif
+ }
+ else
+ size = sizeof(struct shared_info);
+
+ if ( is_pv_domain(d) )
+ {
+ shared_info_t *shinfo = xzalloc(shared_info_t);
+
+ if ( !shinfo )
+ return -ENOMEM;
+
+ rc = domain_load_ctxt_rec_data(c, shinfo, size);
+ if ( rc )
+ goto out;
+
+ memcpy(&shared_info(d, vcpu_info), &__shared_info(d, shinfo, vcpu_info),
+ sizeof(shared_info(d, vcpu_info)));
+ memcpy(&shared_info(d, arch), &__shared_info(d, shinfo, arch),
+ sizeof(shared_info(d, arch)));
+
+ memset(&shared_info(d, evtchn_pending), 0,
+ sizeof(shared_info(d, evtchn_pending)));
+ memset(&shared_info(d, evtchn_mask), 0xff,
+ sizeof(shared_info(d, evtchn_mask)));
+
+#ifdef CONFIG_X86
+ shared_info(d, arch.pfn_to_mfn_frame_list_list) = 0;
+#endif
+ for ( i = 0; i < XEN_LEGACY_MAX_VCPUS; i++ )
+ shared_info(d, vcpu_info[i].evtchn_pending_sel) = 0;
+
+ rc = domain_load_ctxt_rec_end(c, false);
+
+ out:
+ xfree(shinfo);
+ }
+ else
+ {
+ /*
+ * No modifications to shared_info are required for restoring non-PV
+ * domains.
+ */
+ rc = domain_load_ctxt_rec_data(c, NULL, size);
+ if ( !rc )
+ rc = domain_load_ctxt_rec_end(c, true);
+ }
+
+ return rc;
+}
+
+DOMAIN_REGISTER_CTXT_TYPE(SHARED_INFO, save_shared_info, load_shared_info);
+
/*
* Local variables:
* mode: C
diff --git a/xen/include/public/save.h b/xen/include/public/save.h
index c4be9f570c..bccbaadd0b 100644
--- a/xen/include/public/save.h
+++ b/xen/include/public/save.h
@@ -49,6 +49,7 @@ struct domain_context_record {
enum {
DOMAIN_CONTEXT_END,
DOMAIN_CONTEXT_START,
+ DOMAIN_CONTEXT_SHARED_INFO,
/* New types go here */
DOMAIN_CONTEXT_NR_TYPES
};
@@ -58,6 +59,16 @@ struct domain_context_start {
uint32_t xen_major, xen_minor;
};
+struct domain_context_shared_info {
+ uint32_t flags;
+
+#define _DOMAIN_CONTEXT_32BIT_SHARED_INFO 0
+#define DOMAIN_CONTEXT_32BIT_SHARED_INFO \
+ (1U << _DOMAIN_CONTEXT_32BIT_SHARED_INFO)
+
+ uint8_t buffer[XEN_FLEX_ARRAY_DIM];
+};
+
/* Terminating entry */
struct domain_context_end {};
--
2.20.1
... and update xen-domctx to dump some information describing the record.
NOTE: Processing of the content during restore is currently limited to
PV domains, and matches processing of the PV-only SHARED_INFO record
done by libxc. All content is, however, saved such that restore
processing can be modified in future without requiring a new record
format.
Signed-off-by: Paul Durrant <pdurrant@amazon.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Ian Jackson <iwj@xenproject.org>
Cc: Wei Liu <wl@xen.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Julien Grall <julien@xen.org>
Cc: Stefano Stabellini <sstabellini@kernel.org>
v10:
- Re-base
- Amend the specification now there is one
- Dropped Jan's R-b as modifications are not completely trivial
v9:
- Use macros to make the code less verbose
- Add missing check for allocation failure
v8:
- Incorporate zero-ing out of shared info fields that would be done in
processing of SHARED_INFO from older stream versions
v7:
- Only restore vcpu_info and arch sub-structures for PV domains, to match
processing of SHARED_INFO in xc_sr_restore_x86_pv.c
- Use additional option to domain_load_end() to ignore the record for
HVM domains
v6:
- Only save compat_shared_info buffer if has_32bit_shinfo is set
- Validate flags field in load handler
v5:
- Addressed comments from Julien
v4:
- Addressed comments from Jan
v3:
- Actually dump some of the content of shared_info
v2:
- Drop the header change to define a 'Xen' page size and instead use a
variable length struct now that the framework makes this is feasible
- Guard use of 'has_32bit_shinfo' in common code with CONFIG_COMPAT
---
docs/specs/domain-context.md | 29 +++++++++
tools/misc/xen-domctx.c | 80 +++++++++++++++++++++++++
xen/common/domain.c | 113 +++++++++++++++++++++++++++++++++++
xen/include/public/save.h | 11 ++++
4 files changed, 233 insertions(+)
diff --git a/docs/specs/domain-context.md b/docs/specs/domain-context.md
index f177cf24b3..95e9f9d1ab 100644
--- a/docs/specs/domain-context.md
+++ b/docs/specs/domain-context.md
@@ -128,6 +128,33 @@ can no longer be safely inferred.
A record of this type terminates the image. No further data from the buffer
should be consumed.
+### SHARED_INFO
+
+```
+ 0 1 2 3 4 5 6 7 octet
++-------+-------+-------+-------+-------+-------+-------+-------+
+| type == 2 | instance == 0 |
++-------------------------------+-------------------------------+
+| length |
++-------------------------------+-------------------------------+
+| flags | buffer
++-------------------------------+
+...
+```
+
+\pagebreak
+The record body contains the following fields:
+
+| Field | Description |
+|-------------|-------------------------------------------------|
+| `flags` | A bit-wise OR of the following: |
+| | |
+| | 0x00000001: The domain has 32-bit (compat) |
+| | shared info |
+| | |
+| `buffer` | The shared info (`length` being architecture |
+| | dependent[4]) |
+
* * *
[1] See https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/designs/non-cooperative-migration.md
@@ -135,3 +162,5 @@ should be consumed.
[2] See https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=xen/include/public/hvm/save.h
[3] See https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/specs/libxc-migration-stream.pandoc
+
+[4] See https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=tools/include/xen-foreign/reference.size
diff --git a/tools/misc/xen-domctx.c b/tools/misc/xen-domctx.c
index ca135b9a28..5ea6de50d1 100644
--- a/tools/misc/xen-domctx.c
+++ b/tools/misc/xen-domctx.c
@@ -57,6 +57,85 @@ static void dump_start(void)
printf(" START: Xen %u.%u\n", s->xen_major, s->xen_minor);
}
+static void print_binary(const char *prefix, const void *val, size_t size,
+ const char *suffix)
+{
+ printf("%s", prefix);
+
+ while ( size-- )
+ {
+ uint8_t octet = *(const uint8_t *)val++;
+ unsigned int i;
+
+ for ( i = 0; i < 8; i++ )
+ {
+ printf("%u", octet & 1);
+ octet >>= 1;
+ }
+ }
+
+ printf("%s", suffix);
+}
+
+static void dump_shared_info(void)
+{
+ struct domain_context_shared_info *s;
+ bool has_32bit_shinfo;
+ shared_info_any_t *info;
+ unsigned int i, n;
+
+ GET_PTR(s);
+ has_32bit_shinfo = s->flags & DOMAIN_CONTEXT_32BIT_SHARED_INFO;
+
+ printf(" SHARED_INFO: has_32bit_shinfo: %s\n",
+ has_32bit_shinfo ? "true" : "false");
+
+ info = (shared_info_any_t *)s->buffer;
+
+#define GET_FIELD_PTR(_f) \
+ (has_32bit_shinfo ? \
+ (const void *)&(info->x32._f) : \
+ (const void *)&(info->x64._f))
+#define GET_FIELD_SIZE(_f) \
+ (has_32bit_shinfo ? sizeof(info->x32._f) : sizeof(info->x64._f))
+#define GET_FIELD(_f) \
+ (has_32bit_shinfo ? info->x32._f : info->x64._f)
+
+ n = has_32bit_shinfo ?
+ ARRAY_SIZE(info->x32.evtchn_pending) :
+ ARRAY_SIZE(info->x64.evtchn_pending);
+
+ for ( i = 0; i < n; i++ )
+ {
+ const char *prefix = !i ?
+ " evtchn_pending: " :
+ " ";
+
+ print_binary(prefix, GET_FIELD_PTR(evtchn_pending[0]),
+ GET_FIELD_SIZE(evtchn_pending[0]), "\n");
+ }
+
+ for ( i = 0; i < n; i++ )
+ {
+ const char *prefix = !i ?
+ " evtchn_mask: " :
+ " ";
+
+ print_binary(prefix, GET_FIELD_PTR(evtchn_mask[0]),
+ GET_FIELD_SIZE(evtchn_mask[0]), "\n");
+ }
+
+ printf(" wc: version: %u sec: %u nsec: %u",
+ GET_FIELD(wc_version), GET_FIELD(wc_sec), GET_FIELD(wc_nsec));
+ if ( !has_32bit_shinfo )
+ printf(" sec_hi: %u", info->x64.xen_wc_sec_hi);
+ printf("\n");
+
+#undef GET_FIELD
+#undef GET_FIELD_SIZE
+#undef GET_FIELD_PTR
+}
+
static void dump_end(void)
{
struct domain_context_end *e;
@@ -145,6 +224,7 @@ int main(int argc, char **argv)
switch (rec->type)
{
case DOMAIN_CONTEXT_START: dump_start(); break;
+ case DOMAIN_CONTEXT_SHARED_INFO: dump_shared_info(); break;
case DOMAIN_CONTEXT_END: dump_end(); break;
default:
printf("Unknown type %u: skipping\n", rec->type);
diff --git a/xen/common/domain.c b/xen/common/domain.c
index f748806a45..6c223dae38 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -33,6 +33,7 @@
#include <xen/xenoprof.h>
#include <xen/irq.h>
#include <xen/argo.h>
+#include <xen/save.h>
#include <asm/debugger.h>
#include <asm/p2m.h>
#include <asm/processor.h>
@@ -1671,6 +1672,118 @@ int continue_hypercall_on_cpu(
return 0;
}
+static int save_shared_info(struct domain *d, struct domain_ctxt_state *c,
+ bool dry_run)
+{
+#ifdef CONFIG_COMPAT
+ struct domain_context_shared_info s = {
+ .flags = has_32bit_shinfo(d) ? DOMAIN_CONTEXT_32BIT_SHARED_INFO : 0,
+ };
+ size_t size = has_32bit_shinfo(d) ?
+ sizeof(struct compat_shared_info) :
+ sizeof(struct shared_info);
+#else
+ struct domain_context_shared_info s = {};
+ size_t size = sizeof(struct shared_info);
+#endif
+ int rc;
+
+ rc = domain_save_ctxt_rec_begin(c, DOMAIN_CONTEXT_SHARED_INFO, 0);
+ if ( rc )
+ return rc;
+
+ rc = domain_save_ctxt_rec_data(c, &s, offsetof(typeof(s), buffer));
+ if ( rc )
+ return rc;
+
+ rc = domain_save_ctxt_rec_data(c, d->shared_info, size);
+ if ( rc )
+ return rc;
+
+ return domain_save_ctxt_rec_end(c);
+}
+
+static int load_shared_info(struct domain *d, struct domain_ctxt_state *c)
+{
+ struct domain_context_shared_info s = {};
+ size_t size;
+ unsigned int i;
+ int rc;
+
+ rc = domain_load_ctxt_rec_begin(c, DOMAIN_CONTEXT_SHARED_INFO, &i);
+ if ( rc )
+ return rc;
+
+ if ( i ) /* expect only a single instance */
+ return -ENXIO;
+
+ rc = domain_load_ctxt_rec_data(c, &s, offsetof(typeof(s), buffer));
+ if ( rc )
+ return rc;
+
+ if ( s.flags & ~DOMAIN_CONTEXT_32BIT_SHARED_INFO )
+ return -EINVAL;
+
+ if ( s.flags & DOMAIN_CONTEXT_32BIT_SHARED_INFO )
+ {
+#ifdef CONFIG_COMPAT
+ d->arch.has_32bit_shinfo = true;
+ size = sizeof(struct compat_shared_info);
+#else
+ return -EINVAL;
+#endif
+ }
+ else
+ size = sizeof(struct shared_info);
+
+ if ( is_pv_domain(d) )
+ {
+ shared_info_t *shinfo = xzalloc(shared_info_t);
+
+ if ( !shinfo )
+ return -ENOMEM;
+
+ rc = domain_load_ctxt_rec_data(c, shinfo, size);
+ if ( rc )
+ goto out;
+
+ memcpy(&shared_info(d, vcpu_info), &__shared_info(d, shinfo, vcpu_info),
+ sizeof(shared_info(d, vcpu_info)));
+ memcpy(&shared_info(d, arch), &__shared_info(d, shinfo, arch),
+ sizeof(shared_info(d, arch)));
+
+ memset(&shared_info(d, evtchn_pending), 0,
+ sizeof(shared_info(d, evtchn_pending)));
+ memset(&shared_info(d, evtchn_mask), 0xff,
+ sizeof(shared_info(d, evtchn_mask)));
+
+#ifdef CONFIG_X86
+ shared_info(d, arch.pfn_to_mfn_frame_list_list) = 0;
+#endif
+ for ( i = 0; i < XEN_LEGACY_MAX_VCPUS; i++ )
+ shared_info(d, vcpu_info[i].evtchn_pending_sel) = 0;
+
+ rc = domain_load_ctxt_rec_end(c, false);
+
+ out:
+ xfree(shinfo);
+ }
+ else
+ {
+ /*
+ * No modifications to shared_info are required for restoring non-PV
+ * domains.
+ */
+ rc = domain_load_ctxt_rec_data(c, NULL, size);
+ if ( !rc )
+ rc = domain_load_ctxt_rec_end(c, true);
+ }
+
+ return rc;
+}
+
+DOMAIN_REGISTER_CTXT_TYPE(SHARED_INFO, save_shared_info, load_shared_info);
+
/*
* Local variables:
* mode: C
diff --git a/xen/include/public/save.h b/xen/include/public/save.h
index c4be9f570c..bccbaadd0b 100644
--- a/xen/include/public/save.h
+++ b/xen/include/public/save.h
@@ -49,6 +49,7 @@ struct domain_context_record {
enum {
DOMAIN_CONTEXT_END,
DOMAIN_CONTEXT_START,
+ DOMAIN_CONTEXT_SHARED_INFO,
/* New types go here */
DOMAIN_CONTEXT_NR_TYPES
};
@@ -58,6 +59,16 @@ struct domain_context_start {
uint32_t xen_major, xen_minor;
};
+struct domain_context_shared_info {
+ uint32_t flags;
+
+#define _DOMAIN_CONTEXT_32BIT_SHARED_INFO 0
+#define DOMAIN_CONTEXT_32BIT_SHARED_INFO \
+ (1U << _DOMAIN_CONTEXT_32BIT_SHARED_INFO)
+
+ uint8_t buffer[XEN_FLEX_ARRAY_DIM];
+};
+
/* Terminating entry */
struct domain_context_end {};
--
2.20.1