mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
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>
This commit is contained in:
parent
693869a66e
commit
281ac13ece
3 changed files with 110 additions and 58 deletions
|
@ -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;
|
||||
param_ptr = param_blob;
|
||||
|
||||
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,
|
||||
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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue