aboutsummaryrefslogtreecommitdiff
path: root/hw/m68k/virt.c
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2022-10-23 21:13:41 +0200
committerLaurent Vivier <laurent@vivier.eu>2022-10-24 10:47:14 +0200
commit281ac13ecedf8bfe1b83e566f39cb5683e553cb6 (patch)
tree06c9f71d6fc14cde5df9d39d523a4cee919b74a2 /hw/m68k/virt.c
parent693869a66ed7b49f2c790d88a25fc3d0ec791e0c (diff)
downloadqemu-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/virt.c')
-rw-r--r--hw/m68k/virt.c51
1 files changed, 36 insertions, 15 deletions
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index f7b903e..89c4108 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);
}
}