On Mon, Jun 13, 2022 at 10:10 PM Jason A. Donenfeld <ja...@zx2c4.com> wrote: > > If the FDT contains /chosen/rng-seed, then the Linux RNG will use it to > initialize early. Set this using the usual guest random number > generation function. This is confirmed to successfully initialize the > RNG on Linux 5.19-rc2.
I have a Linux 5.8 test case that is failing due to this patch. The command line is: qemu-system-riscv64 \ -machine virt -m 64M \ -cpu rv64,mmu=false \ -serial mon:stdio -serial null -nographic \ -append "root=/dev/vda rw highres=off console=ttyS0 mem=1G ip=dhcp earlycon=sbi" \ -device virtio-net-device,netdev=net0,mac=52:54:00:12:34:02 \ -netdev user,id=net0 \ -object rng-random,filename=/dev/urandom,id=rng0 \ -device virtio-rng-device,rng=rng0 \ -smp 1 \ -d guest_errors \ -kernel ./images/qemuriscv64/nommu-Image \ -drive id=disk0,file=./images/qemuriscv64/nommu-rootfs.ext2,if=none,format=raw \ -device virtio -blk-device,drive=disk0 \ -bios none The working log (before this commit) is: [ 0.000000] Linux version 5.8.0 (alistair@risc6-mainframe) (riscv64-elf-gcc (Arch Linux Repositories) 10.1.0, GNU ld (GNU Binutils) 2.34) #2 SMP Wed Sep 30 12:02:11 PDT 2020 [ 0.000000] earlycon: uart8250 at MMIO 0x0000000010000000 (options '115200n8') [ 0.000000] printk: bootconsole [uart8250] enabled [ 0.000000] Zone ranges: [ 0.000000] DMA32 [mem 0x0000000080000000-0x0000000083ffffff] [ 0.000000] Normal empty [ 0.000000] Movable zone start for each node [ 0.000000] Early memory node ranges [ 0.000000] node 0: [mem 0x0000000080000000-0x0000000083ffffff] [ 0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x0000000083ffffff] [ 0.000000] riscv: ISA extensions abcdefhimnrs [ 0.000000] riscv: ELF capabilities acdfim [ 0.000000] percpu: max_distance=0xc000 too large for vmalloc space 0x0 [ 0.000000] percpu: Embedded 12 pages/cpu s18528 r0 d30624 u49152 [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 16160 [ 0.000000] Kernel command line: root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0 [ 0.000000] Dentry cache hash table entries: 8192 (order: 4, 65536 bytes, linear) [ 0.000000] Inode-cache hash table entries: 4096 (order: 3, 32768 bytes, linear) [ 0.000000] Sorting __ex_table... [ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off [ 0.000000] Memory: 62472K/65536K available (1369K kernel code, 144K rwdata, 238K rodata, 106K init, 134K bss, 3064K reserved, 0K cma-reserved) [ 0.000000] rcu: Hierarchical RCU implementation. [ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1. [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies. [ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1 [ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0 [ 0.000000] riscv-intc: 64 local interrupts mapped sifive_plic_read: Invalid register read 0x200c sifive_plic_write: Invalid enable write 0x200c [ 0.000000] plic: plic@c000000: mapped 96 interrupts with 1 handlers for 2 contexts. [ 0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [0] [ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x24e6a1710, max_idle_ns: 440795202120 ns [ 0.000106] sched_clock: 64 bits at 10MHz, resolution 100ns, wraps every 4398046511100ns [ 0.002649] Console: colour dummy device 80x25 [ 0.003599] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000) [ 0.003960] pid_max: default: 4096 minimum: 301 [ 0.004718] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear) [ 0.004922] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear) [ 0.022781] rcu: Hierarchical SRCU implementation. [ 0.024374] smp: Bringing up secondary CPUs ... [ 0.024583] smp: Brought up 1 node, 1 CPU [ 0.030450] devtmpfs: initialized [ 0.035183] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns [ 0.035600] futex hash table entries: 16 (order: -2, 1024 bytes, linear) [ 0.055175] clocksource: Switched to clocksource riscv_clocksource [ 0.073226] workingset: timestamp_bits=62 max_order=14 bucket_order=0 [ 0.078326] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled [ 0.082509] printk: console [ttyS0] disabled [ 0.083408] 10000000.uart: ttyS0 at MMIO 0x10000000 (irq = 2, base_baud = 230400) is a 16550A [ 0.084805] printk: console [ttyS0] enabled [ 0.084805] printk: console [ttyS0] enabled [ 0.085242] printk: bootconsole [uart8250] disabled [ 0.085242] printk: bootconsole [uart8250] disabled virtio_mmio_write: attempt to write guest features with guest_features_sel > 0 in legacy mode [ 0.095810] virtio_blk virtio2: [vda] 122880 512-byte logical blocks (62.9 MB/60.0 MiB) [ 0.096155] vda: detected capacity change from 0 to 62914560 [ 0.099882] random: get_random_bytes called from 0x0000000080020c8c with crng_init=0 [ 0.120690] EXT4-fs (vda): warning: mounting unchecked fs, running e2fsck is recommended [ 0.160540] EXT4-fs (vda): mounted filesystem without journal. Opts: (null) [ 0.160910] VFS: Mounted root (ext4 filesystem) on device 254:0. [ 0.162645] devtmpfs: mounted [ 0.171902] Freeing unused kernel memory: 104K [ 0.172061] This architecture does not have kernel memory protection. [ 0.172387] Run /sbin/init as init process [ 0.174104] Run /etc/init as init process [ 0.174534] Run /bin/init as init process [ 0.174964] Run /bin/sh as init process BusyBox v1.32.0 (2020-09-24 13:17:53 PDT) hush - the humble shell Enter 'help' for a list of built-in commands. After applying this commit all I see is: Invalid read at addr 0x0, size 8, region '(null)', reason: rejected It looks like the rng-seed property is causing failures on older kernels. Alistair > > Cc: Alistair Francis <alistair.fran...@wdc.com> > Signed-off-by: Jason A. Donenfeld <ja...@zx2c4.com> > --- > hw/riscv/virt.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c > index bc424dd2f5..368a723bf6 100644 > --- a/hw/riscv/virt.c > +++ b/hw/riscv/virt.c > @@ -21,6 +21,7 @@ > #include "qemu/osdep.h" > #include "qemu/units.h" > #include "qemu/error-report.h" > +#include "qemu/guest-random.h" > #include "qapi/error.h" > #include "hw/boards.h" > #include "hw/loader.h" > @@ -998,6 +999,7 @@ static void create_fdt(RISCVVirtState *s, const > MemMapEntry *memmap, > MachineState *mc = MACHINE(s); > uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1; > uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1; > + uint8_t rng_seed[32]; > > if (mc->dtb) { > mc->fdt = load_device_tree(mc->dtb, &s->fdt_size); > @@ -1046,6 +1048,10 @@ update_bootargs: > if (cmdline && *cmdline) { > qemu_fdt_setprop_string(mc->fdt, "/chosen", "bootargs", cmdline); > } > + > + /* Pass seed to RNG. */ > + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); > + qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed", rng_seed, > sizeof(rng_seed)); > } > > static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem, > -- > 2.35.1 > >