Re: [Qemu-devel] [PATCH] target-arm: ARM64: Adding EL1 AARCH32 guest support for KVM.
Hi PMM, On 2 December 2014 at 21:29, Peter Maydell wrote: > On 28 November 2014 at 13:06, Pranavkumar Sawargaonkar > wrote: >> In KVM ARM64 one can choose to run guest in 32bit mode i.e EL1 in AARCH32 >> mode. >> This patch adds qemu support for running guest EL1 in AARCH32 mode with >> virt as a machine model. > > Thanks for sending this patch. > >> This patch also adds a support to run Image (along with zImage) for arm32. > Thanks for reviewing this patch. > I'm a bit confused by this -- we already support running Images > and zImages on 32 bit. We shouldn't need any extra "is this a zImage" > detection code to handle this, I don't think. Yes so I have tried booting Image with arm-soffmmu in emulation mode but it does not boot but zImage was booting. Then realized that it is not putting Image address aligned with 0x8000 as zImage does it during compression. Hence for Image booting I have added a code to put that at 0x8000 aligned address. > > In any case, if we do need something extra here it should probably > be in its own patch. Sure so I will create a separate patch for this. > >> One can specify about 32bit kernel Image by using -cpu host,el1_aarch32 >> argument. >> >> e.g. >> "./qemu/aarch64-softmmu/qemu-system-aarch64 -nographic -display none \ >> -serial stdio -kernel ./Image -m 512 -M virt -cpu host,el1_aarch32 \ >> -initrd rootfs.img -append "console=ttyAMA0 root=/dev/ram" -enable-kvm" >> >> Signed-off-by: Pranavkumar Sawargaonkar >> --- >> hw/arm/boot.c | 44 >> hw/arm/virt.c | 30 +- >> target-arm/cpu.c | 5 ++-- >> target-arm/cpu.h | 2 ++ >> target-arm/kvm64.c | 73 >> ++ >> 5 files changed, 146 insertions(+), 8 deletions(-) >> >> diff --git a/hw/arm/boot.c b/hw/arm/boot.c >> index 0014c34..da8cdc8 100644 >> --- a/hw/arm/boot.c >> +++ b/hw/arm/boot.c >> @@ -476,6 +476,32 @@ static void do_cpu_reset(void *opaque) >> } >> } >> >> +static int check_load_zimage(const char *filename) >> +{ >> +int fd; >> +uint8_t buf[40]; >> +uint32_t *p = (uint32_t *) &buf[36]; >> + >> +fd = open(filename, O_RDONLY | O_BINARY); >> +if (fd < 0) { >> +perror(filename); >> +return -1; >> +} >> + >> +memset(buf, 0, sizeof(buf)); >> +if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { >> +close(fd); >> +return -1; >> +} >> + >> +/* Check for zImage magic number */ >> +if (*p == 0x016F2818) { >> +return 1; >> +} >> + >> + return 0; >> +} >> + >> void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) >> { >> CPUState *cs; >> @@ -515,15 +541,23 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info >> *info) >> return; >> } >> >> -if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { >> +if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && >> +(!cpu->env.el1_aarch32)) { >> primary_loader = bootloader_aarch64; >> kernel_load_offset = KERNEL64_LOAD_ADDR; >> elf_machine = EM_AARCH64; >> } else { >> -primary_loader = bootloader; >> -kernel_load_offset = KERNEL_LOAD_ADDR; >> -elf_machine = EM_ARM; >> -} >> +if (check_load_zimage(info->kernel_filename)) { >> +primary_loader = bootloader; >> +kernel_load_offset = KERNEL_LOAD_ADDR; >> +elf_machine = EM_ARM; >> +} else { >> +primary_loader = bootloader; >> +/* Assuming we are loading Image hence aligning it to 0x8000 */ >> +kernel_load_offset = KERNEL_LOAD_ADDR - 0x8000; >> +elf_machine = EM_ARM; >> +} >> + } >> >> info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb"); >> >> diff --git a/hw/arm/virt.c b/hw/arm/virt.c >> index 314e55b..64213e6 100644 >> --- a/hw/arm/virt.c >> +++ b/hw/arm/virt.c >> @@ -204,7 +204,8 @@ static void fdt_add_psci_node(const VirtBoardInfo *vbi) >> qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp)); >> >> cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF; >> -if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) { >> +if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64) && >> +(!armcpu->env.el1_aarch32)) { >> cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND; >> cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON; >> migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE; >> @@ -527,6 +528,24 @@ static void *machvirt_dtb(const struct arm_boot_info >> *binfo, int *fdt_size) >> return board->fdt; >> } >> >> +#if defined(TARGET_AARCH64) && !defined(CONFIG_USER_ONLY) >> +static void check_special_cpu_model_flags(const char *cpu_model, >> + Object *cpuobj) >> +{ >> +ARMCPU *cpu = ARM_CPU(cpuobj); >> + >> +if (!cpu) { >> +return; >> +}
Re: [Qemu-devel] [PATCH] target-arm: ARM64: Adding EL1 AARCH32 guest support for KVM.
On 28 November 2014 at 13:06, Pranavkumar Sawargaonkar wrote: > In KVM ARM64 one can choose to run guest in 32bit mode i.e EL1 in AARCH32 > mode. > This patch adds qemu support for running guest EL1 in AARCH32 mode with > virt as a machine model. Thanks for sending this patch. > This patch also adds a support to run Image (along with zImage) for arm32. I'm a bit confused by this -- we already support running Images and zImages on 32 bit. We shouldn't need any extra "is this a zImage" detection code to handle this, I don't think. In any case, if we do need something extra here it should probably be in its own patch. > One can specify about 32bit kernel Image by using -cpu host,el1_aarch32 > argument. > > e.g. > "./qemu/aarch64-softmmu/qemu-system-aarch64 -nographic -display none \ > -serial stdio -kernel ./Image -m 512 -M virt -cpu host,el1_aarch32 \ > -initrd rootfs.img -append "console=ttyAMA0 root=/dev/ram" -enable-kvm" > > Signed-off-by: Pranavkumar Sawargaonkar > --- > hw/arm/boot.c | 44 > hw/arm/virt.c | 30 +- > target-arm/cpu.c | 5 ++-- > target-arm/cpu.h | 2 ++ > target-arm/kvm64.c | 73 > ++ > 5 files changed, 146 insertions(+), 8 deletions(-) > > diff --git a/hw/arm/boot.c b/hw/arm/boot.c > index 0014c34..da8cdc8 100644 > --- a/hw/arm/boot.c > +++ b/hw/arm/boot.c > @@ -476,6 +476,32 @@ static void do_cpu_reset(void *opaque) > } > } > > +static int check_load_zimage(const char *filename) > +{ > +int fd; > +uint8_t buf[40]; > +uint32_t *p = (uint32_t *) &buf[36]; > + > +fd = open(filename, O_RDONLY | O_BINARY); > +if (fd < 0) { > +perror(filename); > +return -1; > +} > + > +memset(buf, 0, sizeof(buf)); > +if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { > +close(fd); > +return -1; > +} > + > +/* Check for zImage magic number */ > +if (*p == 0x016F2818) { > +return 1; > +} > + > + return 0; > +} > + > void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) > { > CPUState *cs; > @@ -515,15 +541,23 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info > *info) > return; > } > > -if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { > +if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && > +(!cpu->env.el1_aarch32)) { > primary_loader = bootloader_aarch64; > kernel_load_offset = KERNEL64_LOAD_ADDR; > elf_machine = EM_AARCH64; > } else { > -primary_loader = bootloader; > -kernel_load_offset = KERNEL_LOAD_ADDR; > -elf_machine = EM_ARM; > -} > +if (check_load_zimage(info->kernel_filename)) { > +primary_loader = bootloader; > +kernel_load_offset = KERNEL_LOAD_ADDR; > +elf_machine = EM_ARM; > +} else { > +primary_loader = bootloader; > +/* Assuming we are loading Image hence aligning it to 0x8000 */ > +kernel_load_offset = KERNEL_LOAD_ADDR - 0x8000; > +elf_machine = EM_ARM; > +} > + } > > info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb"); > > diff --git a/hw/arm/virt.c b/hw/arm/virt.c > index 314e55b..64213e6 100644 > --- a/hw/arm/virt.c > +++ b/hw/arm/virt.c > @@ -204,7 +204,8 @@ static void fdt_add_psci_node(const VirtBoardInfo *vbi) > qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp)); > > cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF; > -if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) { > +if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64) && > +(!armcpu->env.el1_aarch32)) { > cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND; > cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON; > migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE; > @@ -527,6 +528,24 @@ static void *machvirt_dtb(const struct arm_boot_info > *binfo, int *fdt_size) > return board->fdt; > } > > +#if defined(TARGET_AARCH64) && !defined(CONFIG_USER_ONLY) > +static void check_special_cpu_model_flags(const char *cpu_model, > + Object *cpuobj) > +{ > +ARMCPU *cpu = ARM_CPU(cpuobj); > + > +if (!cpu) { > +return; > +} > + > +if (strcmp(cpu_model, "host,el1_aarch32") == 0) { This looks wrong -- we should support the "32 bit EL1" flag for all 64 bit CPU types, not just "host". It also should not be in the virt board model, but in target-arm/ code somewhere. > +cpu->env.el1_aarch32 = 1; > +} else { > +cpu->env.el1_aarch32 = 0; > +} > +} > +#endif > + > static void machvirt_init(MachineState *machine) > { > qemu_irq pic[NUM_IRQS]; > @@ -540,6 +559,12 @@ static void machvirt_init(MachineState *machine) > cpu_model = "cortex-a15"; > }
[Qemu-devel] [PATCH] target-arm: ARM64: Adding EL1 AARCH32 guest support for KVM.
In KVM ARM64 one can choose to run guest in 32bit mode i.e EL1 in AARCH32 mode. This patch adds qemu support for running guest EL1 in AARCH32 mode with virt as a machine model. This patch also adds a support to run Image (along with zImage) for arm32. One can specify about 32bit kernel Image by using -cpu host,el1_aarch32 argument. e.g. "./qemu/aarch64-softmmu/qemu-system-aarch64 -nographic -display none \ -serial stdio -kernel ./Image -m 512 -M virt -cpu host,el1_aarch32 \ -initrd rootfs.img -append "console=ttyAMA0 root=/dev/ram" -enable-kvm" Signed-off-by: Pranavkumar Sawargaonkar --- hw/arm/boot.c | 44 hw/arm/virt.c | 30 +- target-arm/cpu.c | 5 ++-- target-arm/cpu.h | 2 ++ target-arm/kvm64.c | 73 ++ 5 files changed, 146 insertions(+), 8 deletions(-) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 0014c34..da8cdc8 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -476,6 +476,32 @@ static void do_cpu_reset(void *opaque) } } +static int check_load_zimage(const char *filename) +{ +int fd; +uint8_t buf[40]; +uint32_t *p = (uint32_t *) &buf[36]; + +fd = open(filename, O_RDONLY | O_BINARY); +if (fd < 0) { +perror(filename); +return -1; +} + +memset(buf, 0, sizeof(buf)); +if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { +close(fd); +return -1; +} + +/* Check for zImage magic number */ +if (*p == 0x016F2818) { +return 1; +} + + return 0; +} + void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) { CPUState *cs; @@ -515,15 +541,23 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) return; } -if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { +if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && +(!cpu->env.el1_aarch32)) { primary_loader = bootloader_aarch64; kernel_load_offset = KERNEL64_LOAD_ADDR; elf_machine = EM_AARCH64; } else { -primary_loader = bootloader; -kernel_load_offset = KERNEL_LOAD_ADDR; -elf_machine = EM_ARM; -} +if (check_load_zimage(info->kernel_filename)) { +primary_loader = bootloader; +kernel_load_offset = KERNEL_LOAD_ADDR; +elf_machine = EM_ARM; +} else { +primary_loader = bootloader; +/* Assuming we are loading Image hence aligning it to 0x8000 */ +kernel_load_offset = KERNEL_LOAD_ADDR - 0x8000; +elf_machine = EM_ARM; +} + } info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb"); diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 314e55b..64213e6 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -204,7 +204,8 @@ static void fdt_add_psci_node(const VirtBoardInfo *vbi) qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp)); cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF; -if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) { +if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64) && +(!armcpu->env.el1_aarch32)) { cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND; cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON; migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE; @@ -527,6 +528,24 @@ static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size) return board->fdt; } +#if defined(TARGET_AARCH64) && !defined(CONFIG_USER_ONLY) +static void check_special_cpu_model_flags(const char *cpu_model, + Object *cpuobj) +{ +ARMCPU *cpu = ARM_CPU(cpuobj); + +if (!cpu) { +return; +} + +if (strcmp(cpu_model, "host,el1_aarch32") == 0) { +cpu->env.el1_aarch32 = 1; +} else { +cpu->env.el1_aarch32 = 0; +} +} +#endif + static void machvirt_init(MachineState *machine) { qemu_irq pic[NUM_IRQS]; @@ -540,6 +559,12 @@ static void machvirt_init(MachineState *machine) cpu_model = "cortex-a15"; } +#if defined(TARGET_AARCH64) && !defined(CONFIG_USER_ONLY) +if (strcmp(cpu_model, "host,el1_aarch32") == 0) { +cpu_model = "host"; +} +#endif + vbi = find_machine_info(cpu_model); if (!vbi) { @@ -578,6 +603,9 @@ static void machvirt_init(MachineState *machine) object_property_set_int(cpuobj, vbi->memmap[VIRT_CPUPERIPHS].base, "reset-cbar", &error_abort); } +#if defined(TARGET_AARCH64) && !defined(CONFIG_USER_ONLY) +check_special_cpu_model_flags(machine->cpu_model, cpuobj); +#endif object_property_set_bool(cpuobj, true, "realized", NULL); } diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 5ce7350..37dfe30 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -103,7 +103,7 @@ st