On Wed, 19 Jun 2024 11:21:14 +0100 John Levon <john.le...@nutanix.com> wrote:
> Older 32-bit Linux VMs (including Ubuntu 16.10) have issues with the > 64-bit pci io window, failing during boot with errors like: > > virtio_balloon virtio2: virtio: device uses modern interface but does not > have VIRTIO_F_VERSION_19734-565debf7b362 > virtio_net virtio0: virtio: device uses modern interface but does not have > VIRTIO_F_VERSION_1 > Virtio_scsi virtio1: virtio: device uses modern interface but does not have > VIRTIO_F_VERSION_1 above aren't exactly indicate 64-bit MMIO window as culprit Can you provide more data on what exactly goes wrong and where? Does adding 'realloc' option to guest kernel CLI help? > Gave up waiting for root device. Common problems: > - Boot args (cat /proc/cmdline) > - Check rootdelay= (did the system wait long enough?) > - Check root= (did the system wait for the right device?) > - Missing modules (cat /proc/modules; ls /dev) > ALERT! /dev/disk/by-uuid/86859879-3f17-443d-a226-077c435291e2 does not exist. > Dropping to a shell! > > Be a bit more conservative, and only enable the window by default when > the ram size extends beyond 64G - a 32-bit guest using PAE cannot > address beyond that anyway. Due to the mmio window this translates > to an effective working configuration limit of 62G/63G, depending on > machine type. > > Fixes: 96a8d130 ("be less conservative with the 64bit pci io window") > Signed-off-by: John Levon <john.le...@nutanix.com> > --- > src/fw/paravirt.c | 28 ++++++++++++++++++++++++---- > src/fw/paravirt.h | 1 + > src/fw/pciinit.c | 6 +++++- > 3 files changed, 30 insertions(+), 5 deletions(-) > > diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c > index 3ad9094b..5b0f191b 100644 > --- a/src/fw/paravirt.c > +++ b/src/fw/paravirt.c > @@ -29,11 +29,14 @@ > #include "stacks.h" // yield > > #define MEM_4G (0x100000000ULL) > +#define MEM_64G (16 * 0x100000000ULL) > > // Amount of continuous ram under 4Gig > u32 RamSize; > // Amount of continuous ram >4Gig > u64 RamSizeOver4G; > +// Amount of continuous ram >64Gig > +u64 RamSizeOver64G; > // physical address space bits > u8 CPUPhysBits; > // 64bit processor > @@ -591,8 +594,12 @@ qemu_cfg_e820(void) > | ((u32)rtc_read(CMOS_MEM_HIGHMEM_MID) << 24) > | ((u64)rtc_read(CMOS_MEM_HIGHMEM_HIGH) << 32)); > RamSizeOver4G = high; > + RamSizeOver64G = 0; > + if (high + MEM_4G > MEM_64G) > + RamSizeOver64G = high + MEM_4G - MEM_64G; > e820_add(MEM_4G, high, E820_RAM); > dprintf(1, "RamSizeOver4G: 0x%016llx [cmos]\n", RamSizeOver4G); > + dprintf(1, "RamSizeOver64G: 0x%016llx [cmos]\n", RamSizeOver64G); > } > > // Populate romfile entries for legacy fw_cfg ports (that predate the > @@ -774,19 +781,32 @@ static int qemu_early_e820(void) > e820_add(table.address, table.length, table.type); > dprintf(1, "qemu/e820: addr 0x%016llx len 0x%016llx [RAM]\n", > table.address, table.length); > + // address below 4g? > if (table.address < MEM_4G) { > - // below 4g > if (RamSize < table.address + table.length) > RamSize = table.address + table.length; > } else { > - // above 4g > - if (RamSizeOver4G < table.address + table.length - MEM_4G) > - RamSizeOver4G = table.address + table.length - MEM_4G; > + u64 table_end = table.address + table.length; > + > + /* > + * Note that this would ignore any span that crosses the 4G > + * boundary. For RamSizeOver64G, we do account for any spans > + * that cross the 64G boundary. > + */ > + if (RamSizeOver4G < table_end - MEM_4G) > + RamSizeOver4G = table_end - MEM_4G; > + > + // crosses 64G ? > + if (table_end > MEM_64G) { > + if (RamSizeOver64G < table_end - MEM_64G) > + RamSizeOver64G = table_end - MEM_64G; > + } > } > } > } > > dprintf(1, "qemu/e820: RamSize: 0x%08x\n", RamSize); > dprintf(1, "qemu/e820: RamSizeOver4G: 0x%016llx\n", RamSizeOver4G); > + dprintf(1, "qemu/e820: RamSizeOver64G: 0x%016llx\n", RamSizeOver64G); > return 1; > } > diff --git a/src/fw/paravirt.h b/src/fw/paravirt.h > index 62a2cd07..b56e96e8 100644 > --- a/src/fw/paravirt.h > +++ b/src/fw/paravirt.h > @@ -30,6 +30,7 @@ typedef struct QemuCfgDmaAccess { > > extern u32 RamSize; > extern u64 RamSizeOver4G; > +extern u64 RamSizeOver64G; > extern int PlatformRunningOn; > extern u8 CPUPhysBits; > extern u8 CPULongMode; > diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c > index 0395fdbf..1247eb12 100644 > --- a/src/fw/pciinit.c > +++ b/src/fw/pciinit.c > @@ -1197,7 +1197,11 @@ pci_setup(void) > } > } > > - if (CPUPhysBits >= 36 && CPULongMode && RamSizeOver4G) { > + /* > + * Only enable this if we exceed 64G, as some older 32-bit Linux VMs > cannot > + * handle the 64-bit window correctly. > + */ > + if (CPUPhysBits >= 36 && CPULongMode && RamSizeOver64G) { > dprintf(1, "enabling 64-bit pci mmio window\n"); > pci_pad_mem64 = 1; > } _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-le...@seabios.org