On 19.08.20 16:28, Alice Guo wrote:
> An AArch64 hypervisor can host both AArch32 and AArch64 virtual machines
> at the same time. If the inmate cell wants to run in AArch32 mode, the
> assigned cpu must change to AArch32. Because AArch64 hypervisor and
> AArch64 root cell are used, when the AArch32 inmate cell is destroyed,
> cpu owned by inmate cell will be reassigned to AArch64 root cell, switch
> the cpu back to AArch64.
> 
> The following is a summary of some of the points when supporting inmate
> cell in AArch32 mode:
> Define a macro "JAILHOUSE_CELL_AARCH32" to indicate AArch32 execution
> state. Add this macro to flags of struct jailhouse_cell_desc, and you can
> use it to indicate whether a cell is AArch32.
> 
> Add "bool aarch32" as second parameter to arm_cpu_reset(), and can use
> it to pass execution state. If aarch32 equals true, switch to AArch32.
> 
> When an exception occurs, the processor must execute handler code which
> corresponds to the exception. When the exception is being taken at a
> lower Exception level, the execution state of the next lower level
> (AArch64 or AArch32) will be used. Fill exception handling functions for
> Lower EL using AArch32 in hypervisor/arch/arm64/entry.S.
> 
> Configure the registers related to changing execution state. If a cell
> is AArch32, SPSR_EL2.M[4] will be set to 0b1 which means AArch32
> execution state, SPSR_EL2.M[3:0] will be set to 0b0011 which means
> Supervisor, and HCR_EL2.RW will be set to 0b0 which means lower levels
> are all AArch32. If a cell is AArch64, make sure HCR_EL2.RW is 0 and the
> other registers are configured according to the previous code.
> 
> After Linux operating system boots up, execute the following commands to
> use AArch32 virtual machine on the i.MX8DXL:
> ./jailhouse enable imx8dxl.cell
> ./jailhouse cell create imx8dxl-gic-demo-aarch32.cell
> ./jailhouse cell load 1 gic-demo.bin (32-bit)
> ./jailhouse cell start 1
> 
> Signed-off-by: Alice Guo <[email protected]>
> ---
>  hypervisor/arch/arm-common/control.c             |  7 +++++--
>  hypervisor/arch/arm-common/include/asm/control.h |  2 +-
>  hypervisor/arch/arm/control.c                    |  2 +-
>  hypervisor/arch/arm64/control.c                  | 14 ++++++++++++--
>  hypervisor/arch/arm64/entry.S                    |  8 ++++----
>  hypervisor/arch/arm64/include/asm/sysregs.h      |  6 +++++-
>  include/jailhouse/cell-config.h                  |  1 +
>  7 files changed, 29 insertions(+), 11 deletions(-)
> 
> diff --git a/hypervisor/arch/arm-common/control.c 
> b/hypervisor/arch/arm-common/control.c
> index 70793432..3caa30c6 100644
> --- a/hypervisor/arch/arm-common/control.c
> +++ b/hypervisor/arch/arm-common/control.c
> @@ -32,7 +32,9 @@ void arm_cpu_park(void)
>       enter_cpu_off(cpu_public);
>       spin_unlock(&cpu_public->control_lock);
>  
> -     arm_cpu_reset(0);
> +     arm_cpu_reset(0, !!(this_cell()->config->flags &
> +                   JAILHOUSE_CELL_AARCH32));
> +
>       arm_paging_vcpu_init(&parking_pt);
>  }
>  
> @@ -100,7 +102,8 @@ static void check_events(struct public_per_cpu 
> *cpu_public)
>       if (cpu_public->wait_for_poweron)
>               arm_cpu_park();
>       else if (reset)
> -             arm_cpu_reset(cpu_public->cpu_on_entry);
> +             arm_cpu_reset(cpu_public->cpu_on_entry,
> +             !!(this_cell()->config->flags & JAILHOUSE_CELL_AARCH32));
>  }
>  
>  void arch_handle_sgi(u32 irqn, unsigned int count_event)
> diff --git a/hypervisor/arch/arm-common/include/asm/control.h 
> b/hypervisor/arch/arm-common/include/asm/control.h
> index 2f54e2b5..9a5eaba7 100644
> --- a/hypervisor/arch/arm-common/include/asm/control.h
> +++ b/hypervisor/arch/arm-common/include/asm/control.h
> @@ -29,7 +29,7 @@ void arch_shutdown_self(struct per_cpu *cpu_data);
>  
>  unsigned int arm_cpu_by_mpidr(struct cell *cell, unsigned long mpidr);
>  
> -void arm_cpu_reset(unsigned long pc);
> +void arm_cpu_reset(unsigned long pc, bool aarch32);
>  void arm_cpu_park(void);
>  
>  #endif /* !__ASSEMBLY__ */
> diff --git a/hypervisor/arch/arm/control.c b/hypervisor/arch/arm/control.c
> index 5e1828f6..cd68dd9a 100644
> --- a/hypervisor/arch/arm/control.c
> +++ b/hypervisor/arch/arm/control.c
> @@ -20,7 +20,7 @@
>  #include <asm/psci.h>
>  #include <asm/sysregs.h>
>  
> -void arm_cpu_reset(unsigned long pc)
> +void arm_cpu_reset(unsigned long pc, bool aarch32)
>  {
>       u32 sctlr;
>  
> diff --git a/hypervisor/arch/arm64/control.c b/hypervisor/arch/arm64/control.c
> index 6e1ffebf..aee81620 100644
> --- a/hypervisor/arch/arm64/control.c
> +++ b/hypervisor/arch/arm64/control.c
> @@ -18,11 +18,12 @@
>  #include <asm/psci.h>
>  #include <asm/traps.h>
>  
> -void arm_cpu_reset(unsigned long pc)
> +void arm_cpu_reset(unsigned long pc, bool aarch32)
>  {
> +     u64 hcr_el2;
> +
>       /* put the cpu in a reset state */
>       /* AARCH64_TODO: handle big endian support */
> -     arm_write_sysreg(SPSR_EL2, RESET_PSR);
>       arm_write_sysreg(SCTLR_EL1, SCTLR_EL1_RES1);
>       arm_write_sysreg(CNTKCTL_EL1, 0);
>       arm_write_sysreg(PMCR_EL0, 0);
> @@ -67,6 +68,15 @@ void arm_cpu_reset(unsigned long pc)
>       /* AARCH64_TODO: handle PMU registers */
>       /* AARCH64_TODO: handle debug registers */
>       /* AARCH64_TODO: handle system registers for AArch32 state */
> +     arm_read_sysreg(HCR_EL2, hcr_el2);
> +     if (aarch32 == true) {
> +             arm_write_sysreg(SPSR_EL2, RESET_PSR_AARCH32);
> +             hcr_el2 &= ~HCR_RW_BIT;
> +     } else {
> +             arm_write_sysreg(SPSR_EL2, RESET_PSR_AARCH64);
> +             hcr_el2 |= HCR_RW_BIT;
> +     }
> +     arm_write_sysreg(HCR_EL2, hcr_el2);
>  
>       arm_write_sysreg(ELR_EL2, pc);
>  
> diff --git a/hypervisor/arch/arm64/entry.S b/hypervisor/arch/arm64/entry.S
> index 27e148c6..4789e933 100644
> --- a/hypervisor/arch/arm64/entry.S
> +++ b/hypervisor/arch/arm64/entry.S
> @@ -401,8 +401,8 @@ hyp_vectors:
>       ventry  .
>       ventry  .
>  
> -     ventry  .
> -     ventry  .
> +     handle_vmexit arch_handle_trap
> +     handle_vmexit irqchip_handle_irq
>       ventry  .
>       ventry  .
>  
> @@ -425,8 +425,8 @@ hyp_vectors_hardened:
>       ventry  .
>       ventry  .
>  
> -     ventry  .
> -     ventry  .
> +     handle_abort_fastpath
> +     handle_vmexit irqchip_handle_irq
>       ventry  .
>       ventry  .
>  
> diff --git a/hypervisor/arch/arm64/include/asm/sysregs.h 
> b/hypervisor/arch/arm64/include/asm/sysregs.h
> index 0105b109..e5984dbc 100644
> --- a/hypervisor/arch/arm64/include/asm/sysregs.h
> +++ b/hypervisor/arch/arm64/include/asm/sysregs.h
> @@ -15,19 +15,23 @@
>  
>  #define PSR_MODE_MASK        0xf
>  #define PSR_MODE_EL0t        0x0
> +#define PSR_MODE_SVC 0x3
>  #define PSR_MODE_EL1t        0x4
>  #define PSR_MODE_EL1h        0x5
>  #define PSR_MODE_EL2t        0x8
>  #define PSR_MODE_EL2h        0x9
>  
> +#define PSR_32_BIT   (1 << 4)
>  #define PSR_F_BIT    (1 << 6)
>  #define PSR_I_BIT    (1 << 7)
>  #define PSR_A_BIT    (1 << 8)
>  #define PSR_D_BIT    (1 << 9)
>  #define PSR_IL_BIT   (1 << 20)
>  #define PSR_SS_BIT   (1 << 21)
> -#define RESET_PSR    (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT \
> +#define RESET_PSR_AARCH64    (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT \
>                       | PSR_MODE_EL1h)
> +#define RESET_PSR_AARCH32    (PSR_A_BIT | PSR_I_BIT | PSR_F_BIT \
> +                     | PSR_32_BIT | PSR_MODE_SVC)
>  
>  #define MPIDR_CPUID_MASK     0xff00ffffffUL
>  #define MPIDR_CLUSTERID_MASK 0xff00ffff00UL
> diff --git a/include/jailhouse/cell-config.h b/include/jailhouse/cell-config.h
> index 6df4a745..2a968dd5 100644
> --- a/include/jailhouse/cell-config.h
> +++ b/include/jailhouse/cell-config.h
> @@ -56,6 +56,7 @@
>  
>  #define JAILHOUSE_CELL_PASSIVE_COMMREG       0x00000001
>  #define JAILHOUSE_CELL_TEST_DEVICE   0x00000002
> +#define JAILHOUSE_CELL_AARCH32               0x00000004
>  
>  /*
>   * The flag JAILHOUSE_CELL_VIRTUAL_CONSOLE_PERMITTED allows inmates to invoke
> 

Thanks, applied with style changes.

Jan

-- 
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/c54edf85-90c8-33ba-f64f-08a17ea93ab5%40siemens.com.

Reply via email to