xen/arch/arm/arch.mk | 1 + xen/arch/arm/arm64/vfp.c | 6 ++++++ 2 files changed, 7 insertions(+)
This patch enables building Xen on arm64 architecture using the Clang compiler.
Changes include:
- Add explicit -march=armv8 flag for arm64 builds.
- Add `__attribute__((target("fp-armv8")))` to `vfp_save_state` and
`vfp_restore_state` functions when building with Clang to allow
FP instructions despite `-mgeneral-regs-only`.
Signed-off-by: Saman Dehghan <samaan.dehghan@gmail.com>
---
xen/arch/arm/arch.mk | 1 +
xen/arch/arm/arm64/vfp.c | 6 ++++++
2 files changed, 7 insertions(+)
diff --git a/xen/arch/arm/arch.mk b/xen/arch/arm/arch.mk
index 9c4bedfb3b..bcf548069b 100644
--- a/xen/arch/arm/arch.mk
+++ b/xen/arch/arm/arch.mk
@@ -13,6 +13,7 @@ ifeq ($(CONFIG_MPU),y)
CFLAGS-$(CONFIG_ARM_64) += -march=armv8-r
else
CFLAGS-$(CONFIG_ARM_64) += -mcpu=generic
+CFLAGS-$(CONFIG_ARM_64) += -march=armv8
endif
CFLAGS-$(CONFIG_ARM_64) += -mgeneral-regs-only # No fp registers etc
$(call cc-option-add,CFLAGS-$(CONFIG_ARM_64),CC,-mno-outline-atomics)
diff --git a/xen/arch/arm/arm64/vfp.c b/xen/arch/arm/arm64/vfp.c
index c4f89c7b0e..51fd2ddc54 100644
--- a/xen/arch/arm/arm64/vfp.c
+++ b/xen/arch/arm/arm64/vfp.c
@@ -46,6 +46,9 @@ static inline void restore_state(const uint64_t *fpregs)
: : "Q" (*fpregs), "r" (fpregs));
}
+#if defined(CONFIG_CC_IS_CLANG)
+__attribute__((target("fp-armv8")))
+#endif
void vfp_save_state(struct vcpu *v)
{
if ( !cpu_has_fp )
@@ -62,6 +65,9 @@ void vfp_save_state(struct vcpu *v)
v->arch.vfp.fpexc32_el2 = READ_SYSREG(FPEXC32_EL2);
}
+#if defined(CONFIG_CC_IS_CLANG)
+__attribute__((target("fp-armv8")))
+#endif
void vfp_restore_state(struct vcpu *v)
{
if ( !cpu_has_fp )
--
2.49.0
On 09.12.2025 01:37, Saman Dehghan wrote:
> This patch enables building Xen on arm64 architecture using the Clang compiler.
> Changes include:
> - Add explicit -march=armv8 flag for arm64 builds.
> - Add `__attribute__((target("fp-armv8")))` to `vfp_save_state` and
> `vfp_restore_state` functions when building with Clang to allow
> FP instructions despite `-mgeneral-regs-only`.
>
> Signed-off-by: Saman Dehghan <samaan.dehghan@gmail.com>
> ---
> xen/arch/arm/arch.mk | 1 +
> xen/arch/arm/arm64/vfp.c | 6 ++++++
> 2 files changed, 7 insertions(+)
Please also update ./README then accordingly.
> --- a/xen/arch/arm/arm64/vfp.c
> +++ b/xen/arch/arm/arm64/vfp.c
> @@ -46,6 +46,9 @@ static inline void restore_state(const uint64_t *fpregs)
> : : "Q" (*fpregs), "r" (fpregs));
> }
>
> +#if defined(CONFIG_CC_IS_CLANG)
> +__attribute__((target("fp-armv8")))
> +#endif
> void vfp_save_state(struct vcpu *v)
> {
> if ( !cpu_has_fp )
> @@ -62,6 +65,9 @@ void vfp_save_state(struct vcpu *v)
> v->arch.vfp.fpexc32_el2 = READ_SYSREG(FPEXC32_EL2);
> }
>
> +#if defined(CONFIG_CC_IS_CLANG)
> +__attribute__((target("fp-armv8")))
> +#endif
> void vfp_restore_state(struct vcpu *v)
> {
> if ( !cpu_has_fp )
Aren't it save_state() and restore_state() which actually use FP registers?
Applying such attributes in too wide a fashion risks the compiler using FP
registers also for other purposes. On x86 we were hit by such when we
suppressed use of SSE registers while not suppressing use of MMX ones. In
some configuration, after many years of this having gone fine, the compiler
chose to use MMX insns for some odd reason.
Seeing that save_state() and restore_state() are a single asm() statement
each, any reason not to actually have them in an assembly file, just like
their SVE counterparts are?
Jan
On Tue, Dec 9, 2025 at 1:49 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 09.12.2025 01:37, Saman Dehghan wrote:
> > This patch enables building Xen on arm64 architecture using the Clang compiler.
> > Changes include:
> > - Add explicit -march=armv8 flag for arm64 builds.
> > - Add `__attribute__((target("fp-armv8")))` to `vfp_save_state` and
> > `vfp_restore_state` functions when building with Clang to allow
> > FP instructions despite `-mgeneral-regs-only`.
> >
> > Signed-off-by: Saman Dehghan <samaan.dehghan@gmail.com>
> > ---
> > xen/arch/arm/arch.mk | 1 +
> > xen/arch/arm/arm64/vfp.c | 6 ++++++
> > 2 files changed, 7 insertions(+)
>
> Please also update ./README then accordingly.
Thank you, Jan, I will do that.
~Saman
>
> > --- a/xen/arch/arm/arm64/vfp.c
> > +++ b/xen/arch/arm/arm64/vfp.c
> > @@ -46,6 +46,9 @@ static inline void restore_state(const uint64_t *fpregs)
> > : : "Q" (*fpregs), "r" (fpregs));
> > }
> >
> > +#if defined(CONFIG_CC_IS_CLANG)
> > +__attribute__((target("fp-armv8")))
> > +#endif
> > void vfp_save_state(struct vcpu *v)
> > {
> > if ( !cpu_has_fp )
> > @@ -62,6 +65,9 @@ void vfp_save_state(struct vcpu *v)
> > v->arch.vfp.fpexc32_el2 = READ_SYSREG(FPEXC32_EL2);
> > }
> >
> > +#if defined(CONFIG_CC_IS_CLANG)
> > +__attribute__((target("fp-armv8")))
> > +#endif
> > void vfp_restore_state(struct vcpu *v)
> > {
> > if ( !cpu_has_fp )
>
> Aren't it save_state() and restore_state() which actually use FP registers?
> Applying such attributes in too wide a fashion risks the compiler using FP
> registers also for other purposes. On x86 we were hit by such when we
> suppressed use of SSE registers while not suppressing use of MMX ones. In
> some configuration, after many years of this having gone fine, the compiler
> chose to use MMX insns for some odd reason.
>
> Seeing that save_state() and restore_state() are a single asm() statement
> each, any reason not to actually have them in an assembly file, just like
> their SVE counterparts are?
>
On top of those, `READ_SYSREG(FPSR)`, `READ_SYSREG(FPCR)`,
`WRITE_SYSREG(v->arch.vfp.fpsr, FPSR)`and
`WRITE_SYSREG(v->arch.vfp.fpcr, FPCR)` using FP.
I think I cannot apply __attribute__ on statements.
~Saman
> Jan
This patch enables building Xen on arm64 architecture using the Clang compiler.
Changes include:
- Add explicit -march=armv8 flag for arm64 builds.
- Add `__attribute__((target("fp-armv8")))` to `vfp_save_state` and
`vfp_restore_state` functions when building with Clang to allow
FP instructions despite `-mgeneral-regs-only`.
Signed-off-by: Saman Dehghan <samaan.dehghan@gmail.com>
---
README | 2 ++
xen/arch/arm/arch.mk | 1 +
xen/arch/arm/arm64/vfp.c | 6 ++++++
3 files changed, 9 insertions(+)
diff --git a/README b/README
index 889a4ea906..67c1aa7fe6 100644
--- a/README
+++ b/README
@@ -45,6 +45,8 @@ provided by your OS distributor:
- For ARM:
- GCC 5.1 or later
- GNU Binutils 2.25 or later
+ or
+ - Clang/LLVM 11 or later
- For RISC-V 64-bit:
- GCC 12.2 or later
- GNU Binutils 2.39 or later
diff --git a/xen/arch/arm/arch.mk b/xen/arch/arm/arch.mk
index 9c4bedfb3b..bcf548069b 100644
--- a/xen/arch/arm/arch.mk
+++ b/xen/arch/arm/arch.mk
@@ -13,6 +13,7 @@ ifeq ($(CONFIG_MPU),y)
CFLAGS-$(CONFIG_ARM_64) += -march=armv8-r
else
CFLAGS-$(CONFIG_ARM_64) += -mcpu=generic
+CFLAGS-$(CONFIG_ARM_64) += -march=armv8
endif
CFLAGS-$(CONFIG_ARM_64) += -mgeneral-regs-only # No fp registers etc
$(call cc-option-add,CFLAGS-$(CONFIG_ARM_64),CC,-mno-outline-atomics)
diff --git a/xen/arch/arm/arm64/vfp.c b/xen/arch/arm/arm64/vfp.c
index c4f89c7b0e..51fd2ddc54 100644
--- a/xen/arch/arm/arm64/vfp.c
+++ b/xen/arch/arm/arm64/vfp.c
@@ -46,6 +46,9 @@ static inline void restore_state(const uint64_t *fpregs)
: : "Q" (*fpregs), "r" (fpregs));
}
+#if defined(CONFIG_CC_IS_CLANG)
+__attribute__((target("fp-armv8")))
+#endif
void vfp_save_state(struct vcpu *v)
{
if ( !cpu_has_fp )
@@ -62,6 +65,9 @@ void vfp_save_state(struct vcpu *v)
v->arch.vfp.fpexc32_el2 = READ_SYSREG(FPEXC32_EL2);
}
+#if defined(CONFIG_CC_IS_CLANG)
+__attribute__((target("fp-armv8")))
+#endif
void vfp_restore_state(struct vcpu *v)
{
if ( !cpu_has_fp )
--
2.49.0
© 2016 - 2025 Red Hat, Inc.