From patchwork Fri Oct 14 07:23:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 13006717 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 65449C4332F for ; Fri, 14 Oct 2022 07:26:51 +0000 (UTC) Received: from localhost ([::1]:40228 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ojF5m-0002de-5O for qemu-devel@archiver.kernel.org; Fri, 14 Oct 2022 03:26:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36848) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ojF3A-0008On-7p for qemu-devel@nongnu.org; Fri, 14 Oct 2022 03:24:13 -0400 Received: from mout.kundenserver.de ([212.227.17.10]:41751) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ojF37-0004rs-EJ for qemu-devel@nongnu.org; Fri, 14 Oct 2022 03:24:08 -0400 Received: from quad ([82.142.8.70]) by mrelayeu.kundenserver.de (mreue108 [212.227.15.183]) with ESMTPSA (Nemesis) id 1MYNS0-1ofViW1Y3u-00VRlF; Fri, 14 Oct 2022 09:23:58 +0200 From: Laurent Vivier To: qemu-devel@nongnu.org Cc: Laurent Vivier , "Jason A. Donenfeld" , Geert Uytterhoeven Subject: [PULL 1/2] m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED Date: Fri, 14 Oct 2022 09:23:55 +0200 Message-Id: <20221014072356.2075517-2-laurent@vivier.eu> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221014072356.2075517-1-laurent@vivier.eu> References: <20221014072356.2075517-1-laurent@vivier.eu> MIME-Version: 1.0 X-Provags-ID: V03:K1:OtVz0zF8+/DJF7qgTPHVihbqtIASO/fHtKo/tgQj0NJrOeCBT8E fQCJCwye7IxU3tJ98HvMCGr4AqPHeovyp4qd8hQY+RKKKAFEkUbo16DBe1c6CzqGYHsIPnh 9yZSII4Bz0YSMEFW9BihLBSpy0SGQeyTOGxOkimshRZvqmgl5e/AfM1rIn5HBU7zY4OIj2O nih9p84KM+FwgTe5IQ8ZA== X-UI-Out-Filterresults: notjunk:1;V03:K0:E4C/QbJ3gJI=:PPwAjOgQYtVYe99lumNUzP E3urka2bqxXpEcVeiWLhVxaQQ6OEUpwO5ZIqaxPpiHcerTpSd1HHunZDiU32OoWJuF5NbEcHg SYtTsYXaxB5vuCBXgrhBecVcFS00gaY2IsHHJYU4gDG94XzPrF2NKYBCb2LSQGwOkOoKNissh MQGv0WWUjfIHCR6YeUgqOa2i8scKhKSwS7Xc6pcgLGt0WRU0BYRK5k2B2nUp9BOscABdvE2VZ WoPbnS7fBXStBHu8c8QNy95l7THXYEJ8HefOtnHCZMTmHGpp+ttMjvU1mcNzliYlrimhyd9SI ZONw5eB5Hy1Yr40u+D6sv90m/fy+sLVL1wbdOd4nTklBzF06QrVq8FeNyTmFkEqm1bNDZPScD AzXs2MIhWaN9I6YHcpyp1sUSaetqRISv1nzo+JJ7md0V19vdGdcuq4UVbmaTKZflQmabtvIvs xwAWPyN230tK0xoOjRilHqFLuFpaO947DAkZfUezQnAFTY0ubY7fMgKEE+D/ueM/Y/PE1VF6i /TdPLVy4je5762tmG+hGDd2J+l+LG/Q7/ZQ2XgPlVmM3Crjq00wS0l9Zvi6jBSR6Keg603TSV jVAoFwd2XVpKpea0M2HkYleQgqpvb9TxUxXgGZeoPGg9wvPQvtQUDvfaLjU08INpOU9wk1HWB K3lS6tIQrAZRrDs+6z47rJ8WoYuFStCc5xm1iyELXXVvMAKaVZ/xcy2jFUxb9cTUGaNGpukkd ADo6l0cCOrVNO46jlPCTvahUIv1PvP7WP7lH//x4li41hCAUDDoWVzJh5P3HAA9snZcmKM4wo eShv3Al Received-SPF: none client-ip=212.227.17.10; envelope-from=laurent@vivier.eu; helo=mout.kundenserver.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Jason A. Donenfeld" 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 Cc: Laurent Vivier Link: https://lore.kernel.org/lkml/20220923170340.4099226-3-Jason@zx2c4.com/ Signed-off-by: Jason A. Donenfeld Message-Id: <20220926113900.1256630-1-Jason@zx2c4.com> [lv: s/^I/ /g] Signed-off-by: Laurent Vivier --- 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) { From patchwork Fri Oct 14 07:23:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 13006718 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 88E9EC433FE for ; Fri, 14 Oct 2022 07:26:53 +0000 (UTC) Received: from localhost ([::1]:40232 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ojF5o-0002ht-C2 for qemu-devel@archiver.kernel.org; Fri, 14 Oct 2022 03:26:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36838) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ojF39-0008Nx-0c for qemu-devel@nongnu.org; Fri, 14 Oct 2022 03:24:07 -0400 Received: from mout.kundenserver.de ([217.72.192.74]:54311) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ojF36-0004rz-HW for qemu-devel@nongnu.org; Fri, 14 Oct 2022 03:24:06 -0400 Received: from quad ([82.142.8.70]) by mrelayeu.kundenserver.de (mreue108 [212.227.15.183]) with ESMTPSA (Nemesis) id 1MHG0U-1owUbW3Z7A-00DEO7; Fri, 14 Oct 2022 09:23:59 +0200 From: Laurent Vivier To: qemu-devel@nongnu.org Cc: Laurent Vivier , "Jason A. Donenfeld" , Geert Uytterhoeven Subject: [PULL 2/2] m68k: write bootinfo as rom section and re-randomize on reboot Date: Fri, 14 Oct 2022 09:23:56 +0200 Message-Id: <20221014072356.2075517-3-laurent@vivier.eu> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221014072356.2075517-1-laurent@vivier.eu> References: <20221014072356.2075517-1-laurent@vivier.eu> MIME-Version: 1.0 X-Provags-ID: V03:K1:wxfD0nIF1C/fq5EFOcT7zgwqhdhKekblcwRBy2oZF6gUyUXjra3 2zk783fSiExibxJ6u0kqi7LAOvXsW+kXsnTzuwVy+izElf/FwOuz4Pkl9+6aw7CrD6DKfjz dEOlQ3Cu2iHWnf04wdOFfnYj4k2TZs3/bm37cuvyj7cVUjJ4FcW055bQTmbq2Rwis+XumS0 O89bkJQT3s1vgjbQI/byQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:CgQ9RlYtODM=:4TKYyUqX8YEP2UsqQFNqLz qGa+MBmsSU9AJJbHtfADlb0Q3Y0j/5oQnvebjIZJfXBn0P711aLo6xRO4VoTxNY4OMsxs4LYw d2ckEcricTJFXfpi4AQ70tN94LsrpaG/913MbK02gHhPzQEj+FzoTzt0qtjLQ6QGoIu+l5FnL MnJ2xg8W8R2ov+m9pBwpowzEcTmyEgDg8eb5buRxLaKQJbRFuq0eUs+NbFzwx8KfJfoMdBsOX 2+w79MndiJaE0g7GLeop0tCtgfKjuG+pzMhjszQEdy7t9dgJX8hhgsM44UCGSHhSFoX+ohVNv dMpjCySXhdE07rW//wGrshM4SwFGI3UqoPpbofNwV5au0GnK5WnO+KdXOU/wEsGfP2wCKtnaZ xPJMDpZILmXl2AECjwu+RJRtTYWZN/bF71ap0Q+FjC6SkxXR3aPOyWN79eSXUf0ZZ/5g3CYxq Ireg4KTCuew6QzJK7+JOEzPa7Dh6bqS1hFUOLpuNLdWyRmh6L2Hig2JfXYdHGWRYxER6D1fLk rsdYsc06gvcZkEAZ99Mb/kxgQNfQV3K/UQ3g4Fk4de8DfLyoAwp6P4RqdQ0DFe0H12r8lSJ7w nQ9Z/SRi3OU38gzI/oCHvOZLpS/iZcPTiP05rB5TmRXjViOPdL0mHQGsEZrn+pf/ztWvdsjEk y7GIJyNSw2NIvsRJeLdf+P/NA/0sHG2FcOZXidXojYiAlYx/EWB0oq6YPTDwAzq9nFbLu5C2K mAwhzYj1IUYiVOa5NMoY+fIfJCl9gdlf8u3J0l+An/75BCLAyi63UQnVUvv0z+/MNThIJHekN NN+xHbc Received-SPF: none client-ip=217.72.192.74; envelope-from=laurent@vivier.eu; helo=mout.kundenserver.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Jason A. Donenfeld" 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 Cc: Laurent Vivier Signed-off-by: Jason A. Donenfeld Message-Id: <20221003110221.971024-1-Jason@zx2c4.com> Signed-off-by: Laurent Vivier --- 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); } }