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

Reply via email to