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.
