Re: [PATCH qemu v6 5/6] spapr: Allow changing offset for -kernel image
On Mon, Feb 03, 2020 at 02:29:42PM +1100, Alexey Kardashevskiy wrote: > This allows moving the kernel in the guest memory. The option is useful > for step debugging (as Linux is linked at 0x0); it also allows loading > grub which is normally linked to run at 0x2. > > This uses the existing kernel address by default. > > Signed-off-by: Alexey Kardashevskiy Applied to ppc-for-5.0, since I think it makes sense even without the rest of the series. > --- > include/hw/ppc/spapr.h | 1 + > hw/ppc/spapr.c | 38 +++--- > 2 files changed, 32 insertions(+), 7 deletions(-) > > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index 3b50f36c338a..32e831a395ae 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -164,6 +164,7 @@ struct SpaprMachineState { > void *fdt_blob; > long kernel_size; > bool kernel_le; > +uint64_t kernel_addr; > uint32_t initrd_base; > long initrd_size; > uint64_t rtc_offset; /* Now used only during incoming migration */ > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 60153bf0b771..b59e9dc360fe 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -1054,7 +1054,7 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, > void *fdt) > } > > if (spapr->kernel_size) { > -uint64_t kprop[2] = { cpu_to_be64(KERNEL_LOAD_ADDR), > +uint64_t kprop[2] = { cpu_to_be64(spapr->kernel_addr), >cpu_to_be64(spapr->kernel_size) }; > > _FDT(fdt_setprop(fdt, chosen, "qemu,boot-kernel", > @@ -1242,7 +1242,8 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool > reset, size_t space) > /* Build memory reserve map */ > if (reset) { > if (spapr->kernel_size) { > -_FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, > spapr->kernel_size))); > +_FDT((fdt_add_mem_rsv(fdt, spapr->kernel_addr, > + spapr->kernel_size))); > } > if (spapr->initrd_size) { > _FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base, > @@ -1270,7 +1271,9 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool > reset, size_t space) > > static uint64_t translate_kernel_address(void *opaque, uint64_t addr) > { > -return (addr & 0x0fff) + KERNEL_LOAD_ADDR; > +SpaprMachineState *spapr = opaque; > + > +return (addr & 0x0fff) + spapr->kernel_addr; > } > > static void emulate_spapr_hypercall(PPCVirtualHypervisor *vhyp, > @@ -2947,14 +2950,15 @@ static void spapr_machine_init(MachineState *machine) > uint64_t lowaddr = 0; > > spapr->kernel_size = load_elf(kernel_filename, NULL, > - translate_kernel_address, NULL, > + translate_kernel_address, spapr, >NULL, &lowaddr, NULL, NULL, 1, >PPC_ELF_MACHINE, 0, 0); > if (spapr->kernel_size == ELF_LOAD_WRONG_ENDIAN) { > spapr->kernel_size = load_elf(kernel_filename, NULL, > - translate_kernel_address, NULL, > NULL, > + translate_kernel_address, spapr, > NULL, >&lowaddr, NULL, NULL, 0, > - PPC_ELF_MACHINE, 0, 0); > + PPC_ELF_MACHINE, > + 0, 0); > spapr->kernel_le = spapr->kernel_size > 0; > } > if (spapr->kernel_size < 0) { > @@ -2968,7 +2972,7 @@ static void spapr_machine_init(MachineState *machine) > /* Try to locate the initrd in the gap between the kernel > * and the firmware. Add a bit of space just in case > */ > -spapr->initrd_base = (KERNEL_LOAD_ADDR + spapr->kernel_size > +spapr->initrd_base = (spapr->kernel_addr + spapr->kernel_size >+ 0x1) & ~0x; > spapr->initrd_size = load_image_targphys(initrd_filename, > spapr->initrd_base, > @@ -3214,6 +3218,18 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, > const char *name, > visit_type_uint32(v, name, (uint32_t *)opaque, errp); > } > > +static void spapr_get_kernel_addr(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > +visit_type_uint64(v, name, (uint64_t *)opaque, errp); > +} > + > +static void spapr_set_kernel_addr(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > +visit_type_uint64(v, name, (uint64_t *)opaque, errp); > +} > + > static char *spapr_get_ic_mode(Object *obj, Error **errp) > { > SpaprMachineState *spapr = SPAPR_MACHINE(obj); > @@ -3
Re: [PATCH qemu v6 5/6] spapr: Allow changing offset for -kernel image
Alexey Kardashevskiy writes: > This allows moving the kernel in the guest memory. The option is useful > for step debugging (as Linux is linked at 0x0); it also allows loading > grub which is normally linked to run at 0x2. > +1, as this fixes half of the '-S' debugging issue. > This uses the existing kernel address by default. > > Signed-off-by: Alexey Kardashevskiy Reviewed-by: Fabiano Rosas > --- > include/hw/ppc/spapr.h | 1 + > hw/ppc/spapr.c | 38 +++--- > 2 files changed, 32 insertions(+), 7 deletions(-) > > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index 3b50f36c338a..32e831a395ae 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -164,6 +164,7 @@ struct SpaprMachineState { > void *fdt_blob; > long kernel_size; > bool kernel_le; > +uint64_t kernel_addr; > uint32_t initrd_base; > long initrd_size; > uint64_t rtc_offset; /* Now used only during incoming migration */ > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 60153bf0b771..b59e9dc360fe 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -1054,7 +1054,7 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, > void *fdt) > } > > if (spapr->kernel_size) { > -uint64_t kprop[2] = { cpu_to_be64(KERNEL_LOAD_ADDR), > +uint64_t kprop[2] = { cpu_to_be64(spapr->kernel_addr), >cpu_to_be64(spapr->kernel_size) }; > > _FDT(fdt_setprop(fdt, chosen, "qemu,boot-kernel", > @@ -1242,7 +1242,8 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool > reset, size_t space) > /* Build memory reserve map */ > if (reset) { > if (spapr->kernel_size) { > -_FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, > spapr->kernel_size))); > +_FDT((fdt_add_mem_rsv(fdt, spapr->kernel_addr, > + spapr->kernel_size))); > } > if (spapr->initrd_size) { > _FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base, > @@ -1270,7 +1271,9 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool > reset, size_t space) > > static uint64_t translate_kernel_address(void *opaque, uint64_t addr) > { > -return (addr & 0x0fff) + KERNEL_LOAD_ADDR; > +SpaprMachineState *spapr = opaque; > + > +return (addr & 0x0fff) + spapr->kernel_addr; > } > > static void emulate_spapr_hypercall(PPCVirtualHypervisor *vhyp, > @@ -2947,14 +2950,15 @@ static void spapr_machine_init(MachineState *machine) > uint64_t lowaddr = 0; > > spapr->kernel_size = load_elf(kernel_filename, NULL, > - translate_kernel_address, NULL, > + translate_kernel_address, spapr, >NULL, &lowaddr, NULL, NULL, 1, >PPC_ELF_MACHINE, 0, 0); > if (spapr->kernel_size == ELF_LOAD_WRONG_ENDIAN) { > spapr->kernel_size = load_elf(kernel_filename, NULL, > - translate_kernel_address, NULL, > NULL, > + translate_kernel_address, spapr, > NULL, >&lowaddr, NULL, NULL, 0, > - PPC_ELF_MACHINE, 0, 0); > + PPC_ELF_MACHINE, > + 0, 0); > spapr->kernel_le = spapr->kernel_size > 0; > } > if (spapr->kernel_size < 0) { > @@ -2968,7 +2972,7 @@ static void spapr_machine_init(MachineState *machine) > /* Try to locate the initrd in the gap between the kernel > * and the firmware. Add a bit of space just in case > */ > -spapr->initrd_base = (KERNEL_LOAD_ADDR + spapr->kernel_size > +spapr->initrd_base = (spapr->kernel_addr + spapr->kernel_size >+ 0x1) & ~0x; > spapr->initrd_size = load_image_targphys(initrd_filename, > spapr->initrd_base, > @@ -3214,6 +3218,18 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, > const char *name, > visit_type_uint32(v, name, (uint32_t *)opaque, errp); > } > > +static void spapr_get_kernel_addr(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > +visit_type_uint64(v, name, (uint64_t *)opaque, errp); > +} > + > +static void spapr_set_kernel_addr(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > +visit_type_uint64(v, name, (uint64_t *)opaque, errp); > +} > + > static char *spapr_get_ic_mode(Object *obj, Error **errp) > { > SpaprMachineState *spapr = SPAPR_MACHINE(obj); > @@ -3319,6 +3335,14 @@ static void spapr_instance_init(
[PATCH qemu v6 5/6] spapr: Allow changing offset for -kernel image
This allows moving the kernel in the guest memory. The option is useful for step debugging (as Linux is linked at 0x0); it also allows loading grub which is normally linked to run at 0x2. This uses the existing kernel address by default. Signed-off-by: Alexey Kardashevskiy --- include/hw/ppc/spapr.h | 1 + hw/ppc/spapr.c | 38 +++--- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 3b50f36c338a..32e831a395ae 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -164,6 +164,7 @@ struct SpaprMachineState { void *fdt_blob; long kernel_size; bool kernel_le; +uint64_t kernel_addr; uint32_t initrd_base; long initrd_size; uint64_t rtc_offset; /* Now used only during incoming migration */ diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 60153bf0b771..b59e9dc360fe 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1054,7 +1054,7 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt) } if (spapr->kernel_size) { -uint64_t kprop[2] = { cpu_to_be64(KERNEL_LOAD_ADDR), +uint64_t kprop[2] = { cpu_to_be64(spapr->kernel_addr), cpu_to_be64(spapr->kernel_size) }; _FDT(fdt_setprop(fdt, chosen, "qemu,boot-kernel", @@ -1242,7 +1242,8 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space) /* Build memory reserve map */ if (reset) { if (spapr->kernel_size) { -_FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, spapr->kernel_size))); +_FDT((fdt_add_mem_rsv(fdt, spapr->kernel_addr, + spapr->kernel_size))); } if (spapr->initrd_size) { _FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base, @@ -1270,7 +1271,9 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space) static uint64_t translate_kernel_address(void *opaque, uint64_t addr) { -return (addr & 0x0fff) + KERNEL_LOAD_ADDR; +SpaprMachineState *spapr = opaque; + +return (addr & 0x0fff) + spapr->kernel_addr; } static void emulate_spapr_hypercall(PPCVirtualHypervisor *vhyp, @@ -2947,14 +2950,15 @@ static void spapr_machine_init(MachineState *machine) uint64_t lowaddr = 0; spapr->kernel_size = load_elf(kernel_filename, NULL, - translate_kernel_address, NULL, + translate_kernel_address, spapr, NULL, &lowaddr, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (spapr->kernel_size == ELF_LOAD_WRONG_ENDIAN) { spapr->kernel_size = load_elf(kernel_filename, NULL, - translate_kernel_address, NULL, NULL, + translate_kernel_address, spapr, NULL, &lowaddr, NULL, NULL, 0, - PPC_ELF_MACHINE, 0, 0); + PPC_ELF_MACHINE, + 0, 0); spapr->kernel_le = spapr->kernel_size > 0; } if (spapr->kernel_size < 0) { @@ -2968,7 +2972,7 @@ static void spapr_machine_init(MachineState *machine) /* Try to locate the initrd in the gap between the kernel * and the firmware. Add a bit of space just in case */ -spapr->initrd_base = (KERNEL_LOAD_ADDR + spapr->kernel_size +spapr->initrd_base = (spapr->kernel_addr + spapr->kernel_size + 0x1) & ~0x; spapr->initrd_size = load_image_targphys(initrd_filename, spapr->initrd_base, @@ -3214,6 +3218,18 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, const char *name, visit_type_uint32(v, name, (uint32_t *)opaque, errp); } +static void spapr_get_kernel_addr(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ +visit_type_uint64(v, name, (uint64_t *)opaque, errp); +} + +static void spapr_set_kernel_addr(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ +visit_type_uint64(v, name, (uint64_t *)opaque, errp); +} + static char *spapr_get_ic_mode(Object *obj, Error **errp) { SpaprMachineState *spapr = SPAPR_MACHINE(obj); @@ -3319,6 +3335,14 @@ static void spapr_instance_init(Object *obj) object_property_add_bool(obj, "vfio-no-msix-emulation", spapr_get_msix_emulation, NULL, NULL); +object_property_add(obj, "kernel-addr", "uint64", spapr_get_kernel_addr, +spapr_set_kernel_addr, NULL, &spapr->kernel_addr, +&error_abort); +