* [PATCH v3 1/4] xen/arm: split set_domain_type() between arm64/arm32
2025-09-11 8:20 [PATCH v3 0/4] xen/arm64: allow to make aarch32 el1 support optional Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 2/4] xen/arm: split is_32bit/64bit_domain() between arm64/arm32 Grygorii Strashko
@ 2025-09-11 8:20 ` Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 4/4] xen/arm64: constify is_32/64bit_domain() macro for CONFIG_ARM64_AARCH32=n Grygorii Strashko
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Grygorii Strashko @ 2025-09-11 8:20 UTC (permalink / raw)
To: xen-devel@lists.xenproject.org
Cc: Grygorii Strashko, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
Anthony PERARD, Jan Beulich, Roger Pau Monné
From: Grygorii Strashko <grygorii_strashko@epam.com>
Split set_domain_type() between Arm64/Arm32 sub-arches as
set_domain_type() implementation is going to be extended for Arm64.
Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
---
v3:
- mark domain-build.c as "init.o" for make
v2:
- no changes, rebase
xen/arch/arm/arm32/Makefile | 1 +
xen/arch/arm/arm32/domain-build.c | 22 ++++++++++++++++++++++
xen/arch/arm/arm64/Makefile | 1 +
xen/arch/arm/arm64/domain-build.c | 24 ++++++++++++++++++++++++
xen/arch/arm/dom0less-build.c | 14 --------------
xen/include/xen/dom0less-build.h | 8 ++++++++
6 files changed, 56 insertions(+), 14 deletions(-)
create mode 100644 xen/arch/arm/arm32/domain-build.c
create mode 100644 xen/arch/arm/arm64/domain-build.c
diff --git a/xen/arch/arm/arm32/Makefile b/xen/arch/arm/arm32/Makefile
index 531168f58a0a..969f24858cb5 100644
--- a/xen/arch/arm/arm32/Makefile
+++ b/xen/arch/arm/arm32/Makefile
@@ -6,6 +6,7 @@ obj-y += cache.o
obj-$(CONFIG_EARLY_PRINTK) += debug.o
obj-y += domctl.o
obj-y += domain.o
+obj-y += domain-build.init.o
obj-y += entry.o
obj-y += head.o
obj-y += insn.o
diff --git a/xen/arch/arm/arm32/domain-build.c b/xen/arch/arm/arm32/domain-build.c
new file mode 100644
index 000000000000..e34261e4a2ad
--- /dev/null
+++ b/xen/arch/arm/arm32/domain-build.c
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <xen/fdt-kernel.h>
+#include <xen/sched.h>
+
+#include <asm/domain.h>
+
+#ifdef CONFIG_DOM0LESS_BOOT
+void __init set_domain_type(struct domain *d, struct kernel_info *kinfo)
+{
+ /* Nothing to do */
+}
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile
index 6491c5350b2e..c5d3479f6b96 100644
--- a/xen/arch/arm/arm64/Makefile
+++ b/xen/arch/arm/arm64/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_HARDEN_BRANCH_PREDICTOR) += bpi.o
obj-$(CONFIG_EARLY_PRINTK) += debug.o
obj-y += domctl.o
obj-y += domain.o
+obj-y += domain-build.init.o
obj-y += entry.o
obj-y += head.o
obj-y += insn.o
diff --git a/xen/arch/arm/arm64/domain-build.c b/xen/arch/arm/arm64/domain-build.c
new file mode 100644
index 000000000000..3a89ee46b8c6
--- /dev/null
+++ b/xen/arch/arm/arm64/domain-build.c
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <xen/fdt-kernel.h>
+#include <xen/sched.h>
+
+#include <asm/domain.h>
+
+#ifdef CONFIG_DOM0LESS_BOOT
+/* TODO: make arch.type generic ? */
+void __init set_domain_type(struct domain *d, struct kernel_info *kinfo)
+{
+ /* type must be set before allocate memory */
+ d->arch.type = kinfo->arch.type;
+}
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
index f00912a1ca85..713a90c3ad79 100644
--- a/xen/arch/arm/dom0less-build.c
+++ b/xen/arch/arm/dom0less-build.c
@@ -237,20 +237,6 @@ int __init make_arch_nodes(struct kernel_info *kinfo)
return 0;
}
-/* TODO: make arch.type generic ? */
-#ifdef CONFIG_ARM_64
-void __init set_domain_type(struct domain *d, struct kernel_info *kinfo)
-{
- /* type must be set before allocate memory */
- d->arch.type = kinfo->arch.type;
-}
-#else
-void __init set_domain_type(struct domain *d, struct kernel_info *kinfo)
-{
- /* Nothing to do */
-}
-#endif
-
int __init init_vuart(struct domain *d, struct kernel_info *kinfo,
const struct dt_device_node *node)
{
diff --git a/xen/include/xen/dom0less-build.h b/xen/include/xen/dom0less-build.h
index faaf660424b2..4de8d9edba52 100644
--- a/xen/include/xen/dom0less-build.h
+++ b/xen/include/xen/dom0less-build.h
@@ -57,6 +57,14 @@ int init_vuart(struct domain *d, struct kernel_info *kinfo,
int make_intc_domU_node(struct kernel_info *kinfo);
int make_arch_nodes(struct kernel_info *kinfo);
+/*
+ * Set domain type from struct kernel_info which defines guest Execution
+ * State 32-bit/64-bit (for Arm AArch32/AArch64).
+ * The domain type must be set before allocate_memory.
+ *
+ * @d: pointer to the domain structure.
+ * @kinfo: pointer to the kinfo structure.
+ */
void set_domain_type(struct domain *d, struct kernel_info *kinfo);
int init_intc_phandle(struct kernel_info *kinfo, const char *name,
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 0/4] xen/arm64: allow to make aarch32 el1 support optional
@ 2025-09-11 8:20 Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 2/4] xen/arm: split is_32bit/64bit_domain() between arm64/arm32 Grygorii Strashko
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Grygorii Strashko @ 2025-09-11 8:20 UTC (permalink / raw)
To: xen-devel@lists.xenproject.org
Cc: Grygorii Strashko, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
Anthony PERARD, Jan Beulich, Roger Pau Monné
From: Grygorii Strashko <grygorii_strashko@epam.com>
Hi,
During review of v1 [1] of this series Julien Grall raised concern that
"If the desire is to make 32-bit domain optional on Arm64.
Then I think it would be better to pass the domain type when the domain is
created (IOW add an extra flags to XEN_DOMCTL_createdomain)." for which
I've sent patches attempting to start solving the problem [2] and try to
probe guest kernels before creating domains. While proposed changes [2] is
under review and hence there are definitely more work is required I'd
appreciated if current series can be considered as it's Arm specific only
and working (and tested) with current Xen in its current state.
Now Arm64 AArch32 EL1 guest support is always enabled and built-in while not
all Arm64 platforms supports AArch32 (for examaple on Armv9A) or this
support might not be needed (Arm64 AArch32 El1 is used quite rarely in embedded
systems). More over, when focusing on safety certification, AArch32 related
code in Xen leaves a gap in terms of coverage that cannot really be
justified in words. This leaves two options: either support it (lots of
additional testing, requirements and documents would be needed) or compile
it out.
The series doesn't affect on Arm64 Guest's EL0 32-bit ARM execution state
support.
Patches 1-2 Prerequisite patches
Patch 3 - allows to make aarch32 support optional by introducing Kconfig option
CONFIG_ARM64_AARCH32
Patch 4 - enables build-time optimization of AArch32 specific code by redefining some
is_32/64bit_domain() macro as constants
Tested (CONFIG_ARM64_AARCH32=y/n):
- dom0 with AArch32/64 kernel
- toolstack create domain with AArch32/64 kernel
- dom0less domains with AArch32/64 kernel
- creating domain with AArch64 kernel and AArch32 EL0 rootfs
Changes in v3:
- Kconfig ARM64_AARCH32 use dependency from EXPERT instead of UNSUPPORTED
- drop code for "do not expose EL1 AArch32 support to guest in ID_AA64PFR0_EL1 reg"
- apply comments from Volodymyr Babchuk
Changes in v2:
- dropped patches
- (licensing issue) "xen/arm: move vcpu_switch_to_aarch64_mode() in arch_vcpu_create()"
- (problematic change) "xen/arm: move vcpu_switch_to_aarch64_mode() in arm64"
- constifying is_32/64bit_domain() macro gives most of results in terms of coverage,
drop regs changes for now (can be added latter):
"xen/arm: regs.h split subarch definitions between arm64/arm32"
"xen/arm64: constify regs_mode_is_32bit macro for CONFIG_ARM64_AARCH32=n"
- use Arm64 "cpu_has_el1_32" in all places to check if HW has AArch32 support
- rework Arm64 XEN_DOMCTL_set_address_size hypercall handling to work with any initial domain type
set (32bit or 64 bit)
- fix comments related to macro parameters evaluation issues
- do not expose EL1 AArch32 support to guest in ID_AA64PFR0_EL1 reg if
AArch32 is disabled
Link on v1:
[1] https://lore.kernel.org/xen-devel/20250723075835.3993182-1-grygorii_strashko@epam.com/
[2] https://patchwork.kernel.org/project/xen-devel/cover/20250731094234.996684-1-grygorii_strashko@epam.com/
Grygorii Strashko (4):
xen/arm: split set_domain_type() between arm64/arm32
xen/arm: split is_32bit/64bit_domain() between arm64/arm32
xen/arm64: allow to make aarch32 support optional
xen/arm64: constify is_32/64bit_domain() macro for
CONFIG_ARM64_AARCH32=n
xen/arch/arm/Kconfig | 9 ++++
xen/arch/arm/arm32/Makefile | 1 +
xen/arch/arm/arm32/domain-build.c | 22 ++++++++
xen/arch/arm/arm64/Makefile | 1 +
xen/arch/arm/arm64/domain-build.c | 67 +++++++++++++++++++++++++
xen/arch/arm/arm64/domctl.c | 12 +++--
xen/arch/arm/dom0less-build.c | 14 ------
xen/arch/arm/domain.c | 9 ++++
xen/arch/arm/domain_build.c | 21 ++------
xen/arch/arm/include/asm/arm32/domain.h | 32 ++++++++++++
xen/arch/arm/include/asm/arm64/domain.h | 54 ++++++++++++++++++++
xen/arch/arm/include/asm/domain.h | 7 ++-
xen/arch/arm/setup.c | 2 +-
xen/include/xen/dom0less-build.h | 8 +++
14 files changed, 220 insertions(+), 39 deletions(-)
create mode 100644 xen/arch/arm/arm32/domain-build.c
create mode 100644 xen/arch/arm/arm64/domain-build.c
create mode 100644 xen/arch/arm/include/asm/arm32/domain.h
create mode 100644 xen/arch/arm/include/asm/arm64/domain.h
--
2.34.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 2/4] xen/arm: split is_32bit/64bit_domain() between arm64/arm32
2025-09-11 8:20 [PATCH v3 0/4] xen/arm64: allow to make aarch32 el1 support optional Grygorii Strashko
@ 2025-09-11 8:20 ` Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 1/4] xen/arm: split set_domain_type() " Grygorii Strashko
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Grygorii Strashko @ 2025-09-11 8:20 UTC (permalink / raw)
To: xen-devel@lists.xenproject.org
Cc: Grygorii Strashko, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk,
Volodymyr Babchuk
From: Grygorii Strashko <grygorii_strashko@epam.com>
Split is_32bit/64bit_domain() macro implementations between arm64/arm32.
Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
---
v3:
- no changes, add tag
v2:
- fix comments related to macro parameters evaluation issues
xen/arch/arm/include/asm/arm32/domain.h | 20 +++++++++++++++++
xen/arch/arm/include/asm/arm64/domain.h | 29 +++++++++++++++++++++++++
xen/arch/arm/include/asm/domain.h | 7 +++---
3 files changed, 52 insertions(+), 4 deletions(-)
create mode 100644 xen/arch/arm/include/asm/arm32/domain.h
create mode 100644 xen/arch/arm/include/asm/arm64/domain.h
diff --git a/xen/arch/arm/include/asm/arm32/domain.h b/xen/arch/arm/include/asm/arm32/domain.h
new file mode 100644
index 000000000000..1bd0735c9194
--- /dev/null
+++ b/xen/arch/arm/include/asm/arm32/domain.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef ARM_ARM32_DOMAIN_H
+#define ARM_ARM32_DOMAIN_H
+
+/* Arm32 always runs guests in AArch32 mode */
+
+#define is_32bit_domain(d) ((void)(d), 1)
+#define is_64bit_domain(d) ((void)(d), 0)
+
+#endif /* ARM_ARM32_DOMAIN_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/include/asm/arm64/domain.h b/xen/arch/arm/include/asm/arm64/domain.h
new file mode 100644
index 000000000000..1a2d73950bf0
--- /dev/null
+++ b/xen/arch/arm/include/asm/arm64/domain.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef ARM_ARM64_DOMAIN_H
+#define ARM_ARM64_DOMAIN_H
+
+/*
+ * Returns true if guest execution state is AArch32
+ *
+ * @d: pointer to the domain structure
+ */
+#define is_32bit_domain(d) ((d)->arch.type == DOMAIN_32BIT)
+
+/*
+ * Returns true if guest execution state is AArch64
+ *
+ * @d: pointer to the domain structure
+ */
+#define is_64bit_domain(d) ((d)->arch.type == DOMAIN_64BIT)
+
+#endif /* ARM_ARM64_DOMAIN_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/include/asm/domain.h b/xen/arch/arm/include/asm/domain.h
index af3e168374b4..1a83f3924fb7 100644
--- a/xen/arch/arm/include/asm/domain.h
+++ b/xen/arch/arm/include/asm/domain.h
@@ -22,11 +22,10 @@ enum domain_type {
DOMAIN_32BIT,
DOMAIN_64BIT,
};
-#define is_32bit_domain(d) ((d)->arch.type == DOMAIN_32BIT)
-#define is_64bit_domain(d) ((d)->arch.type == DOMAIN_64BIT)
+
+# include <asm/arm64/domain.h>
#else
-#define is_32bit_domain(d) (1)
-#define is_64bit_domain(d) (0)
+# include <asm/arm32/domain.h>
#endif
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 4/4] xen/arm64: constify is_32/64bit_domain() macro for CONFIG_ARM64_AARCH32=n
2025-09-11 8:20 [PATCH v3 0/4] xen/arm64: allow to make aarch32 el1 support optional Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 2/4] xen/arm: split is_32bit/64bit_domain() between arm64/arm32 Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 1/4] xen/arm: split set_domain_type() " Grygorii Strashko
@ 2025-09-11 8:20 ` Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 3/4] xen/arm64: allow to make aarch32 el1 support optional Grygorii Strashko
2025-10-03 17:07 ` [PATCH v3 0/4] " Volodymyr Babchuk
4 siblings, 0 replies; 6+ messages in thread
From: Grygorii Strashko @ 2025-09-11 8:20 UTC (permalink / raw)
To: xen-devel@lists.xenproject.org
Cc: Grygorii Strashko, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk,
Volodymyr Babchuk
From: Grygorii Strashko <grygorii_strashko@epam.com>
Constify is_32/64bit_domain() macro for the case CONFIG_ARM64_AARCH32=n and
so allow compiler to opt out Aarch32 specific code.
Before (CONFIG_ARM64_AARCH32=y):
text data bss dec hex filename
861672 322412 274976 1459060 164374 xen-syms-before
After (CONFIG_ARM64_AARCH32=n):
text data bss dec hex filename
857856 322412 274976 1455244 16348c xen-syms-after
Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
---
v3:
- no changes, add tag
v2:
- use IS_ENABLED(CONFIG_ARM64_AARCH32) instead of ifdefs
xen/arch/arm/include/asm/arm64/domain.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/xen/arch/arm/include/asm/arm64/domain.h b/xen/arch/arm/include/asm/arm64/domain.h
index 99c6c97a8057..139d3ce0dd53 100644
--- a/xen/arch/arm/include/asm/arm64/domain.h
+++ b/xen/arch/arm/include/asm/arm64/domain.h
@@ -12,14 +12,16 @@ struct kernel_info;
*
* @d: pointer to the domain structure
*/
-#define is_32bit_domain(d) ((d)->arch.type == DOMAIN_32BIT)
+#define is_32bit_domain(d) \
+ (IS_ENABLED(CONFIG_ARM64_AARCH32) && (d)->arch.type == DOMAIN_32BIT)
/*
* Returns true if guest execution state is AArch64
*
* @d: pointer to the domain structure
*/
-#define is_64bit_domain(d) ((d)->arch.type == DOMAIN_64BIT)
+#define is_64bit_domain(d) \
+ (!IS_ENABLED(CONFIG_ARM64_AARCH32) || (d)->arch.type == DOMAIN_64BIT)
/*
* Arm64 declares AArch32 (32bit) Execution State support in the
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 3/4] xen/arm64: allow to make aarch32 el1 support optional
2025-09-11 8:20 [PATCH v3 0/4] xen/arm64: allow to make aarch32 el1 support optional Grygorii Strashko
` (2 preceding siblings ...)
2025-09-11 8:20 ` [PATCH v3 4/4] xen/arm64: constify is_32/64bit_domain() macro for CONFIG_ARM64_AARCH32=n Grygorii Strashko
@ 2025-09-11 8:20 ` Grygorii Strashko
2025-10-03 17:07 ` [PATCH v3 0/4] " Volodymyr Babchuk
4 siblings, 0 replies; 6+ messages in thread
From: Grygorii Strashko @ 2025-09-11 8:20 UTC (permalink / raw)
To: xen-devel@lists.xenproject.org
Cc: Grygorii Strashko, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk
From: Grygorii Strashko <grygorii_strashko@epam.com>
Now Arm64 AArch32 EL1 guest support is always enabled and built-in while
not all Arm64 platforms supports AArch32 (for example on Armv9A) or this
support might not be needed (Arm64 AArch32 is used quite rarely in embedded
systems). More over, when focusing on safety certification, AArch32 related
code in Xen leaves a gap in terms of coverage that cannot really be
justified in words. This leaves two options: either support it (lots of
additional testing, requirements and documents would be needed) or compile
it out.
Hence, this patch introduces basic support to allow make Arm64
AArch32 EL1 guest support optional. The following changes are introduced:
- Introduce Kconfig option CONFIG_ARM64_AARCH32 to allow enable/disable
Arm64 AArch32 guest support (default y)
- Introduce is_aarch32_enabled() helper which accounts Arm64 HW capability
and CONFIG_ARM64_AARCH32 setting
- Introduce arm64_set_domain_type() to configure Arm64 domain type in
unified way instead of open coding (d)->arch.type, and account
CONFIG_ARM64_AARCH32 configuration.
- toolstack: do not advertise "xen-3.0-armv7l " capability if AArch32 is
disabled.
- Set Arm64 domain type to DOMAIN_64BIT by default.
- the Arm Xen boot code is handling this case properly already;
- for toolstack case the XEN_DOMCTL_set_address_size hypercall handling
updated to forcibly configure domain type regardless of current domain
type configuration, so toolstack behavior is unchanged.
With CONFIG_ARM64_AARCH32=n the Xen will reject AArch32 guests (kernels) if
configured by user in the following way:
- Xen boot will fail with panic during dom0 or dom0less domains creation
- toolstack domain creation will be rejected due to xc_dom_compat_check()
failure.
Making Arm64 EL1 AArch32 guest support open further possibilities for build
optimizations of Arm64 AArch32 guest support code.
The change doesn't affect on Guest's EL0 32-bit ARM execution state
support.
Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
---
changes in v3:
- Kconfig ARM64_AARCH32 use dependency from EXPERT instead of UNSUPPORTED
- drop code for "do not expose EL1 AArch32 support to guest in ID_AA64PFR0_EL1 reg"
- apply comments from Volodymyr Babchuk
- reword commit message to mention that patch affects EL1 only
changes in v2:
- use Arm64 "cpu_has_el1_32" in all places to check if HW has AArch32 support
- rework Arm64 XEN_DOMCTL_set_address_size hypercall handling to work with any
initial domain type set (32bit or 64 bit)
- fix comments related to macro parameters evaluation issues
- do not expose EL1 AArch32 support to guest in ID_AA64PFR0_EL1 reg if
AArch32 is disabled
xen/arch/arm/Kconfig | 9 +++++
xen/arch/arm/arm64/domain-build.c | 47 +++++++++++++++++++++++--
xen/arch/arm/arm64/domctl.c | 12 +++++--
xen/arch/arm/domain.c | 9 +++++
xen/arch/arm/domain_build.c | 21 +++--------
xen/arch/arm/include/asm/arm32/domain.h | 12 +++++++
xen/arch/arm/include/asm/arm64/domain.h | 23 ++++++++++++
xen/arch/arm/setup.c | 2 +-
8 files changed, 112 insertions(+), 23 deletions(-)
diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index 5355534f3d5e..0289ebfe04f6 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -266,6 +266,15 @@ config PCI_PASSTHROUGH
help
This option enables PCI device passthrough
+config ARM64_AARCH32
+ bool "AArch32 (EL1) Guests support on ARM64" if EXPERT
+ depends on ARM_64
+ default y
+ help
+ This option enables AArch32 (EL1) Guests on ARM64.
+ This option doesn't affect on Guest's EL0 ARM 32-bit execution
+ state support.
+
endmenu
menu "ARM errata workaround via the alternative framework"
diff --git a/xen/arch/arm/arm64/domain-build.c b/xen/arch/arm/arm64/domain-build.c
index 3a89ee46b8c6..cb0afc9df19e 100644
--- a/xen/arch/arm/arm64/domain-build.c
+++ b/xen/arch/arm/arm64/domain-build.c
@@ -4,13 +4,56 @@
#include <xen/sched.h>
#include <asm/domain.h>
+#include <asm/arm64/sve.h>
+
+int __init arm64_set_domain_type(struct kernel_info *kinfo)
+{
+ enum domain_type type;
+ struct domain *d;
+
+ ASSERT(kinfo);
+ ASSERT(kinfo->bd.d);
+
+ type = kinfo->arch.type;
+ d = kinfo->bd.d;
+
+ if ( !is_aarch32_enabled() )
+ {
+ ASSERT(d->arch.type == DOMAIN_64BIT);
+
+ if ( type == DOMAIN_32BIT )
+ {
+ const char *str = "not available";
+
+ if ( !IS_ENABLED(CONFIG_ARM64_AARCH32) )
+ str = "disabled";
+ printk(XENLOG_ERR "aarch32 guests support is %s\n", str);
+ return -EINVAL;
+ }
+
+ return 0;
+ }
+
+ if ( is_sve_domain(d) && type == DOMAIN_32BIT )
+ {
+ printk(XENLOG_ERR "SVE is not available for 32-bit domain\n");
+ return -EINVAL;
+ }
+
+ d->arch.type = type;
+
+ return 0;
+}
#ifdef CONFIG_DOM0LESS_BOOT
/* TODO: make arch.type generic ? */
void __init set_domain_type(struct domain *d, struct kernel_info *kinfo)
{
- /* type must be set before allocate memory */
- d->arch.type = kinfo->arch.type;
+ int rc;
+
+ rc = arm64_set_domain_type(kinfo);
+ if ( rc < 0 )
+ panic("Unsupported guest type\n");
}
#endif
diff --git a/xen/arch/arm/arm64/domctl.c b/xen/arch/arm/arm64/domctl.c
index 8720d126c97d..46eb3083cfad 100644
--- a/xen/arch/arm/arm64/domctl.c
+++ b/xen/arch/arm/arm64/domctl.c
@@ -13,6 +13,11 @@
#include <asm/arm64/sve.h>
#include <asm/cpufeature.h>
+static void vcpu_switch_to_aarch32_mode(struct vcpu *v)
+{
+ v->arch.hcr_el2 &= ~HCR_RW;
+}
+
static long switch_mode(struct domain *d, enum domain_type type)
{
struct vcpu *v;
@@ -21,14 +26,15 @@ static long switch_mode(struct domain *d, enum domain_type type)
return -EINVAL;
if ( domain_tot_pages(d) != 0 )
return -EBUSY;
- if ( d->arch.type == type )
- return 0;
d->arch.type = type;
if ( is_64bit_domain(d) )
for_each_vcpu(d, v)
vcpu_switch_to_aarch64_mode(v);
+ else
+ for_each_vcpu(d, v)
+ vcpu_switch_to_aarch32_mode(v);
return 0;
}
@@ -38,7 +44,7 @@ static long set_address_size(struct domain *d, uint32_t address_size)
switch ( address_size )
{
case 32:
- if ( !cpu_has_el1_32 )
+ if ( !is_aarch32_enabled() )
return -EINVAL;
/* SVE is not supported for 32 bit domain */
if ( is_sve_domain(d) )
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 1a8585d02b45..2e084dac0a7f 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -792,6 +792,15 @@ int arch_domain_create(struct domain *d,
d->arch.sve_vl = config->arch.sve_vl;
#endif
+#ifdef CONFIG_ARM_64
+ /*
+ * Set default Execution State to AArch64 (64bit)
+ * - Xen will reconfigure it properly at boot time
+ * - toolstack will reconfigure it properly by XEN_DOMCTL_set_address_size
+ */
+ d->arch.type = DOMAIN_64BIT;
+#endif
+
if ( (rc = sci_domain_init(d, config)) != 0 )
goto fail;
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 89448fb4756e..ce7053ba6d59 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1881,19 +1881,6 @@ int __init construct_domain(struct domain *d, struct kernel_info *kinfo)
BUG_ON(v->is_initialised);
#ifdef CONFIG_ARM_64
- /* if aarch32 mode is not supported at EL1 do not allow 32-bit domain */
- if ( !(cpu_has_el1_32) && kinfo->arch.type == DOMAIN_32BIT )
- {
- printk("Platform does not support 32-bit domain\n");
- return -EINVAL;
- }
-
- if ( is_sve_domain(d) && (kinfo->arch.type == DOMAIN_32BIT) )
- {
- printk("SVE is not available for 32-bit domain\n");
- return -EINVAL;
- }
-
if ( is_64bit_domain(d) )
vcpu_switch_to_aarch64_mode(v);
@@ -1991,6 +1978,10 @@ static int __init construct_dom0(struct domain *d)
if ( rc < 0 )
return rc;
+ rc = arm64_set_domain_type(&kinfo);
+ if ( rc < 0 )
+ return rc;
+
return construct_hwdom(&kinfo, NULL);
}
@@ -2002,10 +1993,6 @@ int __init construct_hwdom(struct kernel_info *kinfo,
iommu_hwdom_init(d);
-#ifdef CONFIG_ARM_64
- /* type must be set before allocate_memory */
- d->arch.type = kinfo->arch.type;
-#endif
find_gnttab_region(d, kinfo);
if ( is_domain_direct_mapped(d) )
allocate_memory_11(d, kinfo);
diff --git a/xen/arch/arm/include/asm/arm32/domain.h b/xen/arch/arm/include/asm/arm32/domain.h
index 1bd0735c9194..30e8818ff2ae 100644
--- a/xen/arch/arm/include/asm/arm32/domain.h
+++ b/xen/arch/arm/include/asm/arm32/domain.h
@@ -3,11 +3,23 @@
#ifndef ARM_ARM32_DOMAIN_H
#define ARM_ARM32_DOMAIN_H
+struct kernel_info;
+
/* Arm32 always runs guests in AArch32 mode */
#define is_32bit_domain(d) ((void)(d), 1)
#define is_64bit_domain(d) ((void)(d), 0)
+static inline bool is_aarch32_enabled(void)
+{
+ return true;
+}
+
+static inline int arm64_set_domain_type(struct kernel_info *kinfo)
+{
+ return 0;
+}
+
#endif /* ARM_ARM32_DOMAIN_H */
/*
diff --git a/xen/arch/arm/include/asm/arm64/domain.h b/xen/arch/arm/include/asm/arm64/domain.h
index 1a2d73950bf0..99c6c97a8057 100644
--- a/xen/arch/arm/include/asm/arm64/domain.h
+++ b/xen/arch/arm/include/asm/arm64/domain.h
@@ -3,6 +3,10 @@
#ifndef ARM_ARM64_DOMAIN_H
#define ARM_ARM64_DOMAIN_H
+#include <asm/cpufeature.h>
+
+struct kernel_info;
+
/*
* Returns true if guest execution state is AArch32
*
@@ -17,6 +21,25 @@
*/
#define is_64bit_domain(d) ((d)->arch.type == DOMAIN_64BIT)
+/*
+ * Arm64 declares AArch32 (32bit) Execution State support in the
+ * Processor Feature Registers (PFR0), but also can be disabled manually.
+ */
+static inline bool is_aarch32_enabled(void)
+{
+ return IS_ENABLED(CONFIG_ARM64_AARCH32) && cpu_has_el1_32;
+}
+
+/*
+ * Set domain type from struct kernel_info which defines guest Execution
+ * State AArch32/AArch64 during regular dom0 or predefined (dom0less)
+ * domains creation.
+ * Type must be set before allocate_memory or create vcpus.
+ *
+ * @kinfo: pointer to the kinfo structure.
+ */
+int arm64_set_domain_type(struct kernel_info *kinfo);
+
#endif /* ARM_ARM64_DOMAIN_H */
/*
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 7ad870e382c2..7e6e0541e024 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -530,7 +530,7 @@ static int __init init_xen_cap_info(void)
#ifdef CONFIG_ARM_64
safe_strcat(xen_cap_info, "xen-3.0-aarch64 ");
#endif
- if ( cpu_has_aarch32 )
+ if ( is_aarch32_enabled() )
safe_strcat(xen_cap_info, "xen-3.0-armv7l ");
return 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 0/4] xen/arm64: allow to make aarch32 el1 support optional
2025-09-11 8:20 [PATCH v3 0/4] xen/arm64: allow to make aarch32 el1 support optional Grygorii Strashko
` (3 preceding siblings ...)
2025-09-11 8:20 ` [PATCH v3 3/4] xen/arm64: allow to make aarch32 el1 support optional Grygorii Strashko
@ 2025-10-03 17:07 ` Volodymyr Babchuk
4 siblings, 0 replies; 6+ messages in thread
From: Volodymyr Babchuk @ 2025-10-03 17:07 UTC (permalink / raw)
To: Grygorii Strashko
Cc: xen-devel@lists.xenproject.org, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Andrew Cooper, Anthony PERARD,
Jan Beulich, Roger Pau Monné
Hi Grygorii,
Grygorii Strashko <grygorii_strashko@epam.com> writes:
> From: Grygorii Strashko <grygorii_strashko@epam.com>
>
> Hi,
>
> During review of v1 [1] of this series Julien Grall raised concern that
> "If the desire is to make 32-bit domain optional on Arm64.
> Then I think it would be better to pass the domain type when the domain is
> created (IOW add an extra flags to XEN_DOMCTL_createdomain)." for which
> I've sent patches attempting to start solving the problem [2] and try to
> probe guest kernels before creating domains. While proposed changes [2] is
> under review and hence there are definitely more work is required I'd
> appreciated if current series can be considered as it's Arm specific only
> and working (and tested) with current Xen in its current state.
I am not sure that this is a great idea. Domain creation process is
convoluted enough and your patch 3 makes it more convoluted and hard to
follow. Probably it is better to wait while [2] series will be merged
and then revisit this series.
[...]
--
WBR, Volodymyr
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-10-03 17:08 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-11 8:20 [PATCH v3 0/4] xen/arm64: allow to make aarch32 el1 support optional Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 2/4] xen/arm: split is_32bit/64bit_domain() between arm64/arm32 Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 1/4] xen/arm: split set_domain_type() " Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 4/4] xen/arm64: constify is_32/64bit_domain() macro for CONFIG_ARM64_AARCH32=n Grygorii Strashko
2025-09-11 8:20 ` [PATCH v3 3/4] xen/arm64: allow to make aarch32 el1 support optional Grygorii Strashko
2025-10-03 17:07 ` [PATCH v3 0/4] " Volodymyr Babchuk
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.