* [PULL 0/2] M68k for 7.2 patches
@ 2022-10-14 7:23 Laurent Vivier
2022-10-14 7:23 ` [PULL 1/2] m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED Laurent Vivier
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Laurent Vivier @ 2022-10-14 7:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
The following changes since commit f1d33f55c47dfdaf8daacd618588ad3ae4c452d1:
Merge tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu into staging (2022-10-06 07:11:56 -0400)
are available in the Git repository at:
https://github.com/vivier/qemu-m68k.git tags/m68k-for-7.2-pull-request
for you to fetch changes up to fa327be58280f76d2565ff0bdb9b0010ac97c3b0:
m68k: write bootinfo as rom section and re-randomize on reboot (2022-10-11 23:02:46 +0200)
----------------------------------------------------------------
Pull request m68k branch 20221014
Update rng seed boot parameter
----------------------------------------------------------------
Jason A. Donenfeld (2):
m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED
m68k: write bootinfo as rom section and re-randomize on reboot
hw/m68k/bootinfo.h | 48 ++++++------
.../standard-headers/asm-m68k/bootinfo-virt.h | 4 +-
include/standard-headers/asm-m68k/bootinfo.h | 8 +-
hw/m68k/q800.c | 76 ++++++++++++++-----
hw/m68k/virt.c | 57 +++++++++-----
5 files changed, 130 insertions(+), 63 deletions(-)
--
2.37.3
^ permalink raw reply [flat|nested] 12+ messages in thread* [PULL 1/2] m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED 2022-10-14 7:23 [PULL 0/2] M68k for 7.2 patches Laurent Vivier @ 2022-10-14 7:23 ` Laurent Vivier 2022-10-14 7:23 ` [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot Laurent Vivier 2022-10-16 19:50 ` [PULL 0/2] M68k for 7.2 patches Stefan Hajnoczi 2 siblings, 0 replies; 12+ messages in thread From: Laurent Vivier @ 2022-10-14 7:23 UTC (permalink / raw) To: qemu-devel; +Cc: Laurent Vivier, Jason A. Donenfeld, Geert Uytterhoeven From: "Jason A. Donenfeld" <Jason@zx2c4.com> Following a change on the kernel side (see link), pass BI_RNG_SEED instead of BI_VIRT_RNG_SEED. This should have no impact on compatibility, as there will simply be no effect if it's an old kernel, which is how things have always been. We then use this as an opportunity to add this to q800, since now we can, which is a nice improvement. Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Laurent Vivier <laurent@vivier.eu> Link: https://lore.kernel.org/lkml/20220923170340.4099226-3-Jason@zx2c4.com/ Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Message-Id: <20220926113900.1256630-1-Jason@zx2c4.com> [lv: s/^I/ /g] Signed-off-by: Laurent Vivier <laurent@vivier.eu> --- include/standard-headers/asm-m68k/bootinfo-virt.h | 4 +++- include/standard-headers/asm-m68k/bootinfo.h | 8 +++++++- hw/m68k/q800.c | 7 +++++++ hw/m68k/virt.c | 8 ++++---- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/include/standard-headers/asm-m68k/bootinfo-virt.h b/include/standard-headers/asm-m68k/bootinfo-virt.h index 1b1ffd4705d6..75ac6bbd7d73 100644 --- a/include/standard-headers/asm-m68k/bootinfo-virt.h +++ b/include/standard-headers/asm-m68k/bootinfo-virt.h @@ -12,7 +12,9 @@ #define BI_VIRT_GF_TTY_BASE 0x8003 #define BI_VIRT_VIRTIO_BASE 0x8004 #define BI_VIRT_CTRL_BASE 0x8005 -#define BI_VIRT_RNG_SEED 0x8006 + +/* No longer used -- replaced with BI_RNG_SEED -- but don't reuse this index: + * #define BI_VIRT_RNG_SEED 0x8006 */ #define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0) diff --git a/include/standard-headers/asm-m68k/bootinfo.h b/include/standard-headers/asm-m68k/bootinfo.h index 7b790e8ec8d6..b7a8dd2514fe 100644 --- a/include/standard-headers/asm-m68k/bootinfo.h +++ b/include/standard-headers/asm-m68k/bootinfo.h @@ -57,7 +57,13 @@ struct mem_info { /* (struct mem_info) */ #define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */ /* (string) */ - +/* + * A random seed used to initialize the RNG. Record format: + * + * - length [ 2 bytes, 16-bit big endian ] + * - seed data [ `length` bytes, padded to preserve 4-byte struct alignment ] + */ +#define BI_RNG_SEED 0x0008 /* * Linux/m68k Architectures (BI_MACHTYPE) diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 101ab0f803f6..a4590c2cb0b1 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -23,6 +23,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qemu/datadir.h" +#include "qemu/guest-random.h" #include "sysemu/sysemu.h" #include "cpu.h" #include "hw/boards.h" @@ -385,6 +386,7 @@ static void q800_init(MachineState *machine) NubusBus *nubus; DeviceState *glue; DriveInfo *dinfo; + uint8_t rng_seed[32]; linux_boot = (kernel_filename != NULL); @@ -634,6 +636,11 @@ static void q800_init(MachineState *machine) kernel_cmdline); } + /* Pass seed to RNG. */ + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + rng_seed, sizeof(rng_seed)); + /* load initrd */ if (initrd_filename) { initrd_size = get_image_size(initrd_filename); diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index 2f3ffc0de677..f7b903ea1b62 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -248,10 +248,10 @@ static void virt_init(MachineState *machine) kernel_cmdline); } - /* Pass seed to RNG. */ - qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_VIRT_RNG_SEED, - rng_seed, sizeof(rng_seed)); + /* Pass seed to RNG. */ + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + rng_seed, sizeof(rng_seed)); /* load initrd */ if (initrd_filename) { -- 2.37.3 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot 2022-10-14 7:23 [PULL 0/2] M68k for 7.2 patches Laurent Vivier 2022-10-14 7:23 ` [PULL 1/2] m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED Laurent Vivier @ 2022-10-14 7:23 ` Laurent Vivier 2022-10-16 19:50 ` [PULL 0/2] M68k for 7.2 patches Stefan Hajnoczi 2 siblings, 0 replies; 12+ messages in thread From: Laurent Vivier @ 2022-10-14 7:23 UTC (permalink / raw) To: qemu-devel; +Cc: Laurent Vivier, Jason A. Donenfeld, Geert Uytterhoeven From: "Jason A. Donenfeld" <Jason@zx2c4.com> Rather than poking directly into RAM, add the bootinfo block as a proper ROM, so that it's restored when rebooting the system. This way, if the guest corrupts any of the bootinfo items, but then tries to reboot, it'll still be restored back to normal as expected. Then, since the RNG seed needs to be fresh on each boot, regenerate the RNG seed in the ROM when reseting the CPU. Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Laurent Vivier <laurent@vivier.eu> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Message-Id: <20221003110221.971024-1-Jason@zx2c4.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu> --- hw/m68k/bootinfo.h | 48 +++++++++++++++---------------- hw/m68k/q800.c | 71 +++++++++++++++++++++++++++++++++------------- hw/m68k/virt.c | 51 +++++++++++++++++++++++---------- 3 files changed, 111 insertions(+), 59 deletions(-) diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h index 897162b8189c..eb92937cf6ca 100644 --- a/hw/m68k/bootinfo.h +++ b/hw/m68k/bootinfo.h @@ -12,66 +12,66 @@ #ifndef HW_M68K_BOOTINFO_H #define HW_M68K_BOOTINFO_H -#define BOOTINFO0(as, base, id) \ +#define BOOTINFO0(base, id) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record)); \ + stw_p(base, sizeof(struct bi_record)); \ base += 2; \ } while (0) -#define BOOTINFO1(as, base, id, value) \ +#define BOOTINFO1(base, id, value) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record) + 4); \ + stw_p(base, sizeof(struct bi_record) + 4); \ base += 2; \ - stl_phys(as, base, value); \ + stl_p(base, value); \ base += 4; \ } while (0) -#define BOOTINFO2(as, base, id, value1, value2) \ +#define BOOTINFO2(base, id, value1, value2) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record) + 8); \ + stw_p(base, sizeof(struct bi_record) + 8); \ base += 2; \ - stl_phys(as, base, value1); \ + stl_p(base, value1); \ base += 4; \ - stl_phys(as, base, value2); \ + stl_p(base, value2); \ base += 4; \ } while (0) -#define BOOTINFOSTR(as, base, id, string) \ +#define BOOTINFOSTR(base, id, string) \ do { \ int i; \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, \ + stw_p(base, \ (sizeof(struct bi_record) + strlen(string) + \ 1 /* null termination */ + 3 /* padding */) & ~3); \ base += 2; \ for (i = 0; string[i]; i++) { \ - stb_phys(as, base++, string[i]); \ + stb_p(base++, string[i]); \ } \ - stb_phys(as, base++, 0); \ - base = (base + 3) & ~3; \ + stb_p(base++, 0); \ + base = (void *)(((unsigned long)base + 3) & ~3); \ } while (0) -#define BOOTINFODATA(as, base, id, data, len) \ +#define BOOTINFODATA(base, id, data, len) \ do { \ int i; \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, \ + stw_p(base, \ (sizeof(struct bi_record) + len + \ 2 /* length field */ + 3 /* padding */) & ~3); \ base += 2; \ - stw_phys(as, base, len); \ + stw_p(base, len); \ base += 2; \ for (i = 0; i < len; ++i) { \ - stb_phys(as, base++, data[i]); \ + stb_p(base++, data[i]); \ } \ - base = (base + 3) & ~3; \ + base = (void *)(((unsigned long)base + 3) & ~3); \ } while (0) #endif diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index a4590c2cb0b1..e09e244ddc1d 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -321,11 +321,22 @@ static const TypeInfo glue_info = { }, }; +typedef struct { + M68kCPU *cpu; + struct bi_record *rng_seed; +} ResetInfo; + static void main_cpu_reset(void *opaque) { - M68kCPU *cpu = opaque; + ResetInfo *reset_info = opaque; + M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); + if (reset_info->rng_seed) { + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); + } + cpu_reset(cs); cpu->env.aregs[7] = ldl_phys(cs->as, 0); cpu->env.pc = ldl_phys(cs->as, 4); @@ -386,6 +397,7 @@ static void q800_init(MachineState *machine) NubusBus *nubus; DeviceState *glue; DriveInfo *dinfo; + ResetInfo *reset_info; uint8_t rng_seed[32]; linux_boot = (kernel_filename != NULL); @@ -396,9 +408,12 @@ static void q800_init(MachineState *machine) exit(1); } + reset_info = g_new0(ResetInfo, 1); + /* init CPUs */ cpu = M68K_CPU(cpu_create(machine->cpu_type)); - qemu_register_reset(main_cpu_reset, cpu); + reset_info->cpu = cpu; + qemu_register_reset(main_cpu_reset, reset_info); /* RAM */ memory_region_add_subregion(get_system_memory(), 0, machine->ram); @@ -598,6 +613,14 @@ static void q800_init(MachineState *machine) cs = CPU(cpu); if (linux_boot) { uint64_t high; + void *param_blob, *param_ptr, *param_rng_seed; + + if (kernel_cmdline) { + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); + } else { + param_blob = g_malloc(1024); + } + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, &high, NULL, 1, EM_68K, 0, 0); @@ -607,23 +630,24 @@ static void q800_init(MachineState *machine) } stl_phys(cs->as, 4, elf_entry); /* reset initial PC */ parameters_base = (high + 1) & ~1; - - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_MAC); - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, CPUB_68040); - BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, MAC_MODEL_Q800); - BOOTINFO1(cs->as, parameters_base, + param_ptr = param_blob; + + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_MAC); + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); + BOOTINFO1(param_ptr, BI_MAC_CPUID, CPUB_68040); + BOOTINFO1(param_ptr, BI_MAC_MODEL, MAC_MODEL_Q800); + BOOTINFO1(param_ptr, BI_MAC_MEMSIZE, ram_size >> 20); /* in MB */ - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR, + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); + BOOTINFO1(param_ptr, BI_MAC_VADDR, VIDEO_BASE + macfb_mode->offset); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDEPTH, graphic_depth); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDIM, + BOOTINFO1(param_ptr, BI_MAC_VDEPTH, graphic_depth); + BOOTINFO1(param_ptr, BI_MAC_VDIM, (graphic_height << 16) | graphic_width); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW, macfb_mode->stride); - BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE); + BOOTINFO1(param_ptr, BI_MAC_VROW, macfb_mode->stride); + BOOTINFO1(param_ptr, BI_MAC_SCCBASE, SCC_BASE); rom = g_malloc(sizeof(*rom)); memory_region_init_ram_ptr(rom, NULL, "m68k_fake_mac.rom", @@ -632,13 +656,14 @@ static void q800_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom); if (kernel_cmdline) { - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, kernel_cmdline); } /* Pass seed to RNG. */ + param_rng_seed = param_ptr; qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + BOOTINFODATA(param_ptr, BI_RNG_SEED, rng_seed, sizeof(rng_seed)); /* load initrd */ @@ -653,13 +678,19 @@ static void q800_init(MachineState *machine) initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; } - BOOTINFO0(cs->as, parameters_base, BI_LAST); + BOOTINFO0(param_ptr, BI_LAST); + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, + parameters_base, cs->as); + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob); + g_free(param_blob); } else { uint8_t *ptr; /* allocate and load BIOS */ diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index f7b903ea1b62..89c4108eb545 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -89,6 +89,7 @@ typedef struct { M68kCPU *cpu; hwaddr initial_pc; hwaddr initial_stack; + struct bi_record *rng_seed; } ResetInfo; static void main_cpu_reset(void *opaque) @@ -97,6 +98,11 @@ static void main_cpu_reset(void *opaque) M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); + if (reset_info->rng_seed) { + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); + } + cpu_reset(cs); cpu->env.aregs[7] = reset_info->initial_stack; cpu->env.pc = reset_info->initial_pc; @@ -212,6 +218,13 @@ static void virt_init(MachineState *machine) if (kernel_filename) { CPUState *cs = CPU(cpu); uint64_t high; + void *param_blob, *param_ptr, *param_rng_seed; + + if (kernel_cmdline) { + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); + } else { + param_blob = g_malloc(1024); + } kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, &high, NULL, 1, @@ -222,35 +235,37 @@ static void virt_init(MachineState *machine) } reset_info->initial_pc = elf_entry; parameters_base = (high + 1) & ~1; + param_ptr = param_blob; - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_VIRT); - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_VIRT); + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); - BOOTINFO1(cs->as, parameters_base, BI_VIRT_QEMU_VERSION, + BOOTINFO1(param_ptr, BI_VIRT_QEMU_VERSION, ((QEMU_VERSION_MAJOR << 24) | (QEMU_VERSION_MINOR << 16) | (QEMU_VERSION_MICRO << 8))); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_PIC_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_PIC_BASE, VIRT_GF_PIC_MMIO_BASE, VIRT_GF_PIC_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_RTC_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_RTC_BASE, VIRT_GF_RTC_MMIO_BASE, VIRT_GF_RTC_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_TTY_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_TTY_BASE, VIRT_GF_TTY_MMIO_BASE, VIRT_GF_TTY_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_CTRL_BASE, + BOOTINFO2(param_ptr, BI_VIRT_CTRL_BASE, VIRT_CTRL_MMIO_BASE, VIRT_CTRL_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_VIRTIO_BASE, + BOOTINFO2(param_ptr, BI_VIRT_VIRTIO_BASE, VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE); if (kernel_cmdline) { - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, kernel_cmdline); } /* Pass seed to RNG. */ + param_rng_seed = param_ptr; qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + BOOTINFODATA(param_ptr, BI_RNG_SEED, rng_seed, sizeof(rng_seed)); /* load initrd */ @@ -265,13 +280,19 @@ static void virt_init(MachineState *machine) initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; } - BOOTINFO0(cs->as, parameters_base, BI_LAST); + BOOTINFO0(param_ptr, BI_LAST); + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, + parameters_base, cs->as); + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob); + g_free(param_blob); } } -- 2.37.3 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PULL 0/2] M68k for 7.2 patches 2022-10-14 7:23 [PULL 0/2] M68k for 7.2 patches Laurent Vivier 2022-10-14 7:23 ` [PULL 1/2] m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED Laurent Vivier 2022-10-14 7:23 ` [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot Laurent Vivier @ 2022-10-16 19:50 ` Stefan Hajnoczi 2022-10-17 3:56 ` Jason A. Donenfeld via 2 siblings, 1 reply; 12+ messages in thread From: Stefan Hajnoczi @ 2022-10-16 19:50 UTC (permalink / raw) To: Laurent Vivier; +Cc: qemu-devel On Fri, 14 Oct 2022 at 03:26, Laurent Vivier <laurent@vivier.eu> wrote: > > The following changes since commit f1d33f55c47dfdaf8daacd618588ad3ae4c452d1: > > Merge tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu into staging (2022-10-06 07:11:56 -0400) > > are available in the Git repository at: > > https://github.com/vivier/qemu-m68k.git tags/m68k-for-7.2-pull-request > > for you to fetch changes up to fa327be58280f76d2565ff0bdb9b0010ac97c3b0: > > m68k: write bootinfo as rom section and re-randomize on reboot (2022-10-11 23:02:46 +0200) > > ---------------------------------------------------------------- > Pull request m68k branch 20221014 > > Update rng seed boot parameter > > ---------------------------------------------------------------- > > Jason A. Donenfeld (2): > m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED > m68k: write bootinfo as rom section and re-randomize on reboot This commit breaks mingw64 due to the Windows LLP64 data model where pointers don't fit into unsigned long (https://en.wikipedia.org/wiki/LP64#64-bit_data_models). Please use uintptr_t instead of unsigned long: x86_64-w64-mingw32-gcc -m64 -mcx16 -Ilibqemu-m68k-softmmu.fa.p -I. -I.. -Itarget/m68k -I../target/m68k -Iqapi -Itrace -Iui -Iui/shader -I/usr/x86_64-w64-mingw32/sys-root/mingw/include/pixman-1 -I/usr/x86_64-w64-mingw32/sys-root/mingw/include/glib-2.0 -I/usr/x86_64-w64-mingw32/sys-root/mingw/lib/glib-2.0/include -fdiagnostics-color=auto -Wall -Winvalid-pch -Werror -std=gnu11 -O2 -g -iquote . -iquote /builds/qemu-project/qemu -iquote /builds/qemu-project/qemu/include -iquote /builds/qemu-project/qemu/tcg/i386 -mms-bitfields -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-pie -no-pie -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -Wold-style-declaration -Wold-style-definition -Wtype-limits -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wempty-body -Wnested-externs -Wendif-labels -Wexpansion-to-defined -Wimplicit-fallthrough=2 -Wno-missing-include-dirs -Wno-shift-negative-value -Wno-psabi -fstack-protector-strong -DNEED_CPU_H '-DCONFIG_TARGET="m68k-softmmu-config-target.h"' '-DCONFIG_DEVICES="m68k-softmmu-config-devices.h"' -MD -MQ libqemu-m68k-softmmu.fa.p/hw_m68k_virt.c.obj -MF libqemu-m68k-softmmu.fa.p/hw_m68k_virt.c.obj.d -o libqemu-m68k-softmmu.fa.p/hw_m68k_virt.c.obj -c ../hw/m68k/virt.c In file included from ../hw/m68k/virt.c:23: ../hw/m68k/virt.c: In function 'virt_init': ../hw/m68k/bootinfo.h:58:26: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast] 58 | base = (void *)(((unsigned long)base + 3) & ~3); \ | ^ ../hw/m68k/virt.c:261:13: note: in expansion of macro 'BOOTINFOSTR' 261 | BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, | ^~~~~~~~~~~ ../hw/m68k/bootinfo.h:58:16: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] 58 | base = (void *)(((unsigned long)base + 3) & ~3); \ | ^ ../hw/m68k/virt.c:261:13: note: in expansion of macro 'BOOTINFOSTR' 261 | BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, | ^~~~~~~~~~~ ../hw/m68k/bootinfo.h:75:26: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast] 75 | base = (void *)(((unsigned long)base + 3) & ~3); \ | ^ ../hw/m68k/virt.c:268:9: note: in expansion of macro 'BOOTINFODATA' 268 | BOOTINFODATA(param_ptr, BI_RNG_SEED, | ^~~~~~~~~~~~ ../hw/m68k/bootinfo.h:75:16: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] 75 | base = (void *)(((unsigned long)base + 3) & ~3); \ | ^ ../hw/m68k/virt.c:268:9: note: in expansion of macro 'BOOTINFODATA' 268 | BOOTINFODATA(param_ptr, BI_RNG_SEED, | ^~~~~~~~~~~~ cc1: all warnings being treated as errors https://gitlab.com/qemu-project/qemu/-/jobs/3179717070 > > hw/m68k/bootinfo.h | 48 ++++++------ > .../standard-headers/asm-m68k/bootinfo-virt.h | 4 +- > include/standard-headers/asm-m68k/bootinfo.h | 8 +- > hw/m68k/q800.c | 76 ++++++++++++++----- > hw/m68k/virt.c | 57 +++++++++----- > 5 files changed, 130 insertions(+), 63 deletions(-) > > -- > 2.37.3 > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PULL 0/2] M68k for 7.2 patches 2022-10-16 19:50 ` [PULL 0/2] M68k for 7.2 patches Stefan Hajnoczi @ 2022-10-17 3:56 ` Jason A. Donenfeld via 2022-10-17 7:25 ` Laurent Vivier 0 siblings, 1 reply; 12+ messages in thread From: Jason A. Donenfeld via @ 2022-10-17 3:56 UTC (permalink / raw) To: Stefan Hajnoczi; +Cc: Laurent Vivier, qemu-devel On Sun, Oct 16, 2022 at 03:50:54PM -0400, Stefan Hajnoczi wrote: > On Fri, 14 Oct 2022 at 03:26, Laurent Vivier <laurent@vivier.eu> wrote: > > > > The following changes since commit f1d33f55c47dfdaf8daacd618588ad3ae4c452d1: > > > > Merge tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu into staging (2022-10-06 07:11:56 -0400) > > > > are available in the Git repository at: > > > > https://github.com/vivier/qemu-m68k.git tags/m68k-for-7.2-pull-request > > > > for you to fetch changes up to fa327be58280f76d2565ff0bdb9b0010ac97c3b0: > > > > m68k: write bootinfo as rom section and re-randomize on reboot (2022-10-11 23:02:46 +0200) > > > > ---------------------------------------------------------------- > > Pull request m68k branch 20221014 > > > > Update rng seed boot parameter > > > > ---------------------------------------------------------------- > > > > Jason A. Donenfeld (2): > > m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED > > m68k: write bootinfo as rom section and re-randomize on reboot > > This commit breaks mingw64 due to the Windows LLP64 data model where > pointers don't fit into unsigned long > (https://en.wikipedia.org/wiki/LP64#64-bit_data_models). Please use > uintptr_t instead of unsigned long: Holy smokes; I didn't realize that qemu was ever compiled this way. Laurent - do you want me to send you a follow-up commit fixing that, a new commit fixing that, or do you want to adjust the current commit yourself? Any choice is fine with me. Jason > > x86_64-w64-mingw32-gcc -m64 -mcx16 -Ilibqemu-m68k-softmmu.fa.p -I. > -I.. -Itarget/m68k -I../target/m68k -Iqapi -Itrace -Iui -Iui/shader > -I/usr/x86_64-w64-mingw32/sys-root/mingw/include/pixman-1 > -I/usr/x86_64-w64-mingw32/sys-root/mingw/include/glib-2.0 > -I/usr/x86_64-w64-mingw32/sys-root/mingw/lib/glib-2.0/include > -fdiagnostics-color=auto -Wall -Winvalid-pch -Werror -std=gnu11 -O2 -g > -iquote . -iquote /builds/qemu-project/qemu -iquote > /builds/qemu-project/qemu/include -iquote > /builds/qemu-project/qemu/tcg/i386 -mms-bitfields -U_FORTIFY_SOURCE > -D_FORTIFY_SOURCE=2 -fno-pie -no-pie -D_GNU_SOURCE > -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes > -Wredundant-decls -Wundef -Wwrite-strings -Wmissing-prototypes > -fno-strict-aliasing -fno-common -fwrapv -Wold-style-declaration > -Wold-style-definition -Wtype-limits -Wformat-security -Wformat-y2k > -Winit-self -Wignored-qualifiers -Wempty-body -Wnested-externs > -Wendif-labels -Wexpansion-to-defined -Wimplicit-fallthrough=2 > -Wno-missing-include-dirs -Wno-shift-negative-value -Wno-psabi > -fstack-protector-strong -DNEED_CPU_H > '-DCONFIG_TARGET="m68k-softmmu-config-target.h"' > '-DCONFIG_DEVICES="m68k-softmmu-config-devices.h"' -MD -MQ > libqemu-m68k-softmmu.fa.p/hw_m68k_virt.c.obj -MF > libqemu-m68k-softmmu.fa.p/hw_m68k_virt.c.obj.d -o > libqemu-m68k-softmmu.fa.p/hw_m68k_virt.c.obj -c ../hw/m68k/virt.c > In file included from ../hw/m68k/virt.c:23: > ../hw/m68k/virt.c: In function 'virt_init': > ../hw/m68k/bootinfo.h:58:26: error: cast from pointer to integer of > different size [-Werror=pointer-to-int-cast] > 58 | base = (void *)(((unsigned long)base + 3) & ~3); \ > | ^ > ../hw/m68k/virt.c:261:13: note: in expansion of macro 'BOOTINFOSTR' > 261 | BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, > | ^~~~~~~~~~~ > ../hw/m68k/bootinfo.h:58:16: error: cast to pointer from integer of > different size [-Werror=int-to-pointer-cast] > 58 | base = (void *)(((unsigned long)base + 3) & ~3); \ > | ^ > ../hw/m68k/virt.c:261:13: note: in expansion of macro 'BOOTINFOSTR' > 261 | BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, > | ^~~~~~~~~~~ > ../hw/m68k/bootinfo.h:75:26: error: cast from pointer to integer of > different size [-Werror=pointer-to-int-cast] > 75 | base = (void *)(((unsigned long)base + 3) & ~3); \ > | ^ > ../hw/m68k/virt.c:268:9: note: in expansion of macro 'BOOTINFODATA' > 268 | BOOTINFODATA(param_ptr, BI_RNG_SEED, > | ^~~~~~~~~~~~ > ../hw/m68k/bootinfo.h:75:16: error: cast to pointer from integer of > different size [-Werror=int-to-pointer-cast] > 75 | base = (void *)(((unsigned long)base + 3) & ~3); \ > | ^ > ../hw/m68k/virt.c:268:9: note: in expansion of macro 'BOOTINFODATA' > 268 | BOOTINFODATA(param_ptr, BI_RNG_SEED, > | ^~~~~~~~~~~~ > cc1: all warnings being treated as errors > > https://gitlab.com/qemu-project/qemu/-/jobs/3179717070 > > > > > hw/m68k/bootinfo.h | 48 ++++++------ > > .../standard-headers/asm-m68k/bootinfo-virt.h | 4 +- > > include/standard-headers/asm-m68k/bootinfo.h | 8 +- > > hw/m68k/q800.c | 76 ++++++++++++++----- > > hw/m68k/virt.c | 57 +++++++++----- > > 5 files changed, 130 insertions(+), 63 deletions(-) > > > > -- > > 2.37.3 > > > > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PULL 0/2] M68k for 7.2 patches 2022-10-17 3:56 ` Jason A. Donenfeld via @ 2022-10-17 7:25 ` Laurent Vivier 2022-10-17 20:29 ` [PATCH v4] m68k: write bootinfo as rom section and re-randomize on reboot Jason A. Donenfeld 0 siblings, 1 reply; 12+ messages in thread From: Laurent Vivier @ 2022-10-17 7:25 UTC (permalink / raw) To: Jason A. Donenfeld; +Cc: qemu-devel, Stefan Hajnoczi Le 17/10/2022 à 05:56, Jason A. Donenfeld via a écrit : > On Sun, Oct 16, 2022 at 03:50:54PM -0400, Stefan Hajnoczi wrote: >> On Fri, 14 Oct 2022 at 03:26, Laurent Vivier <laurent@vivier.eu> wrote: >>> >>> The following changes since commit f1d33f55c47dfdaf8daacd618588ad3ae4c452d1: >>> >>> Merge tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu into staging (2022-10-06 07:11:56 -0400) >>> >>> are available in the Git repository at: >>> >>> https://github.com/vivier/qemu-m68k.git tags/m68k-for-7.2-pull-request >>> >>> for you to fetch changes up to fa327be58280f76d2565ff0bdb9b0010ac97c3b0: >>> >>> m68k: write bootinfo as rom section and re-randomize on reboot (2022-10-11 23:02:46 +0200) >>> >>> ---------------------------------------------------------------- >>> Pull request m68k branch 20221014 >>> >>> Update rng seed boot parameter >>> >>> ---------------------------------------------------------------- >>> >>> Jason A. Donenfeld (2): >>> m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED >>> m68k: write bootinfo as rom section and re-randomize on reboot >> >> This commit breaks mingw64 due to the Windows LLP64 data model where >> pointers don't fit into unsigned long >> (https://en.wikipedia.org/wiki/LP64#64-bit_data_models). Please use >> uintptr_t instead of unsigned long: > > Holy smokes; I didn't realize that qemu was ever compiled this way. > > Laurent - do you want me to send you a follow-up commit fixing that, a > new commit fixing that, or do you want to adjust the current commit > yourself? Any choice is fine with me. Please update the current patch to fix that and resend. Thanks, Laurent ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4] m68k: write bootinfo as rom section and re-randomize on reboot 2022-10-17 7:25 ` Laurent Vivier @ 2022-10-17 20:29 ` Jason A. Donenfeld 2022-10-21 19:25 ` Laurent Vivier 0 siblings, 1 reply; 12+ messages in thread From: Jason A. Donenfeld @ 2022-10-17 20:29 UTC (permalink / raw) To: laurent, qemu-devel; +Cc: Jason A. Donenfeld, Geert Uytterhoeven Rather than poking directly into RAM, add the bootinfo block as a proper ROM, so that it's restored when rebooting the system. This way, if the guest corrupts any of the bootinfo items, but then tries to reboot, it'll still be restored back to normal as expected. Then, since the RNG seed needs to be fresh on each boot, regenerate the RNG seed in the ROM when reseting the CPU. Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Laurent Vivier <laurent@vivier.eu> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> --- hw/m68k/bootinfo.h | 48 +++++++++++++++---------------- hw/m68k/q800.c | 71 +++++++++++++++++++++++++++++++++------------- hw/m68k/virt.c | 51 +++++++++++++++++++++++---------- 3 files changed, 111 insertions(+), 59 deletions(-) diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h index 897162b818..67e6b66b7d 100644 --- a/hw/m68k/bootinfo.h +++ b/hw/m68k/bootinfo.h @@ -12,66 +12,66 @@ #ifndef HW_M68K_BOOTINFO_H #define HW_M68K_BOOTINFO_H -#define BOOTINFO0(as, base, id) \ +#define BOOTINFO0(base, id) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record)); \ + stw_p(base, sizeof(struct bi_record)); \ base += 2; \ } while (0) -#define BOOTINFO1(as, base, id, value) \ +#define BOOTINFO1(base, id, value) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record) + 4); \ + stw_p(base, sizeof(struct bi_record) + 4); \ base += 2; \ - stl_phys(as, base, value); \ + stl_p(base, value); \ base += 4; \ } while (0) -#define BOOTINFO2(as, base, id, value1, value2) \ +#define BOOTINFO2(base, id, value1, value2) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record) + 8); \ + stw_p(base, sizeof(struct bi_record) + 8); \ base += 2; \ - stl_phys(as, base, value1); \ + stl_p(base, value1); \ base += 4; \ - stl_phys(as, base, value2); \ + stl_p(base, value2); \ base += 4; \ } while (0) -#define BOOTINFOSTR(as, base, id, string) \ +#define BOOTINFOSTR(base, id, string) \ do { \ int i; \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, \ + stw_p(base, \ (sizeof(struct bi_record) + strlen(string) + \ 1 /* null termination */ + 3 /* padding */) & ~3); \ base += 2; \ for (i = 0; string[i]; i++) { \ - stb_phys(as, base++, string[i]); \ + stb_p(base++, string[i]); \ } \ - stb_phys(as, base++, 0); \ - base = (base + 3) & ~3; \ + stb_p(base++, 0); \ + base = (void *)(((uintptr_t)base + 3) & ~3); \ } while (0) -#define BOOTINFODATA(as, base, id, data, len) \ +#define BOOTINFODATA(base, id, data, len) \ do { \ int i; \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, \ + stw_p(base, \ (sizeof(struct bi_record) + len + \ 2 /* length field */ + 3 /* padding */) & ~3); \ base += 2; \ - stw_phys(as, base, len); \ + stw_p(base, len); \ base += 2; \ for (i = 0; i < len; ++i) { \ - stb_phys(as, base++, data[i]); \ + stb_p(base++, data[i]); \ } \ - base = (base + 3) & ~3; \ + base = (void *)(((uintptr_t)base + 3) & ~3); \ } while (0) #endif diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index a4590c2cb0..e09e244ddc 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -321,11 +321,22 @@ static const TypeInfo glue_info = { }, }; +typedef struct { + M68kCPU *cpu; + struct bi_record *rng_seed; +} ResetInfo; + static void main_cpu_reset(void *opaque) { - M68kCPU *cpu = opaque; + ResetInfo *reset_info = opaque; + M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); + if (reset_info->rng_seed) { + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); + } + cpu_reset(cs); cpu->env.aregs[7] = ldl_phys(cs->as, 0); cpu->env.pc = ldl_phys(cs->as, 4); @@ -386,6 +397,7 @@ static void q800_init(MachineState *machine) NubusBus *nubus; DeviceState *glue; DriveInfo *dinfo; + ResetInfo *reset_info; uint8_t rng_seed[32]; linux_boot = (kernel_filename != NULL); @@ -396,9 +408,12 @@ static void q800_init(MachineState *machine) exit(1); } + reset_info = g_new0(ResetInfo, 1); + /* init CPUs */ cpu = M68K_CPU(cpu_create(machine->cpu_type)); - qemu_register_reset(main_cpu_reset, cpu); + reset_info->cpu = cpu; + qemu_register_reset(main_cpu_reset, reset_info); /* RAM */ memory_region_add_subregion(get_system_memory(), 0, machine->ram); @@ -598,6 +613,14 @@ static void q800_init(MachineState *machine) cs = CPU(cpu); if (linux_boot) { uint64_t high; + void *param_blob, *param_ptr, *param_rng_seed; + + if (kernel_cmdline) { + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); + } else { + param_blob = g_malloc(1024); + } + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, &high, NULL, 1, EM_68K, 0, 0); @@ -607,23 +630,24 @@ static void q800_init(MachineState *machine) } stl_phys(cs->as, 4, elf_entry); /* reset initial PC */ parameters_base = (high + 1) & ~1; - - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_MAC); - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, CPUB_68040); - BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, MAC_MODEL_Q800); - BOOTINFO1(cs->as, parameters_base, + param_ptr = param_blob; + + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_MAC); + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); + BOOTINFO1(param_ptr, BI_MAC_CPUID, CPUB_68040); + BOOTINFO1(param_ptr, BI_MAC_MODEL, MAC_MODEL_Q800); + BOOTINFO1(param_ptr, BI_MAC_MEMSIZE, ram_size >> 20); /* in MB */ - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR, + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); + BOOTINFO1(param_ptr, BI_MAC_VADDR, VIDEO_BASE + macfb_mode->offset); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDEPTH, graphic_depth); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDIM, + BOOTINFO1(param_ptr, BI_MAC_VDEPTH, graphic_depth); + BOOTINFO1(param_ptr, BI_MAC_VDIM, (graphic_height << 16) | graphic_width); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW, macfb_mode->stride); - BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE); + BOOTINFO1(param_ptr, BI_MAC_VROW, macfb_mode->stride); + BOOTINFO1(param_ptr, BI_MAC_SCCBASE, SCC_BASE); rom = g_malloc(sizeof(*rom)); memory_region_init_ram_ptr(rom, NULL, "m68k_fake_mac.rom", @@ -632,13 +656,14 @@ static void q800_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom); if (kernel_cmdline) { - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, kernel_cmdline); } /* Pass seed to RNG. */ + param_rng_seed = param_ptr; qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + BOOTINFODATA(param_ptr, BI_RNG_SEED, rng_seed, sizeof(rng_seed)); /* load initrd */ @@ -653,13 +678,19 @@ static void q800_init(MachineState *machine) initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; } - BOOTINFO0(cs->as, parameters_base, BI_LAST); + BOOTINFO0(param_ptr, BI_LAST); + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, + parameters_base, cs->as); + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob); + g_free(param_blob); } else { uint8_t *ptr; /* allocate and load BIOS */ diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index f7b903ea1b..89c4108eb5 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -89,6 +89,7 @@ typedef struct { M68kCPU *cpu; hwaddr initial_pc; hwaddr initial_stack; + struct bi_record *rng_seed; } ResetInfo; static void main_cpu_reset(void *opaque) @@ -97,6 +98,11 @@ static void main_cpu_reset(void *opaque) M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); + if (reset_info->rng_seed) { + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); + } + cpu_reset(cs); cpu->env.aregs[7] = reset_info->initial_stack; cpu->env.pc = reset_info->initial_pc; @@ -212,6 +218,13 @@ static void virt_init(MachineState *machine) if (kernel_filename) { CPUState *cs = CPU(cpu); uint64_t high; + void *param_blob, *param_ptr, *param_rng_seed; + + if (kernel_cmdline) { + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); + } else { + param_blob = g_malloc(1024); + } kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, &high, NULL, 1, @@ -222,35 +235,37 @@ static void virt_init(MachineState *machine) } reset_info->initial_pc = elf_entry; parameters_base = (high + 1) & ~1; + param_ptr = param_blob; - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_VIRT); - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_VIRT); + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); - BOOTINFO1(cs->as, parameters_base, BI_VIRT_QEMU_VERSION, + BOOTINFO1(param_ptr, BI_VIRT_QEMU_VERSION, ((QEMU_VERSION_MAJOR << 24) | (QEMU_VERSION_MINOR << 16) | (QEMU_VERSION_MICRO << 8))); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_PIC_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_PIC_BASE, VIRT_GF_PIC_MMIO_BASE, VIRT_GF_PIC_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_RTC_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_RTC_BASE, VIRT_GF_RTC_MMIO_BASE, VIRT_GF_RTC_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_TTY_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_TTY_BASE, VIRT_GF_TTY_MMIO_BASE, VIRT_GF_TTY_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_CTRL_BASE, + BOOTINFO2(param_ptr, BI_VIRT_CTRL_BASE, VIRT_CTRL_MMIO_BASE, VIRT_CTRL_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_VIRTIO_BASE, + BOOTINFO2(param_ptr, BI_VIRT_VIRTIO_BASE, VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE); if (kernel_cmdline) { - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, kernel_cmdline); } /* Pass seed to RNG. */ + param_rng_seed = param_ptr; qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + BOOTINFODATA(param_ptr, BI_RNG_SEED, rng_seed, sizeof(rng_seed)); /* load initrd */ @@ -265,13 +280,19 @@ static void virt_init(MachineState *machine) initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; } - BOOTINFO0(cs->as, parameters_base, BI_LAST); + BOOTINFO0(param_ptr, BI_LAST); + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, + parameters_base, cs->as); + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob); + g_free(param_blob); } } -- 2.37.3 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v4] m68k: write bootinfo as rom section and re-randomize on reboot 2022-10-17 20:29 ` [PATCH v4] m68k: write bootinfo as rom section and re-randomize on reboot Jason A. Donenfeld @ 2022-10-21 19:25 ` Laurent Vivier 2022-10-22 6:41 ` Richard Henderson 0 siblings, 1 reply; 12+ messages in thread From: Laurent Vivier @ 2022-10-21 19:25 UTC (permalink / raw) To: Jason A. Donenfeld, qemu-devel; +Cc: Geert Uytterhoeven Le 17/10/2022 à 22:29, Jason A. Donenfeld a écrit : > Rather than poking directly into RAM, add the bootinfo block as a proper > ROM, so that it's restored when rebooting the system. This way, if the > guest corrupts any of the bootinfo items, but then tries to reboot, > it'll still be restored back to normal as expected. > > Then, since the RNG seed needs to be fresh on each boot, regenerate the > RNG seed in the ROM when reseting the CPU. > > Cc: Geert Uytterhoeven <geert@linux-m68k.org> > Cc: Laurent Vivier <laurent@vivier.eu> > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> > --- > hw/m68k/bootinfo.h | 48 +++++++++++++++---------------- > hw/m68k/q800.c | 71 +++++++++++++++++++++++++++++++++------------- > hw/m68k/virt.c | 51 +++++++++++++++++++++++---------- > 3 files changed, 111 insertions(+), 59 deletions(-) Notes: - don't send your patch as a reply to a previous version - add an history: v4: replace (void *)(((unsigned long)base + 3) & ~3) by (void *)(((uintptr_t)base + 3) & ~3); Reviewed-by: Laurent Vivier <laurent@vivier.eu> Thanks, Laurent > diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h > index 897162b818..67e6b66b7d 100644 > --- a/hw/m68k/bootinfo.h > +++ b/hw/m68k/bootinfo.h > @@ -12,66 +12,66 @@ > #ifndef HW_M68K_BOOTINFO_H > #define HW_M68K_BOOTINFO_H > > -#define BOOTINFO0(as, base, id) \ > +#define BOOTINFO0(base, id) \ > do { \ > - stw_phys(as, base, id); \ > + stw_p(base, id); \ > base += 2; \ > - stw_phys(as, base, sizeof(struct bi_record)); \ > + stw_p(base, sizeof(struct bi_record)); \ > base += 2; \ > } while (0) > > -#define BOOTINFO1(as, base, id, value) \ > +#define BOOTINFO1(base, id, value) \ > do { \ > - stw_phys(as, base, id); \ > + stw_p(base, id); \ > base += 2; \ > - stw_phys(as, base, sizeof(struct bi_record) + 4); \ > + stw_p(base, sizeof(struct bi_record) + 4); \ > base += 2; \ > - stl_phys(as, base, value); \ > + stl_p(base, value); \ > base += 4; \ > } while (0) > > -#define BOOTINFO2(as, base, id, value1, value2) \ > +#define BOOTINFO2(base, id, value1, value2) \ > do { \ > - stw_phys(as, base, id); \ > + stw_p(base, id); \ > base += 2; \ > - stw_phys(as, base, sizeof(struct bi_record) + 8); \ > + stw_p(base, sizeof(struct bi_record) + 8); \ > base += 2; \ > - stl_phys(as, base, value1); \ > + stl_p(base, value1); \ > base += 4; \ > - stl_phys(as, base, value2); \ > + stl_p(base, value2); \ > base += 4; \ > } while (0) > > -#define BOOTINFOSTR(as, base, id, string) \ > +#define BOOTINFOSTR(base, id, string) \ > do { \ > int i; \ > - stw_phys(as, base, id); \ > + stw_p(base, id); \ > base += 2; \ > - stw_phys(as, base, \ > + stw_p(base, \ > (sizeof(struct bi_record) + strlen(string) + \ > 1 /* null termination */ + 3 /* padding */) & ~3); \ > base += 2; \ > for (i = 0; string[i]; i++) { \ > - stb_phys(as, base++, string[i]); \ > + stb_p(base++, string[i]); \ > } \ > - stb_phys(as, base++, 0); \ > - base = (base + 3) & ~3; \ > + stb_p(base++, 0); \ > + base = (void *)(((uintptr_t)base + 3) & ~3); \ > } while (0) > > -#define BOOTINFODATA(as, base, id, data, len) \ > +#define BOOTINFODATA(base, id, data, len) \ > do { \ > int i; \ > - stw_phys(as, base, id); \ > + stw_p(base, id); \ > base += 2; \ > - stw_phys(as, base, \ > + stw_p(base, \ > (sizeof(struct bi_record) + len + \ > 2 /* length field */ + 3 /* padding */) & ~3); \ > base += 2; \ > - stw_phys(as, base, len); \ > + stw_p(base, len); \ > base += 2; \ > for (i = 0; i < len; ++i) { \ > - stb_phys(as, base++, data[i]); \ > + stb_p(base++, data[i]); \ > } \ > - base = (base + 3) & ~3; \ > + base = (void *)(((uintptr_t)base + 3) & ~3); \ > } while (0) > #endif > diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c > index a4590c2cb0..e09e244ddc 100644 > --- a/hw/m68k/q800.c > +++ b/hw/m68k/q800.c > @@ -321,11 +321,22 @@ static const TypeInfo glue_info = { > }, > }; > > +typedef struct { > + M68kCPU *cpu; > + struct bi_record *rng_seed; > +} ResetInfo; > + > static void main_cpu_reset(void *opaque) > { > - M68kCPU *cpu = opaque; > + ResetInfo *reset_info = opaque; > + M68kCPU *cpu = reset_info->cpu; > CPUState *cs = CPU(cpu); > > + if (reset_info->rng_seed) { > + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, > + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); > + } > + > cpu_reset(cs); > cpu->env.aregs[7] = ldl_phys(cs->as, 0); > cpu->env.pc = ldl_phys(cs->as, 4); > @@ -386,6 +397,7 @@ static void q800_init(MachineState *machine) > NubusBus *nubus; > DeviceState *glue; > DriveInfo *dinfo; > + ResetInfo *reset_info; > uint8_t rng_seed[32]; > > linux_boot = (kernel_filename != NULL); > @@ -396,9 +408,12 @@ static void q800_init(MachineState *machine) > exit(1); > } > > + reset_info = g_new0(ResetInfo, 1); > + > /* init CPUs */ > cpu = M68K_CPU(cpu_create(machine->cpu_type)); > - qemu_register_reset(main_cpu_reset, cpu); > + reset_info->cpu = cpu; > + qemu_register_reset(main_cpu_reset, reset_info); > > /* RAM */ > memory_region_add_subregion(get_system_memory(), 0, machine->ram); > @@ -598,6 +613,14 @@ static void q800_init(MachineState *machine) > cs = CPU(cpu); > if (linux_boot) { > uint64_t high; > + void *param_blob, *param_ptr, *param_rng_seed; > + > + if (kernel_cmdline) { > + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); > + } else { > + param_blob = g_malloc(1024); > + } > + > kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, > &elf_entry, NULL, &high, NULL, 1, > EM_68K, 0, 0); > @@ -607,23 +630,24 @@ static void q800_init(MachineState *machine) > } > stl_phys(cs->as, 4, elf_entry); /* reset initial PC */ > parameters_base = (high + 1) & ~1; > - > - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_MAC); > - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); > - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); > - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); > - BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, CPUB_68040); > - BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, MAC_MODEL_Q800); > - BOOTINFO1(cs->as, parameters_base, > + param_ptr = param_blob; > + > + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_MAC); > + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); > + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); > + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); > + BOOTINFO1(param_ptr, BI_MAC_CPUID, CPUB_68040); > + BOOTINFO1(param_ptr, BI_MAC_MODEL, MAC_MODEL_Q800); > + BOOTINFO1(param_ptr, > BI_MAC_MEMSIZE, ram_size >> 20); /* in MB */ > - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); > - BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR, > + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); > + BOOTINFO1(param_ptr, BI_MAC_VADDR, > VIDEO_BASE + macfb_mode->offset); > - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDEPTH, graphic_depth); > - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDIM, > + BOOTINFO1(param_ptr, BI_MAC_VDEPTH, graphic_depth); > + BOOTINFO1(param_ptr, BI_MAC_VDIM, > (graphic_height << 16) | graphic_width); > - BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW, macfb_mode->stride); > - BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE); > + BOOTINFO1(param_ptr, BI_MAC_VROW, macfb_mode->stride); > + BOOTINFO1(param_ptr, BI_MAC_SCCBASE, SCC_BASE); > > rom = g_malloc(sizeof(*rom)); > memory_region_init_ram_ptr(rom, NULL, "m68k_fake_mac.rom", > @@ -632,13 +656,14 @@ static void q800_init(MachineState *machine) > memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom); > > if (kernel_cmdline) { > - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, > + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, > kernel_cmdline); > } > > /* Pass seed to RNG. */ > + param_rng_seed = param_ptr; > qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); > - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, > + BOOTINFODATA(param_ptr, BI_RNG_SEED, > rng_seed, sizeof(rng_seed)); > > /* load initrd */ > @@ -653,13 +678,19 @@ static void q800_init(MachineState *machine) > initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; > load_image_targphys(initrd_filename, initrd_base, > ram_size - initrd_base); > - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, > + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, > initrd_size); > } else { > initrd_base = 0; > initrd_size = 0; > } > - BOOTINFO0(cs->as, parameters_base, BI_LAST); > + BOOTINFO0(param_ptr, BI_LAST); > + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, > + parameters_base, cs->as); > + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, > + param_ptr - param_blob) + > + (param_rng_seed - param_blob); > + g_free(param_blob); > } else { > uint8_t *ptr; > /* allocate and load BIOS */ > diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c > index f7b903ea1b..89c4108eb5 100644 > --- a/hw/m68k/virt.c > +++ b/hw/m68k/virt.c > @@ -89,6 +89,7 @@ typedef struct { > M68kCPU *cpu; > hwaddr initial_pc; > hwaddr initial_stack; > + struct bi_record *rng_seed; > } ResetInfo; > > static void main_cpu_reset(void *opaque) > @@ -97,6 +98,11 @@ static void main_cpu_reset(void *opaque) > M68kCPU *cpu = reset_info->cpu; > CPUState *cs = CPU(cpu); > > + if (reset_info->rng_seed) { > + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, > + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); > + } > + > cpu_reset(cs); > cpu->env.aregs[7] = reset_info->initial_stack; > cpu->env.pc = reset_info->initial_pc; > @@ -212,6 +218,13 @@ static void virt_init(MachineState *machine) > if (kernel_filename) { > CPUState *cs = CPU(cpu); > uint64_t high; > + void *param_blob, *param_ptr, *param_rng_seed; > + > + if (kernel_cmdline) { > + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); > + } else { > + param_blob = g_malloc(1024); > + } > > kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, > &elf_entry, NULL, &high, NULL, 1, > @@ -222,35 +235,37 @@ static void virt_init(MachineState *machine) > } > reset_info->initial_pc = elf_entry; > parameters_base = (high + 1) & ~1; > + param_ptr = param_blob; > > - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_VIRT); > - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); > - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); > - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); > - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); > + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_VIRT); > + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); > + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); > + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); > + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); > > - BOOTINFO1(cs->as, parameters_base, BI_VIRT_QEMU_VERSION, > + BOOTINFO1(param_ptr, BI_VIRT_QEMU_VERSION, > ((QEMU_VERSION_MAJOR << 24) | (QEMU_VERSION_MINOR << 16) | > (QEMU_VERSION_MICRO << 8))); > - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_PIC_BASE, > + BOOTINFO2(param_ptr, BI_VIRT_GF_PIC_BASE, > VIRT_GF_PIC_MMIO_BASE, VIRT_GF_PIC_IRQ_BASE); > - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_RTC_BASE, > + BOOTINFO2(param_ptr, BI_VIRT_GF_RTC_BASE, > VIRT_GF_RTC_MMIO_BASE, VIRT_GF_RTC_IRQ_BASE); > - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_TTY_BASE, > + BOOTINFO2(param_ptr, BI_VIRT_GF_TTY_BASE, > VIRT_GF_TTY_MMIO_BASE, VIRT_GF_TTY_IRQ_BASE); > - BOOTINFO2(cs->as, parameters_base, BI_VIRT_CTRL_BASE, > + BOOTINFO2(param_ptr, BI_VIRT_CTRL_BASE, > VIRT_CTRL_MMIO_BASE, VIRT_CTRL_IRQ_BASE); > - BOOTINFO2(cs->as, parameters_base, BI_VIRT_VIRTIO_BASE, > + BOOTINFO2(param_ptr, BI_VIRT_VIRTIO_BASE, > VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE); > > if (kernel_cmdline) { > - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, > + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, > kernel_cmdline); > } > > /* Pass seed to RNG. */ > + param_rng_seed = param_ptr; > qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); > - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, > + BOOTINFODATA(param_ptr, BI_RNG_SEED, > rng_seed, sizeof(rng_seed)); > > /* load initrd */ > @@ -265,13 +280,19 @@ static void virt_init(MachineState *machine) > initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; > load_image_targphys(initrd_filename, initrd_base, > ram_size - initrd_base); > - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, > + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, > initrd_size); > } else { > initrd_base = 0; > initrd_size = 0; > } > - BOOTINFO0(cs->as, parameters_base, BI_LAST); > + BOOTINFO0(param_ptr, BI_LAST); > + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, > + parameters_base, cs->as); > + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, > + param_ptr - param_blob) + > + (param_rng_seed - param_blob); > + g_free(param_blob); > } > } > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4] m68k: write bootinfo as rom section and re-randomize on reboot 2022-10-21 19:25 ` Laurent Vivier @ 2022-10-22 6:41 ` Richard Henderson 2022-10-23 19:09 ` Jason A. Donenfeld 0 siblings, 1 reply; 12+ messages in thread From: Richard Henderson @ 2022-10-22 6:41 UTC (permalink / raw) To: Laurent Vivier Cc: Jason A. Donenfeld, qemu-devel@nongnu.org Developers, Geert Uytterhoeven [-- Attachment #1: Type: text/plain, Size: 380 bytes --] On Sat, 22 Oct 2022, 08:33 Laurent Vivier, <laurent@vivier.eu> wrote: > Le 17/10/2022 à 22:29, Jason A. Donenfeld a écrit : > > > Notes: > - don't send your patch as a reply to a previous version > - add an history: > > v4: replace (void *)(((unsigned long)base + 3) & ~3) by > (void *)(((uintptr_t)base + 3) & ~3); > QEMU_ALIGN_PTR_UP. r~ [-- Attachment #2: Type: text/html, Size: 817 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4] m68k: write bootinfo as rom section and re-randomize on reboot 2022-10-22 6:41 ` Richard Henderson @ 2022-10-23 19:09 ` Jason A. Donenfeld 0 siblings, 0 replies; 12+ messages in thread From: Jason A. Donenfeld @ 2022-10-23 19:09 UTC (permalink / raw) To: Richard Henderson Cc: Laurent Vivier, qemu-devel@nongnu.org Developers, Geert Uytterhoeven On Sat, Oct 22, 2022 at 8:41 AM Richard Henderson <richard.henderson@linaro.org> wrote: > > On Sat, 22 Oct 2022, 08:33 Laurent Vivier, <laurent@vivier.eu> wrote: >> >> Le 17/10/2022 à 22:29, Jason A. Donenfeld a écrit : >> >> >> Notes: >> - don't send your patch as a reply to a previous version >> - add an history: >> >> v4: replace (void *)(((unsigned long)base + 3) & ~3) by >> (void *)(((uintptr_t)base + 3) & ~3); > > > > QEMU_ALIGN_PTR_UP. Will do. v5 on its way. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PULL 0/2] M68k for 7.2 patches @ 2022-10-22 9:17 Laurent Vivier 2022-10-22 9:17 ` [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot Laurent Vivier 0 siblings, 1 reply; 12+ messages in thread From: Laurent Vivier @ 2022-10-22 9:17 UTC (permalink / raw) To: qemu-devel; +Cc: Laurent Vivier The following changes since commit 0529245488865038344d64fff7ee05864d3d17f6: Merge tag 'pull-target-arm-20221020' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2022-10-20 14:36:12 -0400) are available in the Git repository at: https://github.com/vivier/qemu-m68k.git tags/m68k-for-7.2-pull-request for you to fetch changes up to d3c7b59be912d257ae7773eb3f1127f81a710a4d: m68k: write bootinfo as rom section and re-randomize on reboot (2022-10-22 09:58:24 +0200) ---------------------------------------------------------------- Pull request m68k branch 20221022 Update rng seed boot parameter ---------------------------------------------------------------- Jason A. Donenfeld (2): m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED m68k: write bootinfo as rom section and re-randomize on reboot hw/m68k/bootinfo.h | 48 ++++++------ .../standard-headers/asm-m68k/bootinfo-virt.h | 4 +- include/standard-headers/asm-m68k/bootinfo.h | 8 +- hw/m68k/q800.c | 76 ++++++++++++++----- hw/m68k/virt.c | 57 +++++++++----- 5 files changed, 130 insertions(+), 63 deletions(-) -- 2.37.3 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot 2022-10-22 9:17 [PULL 0/2] M68k for 7.2 patches Laurent Vivier @ 2022-10-22 9:17 ` Laurent Vivier 0 siblings, 0 replies; 12+ messages in thread From: Laurent Vivier @ 2022-10-22 9:17 UTC (permalink / raw) To: qemu-devel; +Cc: Laurent Vivier, Jason A. Donenfeld, Geert Uytterhoeven From: "Jason A. Donenfeld" <Jason@zx2c4.com> Rather than poking directly into RAM, add the bootinfo block as a proper ROM, so that it's restored when rebooting the system. This way, if the guest corrupts any of the bootinfo items, but then tries to reboot, it'll still be restored back to normal as expected. Then, since the RNG seed needs to be fresh on each boot, regenerate the RNG seed in the ROM when reseting the CPU. Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Laurent Vivier <laurent@vivier.eu> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20221017202952.60762-1-Jason@zx2c4.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu> --- hw/m68k/bootinfo.h | 48 +++++++++++++++---------------- hw/m68k/q800.c | 71 +++++++++++++++++++++++++++++++++------------- hw/m68k/virt.c | 51 +++++++++++++++++++++++---------- 3 files changed, 111 insertions(+), 59 deletions(-) diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h index 897162b8189c..67e6b66b7d47 100644 --- a/hw/m68k/bootinfo.h +++ b/hw/m68k/bootinfo.h @@ -12,66 +12,66 @@ #ifndef HW_M68K_BOOTINFO_H #define HW_M68K_BOOTINFO_H -#define BOOTINFO0(as, base, id) \ +#define BOOTINFO0(base, id) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record)); \ + stw_p(base, sizeof(struct bi_record)); \ base += 2; \ } while (0) -#define BOOTINFO1(as, base, id, value) \ +#define BOOTINFO1(base, id, value) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record) + 4); \ + stw_p(base, sizeof(struct bi_record) + 4); \ base += 2; \ - stl_phys(as, base, value); \ + stl_p(base, value); \ base += 4; \ } while (0) -#define BOOTINFO2(as, base, id, value1, value2) \ +#define BOOTINFO2(base, id, value1, value2) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record) + 8); \ + stw_p(base, sizeof(struct bi_record) + 8); \ base += 2; \ - stl_phys(as, base, value1); \ + stl_p(base, value1); \ base += 4; \ - stl_phys(as, base, value2); \ + stl_p(base, value2); \ base += 4; \ } while (0) -#define BOOTINFOSTR(as, base, id, string) \ +#define BOOTINFOSTR(base, id, string) \ do { \ int i; \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, \ + stw_p(base, \ (sizeof(struct bi_record) + strlen(string) + \ 1 /* null termination */ + 3 /* padding */) & ~3); \ base += 2; \ for (i = 0; string[i]; i++) { \ - stb_phys(as, base++, string[i]); \ + stb_p(base++, string[i]); \ } \ - stb_phys(as, base++, 0); \ - base = (base + 3) & ~3; \ + stb_p(base++, 0); \ + base = (void *)(((uintptr_t)base + 3) & ~3); \ } while (0) -#define BOOTINFODATA(as, base, id, data, len) \ +#define BOOTINFODATA(base, id, data, len) \ do { \ int i; \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, \ + stw_p(base, \ (sizeof(struct bi_record) + len + \ 2 /* length field */ + 3 /* padding */) & ~3); \ base += 2; \ - stw_phys(as, base, len); \ + stw_p(base, len); \ base += 2; \ for (i = 0; i < len; ++i) { \ - stb_phys(as, base++, data[i]); \ + stb_p(base++, data[i]); \ } \ - base = (base + 3) & ~3; \ + base = (void *)(((uintptr_t)base + 3) & ~3); \ } while (0) #endif diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index a4590c2cb0b1..e09e244ddc1d 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -321,11 +321,22 @@ static const TypeInfo glue_info = { }, }; +typedef struct { + M68kCPU *cpu; + struct bi_record *rng_seed; +} ResetInfo; + static void main_cpu_reset(void *opaque) { - M68kCPU *cpu = opaque; + ResetInfo *reset_info = opaque; + M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); + if (reset_info->rng_seed) { + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); + } + cpu_reset(cs); cpu->env.aregs[7] = ldl_phys(cs->as, 0); cpu->env.pc = ldl_phys(cs->as, 4); @@ -386,6 +397,7 @@ static void q800_init(MachineState *machine) NubusBus *nubus; DeviceState *glue; DriveInfo *dinfo; + ResetInfo *reset_info; uint8_t rng_seed[32]; linux_boot = (kernel_filename != NULL); @@ -396,9 +408,12 @@ static void q800_init(MachineState *machine) exit(1); } + reset_info = g_new0(ResetInfo, 1); + /* init CPUs */ cpu = M68K_CPU(cpu_create(machine->cpu_type)); - qemu_register_reset(main_cpu_reset, cpu); + reset_info->cpu = cpu; + qemu_register_reset(main_cpu_reset, reset_info); /* RAM */ memory_region_add_subregion(get_system_memory(), 0, machine->ram); @@ -598,6 +613,14 @@ static void q800_init(MachineState *machine) cs = CPU(cpu); if (linux_boot) { uint64_t high; + void *param_blob, *param_ptr, *param_rng_seed; + + if (kernel_cmdline) { + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); + } else { + param_blob = g_malloc(1024); + } + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, &high, NULL, 1, EM_68K, 0, 0); @@ -607,23 +630,24 @@ static void q800_init(MachineState *machine) } stl_phys(cs->as, 4, elf_entry); /* reset initial PC */ parameters_base = (high + 1) & ~1; - - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_MAC); - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, CPUB_68040); - BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, MAC_MODEL_Q800); - BOOTINFO1(cs->as, parameters_base, + param_ptr = param_blob; + + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_MAC); + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); + BOOTINFO1(param_ptr, BI_MAC_CPUID, CPUB_68040); + BOOTINFO1(param_ptr, BI_MAC_MODEL, MAC_MODEL_Q800); + BOOTINFO1(param_ptr, BI_MAC_MEMSIZE, ram_size >> 20); /* in MB */ - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR, + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); + BOOTINFO1(param_ptr, BI_MAC_VADDR, VIDEO_BASE + macfb_mode->offset); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDEPTH, graphic_depth); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDIM, + BOOTINFO1(param_ptr, BI_MAC_VDEPTH, graphic_depth); + BOOTINFO1(param_ptr, BI_MAC_VDIM, (graphic_height << 16) | graphic_width); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW, macfb_mode->stride); - BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE); + BOOTINFO1(param_ptr, BI_MAC_VROW, macfb_mode->stride); + BOOTINFO1(param_ptr, BI_MAC_SCCBASE, SCC_BASE); rom = g_malloc(sizeof(*rom)); memory_region_init_ram_ptr(rom, NULL, "m68k_fake_mac.rom", @@ -632,13 +656,14 @@ static void q800_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom); if (kernel_cmdline) { - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, kernel_cmdline); } /* Pass seed to RNG. */ + param_rng_seed = param_ptr; qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + BOOTINFODATA(param_ptr, BI_RNG_SEED, rng_seed, sizeof(rng_seed)); /* load initrd */ @@ -653,13 +678,19 @@ static void q800_init(MachineState *machine) initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; } - BOOTINFO0(cs->as, parameters_base, BI_LAST); + BOOTINFO0(param_ptr, BI_LAST); + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, + parameters_base, cs->as); + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob); + g_free(param_blob); } else { uint8_t *ptr; /* allocate and load BIOS */ diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index f7b903ea1b62..89c4108eb545 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -89,6 +89,7 @@ typedef struct { M68kCPU *cpu; hwaddr initial_pc; hwaddr initial_stack; + struct bi_record *rng_seed; } ResetInfo; static void main_cpu_reset(void *opaque) @@ -97,6 +98,11 @@ static void main_cpu_reset(void *opaque) M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); + if (reset_info->rng_seed) { + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); + } + cpu_reset(cs); cpu->env.aregs[7] = reset_info->initial_stack; cpu->env.pc = reset_info->initial_pc; @@ -212,6 +218,13 @@ static void virt_init(MachineState *machine) if (kernel_filename) { CPUState *cs = CPU(cpu); uint64_t high; + void *param_blob, *param_ptr, *param_rng_seed; + + if (kernel_cmdline) { + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); + } else { + param_blob = g_malloc(1024); + } kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, &high, NULL, 1, @@ -222,35 +235,37 @@ static void virt_init(MachineState *machine) } reset_info->initial_pc = elf_entry; parameters_base = (high + 1) & ~1; + param_ptr = param_blob; - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_VIRT); - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_VIRT); + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); - BOOTINFO1(cs->as, parameters_base, BI_VIRT_QEMU_VERSION, + BOOTINFO1(param_ptr, BI_VIRT_QEMU_VERSION, ((QEMU_VERSION_MAJOR << 24) | (QEMU_VERSION_MINOR << 16) | (QEMU_VERSION_MICRO << 8))); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_PIC_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_PIC_BASE, VIRT_GF_PIC_MMIO_BASE, VIRT_GF_PIC_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_RTC_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_RTC_BASE, VIRT_GF_RTC_MMIO_BASE, VIRT_GF_RTC_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_TTY_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_TTY_BASE, VIRT_GF_TTY_MMIO_BASE, VIRT_GF_TTY_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_CTRL_BASE, + BOOTINFO2(param_ptr, BI_VIRT_CTRL_BASE, VIRT_CTRL_MMIO_BASE, VIRT_CTRL_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_VIRTIO_BASE, + BOOTINFO2(param_ptr, BI_VIRT_VIRTIO_BASE, VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE); if (kernel_cmdline) { - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, kernel_cmdline); } /* Pass seed to RNG. */ + param_rng_seed = param_ptr; qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + BOOTINFODATA(param_ptr, BI_RNG_SEED, rng_seed, sizeof(rng_seed)); /* load initrd */ @@ -265,13 +280,19 @@ static void virt_init(MachineState *machine) initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; } - BOOTINFO0(cs->as, parameters_base, BI_LAST); + BOOTINFO0(param_ptr, BI_LAST); + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, + parameters_base, cs->as); + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob); + g_free(param_blob); } } -- 2.37.3 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 0/2] M68k for 7.2 patches @ 2022-10-24 8:58 Laurent Vivier 2022-10-24 8:58 ` [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot Laurent Vivier 0 siblings, 1 reply; 12+ messages in thread From: Laurent Vivier @ 2022-10-24 8:58 UTC (permalink / raw) To: qemu-devel; +Cc: Laurent Vivier The following changes since commit 0529245488865038344d64fff7ee05864d3d17f6: Merge tag 'pull-target-arm-20221020' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2022-10-20 14:36:12 -0400) are available in the Git repository at: https://github.com/vivier/qemu-m68k.git tags/m68k-for-7.2-pull-request for you to fetch changes up to 281ac13ecedf8bfe1b83e566f39cb5683e553cb6: m68k: write bootinfo as rom section and re-randomize on reboot (2022-10-24 10:47:14 +0200) ---------------------------------------------------------------- Pull request m68k branch 20221024 Update rng seed boot parameter ---------------------------------------------------------------- Jason A. Donenfeld (2): m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED m68k: write bootinfo as rom section and re-randomize on reboot hw/m68k/bootinfo.h | 48 ++++++------ .../standard-headers/asm-m68k/bootinfo-virt.h | 4 +- include/standard-headers/asm-m68k/bootinfo.h | 8 +- hw/m68k/q800.c | 76 ++++++++++++++----- hw/m68k/virt.c | 57 +++++++++----- 5 files changed, 130 insertions(+), 63 deletions(-) -- 2.37.3 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot 2022-10-24 8:58 [PULL 0/2] M68k for 7.2 patches Laurent Vivier @ 2022-10-24 8:58 ` Laurent Vivier 0 siblings, 0 replies; 12+ messages in thread From: Laurent Vivier @ 2022-10-24 8:58 UTC (permalink / raw) To: qemu-devel; +Cc: Laurent Vivier, Jason A. Donenfeld, Geert Uytterhoeven From: "Jason A. Donenfeld" <Jason@zx2c4.com> Rather than poking directly into RAM, add the bootinfo block as a proper ROM, so that it's restored when rebooting the system. This way, if the guest corrupts any of the bootinfo items, but then tries to reboot, it'll still be restored back to normal as expected. Then, since the RNG seed needs to be fresh on each boot, regenerate the RNG seed in the ROM when reseting the CPU. Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Laurent Vivier <laurent@vivier.eu> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Message-Id: <20221023191340.36238-1-Jason@zx2c4.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu> --- hw/m68k/bootinfo.h | 48 +++++++++++++++---------------- hw/m68k/q800.c | 71 +++++++++++++++++++++++++++++++++------------- hw/m68k/virt.c | 51 +++++++++++++++++++++++---------- 3 files changed, 111 insertions(+), 59 deletions(-) diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h index 897162b8189c..a3d37e3c8094 100644 --- a/hw/m68k/bootinfo.h +++ b/hw/m68k/bootinfo.h @@ -12,66 +12,66 @@ #ifndef HW_M68K_BOOTINFO_H #define HW_M68K_BOOTINFO_H -#define BOOTINFO0(as, base, id) \ +#define BOOTINFO0(base, id) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record)); \ + stw_p(base, sizeof(struct bi_record)); \ base += 2; \ } while (0) -#define BOOTINFO1(as, base, id, value) \ +#define BOOTINFO1(base, id, value) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record) + 4); \ + stw_p(base, sizeof(struct bi_record) + 4); \ base += 2; \ - stl_phys(as, base, value); \ + stl_p(base, value); \ base += 4; \ } while (0) -#define BOOTINFO2(as, base, id, value1, value2) \ +#define BOOTINFO2(base, id, value1, value2) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record) + 8); \ + stw_p(base, sizeof(struct bi_record) + 8); \ base += 2; \ - stl_phys(as, base, value1); \ + stl_p(base, value1); \ base += 4; \ - stl_phys(as, base, value2); \ + stl_p(base, value2); \ base += 4; \ } while (0) -#define BOOTINFOSTR(as, base, id, string) \ +#define BOOTINFOSTR(base, id, string) \ do { \ int i; \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, \ + stw_p(base, \ (sizeof(struct bi_record) + strlen(string) + \ 1 /* null termination */ + 3 /* padding */) & ~3); \ base += 2; \ for (i = 0; string[i]; i++) { \ - stb_phys(as, base++, string[i]); \ + stb_p(base++, string[i]); \ } \ - stb_phys(as, base++, 0); \ - base = (base + 3) & ~3; \ + stb_p(base++, 0); \ + base = QEMU_ALIGN_PTR_UP(base, 4); \ } while (0) -#define BOOTINFODATA(as, base, id, data, len) \ +#define BOOTINFODATA(base, id, data, len) \ do { \ int i; \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, \ + stw_p(base, \ (sizeof(struct bi_record) + len + \ 2 /* length field */ + 3 /* padding */) & ~3); \ base += 2; \ - stw_phys(as, base, len); \ + stw_p(base, len); \ base += 2; \ for (i = 0; i < len; ++i) { \ - stb_phys(as, base++, data[i]); \ + stb_p(base++, data[i]); \ } \ - base = (base + 3) & ~3; \ + base = QEMU_ALIGN_PTR_UP(base, 4); \ } while (0) #endif diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index a4590c2cb0b1..e09e244ddc1d 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -321,11 +321,22 @@ static const TypeInfo glue_info = { }, }; +typedef struct { + M68kCPU *cpu; + struct bi_record *rng_seed; +} ResetInfo; + static void main_cpu_reset(void *opaque) { - M68kCPU *cpu = opaque; + ResetInfo *reset_info = opaque; + M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); + if (reset_info->rng_seed) { + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); + } + cpu_reset(cs); cpu->env.aregs[7] = ldl_phys(cs->as, 0); cpu->env.pc = ldl_phys(cs->as, 4); @@ -386,6 +397,7 @@ static void q800_init(MachineState *machine) NubusBus *nubus; DeviceState *glue; DriveInfo *dinfo; + ResetInfo *reset_info; uint8_t rng_seed[32]; linux_boot = (kernel_filename != NULL); @@ -396,9 +408,12 @@ static void q800_init(MachineState *machine) exit(1); } + reset_info = g_new0(ResetInfo, 1); + /* init CPUs */ cpu = M68K_CPU(cpu_create(machine->cpu_type)); - qemu_register_reset(main_cpu_reset, cpu); + reset_info->cpu = cpu; + qemu_register_reset(main_cpu_reset, reset_info); /* RAM */ memory_region_add_subregion(get_system_memory(), 0, machine->ram); @@ -598,6 +613,14 @@ static void q800_init(MachineState *machine) cs = CPU(cpu); if (linux_boot) { uint64_t high; + void *param_blob, *param_ptr, *param_rng_seed; + + if (kernel_cmdline) { + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); + } else { + param_blob = g_malloc(1024); + } + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, &high, NULL, 1, EM_68K, 0, 0); @@ -607,23 +630,24 @@ static void q800_init(MachineState *machine) } stl_phys(cs->as, 4, elf_entry); /* reset initial PC */ parameters_base = (high + 1) & ~1; - - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_MAC); - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, CPUB_68040); - BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, MAC_MODEL_Q800); - BOOTINFO1(cs->as, parameters_base, + param_ptr = param_blob; + + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_MAC); + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); + BOOTINFO1(param_ptr, BI_MAC_CPUID, CPUB_68040); + BOOTINFO1(param_ptr, BI_MAC_MODEL, MAC_MODEL_Q800); + BOOTINFO1(param_ptr, BI_MAC_MEMSIZE, ram_size >> 20); /* in MB */ - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR, + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); + BOOTINFO1(param_ptr, BI_MAC_VADDR, VIDEO_BASE + macfb_mode->offset); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDEPTH, graphic_depth); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDIM, + BOOTINFO1(param_ptr, BI_MAC_VDEPTH, graphic_depth); + BOOTINFO1(param_ptr, BI_MAC_VDIM, (graphic_height << 16) | graphic_width); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW, macfb_mode->stride); - BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE); + BOOTINFO1(param_ptr, BI_MAC_VROW, macfb_mode->stride); + BOOTINFO1(param_ptr, BI_MAC_SCCBASE, SCC_BASE); rom = g_malloc(sizeof(*rom)); memory_region_init_ram_ptr(rom, NULL, "m68k_fake_mac.rom", @@ -632,13 +656,14 @@ static void q800_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom); if (kernel_cmdline) { - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, kernel_cmdline); } /* Pass seed to RNG. */ + param_rng_seed = param_ptr; qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + BOOTINFODATA(param_ptr, BI_RNG_SEED, rng_seed, sizeof(rng_seed)); /* load initrd */ @@ -653,13 +678,19 @@ static void q800_init(MachineState *machine) initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; } - BOOTINFO0(cs->as, parameters_base, BI_LAST); + BOOTINFO0(param_ptr, BI_LAST); + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, + parameters_base, cs->as); + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob); + g_free(param_blob); } else { uint8_t *ptr; /* allocate and load BIOS */ diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index f7b903ea1b62..89c4108eb545 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -89,6 +89,7 @@ typedef struct { M68kCPU *cpu; hwaddr initial_pc; hwaddr initial_stack; + struct bi_record *rng_seed; } ResetInfo; static void main_cpu_reset(void *opaque) @@ -97,6 +98,11 @@ static void main_cpu_reset(void *opaque) M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); + if (reset_info->rng_seed) { + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); + } + cpu_reset(cs); cpu->env.aregs[7] = reset_info->initial_stack; cpu->env.pc = reset_info->initial_pc; @@ -212,6 +218,13 @@ static void virt_init(MachineState *machine) if (kernel_filename) { CPUState *cs = CPU(cpu); uint64_t high; + void *param_blob, *param_ptr, *param_rng_seed; + + if (kernel_cmdline) { + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); + } else { + param_blob = g_malloc(1024); + } kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, &high, NULL, 1, @@ -222,35 +235,37 @@ static void virt_init(MachineState *machine) } reset_info->initial_pc = elf_entry; parameters_base = (high + 1) & ~1; + param_ptr = param_blob; - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_VIRT); - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_VIRT); + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); - BOOTINFO1(cs->as, parameters_base, BI_VIRT_QEMU_VERSION, + BOOTINFO1(param_ptr, BI_VIRT_QEMU_VERSION, ((QEMU_VERSION_MAJOR << 24) | (QEMU_VERSION_MINOR << 16) | (QEMU_VERSION_MICRO << 8))); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_PIC_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_PIC_BASE, VIRT_GF_PIC_MMIO_BASE, VIRT_GF_PIC_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_RTC_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_RTC_BASE, VIRT_GF_RTC_MMIO_BASE, VIRT_GF_RTC_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_TTY_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_TTY_BASE, VIRT_GF_TTY_MMIO_BASE, VIRT_GF_TTY_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_CTRL_BASE, + BOOTINFO2(param_ptr, BI_VIRT_CTRL_BASE, VIRT_CTRL_MMIO_BASE, VIRT_CTRL_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_VIRTIO_BASE, + BOOTINFO2(param_ptr, BI_VIRT_VIRTIO_BASE, VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE); if (kernel_cmdline) { - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, kernel_cmdline); } /* Pass seed to RNG. */ + param_rng_seed = param_ptr; qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + BOOTINFODATA(param_ptr, BI_RNG_SEED, rng_seed, sizeof(rng_seed)); /* load initrd */ @@ -265,13 +280,19 @@ static void virt_init(MachineState *machine) initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; } - BOOTINFO0(cs->as, parameters_base, BI_LAST); + BOOTINFO0(param_ptr, BI_LAST); + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, + parameters_base, cs->as); + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob); + g_free(param_blob); } } -- 2.37.3 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2022-10-24 11:03 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-10-14 7:23 [PULL 0/2] M68k for 7.2 patches Laurent Vivier 2022-10-14 7:23 ` [PULL 1/2] m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED Laurent Vivier 2022-10-14 7:23 ` [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot Laurent Vivier 2022-10-16 19:50 ` [PULL 0/2] M68k for 7.2 patches Stefan Hajnoczi 2022-10-17 3:56 ` Jason A. Donenfeld via 2022-10-17 7:25 ` Laurent Vivier 2022-10-17 20:29 ` [PATCH v4] m68k: write bootinfo as rom section and re-randomize on reboot Jason A. Donenfeld 2022-10-21 19:25 ` Laurent Vivier 2022-10-22 6:41 ` Richard Henderson 2022-10-23 19:09 ` Jason A. Donenfeld -- strict thread matches above, loose matches on Subject: below -- 2022-10-22 9:17 [PULL 0/2] M68k for 7.2 patches Laurent Vivier 2022-10-22 9:17 ` [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot Laurent Vivier 2022-10-24 8:58 [PULL 0/2] M68k for 7.2 patches Laurent Vivier 2022-10-24 8:58 ` [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot Laurent Vivier
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).