* [kvm-unit-tests PATCH v3 01/10] arm64: drop to EL1 if booted at EL2
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
@ 2025-09-25 14:19 ` Joey Gouly
2025-11-27 17:07 ` Eric Auger
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 02/10] arm64: efi: initialise SCTLR_ELx fully Joey Gouly
` (11 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-09-25 14:19 UTC (permalink / raw)
To: kvm
Cc: alexandru.elisei, joey.gouly, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
EL2 is not currently supported, drop to EL1 to conitnue booting.
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
arm/cstart64.S | 47 +++++++++++++++++++++++++++++++++++++++---
lib/arm64/asm/sysreg.h | 14 +++++++++++++
2 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/arm/cstart64.S b/arm/cstart64.S
index 014c9c7b..79b93dd4 100644
--- a/arm/cstart64.S
+++ b/arm/cstart64.S
@@ -15,6 +15,46 @@
#include <asm/thread_info.h>
#include <asm/sysreg.h>
+.macro init_el, tmp
+ mrs \tmp, CurrentEL
+ cmp \tmp, CurrentEL_EL2
+ b.ne 1f
+ /* EL2 setup */
+ mrs \tmp, mpidr_el1
+ msr vmpidr_el2, \tmp
+ mrs \tmp, midr_el1
+ msr vpidr_el2, \tmp
+ /* clear trap registers */
+ mrs \tmp, id_aa64mmfr0_el1
+ ubfx \tmp, \tmp, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
+ cbz \tmp, .Lskip_fgt_\@
+ mov \tmp, #0
+ msr_s SYS_HFGRTR_EL2, \tmp
+ msr_s SYS_HFGWTR_EL2, \tmp
+ msr_s SYS_HFGITR_EL2, \tmp
+ mrs \tmp, id_aa64mmfr0_el1
+ ubfx \tmp, \tmp, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
+ cmp \tmp, #ID_AA64MMFR0_EL1_FGT_FGT2
+ bne .Lskip_fgt_\@
+ mov \tmp, #0
+ msr_s SYS_HFGRTR2_EL2, \tmp
+ msr_s SYS_HFGWTR2_EL2, \tmp
+ msr_s SYS_HFGITR2_EL2, \tmp
+.Lskip_fgt_\@:
+ mov \tmp, #0
+ msr cptr_el2, \tmp
+ ldr \tmp, =(INIT_HCR_EL2_EL1_ONLY)
+ msr hcr_el2, \tmp
+ mov \tmp, PSR_MODE_EL1t
+ msr spsr_el2, \tmp
+ adrp \tmp, 1f
+ add \tmp, \tmp, :lo12:1f
+ msr elr_el2, \tmp
+ eret
+1:
+.endm
+
+
#ifdef CONFIG_EFI
#include "efi/crt0-efi-aarch64.S"
#else
@@ -56,15 +96,15 @@ start:
add x6, x6, :lo12:reloc_end
1:
cmp x5, x6
- b.hs 1f
+ b.hs reloc_done
ldr x7, [x5] // r_offset
ldr x8, [x5, #16] // r_addend
add x8, x8, x4 // val = base + r_addend
str x8, [x4, x7] // base[r_offset] = val
add x5, x5, #24
b 1b
-
-1:
+reloc_done:
+ init_el x4
/* zero BSS */
adrp x4, bss
add x4, x4, :lo12:bss
@@ -185,6 +225,7 @@ get_mmu_off:
.globl secondary_entry
secondary_entry:
+ init_el x0
/* enable FP/ASIMD and SVE */
mov x0, #(3 << 20)
orr x0, x0, #(3 << 16)
diff --git a/lib/arm64/asm/sysreg.h b/lib/arm64/asm/sysreg.h
index e537bb46..ed776716 100644
--- a/lib/arm64/asm/sysreg.h
+++ b/lib/arm64/asm/sysreg.h
@@ -77,6 +77,9 @@ asm(
#define ID_AA64ISAR0_EL1_RNDR_SHIFT 60
#define ID_AA64PFR1_EL1_MTE_SHIFT 8
+#define ID_AA64MMFR0_EL1_FGT_SHIFT 56
+#define ID_AA64MMFR0_EL1_FGT_FGT2 0x2
+
#define ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0)
#define ICC_SGI1R_EL1 sys_reg(3, 0, 12, 11, 5)
#define ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0)
@@ -113,6 +116,17 @@ asm(
#define SCTLR_EL1_TCF0_SHIFT 38
#define SCTLR_EL1_TCF0_MASK GENMASK_ULL(39, 38)
+#define HCR_EL2_RW _BITULL(31)
+
+#define INIT_HCR_EL2_EL1_ONLY (HCR_EL2_RW)
+
+#define SYS_HFGRTR_EL2 sys_reg(3, 4, 1, 1, 4)
+#define SYS_HFGWTR_EL2 sys_reg(3, 4, 1, 1, 5)
+#define SYS_HFGITR_EL2 sys_reg(3, 4, 1, 1, 6)
+#define SYS_HFGRTR2_EL2 sys_reg(3, 4, 3, 1, 2)
+#define SYS_HFGWTR2_EL2 sys_reg(3, 4, 3, 1, 3)
+#define SYS_HFGITR2_EL2 sys_reg(3, 4, 3, 1, 7)
+
#define INIT_SCTLR_EL1_MMU_OFF \
(SCTLR_EL1_ITD | SCTLR_EL1_SED | SCTLR_EL1_EOS | \
SCTLR_EL1_TSCXT | SCTLR_EL1_EIS | SCTLR_EL1_SPAN | \
--
2.25.1
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 01/10] arm64: drop to EL1 if booted at EL2
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 01/10] arm64: drop to EL1 if booted at EL2 Joey Gouly
@ 2025-11-27 17:07 ` Eric Auger
2025-11-28 15:11 ` Joey Gouly
0 siblings, 1 reply; 38+ messages in thread
From: Eric Auger @ 2025-11-27 17:07 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
Hi Joey,
On 9/25/25 4:19 PM, Joey Gouly wrote:
> EL2 is not currently supported, drop to EL1 to conitnue booting.
continue
>
> Signed-off-by: Joey Gouly <joey.gouly@arm.com>
> ---
> arm/cstart64.S | 47 +++++++++++++++++++++++++++++++++++++++---
> lib/arm64/asm/sysreg.h | 14 +++++++++++++
> 2 files changed, 58 insertions(+), 3 deletions(-)
>
> diff --git a/arm/cstart64.S b/arm/cstart64.S
> index 014c9c7b..79b93dd4 100644
> --- a/arm/cstart64.S
> +++ b/arm/cstart64.S
> @@ -15,6 +15,46 @@
> #include <asm/thread_info.h>
> #include <asm/sysreg.h>
>
> +.macro init_el, tmp
init_el2? but also likely to fall back to EL1. At least add a doc comment to explain what the function does.
> + mrs \tmp, CurrentEL
> + cmp \tmp, CurrentEL_EL2
> + b.ne 1f
> + /* EL2 setup */
> + mrs \tmp, mpidr_el1
> + msr vmpidr_el2, \tmp
> + mrs \tmp, midr_el1
> + msr vpidr_el2, \tmp
> + /* clear trap registers */
clear FGT registers if FGT feature supported
> + mrs \tmp, id_aa64mmfr0_el1
> + ubfx \tmp, \tmp, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
> + cbz \tmp, .Lskip_fgt_\@
> + mov \tmp, #0
> + msr_s SYS_HFGRTR_EL2, \tmp
> + msr_s SYS_HFGWTR_EL2, \tmp
> + msr_s SYS_HFGITR_EL2, \tmp
> + mrs \tmp, id_aa64mmfr0_el1
> + ubfx \tmp, \tmp, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
> + cmp \tmp, #ID_AA64MMFR0_EL1_FGT_FGT2
> + bne .Lskip_fgt_\@
> + mov \tmp, #0
> + msr_s SYS_HFGRTR2_EL2, \tmp
> + msr_s SYS_HFGWTR2_EL2, \tmp
> + msr_s SYS_HFGITR2_EL2, \tmp
> +.Lskip_fgt_\@:
> + mov \tmp, #0
> + msr cptr_el2, \tmp
> + ldr \tmp, =(INIT_HCR_EL2_EL1_ONLY)
> + msr hcr_el2, \tmp
> + mov \tmp, PSR_MODE_EL1t
> + msr spsr_el2, \tmp
> + adrp \tmp, 1f
> + add \tmp, \tmp, :lo12:1f
> + msr elr_el2, \tmp
> + eret
> +1:
> +.endm
I read in the coverletter you chose to not reuse include/asm/el2_setup.h
which indeed would look overkill given the reduced scope that we target
here. However compared to init_el2_state we seem to do very few things
in the EL2 setup before switching to EL1. I would give a bit more info
in the commit msg about what you keep and what you dropped and why it is
reasonable (stage2, timers, debug at least).
> +
> +
> #ifdef CONFIG_EFI
> #include "efi/crt0-efi-aarch64.S"
> #else
> @@ -56,15 +96,15 @@ start:
> add x6, x6, :lo12:reloc_end
> 1:
> cmp x5, x6
> - b.hs 1f
> + b.hs reloc_done
> ldr x7, [x5] // r_offset
> ldr x8, [x5, #16] // r_addend
> add x8, x8, x4 // val = base + r_addend
> str x8, [x4, x7] // base[r_offset] = val
> add x5, x5, #24
> b 1b
> -
> -1:
> +reloc_done:
> + init_el x4
> /* zero BSS */
> adrp x4, bss
> add x4, x4, :lo12:bss
> @@ -185,6 +225,7 @@ get_mmu_off:
>
> .globl secondary_entry
> secondary_entry:
> + init_el x0
> /* enable FP/ASIMD and SVE */
> mov x0, #(3 << 20)
> orr x0, x0, #(3 << 16)
> diff --git a/lib/arm64/asm/sysreg.h b/lib/arm64/asm/sysreg.h
> index e537bb46..ed776716 100644
> --- a/lib/arm64/asm/sysreg.h
> +++ b/lib/arm64/asm/sysreg.h
> @@ -77,6 +77,9 @@ asm(
> #define ID_AA64ISAR0_EL1_RNDR_SHIFT 60
> #define ID_AA64PFR1_EL1_MTE_SHIFT 8
>
> +#define ID_AA64MMFR0_EL1_FGT_SHIFT 56
> +#define ID_AA64MMFR0_EL1_FGT_FGT2 0x2
> +
> #define ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0)
> #define ICC_SGI1R_EL1 sys_reg(3, 0, 12, 11, 5)
> #define ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0)
> @@ -113,6 +116,17 @@ asm(
> #define SCTLR_EL1_TCF0_SHIFT 38
> #define SCTLR_EL1_TCF0_MASK GENMASK_ULL(39, 38)
>
> +#define HCR_EL2_RW _BITULL(31)
> +
> +#define INIT_HCR_EL2_EL1_ONLY (HCR_EL2_RW)
I don't really understand the renaming
> +
> +#define SYS_HFGRTR_EL2 sys_reg(3, 4, 1, 1, 4)
> +#define SYS_HFGWTR_EL2 sys_reg(3, 4, 1, 1, 5)
> +#define SYS_HFGITR_EL2 sys_reg(3, 4, 1, 1, 6)
> +#define SYS_HFGRTR2_EL2 sys_reg(3, 4, 3, 1, 2)
> +#define SYS_HFGWTR2_EL2 sys_reg(3, 4, 3, 1, 3)
> +#define SYS_HFGITR2_EL2 sys_reg(3, 4, 3, 1, 7)
> +
> #define INIT_SCTLR_EL1_MMU_OFF \
> (SCTLR_EL1_ITD | SCTLR_EL1_SED | SCTLR_EL1_EOS | \
> SCTLR_EL1_TSCXT | SCTLR_EL1_EIS | SCTLR_EL1_SPAN | \
Thanks
Eric
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [kvm-unit-tests PATCH v3 01/10] arm64: drop to EL1 if booted at EL2
2025-11-27 17:07 ` Eric Auger
@ 2025-11-28 15:11 ` Joey Gouly
0 siblings, 0 replies; 38+ messages in thread
From: Joey Gouly @ 2025-11-28 15:11 UTC (permalink / raw)
To: Eric Auger
Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On Thu, Nov 27, 2025 at 06:07:27PM +0100, Eric Auger wrote:
> Hi Joey,
>
> On 9/25/25 4:19 PM, Joey Gouly wrote:
> > EL2 is not currently supported, drop to EL1 to conitnue booting.
> continue
> >
> > Signed-off-by: Joey Gouly <joey.gouly@arm.com>
> > ---
> > arm/cstart64.S | 47 +++++++++++++++++++++++++++++++++++++++---
> > lib/arm64/asm/sysreg.h | 14 +++++++++++++
> > 2 files changed, 58 insertions(+), 3 deletions(-)
> >
> > diff --git a/arm/cstart64.S b/arm/cstart64.S
> > index 014c9c7b..79b93dd4 100644
> > --- a/arm/cstart64.S
> > +++ b/arm/cstart64.S
> > @@ -15,6 +15,46 @@
> > #include <asm/thread_info.h>
> > #include <asm/sysreg.h>
> >
> > +.macro init_el, tmp
>
> init_el2? but also likely to fall back to EL1. At least add a doc comment to explain what the function does.
>
> > + mrs \tmp, CurrentEL
> > + cmp \tmp, CurrentEL_EL2
> > + b.ne 1f
> > + /* EL2 setup */
> > + mrs \tmp, mpidr_el1
> > + msr vmpidr_el2, \tmp
> > + mrs \tmp, midr_el1
> > + msr vpidr_el2, \tmp
> > + /* clear trap registers */
> clear FGT registers if FGT feature supported
> > + mrs \tmp, id_aa64mmfr0_el1
> > + ubfx \tmp, \tmp, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
> > + cbz \tmp, .Lskip_fgt_\@
> > + mov \tmp, #0
> > + msr_s SYS_HFGRTR_EL2, \tmp
> > + msr_s SYS_HFGWTR_EL2, \tmp
> > + msr_s SYS_HFGITR_EL2, \tmp
> > + mrs \tmp, id_aa64mmfr0_el1
> > + ubfx \tmp, \tmp, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
> > + cmp \tmp, #ID_AA64MMFR0_EL1_FGT_FGT2
> > + bne .Lskip_fgt_\@
> > + mov \tmp, #0
> > + msr_s SYS_HFGRTR2_EL2, \tmp
> > + msr_s SYS_HFGWTR2_EL2, \tmp
> > + msr_s SYS_HFGITR2_EL2, \tmp
> > +.Lskip_fgt_\@:
> > + mov \tmp, #0
> > + msr cptr_el2, \tmp
> > + ldr \tmp, =(INIT_HCR_EL2_EL1_ONLY)
> > + msr hcr_el2, \tmp
> > + mov \tmp, PSR_MODE_EL1t
> > + msr spsr_el2, \tmp
> > + adrp \tmp, 1f
> > + add \tmp, \tmp, :lo12:1f
> > + msr elr_el2, \tmp
> > + eret
> > +1:
> > +.endm
>
> I read in the coverletter you chose to not reuse include/asm/el2_setup.h
> which indeed would look overkill given the reduced scope that we target
> here. However compared to init_el2_state we seem to do very few things
> in the EL2 setup before switching to EL1. I would give a bit more info
> in the commit msg about what you keep and what you dropped and why it is
> reasonable (stage2, timers, debug at least).
>
> > +
> > +
> > #ifdef CONFIG_EFI
> > #include "efi/crt0-efi-aarch64.S"
> > #else
> > @@ -56,15 +96,15 @@ start:
> > add x6, x6, :lo12:reloc_end
> > 1:
> > cmp x5, x6
> > - b.hs 1f
> > + b.hs reloc_done
> > ldr x7, [x5] // r_offset
> > ldr x8, [x5, #16] // r_addend
> > add x8, x8, x4 // val = base + r_addend
> > str x8, [x4, x7] // base[r_offset] = val
> > add x5, x5, #24
> > b 1b
> > -
> > -1:
> > +reloc_done:
> > + init_el x4
> > /* zero BSS */
> > adrp x4, bss
> > add x4, x4, :lo12:bss
> > @@ -185,6 +225,7 @@ get_mmu_off:
> >
> > .globl secondary_entry
> > secondary_entry:
> > + init_el x0
> > /* enable FP/ASIMD and SVE */
> > mov x0, #(3 << 20)
> > orr x0, x0, #(3 << 16)
> > diff --git a/lib/arm64/asm/sysreg.h b/lib/arm64/asm/sysreg.h
> > index e537bb46..ed776716 100644
> > --- a/lib/arm64/asm/sysreg.h
> > +++ b/lib/arm64/asm/sysreg.h
> > @@ -77,6 +77,9 @@ asm(
> > #define ID_AA64ISAR0_EL1_RNDR_SHIFT 60
> > #define ID_AA64PFR1_EL1_MTE_SHIFT 8
> >
> > +#define ID_AA64MMFR0_EL1_FGT_SHIFT 56
> > +#define ID_AA64MMFR0_EL1_FGT_FGT2 0x2
> > +
> > #define ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0)
> > #define ICC_SGI1R_EL1 sys_reg(3, 0, 12, 11, 5)
> > #define ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0)
> > @@ -113,6 +116,17 @@ asm(
> > #define SCTLR_EL1_TCF0_SHIFT 38
> > #define SCTLR_EL1_TCF0_MASK GENMASK_ULL(39, 38)
> >
> > +#define HCR_EL2_RW _BITULL(31)
> > +
> > +#define INIT_HCR_EL2_EL1_ONLY (HCR_EL2_RW)
>
> I don't really understand the renaming
It's just a define similar to INIT_HCR_EL2, that's added in patch 9.
>
> > +
> > +#define SYS_HFGRTR_EL2 sys_reg(3, 4, 1, 1, 4)
> > +#define SYS_HFGWTR_EL2 sys_reg(3, 4, 1, 1, 5)
> > +#define SYS_HFGITR_EL2 sys_reg(3, 4, 1, 1, 6)
> > +#define SYS_HFGRTR2_EL2 sys_reg(3, 4, 3, 1, 2)
> > +#define SYS_HFGWTR2_EL2 sys_reg(3, 4, 3, 1, 3)
> > +#define SYS_HFGITR2_EL2 sys_reg(3, 4, 3, 1, 7)
> > +
> > #define INIT_SCTLR_EL1_MMU_OFF \
> > (SCTLR_EL1_ITD | SCTLR_EL1_SED | SCTLR_EL1_EOS | \
> > SCTLR_EL1_TSCXT | SCTLR_EL1_EIS | SCTLR_EL1_SPAN | \
> Thanks
>
> Eric
>
Thanks,
Joey
^ permalink raw reply [flat|nested] 38+ messages in thread
* [kvm-unit-tests PATCH v3 02/10] arm64: efi: initialise SCTLR_ELx fully
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 01/10] arm64: drop to EL1 if booted at EL2 Joey Gouly
@ 2025-09-25 14:19 ` Joey Gouly
2025-11-27 16:49 ` Eric Auger
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 03/10] arm64: efi: initialise the EL Joey Gouly
` (10 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-09-25 14:19 UTC (permalink / raw)
To: kvm
Cc: alexandru.elisei, joey.gouly, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
Don't rely on the value of SCTLR_ELx when booting via EFI.
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
lib/arm/asm/setup.h | 6 ++++++
lib/arm/setup.c | 3 +++
lib/arm64/processor.c | 12 ++++++++++++
3 files changed, 21 insertions(+)
diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
index 9f8ef82e..4e60d552 100644
--- a/lib/arm/asm/setup.h
+++ b/lib/arm/asm/setup.h
@@ -28,6 +28,12 @@ void setup(const void *fdt, phys_addr_t freemem_start);
#include <efi.h>
+#ifdef __aarch64__
+void setup_efi_sctlr(void);
+#else
+static inline void setup_efi_sctlr(void) {}
+#endif
+
efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo);
#endif
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 67b5db07..0aaa1d3a 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -349,6 +349,9 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo)
{
efi_status_t status;
+
+ setup_efi_sctlr();
+
exceptions_init();
memregions_init(arm_mem_regions, NR_MEM_REGIONS);
diff --git a/lib/arm64/processor.c b/lib/arm64/processor.c
index eb93fd7c..edc0ad87 100644
--- a/lib/arm64/processor.c
+++ b/lib/arm64/processor.c
@@ -8,6 +8,7 @@
#include <libcflat.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
+#include <asm/setup.h>
#include <asm/thread_info.h>
static const char *vector_names[] = {
@@ -271,3 +272,14 @@ bool __mmu_enabled(void)
{
return read_sysreg(sctlr_el1) & SCTLR_EL1_M;
}
+
+#ifdef CONFIG_EFI
+
+void setup_efi_sctlr(void)
+{
+ // EFI exits boot services with SCTLR_ELx.M=1, so keep
+ // the MMU enabled.
+ write_sysreg(INIT_SCTLR_EL1_MMU_OFF | SCTLR_EL1_M, sctlr_el1);
+}
+
+#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 02/10] arm64: efi: initialise SCTLR_ELx fully
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 02/10] arm64: efi: initialise SCTLR_ELx fully Joey Gouly
@ 2025-11-27 16:49 ` Eric Auger
2025-11-28 15:18 ` Joey Gouly
0 siblings, 1 reply; 38+ messages in thread
From: Eric Auger @ 2025-11-27 16:49 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
Hi Joey,
On 9/25/25 4:19 PM, Joey Gouly wrote:
> Don't rely on the value of SCTLR_ELx when booting via EFI.
>
> Signed-off-by: Joey Gouly <joey.gouly@arm.com>
> ---
> lib/arm/asm/setup.h | 6 ++++++
> lib/arm/setup.c | 3 +++
> lib/arm64/processor.c | 12 ++++++++++++
> 3 files changed, 21 insertions(+)
>
> diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
> index 9f8ef82e..4e60d552 100644
> --- a/lib/arm/asm/setup.h
> +++ b/lib/arm/asm/setup.h
> @@ -28,6 +28,12 @@ void setup(const void *fdt, phys_addr_t freemem_start);
>
> #include <efi.h>
>
> +#ifdef __aarch64__
> +void setup_efi_sctlr(void);
> +#else
> +static inline void setup_efi_sctlr(void) {}
> +#endif
> +
> efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo);
>
> #endif
> diff --git a/lib/arm/setup.c b/lib/arm/setup.c
> index 67b5db07..0aaa1d3a 100644
> --- a/lib/arm/setup.c
> +++ b/lib/arm/setup.c
> @@ -349,6 +349,9 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo)
> {
> efi_status_t status;
>
> +
spurious line
> + setup_efi_sctlr();
> +
> exceptions_init();
>
> memregions_init(arm_mem_regions, NR_MEM_REGIONS);
> diff --git a/lib/arm64/processor.c b/lib/arm64/processor.c
> index eb93fd7c..edc0ad87 100644
> --- a/lib/arm64/processor.c
> +++ b/lib/arm64/processor.c
> @@ -8,6 +8,7 @@
> #include <libcflat.h>
> #include <asm/ptrace.h>
> #include <asm/processor.h>
> +#include <asm/setup.h>
> #include <asm/thread_info.h>
>
> static const char *vector_names[] = {
> @@ -271,3 +272,14 @@ bool __mmu_enabled(void)
> {
> return read_sysreg(sctlr_el1) & SCTLR_EL1_M;
> }
> +
> +#ifdef CONFIG_EFI
> +
> +void setup_efi_sctlr(void)
> +{
> + // EFI exits boot services with SCTLR_ELx.M=1, so keep
> + // the MMU enabled.
I don't really understand the comment, if MMU was enabled why are we
mandated to set M bit again?
Eric
> + write_sysreg(INIT_SCTLR_EL1_MMU_OFF | SCTLR_EL1_M, sctlr_el1);
> +}
> +
> +#endif
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 02/10] arm64: efi: initialise SCTLR_ELx fully
2025-11-27 16:49 ` Eric Auger
@ 2025-11-28 15:18 ` Joey Gouly
0 siblings, 0 replies; 38+ messages in thread
From: Joey Gouly @ 2025-11-28 15:18 UTC (permalink / raw)
To: Eric Auger
Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On Thu, Nov 27, 2025 at 05:49:45PM +0100, Eric Auger wrote:
> Hi Joey,
>
> On 9/25/25 4:19 PM, Joey Gouly wrote:
> > Don't rely on the value of SCTLR_ELx when booting via EFI.
> >
> > Signed-off-by: Joey Gouly <joey.gouly@arm.com>
> > ---
> > lib/arm/asm/setup.h | 6 ++++++
> > lib/arm/setup.c | 3 +++
> > lib/arm64/processor.c | 12 ++++++++++++
> > 3 files changed, 21 insertions(+)
> >
> > diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
> > index 9f8ef82e..4e60d552 100644
> > --- a/lib/arm/asm/setup.h
> > +++ b/lib/arm/asm/setup.h
> > @@ -28,6 +28,12 @@ void setup(const void *fdt, phys_addr_t freemem_start);
> >
> > #include <efi.h>
> >
> > +#ifdef __aarch64__
> > +void setup_efi_sctlr(void);
> > +#else
> > +static inline void setup_efi_sctlr(void) {}
> > +#endif
> > +
> > efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo);
> >
> > #endif
> > diff --git a/lib/arm/setup.c b/lib/arm/setup.c
> > index 67b5db07..0aaa1d3a 100644
> > --- a/lib/arm/setup.c
> > +++ b/lib/arm/setup.c
> > @@ -349,6 +349,9 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo)
> > {
> > efi_status_t status;
> >
> > +
> spurious line
> > + setup_efi_sctlr();
> > +
> > exceptions_init();
> >
> > memregions_init(arm_mem_regions, NR_MEM_REGIONS);
> > diff --git a/lib/arm64/processor.c b/lib/arm64/processor.c
> > index eb93fd7c..edc0ad87 100644
> > --- a/lib/arm64/processor.c
> > +++ b/lib/arm64/processor.c
> > @@ -8,6 +8,7 @@
> > #include <libcflat.h>
> > #include <asm/ptrace.h>
> > #include <asm/processor.h>
> > +#include <asm/setup.h>
> > #include <asm/thread_info.h>
> >
> > static const char *vector_names[] = {
> > @@ -271,3 +272,14 @@ bool __mmu_enabled(void)
> > {
> > return read_sysreg(sctlr_el1) & SCTLR_EL1_M;
> > }
> > +
> > +#ifdef CONFIG_EFI
> > +
> > +void setup_efi_sctlr(void)
> > +{
> > + // EFI exits boot services with SCTLR_ELx.M=1, so keep
> > + // the MMU enabled.
> I don't really understand the comment, if MMU was enabled why are we
> mandated to set M bit again?
I'm overwriting sctlr_el1 with a fully new value, rather than using a
'read-modify-write' style. So the comment is justifying why I'm using the
INIT_SCTLR_EL1_MMU_OFF define but also or-ing in the M bit.
>
> Eric
> > + write_sysreg(INIT_SCTLR_EL1_MMU_OFF | SCTLR_EL1_M, sctlr_el1);
> > +}
> > +
> > +#endif
>
Thanks,
Joey
^ permalink raw reply [flat|nested] 38+ messages in thread
* [kvm-unit-tests PATCH v3 03/10] arm64: efi: initialise the EL
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 01/10] arm64: drop to EL1 if booted at EL2 Joey Gouly
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 02/10] arm64: efi: initialise SCTLR_ELx fully Joey Gouly
@ 2025-09-25 14:19 ` Joey Gouly
2025-11-27 17:08 ` Eric Auger
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 04/10] arm64: timer: use hypervisor timers when at EL2 Joey Gouly
` (9 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-09-25 14:19 UTC (permalink / raw)
To: kvm
Cc: alexandru.elisei, joey.gouly, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
Initialise the exception level, which may include dropping to EL1 from EL2, if
VHE is not supported.
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
arm/efi/crt0-efi-aarch64.S | 5 +++++
lib/arm/asm/setup.h | 2 ++
lib/arm/setup.c | 1 +
3 files changed, 8 insertions(+)
diff --git a/arm/efi/crt0-efi-aarch64.S b/arm/efi/crt0-efi-aarch64.S
index 71ce2794..5632fee0 100644
--- a/arm/efi/crt0-efi-aarch64.S
+++ b/arm/efi/crt0-efi-aarch64.S
@@ -147,6 +147,11 @@ _start:
0: ldp x29, x30, [sp], #32
ret
+.globl do_init_el
+do_init_el:
+ init_el x16
+ ret
+
.section .data
.balign 65536
diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
index 4e60d552..bf05ffbb 100644
--- a/lib/arm/asm/setup.h
+++ b/lib/arm/asm/setup.h
@@ -29,8 +29,10 @@ void setup(const void *fdt, phys_addr_t freemem_start);
#include <efi.h>
#ifdef __aarch64__
+void do_init_el(void);
void setup_efi_sctlr(void);
#else
+static inline void do_init_el(void) {}
static inline void setup_efi_sctlr(void) {}
#endif
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 0aaa1d3a..5ff40b54 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -349,6 +349,7 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo)
{
efi_status_t status;
+ do_init_el();
setup_efi_sctlr();
--
2.25.1
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 03/10] arm64: efi: initialise the EL
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 03/10] arm64: efi: initialise the EL Joey Gouly
@ 2025-11-27 17:08 ` Eric Auger
0 siblings, 0 replies; 38+ messages in thread
From: Eric Auger @ 2025-11-27 17:08 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On 9/25/25 4:19 PM, Joey Gouly wrote:
> Initialise the exception level, which may include dropping to EL1 from EL2, if
> VHE is not supported.
>
> Signed-off-by: Joey Gouly <joey.gouly@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
> ---
> arm/efi/crt0-efi-aarch64.S | 5 +++++
> lib/arm/asm/setup.h | 2 ++
> lib/arm/setup.c | 1 +
> 3 files changed, 8 insertions(+)
>
> diff --git a/arm/efi/crt0-efi-aarch64.S b/arm/efi/crt0-efi-aarch64.S
> index 71ce2794..5632fee0 100644
> --- a/arm/efi/crt0-efi-aarch64.S
> +++ b/arm/efi/crt0-efi-aarch64.S
> @@ -147,6 +147,11 @@ _start:
> 0: ldp x29, x30, [sp], #32
> ret
>
> +.globl do_init_el
> +do_init_el:
> + init_el x16
> + ret
> +
> .section .data
>
> .balign 65536
> diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
> index 4e60d552..bf05ffbb 100644
> --- a/lib/arm/asm/setup.h
> +++ b/lib/arm/asm/setup.h
> @@ -29,8 +29,10 @@ void setup(const void *fdt, phys_addr_t freemem_start);
> #include <efi.h>
>
> #ifdef __aarch64__
> +void do_init_el(void);
> void setup_efi_sctlr(void);
> #else
> +static inline void do_init_el(void) {}
> static inline void setup_efi_sctlr(void) {}
> #endif
>
> diff --git a/lib/arm/setup.c b/lib/arm/setup.c
> index 0aaa1d3a..5ff40b54 100644
> --- a/lib/arm/setup.c
> +++ b/lib/arm/setup.c
> @@ -349,6 +349,7 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo)
> {
> efi_status_t status;
>
> + do_init_el();
>
> setup_efi_sctlr();
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* [kvm-unit-tests PATCH v3 04/10] arm64: timer: use hypervisor timers when at EL2
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (2 preceding siblings ...)
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 03/10] arm64: efi: initialise the EL Joey Gouly
@ 2025-09-25 14:19 ` Joey Gouly
2025-12-02 8:36 ` Eric Auger
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 05/10] arm64: micro-bench: fix timer IRQ Joey Gouly
` (8 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-09-25 14:19 UTC (permalink / raw)
To: kvm
Cc: alexandru.elisei, joey.gouly, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
At EL2, with VHE:
CNT{P,V}_{TVAL,CTL}_EL0 is forwarded to CNTH{P,V}_{CVAL,TVAL,CTL}_EL0.
Save the hypervisor physical and virtual timer IRQ numbers from the DT/ACPI.
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
arm/timer.c | 10 ++++++++--
lib/acpi.h | 2 ++
lib/arm/asm/timer.h | 11 +++++++++++
lib/arm/timer.c | 19 +++++++++++++++++--
4 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/arm/timer.c b/arm/timer.c
index 2cb80518..c6287ca7 100644
--- a/arm/timer.c
+++ b/arm/timer.c
@@ -347,8 +347,14 @@ static void test_ptimer(void)
static void test_init(void)
{
assert(TIMER_PTIMER_IRQ != -1 && TIMER_VTIMER_IRQ != -1);
- ptimer_info.irq = TIMER_PTIMER_IRQ;
- vtimer_info.irq = TIMER_VTIMER_IRQ;
+ if (current_level() == CurrentEL_EL1) {
+ ptimer_info.irq = TIMER_PTIMER_IRQ;
+ vtimer_info.irq = TIMER_VTIMER_IRQ;
+ } else {
+ assert(TIMER_HPTIMER_IRQ != -1 && TIMER_HVTIMER_IRQ != -1);
+ ptimer_info.irq = TIMER_HPTIMER_IRQ;
+ vtimer_info.irq = TIMER_HVTIMER_IRQ;
+ }
install_exception_handler(EL1H_SYNC, ESR_EL1_EC_UNKNOWN, ptimer_unsupported_handler);
ptimer_info.read_ctl();
diff --git a/lib/acpi.h b/lib/acpi.h
index c330c877..66e3062d 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -290,6 +290,8 @@ struct acpi_table_gtdt {
u64 counter_read_block_address;
u32 platform_timer_count;
u32 platform_timer_offset;
+ u32 virtual_el2_timer_interrupt;
+ u32 virtual_el2_timer_flags;
};
/* Reset to default packing */
diff --git a/lib/arm/asm/timer.h b/lib/arm/asm/timer.h
index fd8f7796..0dcebc1c 100644
--- a/lib/arm/asm/timer.h
+++ b/lib/arm/asm/timer.h
@@ -21,12 +21,23 @@ struct timer_state {
u32 irq;
u32 irq_flags;
} vtimer;
+ struct {
+ u32 irq;
+ u32 irq_flags;
+ } hptimer;
+ struct {
+ u32 irq;
+ u32 irq_flags;
+ } hvtimer;
};
extern struct timer_state __timer_state;
#define TIMER_PTIMER_IRQ (__timer_state.ptimer.irq)
#define TIMER_VTIMER_IRQ (__timer_state.vtimer.irq)
+#define TIMER_HPTIMER_IRQ (__timer_state.hptimer.irq)
+#define TIMER_HVTIMER_IRQ (__timer_state.hvtimer.irq)
+
void timer_save_state(void);
#endif /* !__ASSEMBLER__ */
diff --git a/lib/arm/timer.c b/lib/arm/timer.c
index ae702e41..57f504e2 100644
--- a/lib/arm/timer.c
+++ b/lib/arm/timer.c
@@ -38,10 +38,11 @@ static void timer_save_state_fdt(void)
* secure timer irq
* non-secure timer irq (ptimer)
* virtual timer irq (vtimer)
- * hypervisor timer irq
+ * hypervisor timer irq (hptimer)
+ * hypervisor virtual timer irq (hvtimer)
*/
prop = fdt_get_property(fdt, node, "interrupts", &len);
- assert(prop && len == (4 * 3 * sizeof(u32)));
+ assert(prop && len >= (4 * 3 * sizeof(u32)));
data = (u32 *) prop->data;
assert(fdt32_to_cpu(data[3]) == 1 /* PPI */ );
@@ -50,6 +51,14 @@ static void timer_save_state_fdt(void)
assert(fdt32_to_cpu(data[6]) == 1 /* PPI */ );
__timer_state.vtimer.irq = PPI(fdt32_to_cpu(data[7]));
__timer_state.vtimer.irq_flags = fdt32_to_cpu(data[8]);
+ if (len == (5 * 3 * sizeof(u32))) {
+ assert(fdt32_to_cpu(data[9]) == 1 /* PPI */ );
+ __timer_state.hptimer.irq = PPI(fdt32_to_cpu(data[10]));
+ __timer_state.hptimer.irq_flags = fdt32_to_cpu(data[11]);
+ assert(fdt32_to_cpu(data[12]) == 1 /* PPI */ );
+ __timer_state.hvtimer.irq = PPI(fdt32_to_cpu(data[13]));
+ __timer_state.hvtimer.irq_flags = fdt32_to_cpu(data[14]);
+ }
}
#ifdef CONFIG_EFI
@@ -72,6 +81,12 @@ static void timer_save_state_acpi(void)
__timer_state.vtimer.irq = gtdt->virtual_timer_interrupt;
__timer_state.vtimer.irq_flags = gtdt->virtual_timer_flags;
+
+ __timer_state.hptimer.irq = gtdt->non_secure_el2_interrupt;
+ __timer_state.hptimer.irq_flags = gtdt->non_secure_el2_flags;
+
+ __timer_state.hvtimer.irq = gtdt->virtual_el2_timer_interrupt;
+ __timer_state.hvtimer.irq_flags = gtdt->virtual_el2_timer_flags;
}
#else
--
2.25.1
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 04/10] arm64: timer: use hypervisor timers when at EL2
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 04/10] arm64: timer: use hypervisor timers when at EL2 Joey Gouly
@ 2025-12-02 8:36 ` Eric Auger
0 siblings, 0 replies; 38+ messages in thread
From: Eric Auger @ 2025-12-02 8:36 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On 9/25/25 4:19 PM, Joey Gouly wrote:
> At EL2, with VHE:
> CNT{P,V}_{TVAL,CTL}_EL0 is forwarded to CNTH{P,V}_{CVAL,TVAL,CTL}_EL0.
>
> Save the hypervisor physical and virtual timer IRQ numbers from the DT/ACPI.
>
> Signed-off-by: Joey Gouly <joey.gouly@arm.com>
> Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
> arm/timer.c | 10 ++++++++--
> lib/acpi.h | 2 ++
> lib/arm/asm/timer.h | 11 +++++++++++
> lib/arm/timer.c | 19 +++++++++++++++++--
> 4 files changed, 38 insertions(+), 4 deletions(-)
>
> diff --git a/arm/timer.c b/arm/timer.c
> index 2cb80518..c6287ca7 100644
> --- a/arm/timer.c
> +++ b/arm/timer.c
> @@ -347,8 +347,14 @@ static void test_ptimer(void)
> static void test_init(void)
> {
> assert(TIMER_PTIMER_IRQ != -1 && TIMER_VTIMER_IRQ != -1);
nit: move above assert to
if (current_level() == CurrentEL_EL1) block?
> - ptimer_info.irq = TIMER_PTIMER_IRQ;
> - vtimer_info.irq = TIMER_VTIMER_IRQ;
> + if (current_level() == CurrentEL_EL1) {
> + ptimer_info.irq = TIMER_PTIMER_IRQ;
> + vtimer_info.irq = TIMER_VTIMER_IRQ;
> + } else {
> + assert(TIMER_HPTIMER_IRQ != -1 && TIMER_HVTIMER_IRQ != -1);
> + ptimer_info.irq = TIMER_HPTIMER_IRQ;
> + vtimer_info.irq = TIMER_HVTIMER_IRQ;
> + }
>
> install_exception_handler(EL1H_SYNC, ESR_EL1_EC_UNKNOWN, ptimer_unsupported_handler);
> ptimer_info.read_ctl();
> diff --git a/lib/acpi.h b/lib/acpi.h
> index c330c877..66e3062d 100644
> --- a/lib/acpi.h
> +++ b/lib/acpi.h
> @@ -290,6 +290,8 @@ struct acpi_table_gtdt {
> u64 counter_read_block_address;
> u32 platform_timer_count;
> u32 platform_timer_offset;
> + u32 virtual_el2_timer_interrupt;
> + u32 virtual_el2_timer_flags;
> };
>
> /* Reset to default packing */
> diff --git a/lib/arm/asm/timer.h b/lib/arm/asm/timer.h
> index fd8f7796..0dcebc1c 100644
> --- a/lib/arm/asm/timer.h
> +++ b/lib/arm/asm/timer.h
> @@ -21,12 +21,23 @@ struct timer_state {
> u32 irq;
> u32 irq_flags;
> } vtimer;
> + struct {
> + u32 irq;
> + u32 irq_flags;
> + } hptimer;
> + struct {
> + u32 irq;
> + u32 irq_flags;
> + } hvtimer;
> };
> extern struct timer_state __timer_state;
>
> #define TIMER_PTIMER_IRQ (__timer_state.ptimer.irq)
> #define TIMER_VTIMER_IRQ (__timer_state.vtimer.irq)
>
> +#define TIMER_HPTIMER_IRQ (__timer_state.hptimer.irq)
> +#define TIMER_HVTIMER_IRQ (__timer_state.hvtimer.irq)
> +
> void timer_save_state(void);
>
> #endif /* !__ASSEMBLER__ */
> diff --git a/lib/arm/timer.c b/lib/arm/timer.c
> index ae702e41..57f504e2 100644
> --- a/lib/arm/timer.c
> +++ b/lib/arm/timer.c
> @@ -38,10 +38,11 @@ static void timer_save_state_fdt(void)
> * secure timer irq
> * non-secure timer irq (ptimer)
> * virtual timer irq (vtimer)
> - * hypervisor timer irq
> + * hypervisor timer irq (hptimer)
> + * hypervisor virtual timer irq (hvtimer)
> */
> prop = fdt_get_property(fdt, node, "interrupts", &len);
> - assert(prop && len == (4 * 3 * sizeof(u32)));
> + assert(prop && len >= (4 * 3 * sizeof(u32)));
>
> data = (u32 *) prop->data;
> assert(fdt32_to_cpu(data[3]) == 1 /* PPI */ );
> @@ -50,6 +51,14 @@ static void timer_save_state_fdt(void)
> assert(fdt32_to_cpu(data[6]) == 1 /* PPI */ );
> __timer_state.vtimer.irq = PPI(fdt32_to_cpu(data[7]));
> __timer_state.vtimer.irq_flags = fdt32_to_cpu(data[8]);
> + if (len == (5 * 3 * sizeof(u32))) {
> + assert(fdt32_to_cpu(data[9]) == 1 /* PPI */ );
> + __timer_state.hptimer.irq = PPI(fdt32_to_cpu(data[10]));
> + __timer_state.hptimer.irq_flags = fdt32_to_cpu(data[11]);
> + assert(fdt32_to_cpu(data[12]) == 1 /* PPI */ );
> + __timer_state.hvtimer.irq = PPI(fdt32_to_cpu(data[13]));
> + __timer_state.hvtimer.irq_flags = fdt32_to_cpu(data[14]);
> + }
> }
>
> #ifdef CONFIG_EFI
> @@ -72,6 +81,12 @@ static void timer_save_state_acpi(void)
>
> __timer_state.vtimer.irq = gtdt->virtual_timer_interrupt;
> __timer_state.vtimer.irq_flags = gtdt->virtual_timer_flags;
> +
> + __timer_state.hptimer.irq = gtdt->non_secure_el2_interrupt;
> + __timer_state.hptimer.irq_flags = gtdt->non_secure_el2_flags;
> +
> + __timer_state.hvtimer.irq = gtdt->virtual_el2_timer_interrupt;
> + __timer_state.hvtimer.irq_flags = gtdt->virtual_el2_timer_flags;
> }
>
> #else
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
^ permalink raw reply [flat|nested] 38+ messages in thread
* [kvm-unit-tests PATCH v3 05/10] arm64: micro-bench: fix timer IRQ
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (3 preceding siblings ...)
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 04/10] arm64: timer: use hypervisor timers when at EL2 Joey Gouly
@ 2025-09-25 14:19 ` Joey Gouly
2025-12-02 8:36 ` Eric Auger
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 06/10] arm64: micro-bench: use smc when at EL2 Joey Gouly
` (7 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-09-25 14:19 UTC (permalink / raw)
To: kvm
Cc: alexandru.elisei, joey.gouly, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
Enable the correct (hvtimer) IRQ when at EL2.
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
arm/micro-bench.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arm/micro-bench.c b/arm/micro-bench.c
index 22408955..f47c5fc1 100644
--- a/arm/micro-bench.c
+++ b/arm/micro-bench.c
@@ -42,7 +42,7 @@ static void gic_irq_handler(struct pt_regs *regs)
irq_received = true;
gic_write_eoir(irqstat);
- if (irqstat == TIMER_VTIMER_IRQ) {
+ if (irqstat == TIMER_VTIMER_IRQ || irqstat == TIMER_HVTIMER_IRQ) {
write_sysreg((ARCH_TIMER_CTL_IMASK | ARCH_TIMER_CTL_ENABLE),
cntv_ctl_el0);
isb();
@@ -215,7 +215,11 @@ static bool timer_prep(void)
install_irq_handler(EL1H_IRQ, gic_irq_handler);
local_irq_enable();
- gic_enable_irq(TIMER_VTIMER_IRQ);
+ if (current_level() == CurrentEL_EL1)
+ gic_enable_irq(TIMER_VTIMER_IRQ);
+ else
+ gic_enable_irq(TIMER_HVTIMER_IRQ);
+
write_sysreg(ARCH_TIMER_CTL_IMASK | ARCH_TIMER_CTL_ENABLE, cntv_ctl_el0);
isb();
--
2.25.1
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 05/10] arm64: micro-bench: fix timer IRQ
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 05/10] arm64: micro-bench: fix timer IRQ Joey Gouly
@ 2025-12-02 8:36 ` Eric Auger
0 siblings, 0 replies; 38+ messages in thread
From: Eric Auger @ 2025-12-02 8:36 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On 9/25/25 4:19 PM, Joey Gouly wrote:
> Enable the correct (hvtimer) IRQ when at EL2.
>
> Signed-off-by: Joey Gouly <joey.gouly@arm.com>
> Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
> ---
> arm/micro-bench.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/arm/micro-bench.c b/arm/micro-bench.c
> index 22408955..f47c5fc1 100644
> --- a/arm/micro-bench.c
> +++ b/arm/micro-bench.c
> @@ -42,7 +42,7 @@ static void gic_irq_handler(struct pt_regs *regs)
> irq_received = true;
> gic_write_eoir(irqstat);
>
> - if (irqstat == TIMER_VTIMER_IRQ) {
> + if (irqstat == TIMER_VTIMER_IRQ || irqstat == TIMER_HVTIMER_IRQ) {
> write_sysreg((ARCH_TIMER_CTL_IMASK | ARCH_TIMER_CTL_ENABLE),
> cntv_ctl_el0);
> isb();
> @@ -215,7 +215,11 @@ static bool timer_prep(void)
> install_irq_handler(EL1H_IRQ, gic_irq_handler);
> local_irq_enable();
>
> - gic_enable_irq(TIMER_VTIMER_IRQ);
> + if (current_level() == CurrentEL_EL1)
> + gic_enable_irq(TIMER_VTIMER_IRQ);
> + else
> + gic_enable_irq(TIMER_HVTIMER_IRQ);
> +
> write_sysreg(ARCH_TIMER_CTL_IMASK | ARCH_TIMER_CTL_ENABLE, cntv_ctl_el0);
> isb();
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* [kvm-unit-tests PATCH v3 06/10] arm64: micro-bench: use smc when at EL2
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (4 preceding siblings ...)
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 05/10] arm64: micro-bench: fix timer IRQ Joey Gouly
@ 2025-09-25 14:19 ` Joey Gouly
2025-12-02 9:11 ` Eric Auger
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 07/10] arm64: selftest: update test for running " Joey Gouly
` (6 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-09-25 14:19 UTC (permalink / raw)
To: kvm
Cc: alexandru.elisei, joey.gouly, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
From: Alexandru Elisei <alexandru.elisei@arm.com>
At EL2, hvc would target the current EL, use smc so that it targets EL3.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
arm/micro-bench.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/arm/micro-bench.c b/arm/micro-bench.c
index f47c5fc1..32029c5a 100644
--- a/arm/micro-bench.c
+++ b/arm/micro-bench.c
@@ -282,6 +282,11 @@ static bool mmio_read_user_prep(void)
return true;
}
+static void smc_exec(void)
+{
+ asm volatile("mov w0, #0x4b000000; smc #0" ::: "w0");
+}
+
static void mmio_read_user_exec(void)
{
readl(userspace_emulated_addr);
@@ -300,6 +305,8 @@ static void eoi_exec(void)
write_eoir(spurious_id);
}
+static bool exec_select(void);
+
struct exit_test {
const char *name;
bool (*prep)(void);
@@ -310,7 +317,7 @@ struct exit_test {
};
static struct exit_test tests[] = {
- {"hvc", NULL, hvc_exec, NULL, 65536, true},
+ {"hyp_call", exec_select, hvc_exec, NULL, 65536, true},
{"mmio_read_user", mmio_read_user_prep, mmio_read_user_exec, NULL, 65536, true},
{"mmio_read_vgic", NULL, mmio_read_vgic_exec, NULL, 65536, true},
{"eoi", NULL, eoi_exec, NULL, 65536, true},
@@ -320,6 +327,15 @@ static struct exit_test tests[] = {
{"timer_10ms", timer_prep, timer_exec, timer_post, 256, true},
};
+static bool exec_select(void)
+{
+ if (current_level() == CurrentEL_EL2)
+ tests[0].exec = &smc_exec;
+ else
+ tests[0].exec = &hvc_exec;
+ return true;
+}
+
struct ns_time {
uint64_t ns;
uint64_t ns_frac;
--
2.25.1
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 06/10] arm64: micro-bench: use smc when at EL2
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 06/10] arm64: micro-bench: use smc when at EL2 Joey Gouly
@ 2025-12-02 9:11 ` Eric Auger
0 siblings, 0 replies; 38+ messages in thread
From: Eric Auger @ 2025-12-02 9:11 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On 9/25/25 4:19 PM, Joey Gouly wrote:
> From: Alexandru Elisei <alexandru.elisei@arm.com>
>
> At EL2, hvc would target the current EL, use smc so that it targets EL3.
>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> Signed-off-by: Joey Gouly <joey.gouly@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
> ---
> arm/micro-bench.c | 18 +++++++++++++++++-
> 1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/arm/micro-bench.c b/arm/micro-bench.c
> index f47c5fc1..32029c5a 100644
> --- a/arm/micro-bench.c
> +++ b/arm/micro-bench.c
> @@ -282,6 +282,11 @@ static bool mmio_read_user_prep(void)
> return true;
> }
>
> +static void smc_exec(void)
> +{
> + asm volatile("mov w0, #0x4b000000; smc #0" ::: "w0");
> +}
> +
> static void mmio_read_user_exec(void)
> {
> readl(userspace_emulated_addr);
> @@ -300,6 +305,8 @@ static void eoi_exec(void)
> write_eoir(spurious_id);
> }
>
> +static bool exec_select(void);
> +
> struct exit_test {
> const char *name;
> bool (*prep)(void);
> @@ -310,7 +317,7 @@ struct exit_test {
> };
>
> static struct exit_test tests[] = {
> - {"hvc", NULL, hvc_exec, NULL, 65536, true},
> + {"hyp_call", exec_select, hvc_exec, NULL, 65536, true},
> {"mmio_read_user", mmio_read_user_prep, mmio_read_user_exec, NULL, 65536, true},
> {"mmio_read_vgic", NULL, mmio_read_vgic_exec, NULL, 65536, true},
> {"eoi", NULL, eoi_exec, NULL, 65536, true},
> @@ -320,6 +327,15 @@ static struct exit_test tests[] = {
> {"timer_10ms", timer_prep, timer_exec, timer_post, 256, true},
> };
>
> +static bool exec_select(void)
> +{
> + if (current_level() == CurrentEL_EL2)
> + tests[0].exec = &smc_exec;
> + else
> + tests[0].exec = &hvc_exec;
> + return true;
> +}
> +
> struct ns_time {
> uint64_t ns;
> uint64_t ns_frac;
^ permalink raw reply [flat|nested] 38+ messages in thread
* [kvm-unit-tests PATCH v3 07/10] arm64: selftest: update test for running at EL2
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (5 preceding siblings ...)
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 06/10] arm64: micro-bench: use smc when at EL2 Joey Gouly
@ 2025-09-25 14:19 ` Joey Gouly
2025-12-02 9:16 ` Eric Auger
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 08/10] arm64: pmu: count EL2 cycles Joey Gouly
` (5 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-09-25 14:19 UTC (permalink / raw)
To: kvm
Cc: alexandru.elisei, joey.gouly, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
From: Alexandru Elisei <alexandru.elisei@arm.com>
Remove some hard-coded assumptions that this test is running at EL1.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
arm/selftest.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/arm/selftest.c b/arm/selftest.c
index 1553ed8e..01691389 100644
--- a/arm/selftest.c
+++ b/arm/selftest.c
@@ -232,6 +232,7 @@ static void user_psci_system_off(struct pt_regs *regs)
__user_psci_system_off();
}
#elif defined(__aarch64__)
+static unsigned long expected_level;
/*
* Capture the current register state and execute an instruction
@@ -276,8 +277,7 @@ static bool check_regs(struct pt_regs *regs)
{
unsigned i;
- /* exception handlers should always run in EL1 */
- if (current_level() != CurrentEL_EL1)
+ if (current_level() != expected_level)
return false;
for (i = 0; i < ARRAY_SIZE(regs->regs); ++i) {
@@ -301,7 +301,11 @@ static enum vector check_vector_prep(void)
return EL0_SYNC_64;
asm volatile("mrs %0, daif" : "=r" (daif) ::);
- expected_regs.pstate = daif | PSR_MODE_EL1h;
+ expected_regs.pstate = daif;
+ if (current_level() == CurrentEL_EL1)
+ expected_regs.pstate |= PSR_MODE_EL1h;
+ else
+ expected_regs.pstate |= PSR_MODE_EL2h;
return EL1H_SYNC;
}
@@ -317,8 +321,8 @@ static bool check_und(void)
install_exception_handler(v, ESR_EL1_EC_UNKNOWN, unknown_handler);
- /* try to read an el2 sysreg from el0/1 */
- test_exception("", "mrs x0, sctlr_el2", "", "x0");
+ /* try to read an el3 sysreg from el0/1/2 */
+ test_exception("", "mrs x0, sctlr_el3", "", "x0");
install_exception_handler(v, ESR_EL1_EC_UNKNOWN, NULL);
@@ -429,6 +433,10 @@ int main(int argc, char **argv)
if (argc < 2)
report_abort("no test specified");
+#if defined(__aarch64__)
+ expected_level = current_level();
+#endif
+
report_prefix_push(argv[1]);
if (strcmp(argv[1], "setup") == 0) {
--
2.25.1
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 07/10] arm64: selftest: update test for running at EL2
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 07/10] arm64: selftest: update test for running " Joey Gouly
@ 2025-12-02 9:16 ` Eric Auger
2025-12-02 12:21 ` Joey Gouly
0 siblings, 1 reply; 38+ messages in thread
From: Eric Auger @ 2025-12-02 9:16 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On 9/25/25 4:19 PM, Joey Gouly wrote:
> From: Alexandru Elisei <alexandru.elisei@arm.com>
>
> Remove some hard-coded assumptions that this test is running at EL1.
>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> Signed-off-by: Joey Gouly <joey.gouly@arm.com>
> ---
> arm/selftest.c | 18 +++++++++++++-----
> 1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/arm/selftest.c b/arm/selftest.c
> index 1553ed8e..01691389 100644
> --- a/arm/selftest.c
> +++ b/arm/selftest.c
> @@ -232,6 +232,7 @@ static void user_psci_system_off(struct pt_regs *regs)
> __user_psci_system_off();
> }
> #elif defined(__aarch64__)
> +static unsigned long expected_level;
>
> /*
> * Capture the current register state and execute an instruction
> @@ -276,8 +277,7 @@ static bool check_regs(struct pt_regs *regs)
> {
> unsigned i;
>
> - /* exception handlers should always run in EL1 */
> - if (current_level() != CurrentEL_EL1)
> + if (current_level() != expected_level)
> return false;
>
> for (i = 0; i < ARRAY_SIZE(regs->regs); ++i) {
> @@ -301,7 +301,11 @@ static enum vector check_vector_prep(void)
> return EL0_SYNC_64;
>
> asm volatile("mrs %0, daif" : "=r" (daif) ::);
> - expected_regs.pstate = daif | PSR_MODE_EL1h;
> + expected_regs.pstate = daif;
> + if (current_level() == CurrentEL_EL1)
> + expected_regs.pstate |= PSR_MODE_EL1h;
> + else
> + expected_regs.pstate |= PSR_MODE_EL2h;
> return EL1H_SYNC;
> }
>
> @@ -317,8 +321,8 @@ static bool check_und(void)
>
> install_exception_handler(v, ESR_EL1_EC_UNKNOWN, unknown_handler);
>
> - /* try to read an el2 sysreg from el0/1 */
> - test_exception("", "mrs x0, sctlr_el2", "", "x0");
> + /* try to read an el3 sysreg from el0/1/2 */
> + test_exception("", "mrs x0, sctlr_el3", "", "x0");
>
> install_exception_handler(v, ESR_EL1_EC_UNKNOWN, NULL);
>
> @@ -429,6 +433,10 @@ int main(int argc, char **argv)
> if (argc < 2)
> report_abort("no test specified");
>
> +#if defined(__aarch64__)
> + expected_level = current_level();
nit I would directly use current_level() in the calling function,
check_regs() to avoid that #ifdef
Eric
> +#endif
> +
> report_prefix_push(argv[1]);
>
> if (strcmp(argv[1], "setup") == 0) {
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 07/10] arm64: selftest: update test for running at EL2
2025-12-02 9:16 ` Eric Auger
@ 2025-12-02 12:21 ` Joey Gouly
2025-12-02 12:30 ` Eric Auger
0 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-12-02 12:21 UTC (permalink / raw)
To: Eric Auger
Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On Tue, Dec 02, 2025 at 10:16:42AM +0100, Eric Auger wrote:
>
>
> On 9/25/25 4:19 PM, Joey Gouly wrote:
> > From: Alexandru Elisei <alexandru.elisei@arm.com>
> >
> > Remove some hard-coded assumptions that this test is running at EL1.
> >
> > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > Signed-off-by: Joey Gouly <joey.gouly@arm.com>
> > ---
> > arm/selftest.c | 18 +++++++++++++-----
> > 1 file changed, 13 insertions(+), 5 deletions(-)
> >
> > diff --git a/arm/selftest.c b/arm/selftest.c
> > index 1553ed8e..01691389 100644
> > --- a/arm/selftest.c
> > +++ b/arm/selftest.c
> > @@ -232,6 +232,7 @@ static void user_psci_system_off(struct pt_regs *regs)
> > __user_psci_system_off();
> > }
> > #elif defined(__aarch64__)
> > +static unsigned long expected_level;
> >
> > /*
> > * Capture the current register state and execute an instruction
> > @@ -276,8 +277,7 @@ static bool check_regs(struct pt_regs *regs)
> > {
> > unsigned i;
> >
> > - /* exception handlers should always run in EL1 */
> > - if (current_level() != CurrentEL_EL1)
> > + if (current_level() != expected_level)
> > return false;
> >
> > for (i = 0; i < ARRAY_SIZE(regs->regs); ++i) {
> > @@ -301,7 +301,11 @@ static enum vector check_vector_prep(void)
> > return EL0_SYNC_64;
> >
> > asm volatile("mrs %0, daif" : "=r" (daif) ::);
> > - expected_regs.pstate = daif | PSR_MODE_EL1h;
> > + expected_regs.pstate = daif;
> > + if (current_level() == CurrentEL_EL1)
> > + expected_regs.pstate |= PSR_MODE_EL1h;
> > + else
> > + expected_regs.pstate |= PSR_MODE_EL2h;
> > return EL1H_SYNC;
> > }
> >
> > @@ -317,8 +321,8 @@ static bool check_und(void)
> >
> > install_exception_handler(v, ESR_EL1_EC_UNKNOWN, unknown_handler);
> >
> > - /* try to read an el2 sysreg from el0/1 */
> > - test_exception("", "mrs x0, sctlr_el2", "", "x0");
> > + /* try to read an el3 sysreg from el0/1/2 */
> > + test_exception("", "mrs x0, sctlr_el3", "", "x0");
> >
> > install_exception_handler(v, ESR_EL1_EC_UNKNOWN, NULL);
> >
> > @@ -429,6 +433,10 @@ int main(int argc, char **argv)
> > if (argc < 2)
> > report_abort("no test specified");
> >
> > +#if defined(__aarch64__)
> > + expected_level = current_level();
> nit I would directly use current_level() in the calling function,
> check_regs() to avoid that #ifdef
I can't move it into check_regs() because that's what's checking the exception
level of the handler is what the expected_level is.
Something like this (untested) would work:
diff --git a/arm/selftest.c b/arm/selftest.c
index 01691389..f173bc99 100644
--- a/arm/selftest.c
+++ b/arm/selftest.c
@@ -215,6 +215,7 @@ static void pabt_handler(struct pt_regs *regs)
static bool check_pabt(void)
{
+ expected_level = current_level();
install_exception_handler(EXCPTN_PABT, pabt_handler);
test_exception("ldr r9, =check_pabt_invalid_paddr\n"
@@ -318,6 +319,7 @@ static void unknown_handler(struct pt_regs *regs, unsigned int esr __unused)
static bool check_und(void)
{
enum vector v = check_vector_prep();
+ expected_level = current_level();
install_exception_handler(v, ESR_EL1_EC_UNKNOWN, unknown_handler);
@@ -340,6 +342,7 @@ static void svc_handler(struct pt_regs *regs, unsigned int esr)
static bool check_svc(void)
{
enum vector v = check_vector_prep();
+ expected_level = current_level();
install_exception_handler(v, ESR_EL1_EC_SVC64, svc_handler);
@@ -433,10 +436,6 @@ int main(int argc, char **argv)
if (argc < 2)
report_abort("no test specified");
-#if defined(__aarch64__)
- expected_level = current_level();
-#endif
-
report_prefix_push(argv[1]);
if (strcmp(argv[1], "setup") == 0) {
Is that preferable than an #ifdef?
Thanks,
Joey
>
> Eric
> > +#endif
> > +
> > report_prefix_push(argv[1]);
> >
> > if (strcmp(argv[1], "setup") == 0) {
>
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 07/10] arm64: selftest: update test for running at EL2
2025-12-02 12:21 ` Joey Gouly
@ 2025-12-02 12:30 ` Eric Auger
0 siblings, 0 replies; 38+ messages in thread
From: Eric Auger @ 2025-12-02 12:30 UTC (permalink / raw)
To: Joey Gouly
Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On 12/2/25 1:21 PM, Joey Gouly wrote:
> On Tue, Dec 02, 2025 at 10:16:42AM +0100, Eric Auger wrote:
>>
>> On 9/25/25 4:19 PM, Joey Gouly wrote:
>>> From: Alexandru Elisei <alexandru.elisei@arm.com>
>>>
>>> Remove some hard-coded assumptions that this test is running at EL1.
>>>
>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
>>> Signed-off-by: Joey Gouly <joey.gouly@arm.com>
>>> ---
>>> arm/selftest.c | 18 +++++++++++++-----
>>> 1 file changed, 13 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/arm/selftest.c b/arm/selftest.c
>>> index 1553ed8e..01691389 100644
>>> --- a/arm/selftest.c
>>> +++ b/arm/selftest.c
>>> @@ -232,6 +232,7 @@ static void user_psci_system_off(struct pt_regs *regs)
>>> __user_psci_system_off();
>>> }
>>> #elif defined(__aarch64__)
>>> +static unsigned long expected_level;
>>>
>>> /*
>>> * Capture the current register state and execute an instruction
>>> @@ -276,8 +277,7 @@ static bool check_regs(struct pt_regs *regs)
>>> {
>>> unsigned i;
>>>
>>> - /* exception handlers should always run in EL1 */
>>> - if (current_level() != CurrentEL_EL1)
>>> + if (current_level() != expected_level)
>>> return false;
>>>
>>> for (i = 0; i < ARRAY_SIZE(regs->regs); ++i) {
>>> @@ -301,7 +301,11 @@ static enum vector check_vector_prep(void)
>>> return EL0_SYNC_64;
>>>
>>> asm volatile("mrs %0, daif" : "=r" (daif) ::);
>>> - expected_regs.pstate = daif | PSR_MODE_EL1h;
>>> + expected_regs.pstate = daif;
>>> + if (current_level() == CurrentEL_EL1)
>>> + expected_regs.pstate |= PSR_MODE_EL1h;
>>> + else
>>> + expected_regs.pstate |= PSR_MODE_EL2h;
>>> return EL1H_SYNC;
>>> }
>>>
>>> @@ -317,8 +321,8 @@ static bool check_und(void)
>>>
>>> install_exception_handler(v, ESR_EL1_EC_UNKNOWN, unknown_handler);
>>>
>>> - /* try to read an el2 sysreg from el0/1 */
>>> - test_exception("", "mrs x0, sctlr_el2", "", "x0");
>>> + /* try to read an el3 sysreg from el0/1/2 */
>>> + test_exception("", "mrs x0, sctlr_el3", "", "x0");
>>>
>>> install_exception_handler(v, ESR_EL1_EC_UNKNOWN, NULL);
>>>
>>> @@ -429,6 +433,10 @@ int main(int argc, char **argv)
>>> if (argc < 2)
>>> report_abort("no test specified");
>>>
>>> +#if defined(__aarch64__)
>>> + expected_level = current_level();
>> nit I would directly use current_level() in the calling function,
>> check_regs() to avoid that #ifdef
> I can't move it into check_regs() because that's what's checking the exception
> level of the handler is what the expected_level is.
>
> Something like this (untested) would work:
>
> diff --git a/arm/selftest.c b/arm/selftest.c
> index 01691389..f173bc99 100644
> --- a/arm/selftest.c
> +++ b/arm/selftest.c
> @@ -215,6 +215,7 @@ static void pabt_handler(struct pt_regs *regs)
>
> static bool check_pabt(void)
> {
> + expected_level = current_level();
> install_exception_handler(EXCPTN_PABT, pabt_handler);
>
> test_exception("ldr r9, =check_pabt_invalid_paddr\n"
> @@ -318,6 +319,7 @@ static void unknown_handler(struct pt_regs *regs, unsigned int esr __unused)
> static bool check_und(void)
> {
> enum vector v = check_vector_prep();
> + expected_level = current_level();
>
> install_exception_handler(v, ESR_EL1_EC_UNKNOWN, unknown_handler);
>
> @@ -340,6 +342,7 @@ static void svc_handler(struct pt_regs *regs, unsigned int esr)
> static bool check_svc(void)
> {
> enum vector v = check_vector_prep();
> + expected_level = current_level();
>
> install_exception_handler(v, ESR_EL1_EC_SVC64, svc_handler);
>
> @@ -433,10 +436,6 @@ int main(int argc, char **argv)
> if (argc < 2)
> report_abort("no test specified");
>
> -#if defined(__aarch64__)
> - expected_level = current_level();
> -#endif
> -
> report_prefix_push(argv[1]);
>
> if (strcmp(argv[1], "setup") == 0) {
>
> Is that preferable than an #ifdef?
OK. yes I think so
Eric
>
> Thanks,
> Joey
>> Eric
>>> +#endif
>>> +
>>> report_prefix_push(argv[1]);
>>>
>>> if (strcmp(argv[1], "setup") == 0) {
^ permalink raw reply [flat|nested] 38+ messages in thread
* [kvm-unit-tests PATCH v3 08/10] arm64: pmu: count EL2 cycles
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (6 preceding siblings ...)
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 07/10] arm64: selftest: update test for running " Joey Gouly
@ 2025-09-25 14:19 ` Joey Gouly
2025-12-02 10:31 ` Eric Auger
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 09/10] arm64: run at EL2 if supported Joey Gouly
` (4 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-09-25 14:19 UTC (permalink / raw)
To: kvm
Cc: alexandru.elisei, joey.gouly, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
Count EL2 cycles if that's the EL kvm-unit-tests is running at!
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
arm/pmu.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/arm/pmu.c b/arm/pmu.c
index 2dc0822b..e6c0f05b 100644
--- a/arm/pmu.c
+++ b/arm/pmu.c
@@ -121,6 +121,8 @@ static struct pmu pmu;
#define PMINTENCLR __ACCESS_CP15(c9, 0, c14, 2)
#define PMCCNTR64 __ACCESS_CP15_64(0, c9)
+#define PMCCFILTR_EL0_DEFAULT 0
+
static inline uint32_t get_id_dfr0(void) { return read_sysreg(ID_DFR0); }
static inline uint32_t get_pmcr(void) { return read_sysreg(PMCR); }
static inline void set_pmcr(uint32_t v) { write_sysreg(v, PMCR); }
@@ -206,6 +208,9 @@ static void test_overflow_interrupt(bool overflow_at_64bits) {}
#define ID_DFR0_PMU_V3_8_5 0b0110
#define ID_DFR0_PMU_IMPDEF 0b1111
+#define PMCCFILTR_EL0_NSH BIT(27)
+#define PMCCFILTR_EL0_DEFAULT (current_level() == CurrentEL_EL2 ? PMCCFILTR_EL0_NSH : 0)
+
static inline uint32_t get_id_aa64dfr0(void) { return read_sysreg(id_aa64dfr0_el1); }
static inline uint32_t get_pmcr(void) { return read_sysreg(pmcr_el0); }
static inline void set_pmcr(uint32_t v) { write_sysreg(v, pmcr_el0); }
@@ -246,8 +251,7 @@ static inline void precise_instrs_loop(int loop, uint32_t pmcr)
#define PMCNTENSET_EL0 sys_reg(3, 3, 9, 12, 1)
#define PMCNTENCLR_EL0 sys_reg(3, 3, 9, 12, 2)
-#define PMEVTYPER_EXCLUDE_EL1 BIT(31)
-#define PMEVTYPER_EXCLUDE_EL0 BIT(30)
+#define PMEVTYPER_EXCLUDE_EL0 BIT(30) | (current_level() == CurrentEL_EL2 ? BIT(27) : 0)
static bool is_event_supported(uint32_t n, bool warn)
{
@@ -1063,7 +1067,8 @@ static bool check_cycles_increase(void)
/* init before event access, this test only cares about cycle count */
pmu_reset();
set_pmcntenset(1 << PMU_CYCLE_IDX);
- set_pmccfiltr(0); /* count cycles in EL0, EL1, but not EL2 */
+
+ set_pmccfiltr(PMCCFILTR_EL0_DEFAULT);
set_pmcr(get_pmcr() | PMU_PMCR_LC | PMU_PMCR_C | PMU_PMCR_E);
isb();
@@ -1118,7 +1123,7 @@ static bool check_cpi(int cpi)
/* init before event access, this test only cares about cycle count */
pmu_reset();
set_pmcntenset(1 << PMU_CYCLE_IDX);
- set_pmccfiltr(0); /* count cycles in EL0, EL1, but not EL2 */
+ set_pmccfiltr(PMCCFILTR_EL0_DEFAULT);
if (cpi > 0)
printf("Checking for CPI=%d.\n", cpi);
--
2.25.1
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 08/10] arm64: pmu: count EL2 cycles
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 08/10] arm64: pmu: count EL2 cycles Joey Gouly
@ 2025-12-02 10:31 ` Eric Auger
0 siblings, 0 replies; 38+ messages in thread
From: Eric Auger @ 2025-12-02 10:31 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On 9/25/25 4:19 PM, Joey Gouly wrote:
> Count EL2 cycles if that's the EL kvm-unit-tests is running at!
>
> Signed-off-by: Joey Gouly <joey.gouly@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
> ---
> arm/pmu.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/arm/pmu.c b/arm/pmu.c
> index 2dc0822b..e6c0f05b 100644
> --- a/arm/pmu.c
> +++ b/arm/pmu.c
> @@ -121,6 +121,8 @@ static struct pmu pmu;
> #define PMINTENCLR __ACCESS_CP15(c9, 0, c14, 2)
> #define PMCCNTR64 __ACCESS_CP15_64(0, c9)
>
> +#define PMCCFILTR_EL0_DEFAULT 0
> +
> static inline uint32_t get_id_dfr0(void) { return read_sysreg(ID_DFR0); }
> static inline uint32_t get_pmcr(void) { return read_sysreg(PMCR); }
> static inline void set_pmcr(uint32_t v) { write_sysreg(v, PMCR); }
> @@ -206,6 +208,9 @@ static void test_overflow_interrupt(bool overflow_at_64bits) {}
> #define ID_DFR0_PMU_V3_8_5 0b0110
> #define ID_DFR0_PMU_IMPDEF 0b1111
>
> +#define PMCCFILTR_EL0_NSH BIT(27)
> +#define PMCCFILTR_EL0_DEFAULT (current_level() == CurrentEL_EL2 ? PMCCFILTR_EL0_NSH : 0)
> +
> static inline uint32_t get_id_aa64dfr0(void) { return read_sysreg(id_aa64dfr0_el1); }
> static inline uint32_t get_pmcr(void) { return read_sysreg(pmcr_el0); }
> static inline void set_pmcr(uint32_t v) { write_sysreg(v, pmcr_el0); }
> @@ -246,8 +251,7 @@ static inline void precise_instrs_loop(int loop, uint32_t pmcr)
> #define PMCNTENSET_EL0 sys_reg(3, 3, 9, 12, 1)
> #define PMCNTENCLR_EL0 sys_reg(3, 3, 9, 12, 2)
>
> -#define PMEVTYPER_EXCLUDE_EL1 BIT(31)
> -#define PMEVTYPER_EXCLUDE_EL0 BIT(30)
> +#define PMEVTYPER_EXCLUDE_EL0 BIT(30) | (current_level() == CurrentEL_EL2 ? BIT(27) : 0)
>
> static bool is_event_supported(uint32_t n, bool warn)
> {
> @@ -1063,7 +1067,8 @@ static bool check_cycles_increase(void)
> /* init before event access, this test only cares about cycle count */
> pmu_reset();
> set_pmcntenset(1 << PMU_CYCLE_IDX);
> - set_pmccfiltr(0); /* count cycles in EL0, EL1, but not EL2 */
> +
> + set_pmccfiltr(PMCCFILTR_EL0_DEFAULT);
>
> set_pmcr(get_pmcr() | PMU_PMCR_LC | PMU_PMCR_C | PMU_PMCR_E);
> isb();
> @@ -1118,7 +1123,7 @@ static bool check_cpi(int cpi)
> /* init before event access, this test only cares about cycle count */
> pmu_reset();
> set_pmcntenset(1 << PMU_CYCLE_IDX);
> - set_pmccfiltr(0); /* count cycles in EL0, EL1, but not EL2 */
> + set_pmccfiltr(PMCCFILTR_EL0_DEFAULT);
>
> if (cpi > 0)
> printf("Checking for CPI=%d.\n", cpi);
^ permalink raw reply [flat|nested] 38+ messages in thread
* [kvm-unit-tests PATCH v3 09/10] arm64: run at EL2 if supported
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (7 preceding siblings ...)
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 08/10] arm64: pmu: count EL2 cycles Joey Gouly
@ 2025-09-25 14:19 ` Joey Gouly
2025-12-02 10:35 ` Eric Auger
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 10/10] arm64: add EL2 environment variable Joey Gouly
` (3 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-09-25 14:19 UTC (permalink / raw)
To: kvm
Cc: alexandru.elisei, joey.gouly, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
If VHE is supported, continue booting at EL2, otherwise continue booting at
EL1.
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
arm/cstart64.S | 17 +++++++++++++----
lib/arm64/asm/sysreg.h | 5 +++++
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/arm/cstart64.S b/arm/cstart64.S
index 79b93dd4..af7c81c1 100644
--- a/arm/cstart64.S
+++ b/arm/cstart64.S
@@ -18,7 +18,7 @@
.macro init_el, tmp
mrs \tmp, CurrentEL
cmp \tmp, CurrentEL_EL2
- b.ne 1f
+ b.ne 2f
/* EL2 setup */
mrs \tmp, mpidr_el1
msr vmpidr_el2, \tmp
@@ -41,17 +41,26 @@
msr_s SYS_HFGWTR2_EL2, \tmp
msr_s SYS_HFGITR2_EL2, \tmp
.Lskip_fgt_\@:
+ /* check VHE is supported */
+ mrs \tmp, ID_AA64MMFR1_EL1
+ ubfx \tmp, \tmp, ID_AA64MMFR1_EL1_VH_SHIFT, #4
+ cbz \tmp, 1f
+ ldr \tmp, =(INIT_HCR_EL2)
+ msr hcr_el2, \tmp
+ isb
+ b 2f
+1:
mov \tmp, #0
msr cptr_el2, \tmp
ldr \tmp, =(INIT_HCR_EL2_EL1_ONLY)
msr hcr_el2, \tmp
mov \tmp, PSR_MODE_EL1t
msr spsr_el2, \tmp
- adrp \tmp, 1f
- add \tmp, \tmp, :lo12:1f
+ adrp \tmp, 2f
+ add \tmp, \tmp, :lo12:2f
msr elr_el2, \tmp
eret
-1:
+2:
.endm
diff --git a/lib/arm64/asm/sysreg.h b/lib/arm64/asm/sysreg.h
index ed776716..f2d05018 100644
--- a/lib/arm64/asm/sysreg.h
+++ b/lib/arm64/asm/sysreg.h
@@ -80,6 +80,8 @@ asm(
#define ID_AA64MMFR0_EL1_FGT_SHIFT 56
#define ID_AA64MMFR0_EL1_FGT_FGT2 0x2
+#define ID_AA64MMFR1_EL1_VH_SHIFT 8
+
#define ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0)
#define ICC_SGI1R_EL1 sys_reg(3, 0, 12, 11, 5)
#define ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0)
@@ -116,9 +118,12 @@ asm(
#define SCTLR_EL1_TCF0_SHIFT 38
#define SCTLR_EL1_TCF0_MASK GENMASK_ULL(39, 38)
+#define HCR_EL2_TGE _BITULL(27)
#define HCR_EL2_RW _BITULL(31)
+#define HCR_EL2_E2H _BITULL(34)
#define INIT_HCR_EL2_EL1_ONLY (HCR_EL2_RW)
+#define INIT_HCR_EL2 (HCR_EL2_TGE | HCR_EL2_E2H | HCR_EL2_RW)
#define SYS_HFGRTR_EL2 sys_reg(3, 4, 1, 1, 4)
#define SYS_HFGWTR_EL2 sys_reg(3, 4, 1, 1, 5)
--
2.25.1
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 09/10] arm64: run at EL2 if supported
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 09/10] arm64: run at EL2 if supported Joey Gouly
@ 2025-12-02 10:35 ` Eric Auger
0 siblings, 0 replies; 38+ messages in thread
From: Eric Auger @ 2025-12-02 10:35 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On 9/25/25 4:19 PM, Joey Gouly wrote:
> If VHE is supported, continue booting at EL2, otherwise continue booting at
> EL1.
>
> Signed-off-by: Joey Gouly <joey.gouly@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
> ---
> arm/cstart64.S | 17 +++++++++++++----
> lib/arm64/asm/sysreg.h | 5 +++++
> 2 files changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/arm/cstart64.S b/arm/cstart64.S
> index 79b93dd4..af7c81c1 100644
> --- a/arm/cstart64.S
> +++ b/arm/cstart64.S
> @@ -18,7 +18,7 @@
> .macro init_el, tmp
> mrs \tmp, CurrentEL
> cmp \tmp, CurrentEL_EL2
> - b.ne 1f
> + b.ne 2f
> /* EL2 setup */
> mrs \tmp, mpidr_el1
> msr vmpidr_el2, \tmp
> @@ -41,17 +41,26 @@
> msr_s SYS_HFGWTR2_EL2, \tmp
> msr_s SYS_HFGITR2_EL2, \tmp
> .Lskip_fgt_\@:
> + /* check VHE is supported */
> + mrs \tmp, ID_AA64MMFR1_EL1
> + ubfx \tmp, \tmp, ID_AA64MMFR1_EL1_VH_SHIFT, #4
> + cbz \tmp, 1f
> + ldr \tmp, =(INIT_HCR_EL2)
> + msr hcr_el2, \tmp
> + isb
> + b 2f
> +1:
> mov \tmp, #0
> msr cptr_el2, \tmp
> ldr \tmp, =(INIT_HCR_EL2_EL1_ONLY)
> msr hcr_el2, \tmp
> mov \tmp, PSR_MODE_EL1t
> msr spsr_el2, \tmp
> - adrp \tmp, 1f
> - add \tmp, \tmp, :lo12:1f
> + adrp \tmp, 2f
> + add \tmp, \tmp, :lo12:2f
> msr elr_el2, \tmp
> eret
> -1:
> +2:
> .endm
>
>
> diff --git a/lib/arm64/asm/sysreg.h b/lib/arm64/asm/sysreg.h
> index ed776716..f2d05018 100644
> --- a/lib/arm64/asm/sysreg.h
> +++ b/lib/arm64/asm/sysreg.h
> @@ -80,6 +80,8 @@ asm(
> #define ID_AA64MMFR0_EL1_FGT_SHIFT 56
> #define ID_AA64MMFR0_EL1_FGT_FGT2 0x2
>
> +#define ID_AA64MMFR1_EL1_VH_SHIFT 8
> +
> #define ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0)
> #define ICC_SGI1R_EL1 sys_reg(3, 0, 12, 11, 5)
> #define ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0)
> @@ -116,9 +118,12 @@ asm(
> #define SCTLR_EL1_TCF0_SHIFT 38
> #define SCTLR_EL1_TCF0_MASK GENMASK_ULL(39, 38)
>
> +#define HCR_EL2_TGE _BITULL(27)
> #define HCR_EL2_RW _BITULL(31)
> +#define HCR_EL2_E2H _BITULL(34)
>
> #define INIT_HCR_EL2_EL1_ONLY (HCR_EL2_RW)
> +#define INIT_HCR_EL2 (HCR_EL2_TGE | HCR_EL2_E2H | HCR_EL2_RW)
>
> #define SYS_HFGRTR_EL2 sys_reg(3, 4, 1, 1, 4)
> #define SYS_HFGWTR_EL2 sys_reg(3, 4, 1, 1, 5)
^ permalink raw reply [flat|nested] 38+ messages in thread
* [kvm-unit-tests PATCH v3 10/10] arm64: add EL2 environment variable
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (8 preceding siblings ...)
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 09/10] arm64: run at EL2 if supported Joey Gouly
@ 2025-09-25 14:19 ` Joey Gouly
2025-11-27 10:34 ` Eric Auger
2025-12-01 23:34 ` Andrew Jones
2025-11-19 13:18 ` [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (2 subsequent siblings)
12 siblings, 2 replies; 38+ messages in thread
From: Joey Gouly @ 2025-09-25 14:19 UTC (permalink / raw)
To: kvm
Cc: alexandru.elisei, joey.gouly, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
This variable when set to 1 will cause QEMU/kvmtool to start at EL2.
---
arm/run | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arm/run b/arm/run
index 858333fc..2a9c0de0 100755
--- a/arm/run
+++ b/arm/run
@@ -59,6 +59,10 @@ function arch_run_qemu()
M+=",highmem=off"
fi
+ if [ "$EL2" = "1" ]; then
+ M+=",virtualization=on"
+ fi
+
if ! $qemu $M -device '?' | grep -q virtconsole; then
echo "$qemu doesn't support virtio-console for chr-testdev. Exiting."
exit 2
@@ -116,6 +120,9 @@ function arch_run_kvmtool()
fi
command="$(timeout_cmd) $kvmtool run"
+ if [ "$EL2" = "1" ]; then
+ command+=" --nested"
+ fi
if [ "$HOST" = "aarch64" ] && [ "$ARCH" = "arm" ]; then
run_test_status $command --kernel "$@" --aarch32
else
--
2.25.1
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 10/10] arm64: add EL2 environment variable
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 10/10] arm64: add EL2 environment variable Joey Gouly
@ 2025-11-27 10:34 ` Eric Auger
2025-11-27 10:40 ` Joey Gouly
2025-12-01 23:34 ` Andrew Jones
1 sibling, 1 reply; 38+ messages in thread
From: Eric Auger @ 2025-11-27 10:34 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
Hi Joey,
On 9/25/25 4:19 PM, Joey Gouly wrote:
> This variable when set to 1 will cause QEMU/kvmtool to start at EL2.
Misses the Sob.
Besides Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
> ---
> arm/run | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arm/run b/arm/run
> index 858333fc..2a9c0de0 100755
> --- a/arm/run
> +++ b/arm/run
> @@ -59,6 +59,10 @@ function arch_run_qemu()
> M+=",highmem=off"
> fi
>
> + if [ "$EL2" = "1" ]; then
> + M+=",virtualization=on"
> + fi
> +
> if ! $qemu $M -device '?' | grep -q virtconsole; then
> echo "$qemu doesn't support virtio-console for chr-testdev. Exiting."
> exit 2
> @@ -116,6 +120,9 @@ function arch_run_kvmtool()
> fi
>
> command="$(timeout_cmd) $kvmtool run"
> + if [ "$EL2" = "1" ]; then
> + command+=" --nested"
> + fi
> if [ "$HOST" = "aarch64" ] && [ "$ARCH" = "arm" ]; then
> run_test_status $command --kernel "$@" --aarch32
> else
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [kvm-unit-tests PATCH v3 10/10] arm64: add EL2 environment variable
2025-11-27 10:34 ` Eric Auger
@ 2025-11-27 10:40 ` Joey Gouly
0 siblings, 0 replies; 38+ messages in thread
From: Joey Gouly @ 2025-11-27 10:40 UTC (permalink / raw)
To: Eric Auger
Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On Thu, Nov 27, 2025 at 11:34:56AM +0100, Eric Auger wrote:
> Hi Joey,
>
> On 9/25/25 4:19 PM, Joey Gouly wrote:
> > This variable when set to 1 will cause QEMU/kvmtool to start at EL2.
>
> Misses the Sob.
If this counts:
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
I have fixed kvm-unit-tests to add that automatically to my commits now, thanks.
>
> Besides Reviewed-by: Eric Auger <eric.auger@redhat.com>
Thanks,
Joey
>
> Eric
>
> > ---
> > arm/run | 7 +++++++
> > 1 file changed, 7 insertions(+)
> >
> > diff --git a/arm/run b/arm/run
> > index 858333fc..2a9c0de0 100755
> > --- a/arm/run
> > +++ b/arm/run
> > @@ -59,6 +59,10 @@ function arch_run_qemu()
> > M+=",highmem=off"
> > fi
> >
> > + if [ "$EL2" = "1" ]; then
> > + M+=",virtualization=on"
> > + fi
> > +
> > if ! $qemu $M -device '?' | grep -q virtconsole; then
> > echo "$qemu doesn't support virtio-console for chr-testdev. Exiting."
> > exit 2
> > @@ -116,6 +120,9 @@ function arch_run_kvmtool()
> > fi
> >
> > command="$(timeout_cmd) $kvmtool run"
> > + if [ "$EL2" = "1" ]; then
> > + command+=" --nested"
> > + fi
> > if [ "$HOST" = "aarch64" ] && [ "$ARCH" = "arm" ]; then
> > run_test_status $command --kernel "$@" --aarch32
> > else
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [kvm-unit-tests PATCH v3 10/10] arm64: add EL2 environment variable
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 10/10] arm64: add EL2 environment variable Joey Gouly
2025-11-27 10:34 ` Eric Auger
@ 2025-12-01 23:34 ` Andrew Jones
1 sibling, 0 replies; 38+ messages in thread
From: Andrew Jones @ 2025-12-01 23:34 UTC (permalink / raw)
To: Joey Gouly; +Cc: kvm, alexandru.elisei, kvmarm, Marc Zyngier, Oliver Upton
On Thu, Sep 25, 2025 at 03:19:58PM +0100, Joey Gouly wrote:
> This variable when set to 1 will cause QEMU/kvmtool to start at EL2.
> ---
> arm/run | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arm/run b/arm/run
> index 858333fc..2a9c0de0 100755
> --- a/arm/run
> +++ b/arm/run
> @@ -59,6 +59,10 @@ function arch_run_qemu()
> M+=",highmem=off"
> fi
>
> + if [ "$EL2" = "1" ]; then
Please also support 'y' and 'Y', e.g. 'EL2=y run_tests.sh -g ...'
Thanks,
drew
> + M+=",virtualization=on"
> + fi
> +
> if ! $qemu $M -device '?' | grep -q virtconsole; then
> echo "$qemu doesn't support virtio-console for chr-testdev. Exiting."
> exit 2
> @@ -116,6 +120,9 @@ function arch_run_kvmtool()
> fi
>
> command="$(timeout_cmd) $kvmtool run"
> + if [ "$EL2" = "1" ]; then
> + command+=" --nested"
> + fi
> if [ "$HOST" = "aarch64" ] && [ "$ARCH" = "arm" ]; then
> run_test_status $command --kernel "$@" --aarch32
> else
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (9 preceding siblings ...)
2025-09-25 14:19 ` [kvm-unit-tests PATCH v3 10/10] arm64: add EL2 environment variable Joey Gouly
@ 2025-11-19 13:18 ` Joey Gouly
2025-11-19 13:48 ` Nadav Amit
2025-11-19 15:34 ` Marc Zyngier
2025-11-27 10:04 ` Eric Auger
12 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-11-19 13:18 UTC (permalink / raw)
To: kvm; +Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On Thu, Sep 25, 2025 at 03:19:48PM +0100, Joey Gouly wrote:
> Hi all,
>
> This series is for adding support to running the kvm-unit-tests at EL2. These
> have been tested with Linux 6.17-rc6 KVM nested virt.
>
> This latest round I also tested using the run_tests.sh script with QEMU TCG,
> running at EL2.
>
> The goal is to later extend and add new tests for Nested Virtualisation,
> however they should also work with bare metal as well.
Any comments on this series, would be nice to get it merged.
Thanks,
Joey
>
> Changes since v2[1]:
> - Move the sctlr setup in EFI to a function.
> - Decided to not re-use el2_setup.h from Linux, looked more
> complicated to use than needed for KUT.
> - Add EL2 env variable for testing, open to feedback for that.
> This was untested with kvmtool as my testing setup only has
> busybox ash currently, and the run_tests.sh script needs bash.
>
> Issues (that I think are fine to investigate/fix later):
> - Some of the debug tests fail with QEMU at EL2 and kvmtool.
> - The gic ipi test times out with QEMU at EL2, but works with kvmtool.
>
> Thanks,
> Joey
>
> [1] https://lore.kernel.org/kvmarm/20250529135557.2439500-1-joey.gouly@arm.com/
>
> Alexandru Elisei (2):
> arm64: micro-bench: use smc when at EL2
> arm64: selftest: update test for running at EL2
>
> Joey Gouly (8):
> arm64: drop to EL1 if booted at EL2
> arm64: efi: initialise SCTLR_ELx fully
> arm64: efi: initialise the EL
> arm64: timer: use hypervisor timers when at EL2
> arm64: micro-bench: fix timer IRQ
> arm64: pmu: count EL2 cycles
> arm64: run at EL2 if supported
> arm64: add EL2 environment variable
>
> arm/cstart64.S | 56 ++++++++++++++++++++++++++++++++++++--
> arm/efi/crt0-efi-aarch64.S | 5 ++++
> arm/micro-bench.c | 26 ++++++++++++++++--
> arm/pmu.c | 13 ++++++---
> arm/run | 7 +++++
> arm/selftest.c | 18 ++++++++----
> arm/timer.c | 10 +++++--
> lib/acpi.h | 2 ++
> lib/arm/asm/setup.h | 8 ++++++
> lib/arm/asm/timer.h | 11 ++++++++
> lib/arm/setup.c | 4 +++
> lib/arm/timer.c | 19 +++++++++++--
> lib/arm64/asm/sysreg.h | 19 +++++++++++++
> lib/arm64/processor.c | 12 ++++++++
> 14 files changed, 191 insertions(+), 19 deletions(-)
>
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-11-19 13:18 ` [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
@ 2025-11-19 13:48 ` Nadav Amit
2025-11-19 14:02 ` Joey Gouly
0 siblings, 1 reply; 38+ messages in thread
From: Nadav Amit @ 2025-11-19 13:48 UTC (permalink / raw)
To: Joey Gouly
Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
> On 19 Nov 2025, at 15:18, Joey Gouly <joey.gouly@arm.com> wrote:
>
> On Thu, Sep 25, 2025 at 03:19:48PM +0100, Joey Gouly wrote:
>> Hi all,
>>
>> This series is for adding support to running the kvm-unit-tests at EL2. These
>> have been tested with Linux 6.17-rc6 KVM nested virt.
>>
>> This latest round I also tested using the run_tests.sh script with QEMU TCG,
>> running at EL2.
>>
>> The goal is to later extend and add new tests for Nested Virtualisation,
>> however they should also work with bare metal as well.
>
> Any comments on this series, would be nice to get it merged.
I wonder, does kvm-unit-tests run on bare-metal arm64 these days?
I ran it in-house some time ago (fixing several issues on the way),
but IIRC this issue was never fixed upstream:
https://lore.kernel.org/all/C812A718-DCD6-4485-BB5A-B24DE73A0FD3@gmail.com/
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-11-19 13:48 ` Nadav Amit
@ 2025-11-19 14:02 ` Joey Gouly
2025-11-19 15:34 ` Andrew Jones
0 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-11-19 14:02 UTC (permalink / raw)
To: Nadav Amit
Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
Hi Nadav,
On Wed, Nov 19, 2025 at 03:48:13PM +0200, Nadav Amit wrote:
>
>
> > On 19 Nov 2025, at 15:18, Joey Gouly <joey.gouly@arm.com> wrote:
> >
> > On Thu, Sep 25, 2025 at 03:19:48PM +0100, Joey Gouly wrote:
> >> Hi all,
> >>
> >> This series is for adding support to running the kvm-unit-tests at EL2. These
> >> have been tested with Linux 6.17-rc6 KVM nested virt.
> >>
> >> This latest round I also tested using the run_tests.sh script with QEMU TCG,
> >> running at EL2.
> >>
> >> The goal is to later extend and add new tests for Nested Virtualisation,
> >> however they should also work with bare metal as well.
> >
> > Any comments on this series, would be nice to get it merged.
>
> I wonder, does kvm-unit-tests run on bare-metal arm64 these days?
>
> I ran it in-house some time ago (fixing several issues on the way),
> but IIRC this issue was never fixed upstream:
>
> https://lore.kernel.org/all/C812A718-DCD6-4485-BB5A-B24DE73A0FD3@gmail.com/
>
I haven't tested on real bare-metal hardware, I have been booting directly in
QEMU with both .flat and .efi.
Thanks,
Joey
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-11-19 14:02 ` Joey Gouly
@ 2025-11-19 15:34 ` Andrew Jones
0 siblings, 0 replies; 38+ messages in thread
From: Andrew Jones @ 2025-11-19 15:34 UTC (permalink / raw)
To: Joey Gouly
Cc: Nadav Amit, kvm, alexandru.elisei, andrew.jones, kvmarm,
Marc Zyngier, Oliver Upton
On Wed, Nov 19, 2025 at 02:02:24PM +0000, Joey Gouly wrote:
> Hi Nadav,
>
> On Wed, Nov 19, 2025 at 03:48:13PM +0200, Nadav Amit wrote:
> >
> >
> > > On 19 Nov 2025, at 15:18, Joey Gouly <joey.gouly@arm.com> wrote:
> > >
> > > On Thu, Sep 25, 2025 at 03:19:48PM +0100, Joey Gouly wrote:
> > >> Hi all,
> > >>
> > >> This series is for adding support to running the kvm-unit-tests at EL2. These
> > >> have been tested with Linux 6.17-rc6 KVM nested virt.
> > >>
> > >> This latest round I also tested using the run_tests.sh script with QEMU TCG,
> > >> running at EL2.
> > >>
> > >> The goal is to later extend and add new tests for Nested Virtualisation,
> > >> however they should also work with bare metal as well.
> > >
> > > Any comments on this series, would be nice to get it merged.
> >
> > I wonder, does kvm-unit-tests run on bare-metal arm64 these days?
> >
> > I ran it in-house some time ago (fixing several issues on the way),
> > but IIRC this issue was never fixed upstream:
> >
> > https://lore.kernel.org/all/C812A718-DCD6-4485-BB5A-B24DE73A0FD3@gmail.com/
> >
>
> I haven't tested on real bare-metal hardware, I have been booting directly in
> QEMU with both .flat and .efi.
At one point arm64 builds worked on bare-metal - I added commit 993c37be77
("arm/arm64: Zero BSS and stack at startup") as part of that effort. I
don't know if it still works, though, since I haven't tested it in years.
As for this series, I was hoping someone more invested in arm64 would do
some reviewing and testing. Then, given we get some r-b's and t-b's, I'd
give it a quick skim and ship it.
Thanks,
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (10 preceding siblings ...)
2025-11-19 13:18 ` [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
@ 2025-11-19 15:34 ` Marc Zyngier
2025-11-27 10:04 ` Eric Auger
12 siblings, 0 replies; 38+ messages in thread
From: Marc Zyngier @ 2025-11-19 15:34 UTC (permalink / raw)
To: Joey Gouly; +Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Oliver Upton
On Thu, 25 Sep 2025 15:19:48 +0100,
Joey Gouly <joey.gouly@arm.com> wrote:
>
> Hi all,
>
> This series is for adding support to running the kvm-unit-tests at EL2. These
> have been tested with Linux 6.17-rc6 KVM nested virt.
>
> This latest round I also tested using the run_tests.sh script with QEMU TCG,
> running at EL2.
I've eyeballed it superficially, and didn't spot anything unexpected.
Given that upstream KVM now supports NV, not having anything in KUT is
becoming a problem, and this is a first step towards proper testing.
FWIW:
Acked-by: Marc Zyngier <maz@kernel.org>
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-09-25 14:19 [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support Joey Gouly
` (11 preceding siblings ...)
2025-11-19 15:34 ` Marc Zyngier
@ 2025-11-27 10:04 ` Eric Auger
2025-11-27 11:08 ` Joey Gouly
12 siblings, 1 reply; 38+ messages in thread
From: Eric Auger @ 2025-11-27 10:04 UTC (permalink / raw)
To: Joey Gouly, kvm
Cc: alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
Hi Joey,
On 9/25/25 4:19 PM, Joey Gouly wrote:
> Hi all,
>
> This series is for adding support to running the kvm-unit-tests at EL2. These
> have been tested with Linux 6.17-rc6 KVM nested virt.
>
> This latest round I also tested using the run_tests.sh script with QEMU TCG,
> running at EL2.
>
> The goal is to later extend and add new tests for Nested Virtualisation,
> however they should also work with bare metal as well.
>
> Changes since v2[1]:
> - Move the sctlr setup in EFI to a function.
> - Decided to not re-use el2_setup.h from Linux, looked more
> complicated to use than needed for KUT.
> - Add EL2 env variable for testing, open to feedback for that.
> This was untested with kvmtool as my testing setup only has
> busybox ash currently, and the run_tests.sh script needs bash.
>
> Issues (that I think are fine to investigate/fix later):
> - Some of the debug tests fail with QEMU at EL2 and kvmtool.
> - The gic ipi test times out with QEMU at EL2, but works with kvmtool.
Have you noticed any failure with migration tests. On my end, as soon as
I set EL2=1 migration tests do fail.
Eric
>
> Thanks,
> Joey
>
> [1] https://lore.kernel.org/kvmarm/20250529135557.2439500-1-joey.gouly@arm.com/
>
> Alexandru Elisei (2):
> arm64: micro-bench: use smc when at EL2
> arm64: selftest: update test for running at EL2
>
> Joey Gouly (8):
> arm64: drop to EL1 if booted at EL2
> arm64: efi: initialise SCTLR_ELx fully
> arm64: efi: initialise the EL
> arm64: timer: use hypervisor timers when at EL2
> arm64: micro-bench: fix timer IRQ
> arm64: pmu: count EL2 cycles
> arm64: run at EL2 if supported
> arm64: add EL2 environment variable
>
> arm/cstart64.S | 56 ++++++++++++++++++++++++++++++++++++--
> arm/efi/crt0-efi-aarch64.S | 5 ++++
> arm/micro-bench.c | 26 ++++++++++++++++--
> arm/pmu.c | 13 ++++++---
> arm/run | 7 +++++
> arm/selftest.c | 18 ++++++++----
> arm/timer.c | 10 +++++--
> lib/acpi.h | 2 ++
> lib/arm/asm/setup.h | 8 ++++++
> lib/arm/asm/timer.h | 11 ++++++++
> lib/arm/setup.c | 4 +++
> lib/arm/timer.c | 19 +++++++++++--
> lib/arm64/asm/sysreg.h | 19 +++++++++++++
> lib/arm64/processor.c | 12 ++++++++
> 14 files changed, 191 insertions(+), 19 deletions(-)
>
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-11-27 10:04 ` Eric Auger
@ 2025-11-27 11:08 ` Joey Gouly
2025-11-27 12:04 ` Eric Auger
0 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-11-27 11:08 UTC (permalink / raw)
To: Eric Auger
Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On Thu, Nov 27, 2025 at 11:04:43AM +0100, Eric Auger wrote:
> Hi Joey,
>
> On 9/25/25 4:19 PM, Joey Gouly wrote:
> > Hi all,
> >
> > This series is for adding support to running the kvm-unit-tests at EL2. These
> > have been tested with Linux 6.17-rc6 KVM nested virt.
> >
> > This latest round I also tested using the run_tests.sh script with QEMU TCG,
> > running at EL2.
> >
> > The goal is to later extend and add new tests for Nested Virtualisation,
> > however they should also work with bare metal as well.
> >
> > Changes since v2[1]:
> > - Move the sctlr setup in EFI to a function.
> > - Decided to not re-use el2_setup.h from Linux, looked more
> > complicated to use than needed for KUT.
> > - Add EL2 env variable for testing, open to feedback for that.
> > This was untested with kvmtool as my testing setup only has
> > busybox ash currently, and the run_tests.sh script needs bash.
> >
> > Issues (that I think are fine to investigate/fix later):
> > - Some of the debug tests fail with QEMU at EL2 and kvmtool.
> > - The gic ipi test times out with QEMU at EL2, but works with kvmtool.
>
> Have you noticed any failure with migration tests. On my end, as soon as
> I set EL2=1 migration tests do fail.
Yes migration also fails here, forgot to mention that.
Seems like migration completes, but then something bad happens on the first
interrupt. I will investigate a bit now and see if it's an easy fix.
Thanks,
Joey
>
> Eric
> >
> > Thanks,
> > Joey
> >
> > [1] https://lore.kernel.org/kvmarm/20250529135557.2439500-1-joey.gouly@arm.com/
> >
> > Alexandru Elisei (2):
> > arm64: micro-bench: use smc when at EL2
> > arm64: selftest: update test for running at EL2
> >
> > Joey Gouly (8):
> > arm64: drop to EL1 if booted at EL2
> > arm64: efi: initialise SCTLR_ELx fully
> > arm64: efi: initialise the EL
> > arm64: timer: use hypervisor timers when at EL2
> > arm64: micro-bench: fix timer IRQ
> > arm64: pmu: count EL2 cycles
> > arm64: run at EL2 if supported
> > arm64: add EL2 environment variable
> >
> > arm/cstart64.S | 56 ++++++++++++++++++++++++++++++++++++--
> > arm/efi/crt0-efi-aarch64.S | 5 ++++
> > arm/micro-bench.c | 26 ++++++++++++++++--
> > arm/pmu.c | 13 ++++++---
> > arm/run | 7 +++++
> > arm/selftest.c | 18 ++++++++----
> > arm/timer.c | 10 +++++--
> > lib/acpi.h | 2 ++
> > lib/arm/asm/setup.h | 8 ++++++
> > lib/arm/asm/timer.h | 11 ++++++++
> > lib/arm/setup.c | 4 +++
> > lib/arm/timer.c | 19 +++++++++++--
> > lib/arm64/asm/sysreg.h | 19 +++++++++++++
> > lib/arm64/processor.c | 12 ++++++++
> > 14 files changed, 191 insertions(+), 19 deletions(-)
> >
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-11-27 11:08 ` Joey Gouly
@ 2025-11-27 12:04 ` Eric Auger
2025-11-27 14:52 ` Joey Gouly
0 siblings, 1 reply; 38+ messages in thread
From: Eric Auger @ 2025-11-27 12:04 UTC (permalink / raw)
To: Joey Gouly
Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
Hi Joey,
On 11/27/25 12:08 PM, Joey Gouly wrote:
> On Thu, Nov 27, 2025 at 11:04:43AM +0100, Eric Auger wrote:
>> Hi Joey,
>>
>> On 9/25/25 4:19 PM, Joey Gouly wrote:
>>> Hi all,
>>>
>>> This series is for adding support to running the kvm-unit-tests at EL2. These
>>> have been tested with Linux 6.17-rc6 KVM nested virt.
>>>
>>> This latest round I also tested using the run_tests.sh script with QEMU TCG,
>>> running at EL2.
>>>
>>> The goal is to later extend and add new tests for Nested Virtualisation,
>>> however they should also work with bare metal as well.
>>>
>>> Changes since v2[1]:
>>> - Move the sctlr setup in EFI to a function.
>>> - Decided to not re-use el2_setup.h from Linux, looked more
>>> complicated to use than needed for KUT.
>>> - Add EL2 env variable for testing, open to feedback for that.
>>> This was untested with kvmtool as my testing setup only has
>>> busybox ash currently, and the run_tests.sh script needs bash.
>>>
>>> Issues (that I think are fine to investigate/fix later):
>>> - Some of the debug tests fail with QEMU at EL2 and kvmtool.
>>> - The gic ipi test times out with QEMU at EL2, but works with kvmtool.
>> Have you noticed any failure with migration tests. On my end, as soon as
>> I set EL2=1 migration tests do fail.
> Yes migration also fails here, forgot to mention that.
>
> Seems like migration completes, but then something bad happens on the first
> interrupt. I will investigate a bit now and see if it's an easy fix.
while you do that I will go through the series. My apologies for the delay
Eric
>
> Thanks,
> Joey
>
>> Eric
>>> Thanks,
>>> Joey
>>>
>>> [1] https://lore.kernel.org/kvmarm/20250529135557.2439500-1-joey.gouly@arm.com/
>>>
>>> Alexandru Elisei (2):
>>> arm64: micro-bench: use smc when at EL2
>>> arm64: selftest: update test for running at EL2
>>>
>>> Joey Gouly (8):
>>> arm64: drop to EL1 if booted at EL2
>>> arm64: efi: initialise SCTLR_ELx fully
>>> arm64: efi: initialise the EL
>>> arm64: timer: use hypervisor timers when at EL2
>>> arm64: micro-bench: fix timer IRQ
>>> arm64: pmu: count EL2 cycles
>>> arm64: run at EL2 if supported
>>> arm64: add EL2 environment variable
>>>
>>> arm/cstart64.S | 56 ++++++++++++++++++++++++++++++++++++--
>>> arm/efi/crt0-efi-aarch64.S | 5 ++++
>>> arm/micro-bench.c | 26 ++++++++++++++++--
>>> arm/pmu.c | 13 ++++++---
>>> arm/run | 7 +++++
>>> arm/selftest.c | 18 ++++++++----
>>> arm/timer.c | 10 +++++--
>>> lib/acpi.h | 2 ++
>>> lib/arm/asm/setup.h | 8 ++++++
>>> lib/arm/asm/timer.h | 11 ++++++++
>>> lib/arm/setup.c | 4 +++
>>> lib/arm/timer.c | 19 +++++++++++--
>>> lib/arm64/asm/sysreg.h | 19 +++++++++++++
>>> lib/arm64/processor.c | 12 ++++++++
>>> 14 files changed, 191 insertions(+), 19 deletions(-)
>>>
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-11-27 12:04 ` Eric Auger
@ 2025-11-27 14:52 ` Joey Gouly
2025-12-01 23:16 ` Andrew Jones
0 siblings, 1 reply; 38+ messages in thread
From: Joey Gouly @ 2025-11-27 14:52 UTC (permalink / raw)
To: Eric Auger
Cc: kvm, alexandru.elisei, andrew.jones, kvmarm, Marc Zyngier,
Oliver Upton
On Thu, Nov 27, 2025 at 01:04:08PM +0100, Eric Auger wrote:
> Hi Joey,
>
> On 11/27/25 12:08 PM, Joey Gouly wrote:
> > On Thu, Nov 27, 2025 at 11:04:43AM +0100, Eric Auger wrote:
> >> Hi Joey,
> >>
> >> On 9/25/25 4:19 PM, Joey Gouly wrote:
> >>> Hi all,
> >>>
> >>> This series is for adding support to running the kvm-unit-tests at EL2. These
> >>> have been tested with Linux 6.17-rc6 KVM nested virt.
> >>>
> >>> This latest round I also tested using the run_tests.sh script with QEMU TCG,
> >>> running at EL2.
> >>>
> >>> The goal is to later extend and add new tests for Nested Virtualisation,
> >>> however they should also work with bare metal as well.
> >>>
> >>> Changes since v2[1]:
> >>> - Move the sctlr setup in EFI to a function.
> >>> - Decided to not re-use el2_setup.h from Linux, looked more
> >>> complicated to use than needed for KUT.
> >>> - Add EL2 env variable for testing, open to feedback for that.
> >>> This was untested with kvmtool as my testing setup only has
> >>> busybox ash currently, and the run_tests.sh script needs bash.
> >>>
> >>> Issues (that I think are fine to investigate/fix later):
> >>> - Some of the debug tests fail with QEMU at EL2 and kvmtool.
> >>> - The gic ipi test times out with QEMU at EL2, but works with kvmtool.
> >> Have you noticed any failure with migration tests. On my end, as soon as
> >> I set EL2=1 migration tests do fail.
> > Yes migration also fails here, forgot to mention that.
> >
> > Seems like migration completes, but then something bad happens on the first
> > interrupt. I will investigate a bit now and see if it's an easy fix.
>
> while you do that I will go through the series. My apologies for the delay
Thanks!
I found the issue, and I thought it was one I had solved before, but maybe I lost the fix somehow:
diff --git a/arm/cstart64.S b/arm/cstart64.S
index af7c81c1..fd8b6690 100644
--- a/arm/cstart64.S
+++ b/arm/cstart64.S
@@ -235,6 +235,11 @@ get_mmu_off:
.globl secondary_entry
secondary_entry:
init_el x0
+
+ /* set SCTLR_EL1 to a known value */
+ ldr x4, =INIT_SCTLR_EL1_MMU_OFF
+ msr sctlr_el1, x4
+ isb
+
/* enable FP/ASIMD and SVE */
mov x0, #(3 << 20)
orr x0, x0, #(3 << 16)
The secondary core code doesn't fully initialise SCTLR_ELx, which means that
SCTLR_ELx.SPAN=0. That's why there was a data abort after the IRQ.
This doesn't affect EL1 (only) because KVM has a different reset value for
SCTLR_EL1 and SCTLR_EL2.
I will send out a new version with this fix, missing sob/reviews/acks, after you've had a look!
Thanks,
Joey
>
> Eric
> >
> > Thanks,
> > Joey
> >
> >> Eric
> >>> Thanks,
> >>> Joey
> >>>
> >>> [1] https://lore.kernel.org/kvmarm/20250529135557.2439500-1-joey.gouly@arm.com/
> >>>
> >>> Alexandru Elisei (2):
> >>> arm64: micro-bench: use smc when at EL2
> >>> arm64: selftest: update test for running at EL2
> >>>
> >>> Joey Gouly (8):
> >>> arm64: drop to EL1 if booted at EL2
> >>> arm64: efi: initialise SCTLR_ELx fully
> >>> arm64: efi: initialise the EL
> >>> arm64: timer: use hypervisor timers when at EL2
> >>> arm64: micro-bench: fix timer IRQ
> >>> arm64: pmu: count EL2 cycles
> >>> arm64: run at EL2 if supported
> >>> arm64: add EL2 environment variable
> >>>
> >>> arm/cstart64.S | 56 ++++++++++++++++++++++++++++++++++++--
> >>> arm/efi/crt0-efi-aarch64.S | 5 ++++
> >>> arm/micro-bench.c | 26 ++++++++++++++++--
> >>> arm/pmu.c | 13 ++++++---
> >>> arm/run | 7 +++++
> >>> arm/selftest.c | 18 ++++++++----
> >>> arm/timer.c | 10 +++++--
> >>> lib/acpi.h | 2 ++
> >>> lib/arm/asm/setup.h | 8 ++++++
> >>> lib/arm/asm/timer.h | 11 ++++++++
> >>> lib/arm/setup.c | 4 +++
> >>> lib/arm/timer.c | 19 +++++++++++--
> >>> lib/arm64/asm/sysreg.h | 19 +++++++++++++
> >>> lib/arm64/processor.c | 12 ++++++++
> >>> 14 files changed, 191 insertions(+), 19 deletions(-)
> >>>
>
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-11-27 14:52 ` Joey Gouly
@ 2025-12-01 23:16 ` Andrew Jones
2025-12-02 14:22 ` Joey Gouly
0 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2025-12-01 23:16 UTC (permalink / raw)
To: Joey Gouly
Cc: Eric Auger, kvm, alexandru.elisei, kvmarm, Marc Zyngier,
Oliver Upton
On Thu, Nov 27, 2025 at 02:52:07PM +0000, Joey Gouly wrote:
...
> I will send out a new version with this fix, missing sob/reviews/acks, after you've had a look!
>
Also please run checkpatch on the series if you haven't already. I think
it should have complained about the C++ comments, for example. And, in
any case, please change the C++ comments to C comments and generally use
the kernel's coding style.
Thanks,
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [kvm-unit-tests PATCH v3 00/10] arm64: EL2 support
2025-12-01 23:16 ` Andrew Jones
@ 2025-12-02 14:22 ` Joey Gouly
0 siblings, 0 replies; 38+ messages in thread
From: Joey Gouly @ 2025-12-02 14:22 UTC (permalink / raw)
To: Andrew Jones
Cc: Eric Auger, kvm, alexandru.elisei, kvmarm, Marc Zyngier,
Oliver Upton
On Mon, Dec 01, 2025 at 05:16:40PM -0600, Andrew Jones wrote:
> On Thu, Nov 27, 2025 at 02:52:07PM +0000, Joey Gouly wrote:
> ...
> > I will send out a new version with this fix, missing sob/reviews/acks, after you've had a look!
> >
>
> Also please run checkpatch on the series if you haven't already. I think
> it should have complained about the C++ comments, for example. And, in
> any case, please change the C++ comments to C comments and generally use
> the kernel's coding style.
I hadn't run it, have done so now, and fixed some style issues.
checkpatch doesn't actually complain about those C++/C99 comments, I guess at
some point Linux started to allow them. If you run with `--ignore
C99_COMMENT_TOLERANCE` it does complain.
I will change the one place I used them to the multiline style anyway.
Thanks,
Joey
^ permalink raw reply [flat|nested] 38+ messages in thread