The new xenstore page allocation scheme might break older unpatches
Linux kernels that do not check for the Xenstore connection status
before proceeding with Xenstore initialization.
Introduce a dom0less configuration option to retain the older behavior.
The older behavior triggered by this option is to allocate the xenstore
page in init-dom0less. That does not work with static-mem guests.
However, it will make it possible to run as regular guests older Linux
kernel versions that are left unpatched.
Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
---
Changes in v6:
- improve wording in commit message and doc
- code style
- add separate alloc_xenstore_params function
docs/misc/arm/device-tree/booting.txt | 5 +++
xen/arch/arm/dom0less-build.c | 45 +++++++++++++++++++--------
xen/arch/arm/include/asm/kernel.h | 30 +++++++++++-------
3 files changed, 56 insertions(+), 24 deletions(-)
diff --git a/docs/misc/arm/device-tree/booting.txt b/docs/misc/arm/device-tree/booting.txt
index 9c881baccc..4d6d859c66 100644
--- a/docs/misc/arm/device-tree/booting.txt
+++ b/docs/misc/arm/device-tree/booting.txt
@@ -222,6 +222,11 @@ with the following properties:
Xen PV interfaces, including grant-table and xenstore, will be
enabled for the VM.
+ - "legacy"
+ Same as above, but the way the xenstore page is allocated is not
+ compatible with static-mem guests. On the other hand, it works with
+ older Linux kernels.
+
- "disabled"
Xen PV interfaces are disabled.
diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
index 6c51f91999..56eb5c6da6 100644
--- a/xen/arch/arm/dom0less-build.c
+++ b/xen/arch/arm/dom0less-build.c
@@ -755,6 +755,30 @@ static int __init alloc_xenstore_page(struct domain *d)
return 0;
}
+static int __init alloc_xenstore_params(struct domain *d,
+ struct kernel_info *kinfo)
+{
+ int rc = 0;
+
+ if ( kinfo->dom0less_feature & (DOM0LESS_XENSTORE | DOM0LESS_XS_LEGACY) )
+ {
+ ASSERT(hardware_domain);
+ rc = alloc_xenstore_evtchn(d);
+ if ( rc < 0 )
+ return rc;
+ d->arch.hvm.params[HVM_PARAM_STORE_PFN] = ~0ULL;
+ }
+
+ if ( kinfo->dom0less_feature & DOM0LESS_XENSTORE )
+ {
+ rc = alloc_xenstore_page(d);
+ if ( rc < 0 )
+ return rc;
+ }
+
+ return rc;
+}
+
static int __init construct_domU(struct domain *d,
const struct dt_device_node *node)
{
@@ -800,6 +824,13 @@ static int __init construct_domU(struct domain *d,
else
panic("At the moment, Xenstore support requires dom0 to be present\n");
}
+ else if ( rc == 0 && !strcmp(dom0less_enhanced, "legacy") )
+ {
+ if ( hardware_domain )
+ kinfo.dom0less_feature = DOM0LESS_ENHANCED_LEGACY;
+ else
+ panic("At the moment, Xenstore support requires dom0 to be present\n");
+ }
else if ( rc == 0 && !strcmp(dom0less_enhanced, "no-xenstore") )
kinfo.dom0less_feature = DOM0LESS_ENHANCED_NO_XS;
@@ -849,19 +880,7 @@ static int __init construct_domU(struct domain *d,
if ( rc < 0 )
return rc;
- if ( kinfo.dom0less_feature & DOM0LESS_XENSTORE )
- {
- ASSERT(hardware_domain);
- rc = alloc_xenstore_evtchn(d);
- if ( rc < 0 )
- return rc;
-
- rc = alloc_xenstore_page(d);
- if ( rc < 0 )
- return rc;
- }
-
- return rc;
+ return alloc_xenstore_params(d, &kinfo);
}
void __init create_domUs(void)
diff --git a/xen/arch/arm/include/asm/kernel.h b/xen/arch/arm/include/asm/kernel.h
index de3f945ae5..bdc96f4c18 100644
--- a/xen/arch/arm/include/asm/kernel.h
+++ b/xen/arch/arm/include/asm/kernel.h
@@ -13,20 +13,28 @@
/*
* List of possible features for dom0less domUs
*
- * DOM0LESS_ENHANCED_NO_XS: Notify the OS it is running on top of Xen. All the
- * default features (excluding Xenstore) will be
- * available. Note that an OS *must* not rely on the
- * availability of Xen features if this is not set.
- * DOM0LESS_XENSTORE: Xenstore will be enabled for the VM. This feature
- * can't be enabled without the
- * DOM0LESS_ENHANCED_NO_XS.
- * DOM0LESS_ENHANCED: Notify the OS it is running on top of Xen. All the
- * default features (including Xenstore) will be
- * available. Note that an OS *must* not rely on the
- * availability of Xen features if this is not set.
+ * DOM0LESS_ENHANCED_NO_XS: Notify the OS it is running on top of Xen. All the
+ * default features (excluding Xenstore) will be
+ * available. Note that an OS *must* not rely on the
+ * availability of Xen features if this is not set.
+ * DOM0LESS_XENSTORE: Xenstore will be enabled for the VM. The
+ * xenstore page allocation is done by Xen at
+ * domain creation. This feature can't be
+ * enabled without the DOM0LESS_ENHANCED_NO_XS.
+ * DOM0LESS_XS_LEGACY Xenstore will be enabled for the VM, the
+ * xenstore page allocation will happen in
+ * init-dom0less. This feature can't be enabled
+ * without the DOM0LESS_ENHANCED_NO_XS.
+ * DOM0LESS_ENHANCED: Notify the OS it is running on top of Xen. All the
+ * default features (including Xenstore) will be
+ * available. Note that an OS *must* not rely on the
+ * availability of Xen features if this is not set.
+ * DOM0LESS_ENHANCED_LEGACY: Same as before, but using DOM0LESS_XS_LEGACY.
*/
#define DOM0LESS_ENHANCED_NO_XS BIT(0, U)
#define DOM0LESS_XENSTORE BIT(1, U)
+#define DOM0LESS_XS_LEGACY BIT(2, U)
+#define DOM0LESS_ENHANCED_LEGACY (DOM0LESS_ENHANCED_NO_XS | DOM0LESS_XS_LEGACY)
#define DOM0LESS_ENHANCED (DOM0LESS_ENHANCED_NO_XS | DOM0LESS_XENSTORE)
struct kernel_info {
--
2.25.1
On 07/02/2025 02:53, Stefano Stabellini wrote:
> The new xenstore page allocation scheme might break older unpatches
s/unpatches/unpatched
> Linux kernels that do not check for the Xenstore connection status
> before proceeding with Xenstore initialization.
>
> Introduce a dom0less configuration option to retain the older behavior.
>
> The older behavior triggered by this option is to allocate the xenstore
> page in init-dom0less. That does not work with static-mem guests.
> However, it will make it possible to run as regular guests older Linux
> kernel versions that are left unpatched.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
> ---
> Changes in v6:
> - improve wording in commit message and doc
> - code style
> - add separate alloc_xenstore_params function
>
> docs/misc/arm/device-tree/booting.txt | 5 +++
> xen/arch/arm/dom0less-build.c | 45 +++++++++++++++++++--------
> xen/arch/arm/include/asm/kernel.h | 30 +++++++++++-------
> 3 files changed, 56 insertions(+), 24 deletions(-)
>
> diff --git a/docs/misc/arm/device-tree/booting.txt b/docs/misc/arm/device-tree/booting.txt
> index 9c881baccc..4d6d859c66 100644
> --- a/docs/misc/arm/device-tree/booting.txt
> +++ b/docs/misc/arm/device-tree/booting.txt
> @@ -222,6 +222,11 @@ with the following properties:
> Xen PV interfaces, including grant-table and xenstore, will be
> enabled for the VM.
>
> + - "legacy"
> + Same as above, but the way the xenstore page is allocated is not
> + compatible with static-mem guests. On the other hand, it works with
> + older Linux kernels.
> +
> - "disabled"
> Xen PV interfaces are disabled.
>
> diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
> index 6c51f91999..56eb5c6da6 100644
> --- a/xen/arch/arm/dom0less-build.c
> +++ b/xen/arch/arm/dom0less-build.c
> @@ -755,6 +755,30 @@ static int __init alloc_xenstore_page(struct domain *d)
> return 0;
> }
>
> +static int __init alloc_xenstore_params(struct domain *d,
> + struct kernel_info *kinfo)
NIT: We should not pass struct domain if we pass struct kernel_info from which we can simply
derive domain pointer. I see this as a bad code practice. I know we have many functions like
that but for new functions I try not to repeat this.
> +{
> + int rc = 0;
> +
> + if ( kinfo->dom0less_feature & (DOM0LESS_XENSTORE | DOM0LESS_XS_LEGACY) )
> + {
> + ASSERT(hardware_domain);
> + rc = alloc_xenstore_evtchn(d);
> + if ( rc < 0 )
> + return rc;
> + d->arch.hvm.params[HVM_PARAM_STORE_PFN] = ~0ULL;
> + }
> +
> + if ( kinfo->dom0less_feature & DOM0LESS_XENSTORE )
> + {
> + rc = alloc_xenstore_page(d);
> + if ( rc < 0 )
> + return rc;
> + }
> +
> + return rc;
> +}
> +
> static int __init construct_domU(struct domain *d,
> const struct dt_device_node *node)
> {
> @@ -800,6 +824,13 @@ static int __init construct_domU(struct domain *d,
> else
> panic("At the moment, Xenstore support requires dom0 to be present\n");
> }
> + else if ( rc == 0 && !strcmp(dom0less_enhanced, "legacy") )
> + {
> + if ( hardware_domain )
> + kinfo.dom0less_feature = DOM0LESS_ENHANCED_LEGACY;
> + else
> + panic("At the moment, Xenstore support requires dom0 to be present\n");
> + }
> else if ( rc == 0 && !strcmp(dom0less_enhanced, "no-xenstore") )
> kinfo.dom0less_feature = DOM0LESS_ENHANCED_NO_XS;
>
> @@ -849,19 +880,7 @@ static int __init construct_domU(struct domain *d,
> if ( rc < 0 )
> return rc;
>
> - if ( kinfo.dom0less_feature & DOM0LESS_XENSTORE )
> - {
> - ASSERT(hardware_domain);
> - rc = alloc_xenstore_evtchn(d);
> - if ( rc < 0 )
> - return rc;
> -
> - rc = alloc_xenstore_page(d);
> - if ( rc < 0 )
> - return rc;
> - }
> -
> - return rc;
> + return alloc_xenstore_params(d, &kinfo);
> }
>
> void __init create_domUs(void)
> diff --git a/xen/arch/arm/include/asm/kernel.h b/xen/arch/arm/include/asm/kernel.h
> index de3f945ae5..bdc96f4c18 100644
> --- a/xen/arch/arm/include/asm/kernel.h
> +++ b/xen/arch/arm/include/asm/kernel.h
> @@ -13,20 +13,28 @@
> /*
> * List of possible features for dom0less domUs
> *
> - * DOM0LESS_ENHANCED_NO_XS: Notify the OS it is running on top of Xen. All the
> - * default features (excluding Xenstore) will be
> - * available. Note that an OS *must* not rely on the
> - * availability of Xen features if this is not set.
> - * DOM0LESS_XENSTORE: Xenstore will be enabled for the VM. This feature
> - * can't be enabled without the
> - * DOM0LESS_ENHANCED_NO_XS.
> - * DOM0LESS_ENHANCED: Notify the OS it is running on top of Xen. All the
> - * default features (including Xenstore) will be
> - * available. Note that an OS *must* not rely on the
> - * availability of Xen features if this is not set.
> + * DOM0LESS_ENHANCED_NO_XS: Notify the OS it is running on top of Xen. All the
> + * default features (excluding Xenstore) will be
> + * available. Note that an OS *must* not rely on the
> + * availability of Xen features if this is not set.
> + * DOM0LESS_XENSTORE: Xenstore will be enabled for the VM. The
> + * xenstore page allocation is done by Xen at
> + * domain creation. This feature can't be
> + * enabled without the DOM0LESS_ENHANCED_NO_XS.
> + * DOM0LESS_XS_LEGACY Xenstore will be enabled for the VM, the
> + * xenstore page allocation will happen in
> + * init-dom0less. This feature can't be enabled
> + * without the DOM0LESS_ENHANCED_NO_XS.
> + * DOM0LESS_ENHANCED: Notify the OS it is running on top of Xen. All the
> + * default features (including Xenstore) will be
> + * available. Note that an OS *must* not rely on the
> + * availability of Xen features if this is not set.
> + * DOM0LESS_ENHANCED_LEGACY: Same as before, but using DOM0LESS_XS_LEGACY.
> */
> #define DOM0LESS_ENHANCED_NO_XS BIT(0, U)
> #define DOM0LESS_XENSTORE BIT(1, U)
> +#define DOM0LESS_XS_LEGACY BIT(2, U)
> +#define DOM0LESS_ENHANCED_LEGACY (DOM0LESS_ENHANCED_NO_XS | DOM0LESS_XS_LEGACY)
> #define DOM0LESS_ENHANCED (DOM0LESS_ENHANCED_NO_XS | DOM0LESS_XENSTORE)
>
> struct kernel_info {
Other than that:
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
~Michal
© 2016 - 2026 Red Hat, Inc.