diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2022-10-23 21:13:41 +0200 |
---|---|---|
committer | Laurent Vivier <laurent@vivier.eu> | 2022-10-24 10:47:14 +0200 |
commit | 281ac13ecedf8bfe1b83e566f39cb5683e553cb6 (patch) | |
tree | 06c9f71d6fc14cde5df9d39d523a4cee919b74a2 /hw/m68k/q800.c | |
parent | 693869a66ed7b49f2c790d88a25fc3d0ec791e0c (diff) | |
download | qemu-281ac13ecedf8bfe1b83e566f39cb5683e553cb6.zip qemu-281ac13ecedf8bfe1b83e566f39cb5683e553cb6.tar.gz qemu-281ac13ecedf8bfe1b83e566f39cb5683e553cb6.tar.bz2 |
m68k: write bootinfo as rom section and re-randomize on reboot
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>
Diffstat (limited to 'hw/m68k/q800.c')
-rw-r--r-- | hw/m68k/q800.c | 71 |
1 files changed, 51 insertions, 20 deletions
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index a4590c2..e09e244 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 */ |