Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock X-Debbugs-Cc: pkg-qemu-de...@lists.alioth.debian.org
Please unblock package seabios [ Reason ] This debian release syncronizes with the upstream stable/bugfix release of 1.16.2. Previous debian release of this package had 1.16.1 difference as a patch because upstream forgot to publish the tarball. 1.16.2-1 has exactly the same stuff the previous debian revision had (1.16.1), plus two more changes from upstream stable/bugfix release 1.16.2. One of the changes is a bugfix for usb hid devices init (which I've hit myself but thought it's some difficult to diagnose QEMU bug). It's definitely worth to have this one on bookworm. The second change is not strictly necessary for bookworm, but I thought there's no good reason to remove it from the upstream stable/bugfix release. It is related to the way how seabios detects Xen, for the rare HVM Xen domU. This change will be useful for more recent qemu (8.0+) though. [ Impact ] There's a relatively small issue with USB HID devices init which can only trigger in certain configurations, which will be unfixed. Plus it will be just a bit more work for the further package maintenance. [ Tests ] I tested the new bios package locally with both qemu (bookworm one and the next version), *and* with actual Xen HVM domU, the change does not break my setups, but allows new qemu to run Xen HVM domains too. Upstream has it integrated into the QEMU CI tests. [ Risks ] I don't see much risks with this change. All involved code paths are quite well tested. [ Checklist ] [X] all changes are documented in the d/changelog [X] I reviewed all changes and I approve them [X] attach debdiff against the package in testing [ Other info ] Unfortunately the debdiff isn't very useful due to 1.16.1=>upstream source move. So I'm also adding the diff with patches applied, which shows only the 2 changes I mentioned above. First comes the diff, next comes the debdiff. unblock seabios/1.16.2-1 ====== begin diff ====== --- seabios-1.16.0/debian/changelog 2022-12-01 17:06:24.000000000 +0300 +++ seabios-1.16.2/debian/changelog 2023-04-11 16:08:25.000000000 +0300 @@ -1,3 +1,14 @@ +seabios (1.16.2-1) unstable; urgency=medium + + * sync with upstream stable 1.16.2 release (rel-1.16.2 tag): + this brings up to the exactly same state as our rel-1.16.1.patch + did, and brings up 2 more fixes: + - usb: fix wrong init of keyboard/mouse's if first interface + is not boot protocol + - xen: require Xen info structure at 0x1000 to detect Xen + + -- Michael Tokarev <m...@tls.msk.ru> Tue, 11 Apr 2023 16:08:25 +0300 + seabios (1.16.0-5) unstable; urgency=medium * d/rules: vgabios.bin compatibility symlink for qemu (Closes: #1024382) diff -u -r -x '*.pc/*' seabios-1.16.0/debian/patches/series seabios-1.16.2/debian/patches/series --- seabios-1.16.0/debian/patches/series 2022-12-01 17:06:12.000000000 +0300 +++ seabios-1.16.2/debian/patches/series 2023-04-11 16:07:44.000000000 +0300 @@ -1,2 +1 @@ nogitversion.patch -rel-1.16.1.patch diff -u -r -x '*.pc/*' seabios-1.16.0/src/fw/xen.c seabios-1.16.2/src/fw/xen.c --- seabios-1.16.0/src/fw/xen.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/fw/xen.c 2023-02-02 04:14:39.000000000 +0300 @@ -40,16 +40,25 @@ u32 e820_nr; } PACKED; -static void validate_info(struct xen_seabios_info *t) +static struct xen_seabios_info *validate_info(void) { - if ( memcmp(t->signature, "XenHVMSeaBIOS", 14) ) - panic("Bad Xen info signature\n"); + struct xen_seabios_info *t = (void *)INFO_PHYSICAL_ADDRESS; - if ( t->length < sizeof(struct xen_seabios_info) ) - panic("Bad Xen info length\n"); + if ( memcmp(t->signature, "XenHVMSeaBIOS", 14) ) { + dprintf(1, "Bad Xen info signature\n"); + return NULL; + } + + if ( t->length < sizeof(struct xen_seabios_info) ) { + dprintf(1, "Bad Xen info length\n"); + return NULL; + } - if (checksum(t, t->length) != 0) - panic("Bad Xen info checksum\n"); + if (checksum(t, t->length) != 0) { + dprintf(1, "Bad Xen info checksum\n"); + return NULL; + } + return t; } void xen_preinit(void) @@ -86,7 +95,10 @@ dprintf(1, "No Xen hypervisor found.\n"); return; } - PlatformRunningOn = PF_QEMU|PF_XEN; + if (validate_info()) + PlatformRunningOn = PF_QEMU|PF_XEN; + else + dprintf(1, "Not enabling Xen support due to lack of Xen info\n"); } static int hypercall_xen_version( int cmd, void *arg) @@ -122,10 +134,14 @@ void xen_biostable_setup(void) { - struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS; - void **tables = (void*)info->tables; + struct xen_seabios_info *info = validate_info(); + void **tables; int i; + if (!info) + panic("Xen info corrupted\n"); + + tables = (void*)info->tables; dprintf(1, "xen: copy BIOS tables...\n"); for (i=0; i<info->tables_nr; i++) copy_table(tables[i]); @@ -136,12 +152,15 @@ void xen_ramsize_preinit(void) { int i; - struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS; - struct e820entry *e820 = (struct e820entry *)info->e820; - validate_info(info); + struct xen_seabios_info *info = validate_info(); + struct e820entry *e820; + + if (!info) + panic("Xen info corrupted\n"); dprintf(1, "xen: copy e820...\n"); + e820 = (struct e820entry *)info->e820; for (i = 0; i < info->e820_nr; i++) { struct e820entry *e = &e820[i]; e820_add(e->start, e->size, e->type); --- seabios-1.16.0/src/hw/usb.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/hw/usb.c 2023-02-02 04:14:39.000000000 +0300 @@ -372,17 +372,19 @@ void *config_end = (void*)config + config->wTotalLength; struct usb_interface_descriptor *iface = (void*)(&config[1]); for (;;) { - if (!num_iface-- || (void*)iface + iface->bLength > config_end) + if (!num_iface || (void*)iface + iface->bLength > config_end) // Not a supported device. goto fail; - if (iface->bDescriptorType == USB_DT_INTERFACE - && (iface->bInterfaceClass == USB_CLASS_HUB + if (iface->bDescriptorType == USB_DT_INTERFACE) { + num_iface--; + if (iface->bInterfaceClass == USB_CLASS_HUB || (iface->bInterfaceClass == USB_CLASS_MASS_STORAGE && (iface->bInterfaceProtocol == US_PR_BULK || iface->bInterfaceProtocol == US_PR_UAS)) || (iface->bInterfaceClass == USB_CLASS_HID - && iface->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT))) - break; + && iface->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT)) + break; + } iface = (void*)iface + iface->bLength; } --- seabios-1.16.0/src/hw/usb-hid.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/hw/usb-hid.c 2023-02-02 04:14:39.000000000 +0300 @@ -22,13 +22,13 @@ // Send USB HID protocol message. static int -set_protocol(struct usb_pipe *pipe, u16 val) +set_protocol(struct usb_pipe *pipe, u16 val, u16 inferface) { struct usb_ctrlrequest req; req.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; req.bRequest = HID_REQ_SET_PROTOCOL; req.wValue = val; - req.wIndex = 0; + req.wIndex = inferface; req.wLength = 0; return usb_send_default_control(pipe, &req, NULL); } @@ -76,9 +76,12 @@ } // Enable "boot" protocol. - int ret = set_protocol(usbdev->defpipe, 0); - if (ret) + int ret = set_protocol(usbdev->defpipe, 0, usbdev->iface->bInterfaceNumber); + if (ret) { + dprintf(3, "Failed to set boot protocol\n"); return -1; + } + // Periodically send reports to enable key repeat. ret = set_idle(usbdev->defpipe, KEYREPEATMS); if (ret) @@ -118,7 +121,7 @@ } // Enable "boot" protocol. - int ret = set_protocol(usbdev->defpipe, 0); + int ret = set_protocol(usbdev->defpipe, 0, usbdev->iface->bInterfaceNumber); if (ret) return -1; --- seabios-1.16.0/.version 2022-03-02 05:09:22.000000000 +0300 +++ seabios-1.16.2/.version 2023-03-16 12:56:04.000000000 +0300 @@ -1 +1 @@ -1.16.0 +1.16.2 ====== end diff ====== debdiff follows: diff -Nru seabios-1.16.0/debian/changelog seabios-1.16.2/debian/changelog --- seabios-1.16.0/debian/changelog 2022-12-01 17:06:24.000000000 +0300 +++ seabios-1.16.2/debian/changelog 2023-04-11 16:08:25.000000000 +0300 @@ -1,3 +1,14 @@ +seabios (1.16.2-1) unstable; urgency=medium + + * sync with upstream stable 1.16.2 release (rel-1.16.2 tag): + this brings up to the exactly same state as our rel-1.16.1.patch + did, and brings up 2 more fixes: + - usb: fix wrong init of keyboard/mouse's if first interface + is not boot protocol + - xen: require Xen info structure at 0x1000 to detect Xen + + -- Michael Tokarev <m...@tls.msk.ru> Tue, 11 Apr 2023 16:08:25 +0300 + seabios (1.16.0-5) unstable; urgency=medium * d/rules: vgabios.bin compatibility symlink for qemu (Closes: #1024382) diff -Nru seabios-1.16.0/debian/patches/rel-1.16.1.patch seabios-1.16.2/debian/patches/rel-1.16.1.patch --- seabios-1.16.0/debian/patches/rel-1.16.1.patch 2022-12-01 17:06:12.000000000 +0300 +++ seabios-1.16.2/debian/patches/rel-1.16.1.patch 1970-01-01 03:00:00.000000000 +0300 @@ -1,731 +0,0 @@ -Subject: rel-1.16.1 patches from git -From: Michael Tokarev <m...@tls.msk.ru> -Date: Tue, 29 Nov 2022 09:37:21 +0300 - -There's no published release of seabios version 1.16.1, -so let's pick the changes (there are just a few) as a -patch file. - -From d24f42b0d819ea473ae05b2f955b822d0126d901 Mon Sep 17 00:00:00 2001 -From: Volker Rümelin <vr_q...@t-online.de> -Date: Sat, 2 Apr 2022 20:28:38 +0200 -Subject: [PATCH 1/9] pci: refactor the pci_config_*() functions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Split out the Standard PCI Configuration Access Mechanism -pci_ioconfig_*() functions from the pci_config_*() functions. -The standard PCI CAM functions will be used in the next patch. - -Reviewed-by: Gerd Hoffmann <kra...@redhat.com> -Signed-off-by: Volker Rümelin <vr_q...@t-online.de> ---- - src/hw/pci.c | 54 ++++++++++++++++++++++++++++++++++++++++------------ - src/hw/pci.h | 12 +++++++++++- - 2 files changed, 53 insertions(+), 13 deletions(-) - -diff --git a/src/hw/pci.c b/src/hw/pci.c -index 3df1dae4..f13cbdea 100644 ---- a/src/hw/pci.c -+++ b/src/hw/pci.c -@@ -26,63 +26,93 @@ static u32 ioconfig_cmd(u16 bdf, u32 addr) - return 0x80000000 | (bdf << 8) | (addr & 0xfc); - } - -+void pci_ioconfig_writel(u16 bdf, u32 addr, u32 val) -+{ -+ outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -+ outl(val, PORT_PCI_DATA); -+} -+ - void pci_config_writel(u16 bdf, u32 addr, u32 val) - { - if (!MODESEGMENT && mmconfig) { - writel(mmconfig_addr(bdf, addr), val); - } else { -- outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -- outl(val, PORT_PCI_DATA); -+ pci_ioconfig_writel(bdf, addr, val); - } - } - -+void pci_ioconfig_writew(u16 bdf, u32 addr, u16 val) -+{ -+ outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -+ outw(val, PORT_PCI_DATA + (addr & 2)); -+} -+ - void pci_config_writew(u16 bdf, u32 addr, u16 val) - { - if (!MODESEGMENT && mmconfig) { - writew(mmconfig_addr(bdf, addr), val); - } else { -- outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -- outw(val, PORT_PCI_DATA + (addr & 2)); -+ pci_ioconfig_writew(bdf, addr, val); - } - } - -+void pci_ioconfig_writeb(u16 bdf, u32 addr, u8 val) -+{ -+ outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -+ outb(val, PORT_PCI_DATA + (addr & 3)); -+} -+ - void pci_config_writeb(u16 bdf, u32 addr, u8 val) - { - if (!MODESEGMENT && mmconfig) { - writeb(mmconfig_addr(bdf, addr), val); - } else { -- outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -- outb(val, PORT_PCI_DATA + (addr & 3)); -+ pci_ioconfig_writeb(bdf, addr, val); - } - } - -+u32 pci_ioconfig_readl(u16 bdf, u32 addr) -+{ -+ outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -+ return inl(PORT_PCI_DATA); -+} -+ - u32 pci_config_readl(u16 bdf, u32 addr) - { - if (!MODESEGMENT && mmconfig) { - return readl(mmconfig_addr(bdf, addr)); - } else { -- outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -- return inl(PORT_PCI_DATA); -+ return pci_ioconfig_readl(bdf, addr); - } - } - -+u16 pci_ioconfig_readw(u16 bdf, u32 addr) -+{ -+ outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -+ return inw(PORT_PCI_DATA + (addr & 2)); -+} -+ - u16 pci_config_readw(u16 bdf, u32 addr) - { - if (!MODESEGMENT && mmconfig) { - return readw(mmconfig_addr(bdf, addr)); - } else { -- outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -- return inw(PORT_PCI_DATA + (addr & 2)); -+ return pci_ioconfig_readw(bdf, addr); - } - } - -+u8 pci_ioconfig_readb(u16 bdf, u32 addr) -+{ -+ outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -+ return inb(PORT_PCI_DATA + (addr & 3)); -+} -+ - u8 pci_config_readb(u16 bdf, u32 addr) - { - if (!MODESEGMENT && mmconfig) { - return readb(mmconfig_addr(bdf, addr)); - } else { -- outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); -- return inb(PORT_PCI_DATA + (addr & 3)); -+ return pci_ioconfig_readb(bdf, addr); - } - } - -diff --git a/src/hw/pci.h b/src/hw/pci.h -index 01c51f70..ee6acafc 100644 ---- a/src/hw/pci.h -+++ b/src/hw/pci.h -@@ -32,6 +32,15 @@ static inline u16 pci_bus_devfn_to_bdf(int bus, u16 devfn) { - ; BDF >= 0 \ - ; BDF=pci_next(BDF, (BUS))) - -+// standard PCI configration access mechanism -+void pci_ioconfig_writel(u16 bdf, u32 addr, u32 val); -+void pci_ioconfig_writew(u16 bdf, u32 addr, u16 val); -+void pci_ioconfig_writeb(u16 bdf, u32 addr, u8 val); -+u32 pci_ioconfig_readl(u16 bdf, u32 addr); -+u16 pci_ioconfig_readw(u16 bdf, u32 addr); -+u8 pci_ioconfig_readb(u16 bdf, u32 addr); -+ -+// PCI configuration access using either PCI CAM or PCIe ECAM - void pci_config_writel(u16 bdf, u32 addr, u32 val); - void pci_config_writew(u16 bdf, u32 addr, u16 val); - void pci_config_writeb(u16 bdf, u32 addr, u8 val); -@@ -39,9 +48,10 @@ u32 pci_config_readl(u16 bdf, u32 addr); - u16 pci_config_readw(u16 bdf, u32 addr); - u8 pci_config_readb(u16 bdf, u32 addr); - void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on); --void pci_enable_mmconfig(u64 addr, const char *name); - u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap); - int pci_next(int bdf, int bus); -+ -+void pci_enable_mmconfig(u64 addr, const char *name); - int pci_probe_host(void); - void pci_reboot(void); - --- -2.30.2 - -From 01774004c7f7fdc9c1e8f1715f70d3b913f8d491 Mon Sep 17 00:00:00 2001 -From: Volker Rümelin <vr_q...@t-online.de> -Date: Sat, 2 Apr 2022 20:28:39 +0200 -Subject: [PATCH 2/9] reset: force standard PCI configuration access -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -After a reset of a QEMU -machine q35 guest, the PCI Express -Enhanced Configuration Mechanism is disabled and the variable -mmconfig no longer matches the configuration register PCIEXBAR -of the Q35 chipset. Until the variable mmconfig is reset to 0, -all pci_config_*() functions no longer work. - -The variable mmconfig is located in one of the read-only C-F -segments. To reset it the pci_config_*() functions are needed, -but they do not work. - -Replace all pci_config_*() calls with Standard PCI Configuration -Mechanism pci_ioconfig_*() calls until mmconfig is overwritten -with 0 by a fresh copy of the BIOS. - -This fixes - -In resume (status=0) -In 32bit resume -Attempting a hard reboot -Unable to unlock ram - bridge not found - -and a reset loop with QEMU -accel tcg. - -Signed-off-by: Volker Rümelin <vr_q...@t-online.de> ---- - src/fw/shadow.c | 14 +++++++------- - src/hw/pci.c | 27 +++++++++++++++++++++++++++ - src/hw/pci.h | 6 ++++++ - 3 files changed, 40 insertions(+), 7 deletions(-) - -diff --git a/src/fw/shadow.c b/src/fw/shadow.c -index 4c627a8f..8930616e 100644 ---- a/src/fw/shadow.c -+++ b/src/fw/shadow.c -@@ -32,8 +32,8 @@ __make_bios_writable_intel(u16 bdf, u32 pam0) - { - // Read in current PAM settings from pci config space - union pamdata_u pamdata; -- pamdata.data32[0] = pci_config_readl(bdf, ALIGN_DOWN(pam0, 4)); -- pamdata.data32[1] = pci_config_readl(bdf, ALIGN_DOWN(pam0, 4) + 4); -+ pamdata.data32[0] = pci_ioconfig_readl(bdf, ALIGN_DOWN(pam0, 4)); -+ pamdata.data32[1] = pci_ioconfig_readl(bdf, ALIGN_DOWN(pam0, 4) + 4); - u8 *pam = &pamdata.data8[pam0 & 0x03]; - - // Make ram from 0xc0000-0xf0000 writable -@@ -46,8 +46,8 @@ __make_bios_writable_intel(u16 bdf, u32 pam0) - pam[0] = 0x30; - - // Write PAM settings back to pci config space -- pci_config_writel(bdf, ALIGN_DOWN(pam0, 4), pamdata.data32[0]); -- pci_config_writel(bdf, ALIGN_DOWN(pam0, 4) + 4, pamdata.data32[1]); -+ pci_ioconfig_writel(bdf, ALIGN_DOWN(pam0, 4), pamdata.data32[0]); -+ pci_ioconfig_writel(bdf, ALIGN_DOWN(pam0, 4) + 4, pamdata.data32[1]); - - if (!ram_present) - // Copy bios. -@@ -59,7 +59,7 @@ __make_bios_writable_intel(u16 bdf, u32 pam0) - static void - make_bios_writable_intel(u16 bdf, u32 pam0) - { -- int reg = pci_config_readb(bdf, pam0); -+ int reg = pci_ioconfig_readb(bdf, pam0); - if (!(reg & 0x10)) { - // QEMU doesn't fully implement the piix shadow capabilities - - // if ram isn't backing the bios segment when shadowing is -@@ -125,8 +125,8 @@ make_bios_writable(void) - // At this point, statically allocated variables can't be written, - // so do this search manually. - int bdf; -- foreachbdf(bdf, 0) { -- u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID); -+ pci_ioconfig_foreachbdf(bdf, 0) { -+ u32 vendev = pci_ioconfig_readl(bdf, PCI_VENDOR_ID); - u16 vendor = vendev & 0xffff, device = vendev >> 16; - if (vendor == PCI_VENDOR_ID_INTEL - && device == PCI_DEVICE_ID_INTEL_82441) { -diff --git a/src/hw/pci.c b/src/hw/pci.c -index f13cbdea..8eda84b2 100644 ---- a/src/hw/pci.c -+++ b/src/hw/pci.c -@@ -157,6 +157,33 @@ u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap) - return 0; - } - -+// Helper function for pci_ioconfig_foreachbdf() macro - return next device -+int pci_ioconfig_next(int bdf, int bus) -+{ -+ if (pci_bdf_to_fn(bdf) == 0 -+ && (pci_ioconfig_readb(bdf, PCI_HEADER_TYPE) & 0x80) == 0) -+ // Last found device wasn't a multi-function device - skip to -+ // the next device. -+ bdf += 8; -+ else -+ bdf += 1; -+ -+ for (;;) { -+ if (pci_bdf_to_bus(bdf) != bus) -+ return -1; -+ -+ u16 v = pci_ioconfig_readw(bdf, PCI_VENDOR_ID); -+ if (v != 0x0000 && v != 0xffff) -+ // Device is present. -+ return bdf; -+ -+ if (pci_bdf_to_fn(bdf) == 0) -+ bdf += 8; -+ else -+ bdf += 1; -+ } -+} -+ - // Helper function for foreachbdf() macro - return next device - int - pci_next(int bdf, int bus) -diff --git a/src/hw/pci.h b/src/hw/pci.h -index ee6acafc..b2f5baf4 100644 ---- a/src/hw/pci.h -+++ b/src/hw/pci.h -@@ -27,6 +27,11 @@ static inline u16 pci_bus_devfn_to_bdf(int bus, u16 devfn) { - return (bus << 8) | devfn; - } - -+#define pci_ioconfig_foreachbdf(BDF, BUS) \ -+ for (BDF=pci_ioconfig_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \ -+ ; BDF >= 0 \ -+ ; BDF=pci_ioconfig_next(BDF, (BUS))) -+ - #define foreachbdf(BDF, BUS) \ - for (BDF=pci_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \ - ; BDF >= 0 \ -@@ -39,6 +44,7 @@ void pci_ioconfig_writeb(u16 bdf, u32 addr, u8 val); - u32 pci_ioconfig_readl(u16 bdf, u32 addr); - u16 pci_ioconfig_readw(u16 bdf, u32 addr); - u8 pci_ioconfig_readb(u16 bdf, u32 addr); -+int pci_ioconfig_next(int bdf, int bus); - - // PCI configuration access using either PCI CAM or PCIe ECAM - void pci_config_writel(u16 bdf, u32 addr, u32 val); --- -2.30.2 - -From 3b91e8e9fe93d5ff7edf17f984c401f9e6ba55fe Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann <kra...@redhat.com> -Date: Mon, 25 Apr 2022 09:20:02 +0200 -Subject: [PATCH 3/9] malloc: use variable for ZoneHigh size - -Use the variable highram_size instead of the BUILD_MAX_HIGHTABLE #define -for the ZoneHigh size. Initialize the new variable with the old #define, -so behavior does not change. - -This allows to easily adjust the ZoneHigh size at runtime in a followup -patch. - -Signed-off-by: Gerd Hoffmann <kra...@redhat.com> ---- - src/malloc.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/src/malloc.c b/src/malloc.c -index 3733855c..ecd8c9ac 100644 ---- a/src/malloc.c -+++ b/src/malloc.c -@@ -422,7 +422,8 @@ malloc_preinit(void) - e820_add(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); - - // Populate temp high ram -- u32 highram = 0; -+ u32 highram_start = 0; -+ u32 highram_size = BUILD_MAX_HIGHTABLE; - int i; - for (i=e820_count-1; i>=0; i--) { - struct e820entry *en = &e820_list[i]; -@@ -432,10 +433,10 @@ malloc_preinit(void) - if (en->type != E820_RAM || end > 0xffffffff) - continue; - u32 s = en->start, e = end; -- if (!highram) { -- u32 newe = ALIGN_DOWN(e - BUILD_MAX_HIGHTABLE, MALLOC_MIN_ALIGN); -+ if (!highram_start) { -+ u32 newe = ALIGN_DOWN(e - highram_size, MALLOC_MIN_ALIGN); - if (newe <= e && newe >= s) { -- highram = newe; -+ highram_start = newe; - e = newe; - } - } -@@ -444,9 +445,9 @@ malloc_preinit(void) - - // Populate regions - alloc_add(&ZoneTmpLow, BUILD_STACK_ADDR, BUILD_EBDA_MINIMUM); -- if (highram) { -- alloc_add(&ZoneHigh, highram, highram + BUILD_MAX_HIGHTABLE); -- e820_add(highram, BUILD_MAX_HIGHTABLE, E820_RESERVED); -+ if (highram_start) { -+ alloc_add(&ZoneHigh, highram_start, highram_start + highram_size); -+ e820_add(highram_start, highram_size, E820_RESERVED); - } - } - --- -2.30.2 - -From dc88f9b72df52b22c35b127b80c487e0b6fca4af Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann <kra...@redhat.com> -Date: Mon, 25 Apr 2022 09:25:31 +0200 -Subject: [PATCH 4/9] malloc: use large ZoneHigh when there is enough memory - -In case there is enough memory installed use a large ZoneHigh. - -Signed-off-by: Gerd Hoffmann <kra...@redhat.com> ---- - src/config.h | 3 ++- - src/malloc.c | 14 +++++++++----- - 2 files changed, 11 insertions(+), 6 deletions(-) - -diff --git a/src/config.h b/src/config.h -index 93c8dbc2..9abe355b 100644 ---- a/src/config.h -+++ b/src/config.h -@@ -17,7 +17,8 @@ - // Maximum number of map entries in the e820 map - #define BUILD_MAX_E820 32 - // Space to reserve in high-memory for tables --#define BUILD_MAX_HIGHTABLE (256*1024) -+#define BUILD_MIN_HIGHTABLE (256*1024) -+#define BUILD_MAX_HIGHTABLE (16*1024*1024) - // Largest supported externaly facing drive id - #define BUILD_MAX_EXTDRIVE 16 - // Number of bytes the smbios may be and still live in the f-segment -diff --git a/src/malloc.c b/src/malloc.c -index ecd8c9ac..da840980 100644 ---- a/src/malloc.c -+++ b/src/malloc.c -@@ -423,7 +423,7 @@ malloc_preinit(void) - - // Populate temp high ram - u32 highram_start = 0; -- u32 highram_size = BUILD_MAX_HIGHTABLE; -+ u32 highram_size = 0; - int i; - for (i=e820_count-1; i>=0; i--) { - struct e820entry *en = &e820_list[i]; -@@ -434,10 +434,14 @@ malloc_preinit(void) - continue; - u32 s = en->start, e = end; - if (!highram_start) { -- u32 newe = ALIGN_DOWN(e - highram_size, MALLOC_MIN_ALIGN); -- if (newe <= e && newe >= s) { -- highram_start = newe; -- e = newe; -+ u32 new_max = ALIGN_DOWN(e - BUILD_MAX_HIGHTABLE, MALLOC_MIN_ALIGN); -+ u32 new_min = ALIGN_DOWN(e - BUILD_MIN_HIGHTABLE, MALLOC_MIN_ALIGN); -+ if (new_max <= e && new_max >= s + BUILD_MAX_HIGHTABLE) { -+ highram_start = e = new_max; -+ highram_size = BUILD_MAX_HIGHTABLE; -+ } else if (new_min <= e && new_min >= s) { -+ highram_start = e = new_min; -+ highram_size = BUILD_MIN_HIGHTABLE; - } - } - alloc_add(&ZoneTmpHigh, s, e); --- -2.30.2 - -From 46de2eec93bffa0706e6229c0da2919763c8eb04 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann <kra...@redhat.com> -Date: Thu, 30 Jun 2022 17:28:40 +0200 -Subject: [PATCH 5/9] virtio-blk: use larger default request size - -Bump default from 8 to 64 blocks. Using 8 by default leads -to requests being splitted on qemu, which slows down boot. - -Some (temporary) debug logging added showed that almost all -requests on a standard fedora install are less than 64 blocks, -so that should bring us back to 1.15 performance levels. - -Signed-off-by: Gerd Hoffmann <kra...@redhat.com> ---- - src/hw/virtio-blk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c -index 929ba887..9b4a05a4 100644 ---- a/src/hw/virtio-blk.c -+++ b/src/hw/virtio-blk.c -@@ -95,7 +95,7 @@ virtio_blk_op(struct disk_op_s *op, int write) - blk_num_max = (u16)max_io_size / vdrive->drive.blksize; - else - /* default blk_num_max if hardware doesnot advise a proper value */ -- blk_num_max = 8; -+ blk_num_max = 64; - - if (op->count <= blk_num_max) { - virtio_blk_op_one_segment(vdrive, write, sg); --- -2.30.2 - -From 85d56f812f4d020b3b486682aff07d9f4a4c60fe Mon Sep 17 00:00:00 2001 -From: Xiaofei Lee <hbuxiao...@gmail.com> -Date: Mon, 21 Nov 2022 22:54:10 +0800 -Subject: [PATCH 6/9] virtio-blk: Fix incorrect type conversion in - virtio_blk_op() - -When using spdk aio bdev driver, the qemu command line like this: - -qemu-system-x86_64 \ - -chardev socket,id=char0,path=/tmp/vhost.0 \ - -device vhost-user-blk-pci,id=blk0,chardev=char0 \ - ... - -Boot failure message as below: - -e820 map has 7 items: - 0: 0000000000000000 - 000000000009fc00 = 1 RAM - 1: 000000000009fc00 - 00000000000a0000 = 2 RESERVED - 2: 00000000000f0000 - 0000000000100000 = 2 RESERVED - 3: 0000000000100000 - 000000007ffdd000 = 1 RAM - 4: 000000007ffdd000 - 0000000080000000 = 2 RESERVED - 5: 00000000feffc000 - 00000000ff000000 = 2 RESERVED - 6: 00000000fffc0000 - 0000000100000000 = 2 RESERVED -enter handle_19: - NULL -Booting from Hard Disk... -Boot failed: could not read the boot disk - -Fixes: a05af290bac5 ("virtio-blk: split large IO according to size_max") - -Acked-by: Andy Pei <andy....@intel.com> -Acked-by: Gerd Hoffmann <kra...@redhat.com> -Acked-by: Michael S. Tsirkin <m...@redhat.com> -Acked-by: Paul Menzel <pmen...@molgen.mpg.de> -Signed-off-by: Xiaofei Lee <hbuxiao...@gmail.com> ---- - src/hw/virtio-blk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c -index 9b4a05a4..ce3265e7 100644 ---- a/src/hw/virtio-blk.c -+++ b/src/hw/virtio-blk.c -@@ -92,7 +92,7 @@ virtio_blk_op(struct disk_op_s *op, int write) - u16 blk_num_max; - - if (vdrive->drive.blksize != 0 && max_io_size != 0) -- blk_num_max = (u16)max_io_size / vdrive->drive.blksize; -+ blk_num_max = (u16)(max_io_size / vdrive->drive.blksize); - else - /* default blk_num_max if hardware doesnot advise a proper value */ - blk_num_max = 64; --- -2.30.2 - -From 61e901bbaadf63080ac6a3911bd29da1308a0751 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov <imamm...@redhat.com> -Date: Fri, 18 Nov 2022 15:27:55 +0100 -Subject: [PATCH 7/9] acpi: parse Alias object -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since QEMU commit - 47a373faa6 (acpi: pc/q35: drop ad-hoc PCI-ISA bridge AML routines and let bus ennumeration generate AML) -SeaBIOS fails to parse ISA bridge AML with: - - parse_termlist: parse error, skip from 92/517 - ... - ACPI: no PS/2 keyboard present - -due to Alias term in DSDT which isn't handled by SeaBIOS properly. -Add dumb Alias parsing which just skips over term, -so the rest of AML could be parsed successfully. - -Signed-off-by: Igor Mammedov <imamm...@redhat.com> -Reported-by: Volker Rümelin <vr_q...@t-online.de> -Message-Id: <20221118142755.3879231-1-imamm...@redhat.com> -Signed-off-by: Gerd Hoffmann <kra...@redhat.com> ---- - src/fw/dsdt_parser.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/fw/dsdt_parser.c b/src/fw/dsdt_parser.c -index eb5496f3..2ac82821 100644 ---- a/src/fw/dsdt_parser.c -+++ b/src/fw/dsdt_parser.c -@@ -417,6 +417,10 @@ static int parse_termobj(struct parse_state *s, - break; - case 0x01: /* one */ - break; -+ case 0x06: /* AliasOp */ -+ offset += parse_namestring(s, ptr + offset, "SourceObject"); -+ offset += parse_namestring(s, ptr + offset, "AliasObject"); -+ break; - case 0x08: /* name op */ - offset += parse_namestring(s, ptr + offset, "name"); - offset += parse_termobj(s, ptr + offset); --- -2.30.2 - -From 5ea5c64c20e97e962c520af3f4e413d4b1b98dea Mon Sep 17 00:00:00 2001 -From: Xuan Zhuo <xuanz...@linux.alibaba.com> -Date: Mon, 14 Nov 2022 11:58:17 +0800 -Subject: [PATCH 8/9] virtio-mmio: read/write the hi 32 features for mmio - -Under mmio, when we read the feature from the device, we should read the -high 32-bit part. Similarly, when writing the feature back, we should -also write back the high 32-bit feature. - -Signed-off-by: Xuan Zhuo <xuanz...@linux.alibaba.com> -Acked-by: Michael S. Tsirkin <m...@redhat.com> -Message-Id: <20221114035818.109511-2-xuanz...@linux.alibaba.com> -Signed-off-by: Gerd Hoffmann <kra...@redhat.com> ---- - src/hw/virtio-pci.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/src/hw/virtio-pci.c b/src/hw/virtio-pci.c -index 213c4977..89a4f505 100644 ---- a/src/hw/virtio-pci.c -+++ b/src/hw/virtio-pci.c -@@ -193,7 +193,8 @@ u64 vp_get_features(struct vp_device *vp) - if (vp->use_mmio) { - vp_write(&vp->common, virtio_mmio_cfg, device_feature_select, 0); - f0 = vp_read(&vp->common, virtio_mmio_cfg, device_feature); -- f1 = 0; -+ vp_write(&vp->common, virtio_mmio_cfg, device_feature_select, 1); -+ f1 = vp_read(&vp->common, virtio_mmio_cfg, device_feature); - } else if (vp->use_modern) { - vp_write(&vp->common, virtio_pci_common_cfg, device_feature_select, 0); - f0 = vp_read(&vp->common, virtio_pci_common_cfg, device_feature); -@@ -214,8 +215,10 @@ void vp_set_features(struct vp_device *vp, u64 features) - f1 = features >> 32; - - if (vp->use_mmio) { -- vp_write(&vp->common, virtio_mmio_cfg, guest_feature_select, f0); -+ vp_write(&vp->common, virtio_mmio_cfg, guest_feature_select, 0); - vp_write(&vp->common, virtio_mmio_cfg, guest_feature, f0); -+ vp_write(&vp->common, virtio_mmio_cfg, guest_feature_select, 1); -+ vp_write(&vp->common, virtio_mmio_cfg, guest_feature, f1); - } else if (vp->use_modern) { - vp_write(&vp->common, virtio_pci_common_cfg, guest_feature_select, 0); - vp_write(&vp->common, virtio_pci_common_cfg, guest_feature, f0); --- -2.30.2 - -From 3208b098f51a9ef96d0dfa71d5ec3a3eaec88f0a Mon Sep 17 00:00:00 2001 -From: Xuan Zhuo <xuanz...@linux.alibaba.com> -Date: Mon, 14 Nov 2022 11:58:18 +0800 -Subject: [PATCH 9/9] virtio: finalize features before using device - -Under the standard of Virtio 1.0, the initialization process of the -device must first write sub-features back to device before -using device, such as finding vqs. - -There are four places using vp_find_vq(). - -1. virtio-blk.pci: put the code of finalizing features in front of using device -2. virtio-blk.mmio: put the code of finalizing features in front of using device -3. virtio-scsi.pci: is ok -4. virtio-scsi.mmio: add the code of finalizing features before vp_find_vq() - -Link: https://www.mail-archive.com/qemu-devel@nongnu.org/msg920776.html -Signed-off-by: Xuan Zhuo <xuanz...@linux.alibaba.com> -Acked-by: Michael S. Tsirkin <m...@redhat.com> -Message-Id: <20221114035818.109511-3-xuanz...@linux.alibaba.com> -Signed-off-by: Gerd Hoffmann <kra...@redhat.com> ---- - src/hw/virtio-blk.c | 22 +++++++++++++--------- - src/hw/virtio-scsi.c | 13 +++++++++++++ - 2 files changed, 26 insertions(+), 9 deletions(-) - -diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c -index ce3265e7..e087fe4f 100644 ---- a/src/hw/virtio-blk.c -+++ b/src/hw/virtio-blk.c -@@ -151,10 +151,6 @@ init_virtio_blk(void *data) - vdrive->drive.cntl_id = pci->bdf; - - vp_init_simple(&vdrive->vp, pci); -- if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { -- dprintf(1, "fail to find vq for virtio-blk %pP\n", pci); -- goto fail; -- } - - if (vdrive->vp.use_modern) { - struct vp_device *vp = &vdrive->vp; -@@ -212,7 +208,14 @@ init_virtio_blk(void *data) - vp_read(&vp->device, struct virtio_blk_config, heads); - vdrive->drive.pchs.sector = - vp_read(&vp->device, struct virtio_blk_config, sectors); -- } else { -+ } -+ -+ if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { -+ dprintf(1, "fail to find vq for virtio-blk %pP\n", pci); -+ goto fail; -+ } -+ -+ if (!vdrive->vp.use_modern) { - struct virtio_blk_config cfg; - vp_get_legacy(&vdrive->vp, 0, &cfg, sizeof(cfg)); - -@@ -272,10 +275,6 @@ init_virtio_blk_mmio(void *mmio) - vdrive->drive.cntl_id = (u32)mmio; - - vp_init_mmio(&vdrive->vp, mmio); -- if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { -- dprintf(1, "fail to find vq for virtio-blk-mmio %p\n", mmio); -- goto fail; -- } - - struct vp_device *vp = &vdrive->vp; - u64 features = vp_get_features(vp); -@@ -294,6 +293,11 @@ init_virtio_blk_mmio(void *mmio) - goto fail; - } - -+ if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { -+ dprintf(1, "fail to find vq for virtio-blk-mmio %p\n", mmio); -+ goto fail; -+ } -+ - if (features & max_segment_size) - vdrive->drive.max_segment_size = - vp_read(&vp->device, struct virtio_blk_config, size_max); -diff --git a/src/hw/virtio-scsi.c b/src/hw/virtio-scsi.c -index 369c9813..79bda0bb 100644 ---- a/src/hw/virtio-scsi.c -+++ b/src/hw/virtio-scsi.c -@@ -239,6 +239,19 @@ init_virtio_scsi_mmio(void *mmio) - vp_init_mmio(vp, mmio); - u8 status = VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER; - -+ u64 features = vp_get_features(vp); -+ u64 version1 = 1ull << VIRTIO_F_VERSION_1; -+ if (features & version1) { -+ u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; -+ -+ vp_set_features(vp, features & (version1 | iommu_platform)); -+ vp_set_status(vp, VIRTIO_CONFIG_S_FEATURES_OK); -+ if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) { -+ dprintf(1, "device didn't accept features: %pP\n", mmio); -+ goto fail; -+ } -+ } -+ - if (vp_find_vq(vp, 2, &vq) < 0 ) { - dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); - goto fail; --- -2.30.2 - diff -Nru seabios-1.16.0/debian/patches/series seabios-1.16.2/debian/patches/series --- seabios-1.16.0/debian/patches/series 2022-12-01 17:06:12.000000000 +0300 +++ seabios-1.16.2/debian/patches/series 2023-04-11 16:07:44.000000000 +0300 @@ -1,2 +1 @@ nogitversion.patch -rel-1.16.1.patch diff -Nru seabios-1.16.0/src/config.h seabios-1.16.2/src/config.h --- seabios-1.16.0/src/config.h 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/config.h 2023-02-02 04:14:39.000000000 +0300 @@ -17,7 +17,8 @@ // Maximum number of map entries in the e820 map #define BUILD_MAX_E820 32 // Space to reserve in high-memory for tables -#define BUILD_MAX_HIGHTABLE (256*1024) +#define BUILD_MIN_HIGHTABLE (256*1024) +#define BUILD_MAX_HIGHTABLE (16*1024*1024) // Largest supported externaly facing drive id #define BUILD_MAX_EXTDRIVE 16 // Number of bytes the smbios may be and still live in the f-segment diff -Nru seabios-1.16.0/src/fw/dsdt_parser.c seabios-1.16.2/src/fw/dsdt_parser.c --- seabios-1.16.0/src/fw/dsdt_parser.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/fw/dsdt_parser.c 2023-02-02 04:14:39.000000000 +0300 @@ -417,6 +417,10 @@ break; case 0x01: /* one */ break; + case 0x06: /* AliasOp */ + offset += parse_namestring(s, ptr + offset, "SourceObject"); + offset += parse_namestring(s, ptr + offset, "AliasObject"); + break; case 0x08: /* name op */ offset += parse_namestring(s, ptr + offset, "name"); offset += parse_termobj(s, ptr + offset); diff -Nru seabios-1.16.0/src/fw/shadow.c seabios-1.16.2/src/fw/shadow.c --- seabios-1.16.0/src/fw/shadow.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/fw/shadow.c 2023-02-02 04:14:39.000000000 +0300 @@ -32,8 +32,8 @@ { // Read in current PAM settings from pci config space union pamdata_u pamdata; - pamdata.data32[0] = pci_config_readl(bdf, ALIGN_DOWN(pam0, 4)); - pamdata.data32[1] = pci_config_readl(bdf, ALIGN_DOWN(pam0, 4) + 4); + pamdata.data32[0] = pci_ioconfig_readl(bdf, ALIGN_DOWN(pam0, 4)); + pamdata.data32[1] = pci_ioconfig_readl(bdf, ALIGN_DOWN(pam0, 4) + 4); u8 *pam = &pamdata.data8[pam0 & 0x03]; // Make ram from 0xc0000-0xf0000 writable @@ -46,8 +46,8 @@ pam[0] = 0x30; // Write PAM settings back to pci config space - pci_config_writel(bdf, ALIGN_DOWN(pam0, 4), pamdata.data32[0]); - pci_config_writel(bdf, ALIGN_DOWN(pam0, 4) + 4, pamdata.data32[1]); + pci_ioconfig_writel(bdf, ALIGN_DOWN(pam0, 4), pamdata.data32[0]); + pci_ioconfig_writel(bdf, ALIGN_DOWN(pam0, 4) + 4, pamdata.data32[1]); if (!ram_present) // Copy bios. @@ -59,7 +59,7 @@ static void make_bios_writable_intel(u16 bdf, u32 pam0) { - int reg = pci_config_readb(bdf, pam0); + int reg = pci_ioconfig_readb(bdf, pam0); if (!(reg & 0x10)) { // QEMU doesn't fully implement the piix shadow capabilities - // if ram isn't backing the bios segment when shadowing is @@ -125,8 +125,8 @@ // At this point, statically allocated variables can't be written, // so do this search manually. int bdf; - foreachbdf(bdf, 0) { - u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID); + pci_ioconfig_foreachbdf(bdf, 0) { + u32 vendev = pci_ioconfig_readl(bdf, PCI_VENDOR_ID); u16 vendor = vendev & 0xffff, device = vendev >> 16; if (vendor == PCI_VENDOR_ID_INTEL && device == PCI_DEVICE_ID_INTEL_82441) { diff -Nru seabios-1.16.0/src/fw/xen.c seabios-1.16.2/src/fw/xen.c --- seabios-1.16.0/src/fw/xen.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/fw/xen.c 2023-02-02 04:14:39.000000000 +0300 @@ -40,16 +40,25 @@ u32 e820_nr; } PACKED; -static void validate_info(struct xen_seabios_info *t) +static struct xen_seabios_info *validate_info(void) { - if ( memcmp(t->signature, "XenHVMSeaBIOS", 14) ) - panic("Bad Xen info signature\n"); + struct xen_seabios_info *t = (void *)INFO_PHYSICAL_ADDRESS; - if ( t->length < sizeof(struct xen_seabios_info) ) - panic("Bad Xen info length\n"); + if ( memcmp(t->signature, "XenHVMSeaBIOS", 14) ) { + dprintf(1, "Bad Xen info signature\n"); + return NULL; + } + + if ( t->length < sizeof(struct xen_seabios_info) ) { + dprintf(1, "Bad Xen info length\n"); + return NULL; + } - if (checksum(t, t->length) != 0) - panic("Bad Xen info checksum\n"); + if (checksum(t, t->length) != 0) { + dprintf(1, "Bad Xen info checksum\n"); + return NULL; + } + return t; } void xen_preinit(void) @@ -86,7 +95,10 @@ dprintf(1, "No Xen hypervisor found.\n"); return; } - PlatformRunningOn = PF_QEMU|PF_XEN; + if (validate_info()) + PlatformRunningOn = PF_QEMU|PF_XEN; + else + dprintf(1, "Not enabling Xen support due to lack of Xen info\n"); } static int hypercall_xen_version( int cmd, void *arg) @@ -122,10 +134,14 @@ void xen_biostable_setup(void) { - struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS; - void **tables = (void*)info->tables; + struct xen_seabios_info *info = validate_info(); + void **tables; int i; + if (!info) + panic("Xen info corrupted\n"); + + tables = (void*)info->tables; dprintf(1, "xen: copy BIOS tables...\n"); for (i=0; i<info->tables_nr; i++) copy_table(tables[i]); @@ -136,12 +152,15 @@ void xen_ramsize_preinit(void) { int i; - struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS; - struct e820entry *e820 = (struct e820entry *)info->e820; - validate_info(info); + struct xen_seabios_info *info = validate_info(); + struct e820entry *e820; + + if (!info) + panic("Xen info corrupted\n"); dprintf(1, "xen: copy e820...\n"); + e820 = (struct e820entry *)info->e820; for (i = 0; i < info->e820_nr; i++) { struct e820entry *e = &e820[i]; e820_add(e->start, e->size, e->type); diff -Nru seabios-1.16.0/src/hw/pci.c seabios-1.16.2/src/hw/pci.c --- seabios-1.16.0/src/hw/pci.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/hw/pci.c 2023-02-02 04:14:39.000000000 +0300 @@ -26,63 +26,93 @@ return 0x80000000 | (bdf << 8) | (addr & 0xfc); } +void pci_ioconfig_writel(u16 bdf, u32 addr, u32 val) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + outl(val, PORT_PCI_DATA); +} + void pci_config_writel(u16 bdf, u32 addr, u32 val) { if (!MODESEGMENT && mmconfig) { writel(mmconfig_addr(bdf, addr), val); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - outl(val, PORT_PCI_DATA); + pci_ioconfig_writel(bdf, addr, val); } } +void pci_ioconfig_writew(u16 bdf, u32 addr, u16 val) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + outw(val, PORT_PCI_DATA + (addr & 2)); +} + void pci_config_writew(u16 bdf, u32 addr, u16 val) { if (!MODESEGMENT && mmconfig) { writew(mmconfig_addr(bdf, addr), val); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - outw(val, PORT_PCI_DATA + (addr & 2)); + pci_ioconfig_writew(bdf, addr, val); } } +void pci_ioconfig_writeb(u16 bdf, u32 addr, u8 val) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + outb(val, PORT_PCI_DATA + (addr & 3)); +} + void pci_config_writeb(u16 bdf, u32 addr, u8 val) { if (!MODESEGMENT && mmconfig) { writeb(mmconfig_addr(bdf, addr), val); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - outb(val, PORT_PCI_DATA + (addr & 3)); + pci_ioconfig_writeb(bdf, addr, val); } } +u32 pci_ioconfig_readl(u16 bdf, u32 addr) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + return inl(PORT_PCI_DATA); +} + u32 pci_config_readl(u16 bdf, u32 addr) { if (!MODESEGMENT && mmconfig) { return readl(mmconfig_addr(bdf, addr)); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - return inl(PORT_PCI_DATA); + return pci_ioconfig_readl(bdf, addr); } } +u16 pci_ioconfig_readw(u16 bdf, u32 addr) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + return inw(PORT_PCI_DATA + (addr & 2)); +} + u16 pci_config_readw(u16 bdf, u32 addr) { if (!MODESEGMENT && mmconfig) { return readw(mmconfig_addr(bdf, addr)); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - return inw(PORT_PCI_DATA + (addr & 2)); + return pci_ioconfig_readw(bdf, addr); } } +u8 pci_ioconfig_readb(u16 bdf, u32 addr) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + return inb(PORT_PCI_DATA + (addr & 3)); +} + u8 pci_config_readb(u16 bdf, u32 addr) { if (!MODESEGMENT && mmconfig) { return readb(mmconfig_addr(bdf, addr)); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - return inb(PORT_PCI_DATA + (addr & 3)); + return pci_ioconfig_readb(bdf, addr); } } @@ -127,6 +157,33 @@ return 0; } +// Helper function for pci_ioconfig_foreachbdf() macro - return next device +int pci_ioconfig_next(int bdf, int bus) +{ + if (pci_bdf_to_fn(bdf) == 0 + && (pci_ioconfig_readb(bdf, PCI_HEADER_TYPE) & 0x80) == 0) + // Last found device wasn't a multi-function device - skip to + // the next device. + bdf += 8; + else + bdf += 1; + + for (;;) { + if (pci_bdf_to_bus(bdf) != bus) + return -1; + + u16 v = pci_ioconfig_readw(bdf, PCI_VENDOR_ID); + if (v != 0x0000 && v != 0xffff) + // Device is present. + return bdf; + + if (pci_bdf_to_fn(bdf) == 0) + bdf += 8; + else + bdf += 1; + } +} + // Helper function for foreachbdf() macro - return next device int pci_next(int bdf, int bus) diff -Nru seabios-1.16.0/src/hw/pci.h seabios-1.16.2/src/hw/pci.h --- seabios-1.16.0/src/hw/pci.h 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/hw/pci.h 2023-02-02 04:14:39.000000000 +0300 @@ -27,11 +27,26 @@ return (bus << 8) | devfn; } +#define pci_ioconfig_foreachbdf(BDF, BUS) \ + for (BDF=pci_ioconfig_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \ + ; BDF >= 0 \ + ; BDF=pci_ioconfig_next(BDF, (BUS))) + #define foreachbdf(BDF, BUS) \ for (BDF=pci_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \ ; BDF >= 0 \ ; BDF=pci_next(BDF, (BUS))) +// standard PCI configration access mechanism +void pci_ioconfig_writel(u16 bdf, u32 addr, u32 val); +void pci_ioconfig_writew(u16 bdf, u32 addr, u16 val); +void pci_ioconfig_writeb(u16 bdf, u32 addr, u8 val); +u32 pci_ioconfig_readl(u16 bdf, u32 addr); +u16 pci_ioconfig_readw(u16 bdf, u32 addr); +u8 pci_ioconfig_readb(u16 bdf, u32 addr); +int pci_ioconfig_next(int bdf, int bus); + +// PCI configuration access using either PCI CAM or PCIe ECAM void pci_config_writel(u16 bdf, u32 addr, u32 val); void pci_config_writew(u16 bdf, u32 addr, u16 val); void pci_config_writeb(u16 bdf, u32 addr, u8 val); @@ -39,9 +54,10 @@ u16 pci_config_readw(u16 bdf, u32 addr); u8 pci_config_readb(u16 bdf, u32 addr); void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on); -void pci_enable_mmconfig(u64 addr, const char *name); u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap); int pci_next(int bdf, int bus); + +void pci_enable_mmconfig(u64 addr, const char *name); int pci_probe_host(void); void pci_reboot(void); diff -Nru seabios-1.16.0/src/hw/usb.c seabios-1.16.2/src/hw/usb.c --- seabios-1.16.0/src/hw/usb.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/hw/usb.c 2023-02-02 04:14:39.000000000 +0300 @@ -372,17 +372,19 @@ void *config_end = (void*)config + config->wTotalLength; struct usb_interface_descriptor *iface = (void*)(&config[1]); for (;;) { - if (!num_iface-- || (void*)iface + iface->bLength > config_end) + if (!num_iface || (void*)iface + iface->bLength > config_end) // Not a supported device. goto fail; - if (iface->bDescriptorType == USB_DT_INTERFACE - && (iface->bInterfaceClass == USB_CLASS_HUB + if (iface->bDescriptorType == USB_DT_INTERFACE) { + num_iface--; + if (iface->bInterfaceClass == USB_CLASS_HUB || (iface->bInterfaceClass == USB_CLASS_MASS_STORAGE && (iface->bInterfaceProtocol == US_PR_BULK || iface->bInterfaceProtocol == US_PR_UAS)) || (iface->bInterfaceClass == USB_CLASS_HID - && iface->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT))) - break; + && iface->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT)) + break; + } iface = (void*)iface + iface->bLength; } diff -Nru seabios-1.16.0/src/hw/usb-hid.c seabios-1.16.2/src/hw/usb-hid.c --- seabios-1.16.0/src/hw/usb-hid.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/hw/usb-hid.c 2023-02-02 04:14:39.000000000 +0300 @@ -22,13 +22,13 @@ // Send USB HID protocol message. static int -set_protocol(struct usb_pipe *pipe, u16 val) +set_protocol(struct usb_pipe *pipe, u16 val, u16 inferface) { struct usb_ctrlrequest req; req.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; req.bRequest = HID_REQ_SET_PROTOCOL; req.wValue = val; - req.wIndex = 0; + req.wIndex = inferface; req.wLength = 0; return usb_send_default_control(pipe, &req, NULL); } @@ -76,9 +76,12 @@ } // Enable "boot" protocol. - int ret = set_protocol(usbdev->defpipe, 0); - if (ret) + int ret = set_protocol(usbdev->defpipe, 0, usbdev->iface->bInterfaceNumber); + if (ret) { + dprintf(3, "Failed to set boot protocol\n"); return -1; + } + // Periodically send reports to enable key repeat. ret = set_idle(usbdev->defpipe, KEYREPEATMS); if (ret) @@ -118,7 +121,7 @@ } // Enable "boot" protocol. - int ret = set_protocol(usbdev->defpipe, 0); + int ret = set_protocol(usbdev->defpipe, 0, usbdev->iface->bInterfaceNumber); if (ret) return -1; diff -Nru seabios-1.16.0/src/hw/virtio-blk.c seabios-1.16.2/src/hw/virtio-blk.c --- seabios-1.16.0/src/hw/virtio-blk.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/hw/virtio-blk.c 2023-02-02 04:14:39.000000000 +0300 @@ -92,10 +92,10 @@ u16 blk_num_max; if (vdrive->drive.blksize != 0 && max_io_size != 0) - blk_num_max = (u16)max_io_size / vdrive->drive.blksize; + blk_num_max = (u16)(max_io_size / vdrive->drive.blksize); else /* default blk_num_max if hardware doesnot advise a proper value */ - blk_num_max = 8; + blk_num_max = 64; if (op->count <= blk_num_max) { virtio_blk_op_one_segment(vdrive, write, sg); @@ -151,10 +151,6 @@ vdrive->drive.cntl_id = pci->bdf; vp_init_simple(&vdrive->vp, pci); - if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { - dprintf(1, "fail to find vq for virtio-blk %pP\n", pci); - goto fail; - } if (vdrive->vp.use_modern) { struct vp_device *vp = &vdrive->vp; @@ -212,7 +208,14 @@ vp_read(&vp->device, struct virtio_blk_config, heads); vdrive->drive.pchs.sector = vp_read(&vp->device, struct virtio_blk_config, sectors); - } else { + } + + if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { + dprintf(1, "fail to find vq for virtio-blk %pP\n", pci); + goto fail; + } + + if (!vdrive->vp.use_modern) { struct virtio_blk_config cfg; vp_get_legacy(&vdrive->vp, 0, &cfg, sizeof(cfg)); @@ -272,10 +275,6 @@ vdrive->drive.cntl_id = (u32)mmio; vp_init_mmio(&vdrive->vp, mmio); - if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { - dprintf(1, "fail to find vq for virtio-blk-mmio %p\n", mmio); - goto fail; - } struct vp_device *vp = &vdrive->vp; u64 features = vp_get_features(vp); @@ -294,6 +293,11 @@ goto fail; } + if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { + dprintf(1, "fail to find vq for virtio-blk-mmio %p\n", mmio); + goto fail; + } + if (features & max_segment_size) vdrive->drive.max_segment_size = vp_read(&vp->device, struct virtio_blk_config, size_max); diff -Nru seabios-1.16.0/src/hw/virtio-pci.c seabios-1.16.2/src/hw/virtio-pci.c --- seabios-1.16.0/src/hw/virtio-pci.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/hw/virtio-pci.c 2023-02-02 04:14:39.000000000 +0300 @@ -193,7 +193,8 @@ if (vp->use_mmio) { vp_write(&vp->common, virtio_mmio_cfg, device_feature_select, 0); f0 = vp_read(&vp->common, virtio_mmio_cfg, device_feature); - f1 = 0; + vp_write(&vp->common, virtio_mmio_cfg, device_feature_select, 1); + f1 = vp_read(&vp->common, virtio_mmio_cfg, device_feature); } else if (vp->use_modern) { vp_write(&vp->common, virtio_pci_common_cfg, device_feature_select, 0); f0 = vp_read(&vp->common, virtio_pci_common_cfg, device_feature); @@ -214,8 +215,10 @@ f1 = features >> 32; if (vp->use_mmio) { - vp_write(&vp->common, virtio_mmio_cfg, guest_feature_select, f0); + vp_write(&vp->common, virtio_mmio_cfg, guest_feature_select, 0); vp_write(&vp->common, virtio_mmio_cfg, guest_feature, f0); + vp_write(&vp->common, virtio_mmio_cfg, guest_feature_select, 1); + vp_write(&vp->common, virtio_mmio_cfg, guest_feature, f1); } else if (vp->use_modern) { vp_write(&vp->common, virtio_pci_common_cfg, guest_feature_select, 0); vp_write(&vp->common, virtio_pci_common_cfg, guest_feature, f0); diff -Nru seabios-1.16.0/src/hw/virtio-scsi.c seabios-1.16.2/src/hw/virtio-scsi.c --- seabios-1.16.0/src/hw/virtio-scsi.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/hw/virtio-scsi.c 2023-02-02 04:14:39.000000000 +0300 @@ -239,6 +239,19 @@ vp_init_mmio(vp, mmio); u8 status = VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER; + u64 features = vp_get_features(vp); + u64 version1 = 1ull << VIRTIO_F_VERSION_1; + if (features & version1) { + u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; + + vp_set_features(vp, features & (version1 | iommu_platform)); + vp_set_status(vp, VIRTIO_CONFIG_S_FEATURES_OK); + if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) { + dprintf(1, "device didn't accept features: %pP\n", mmio); + goto fail; + } + } + if (vp_find_vq(vp, 2, &vq) < 0 ) { dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); goto fail; diff -Nru seabios-1.16.0/src/malloc.c seabios-1.16.2/src/malloc.c --- seabios-1.16.0/src/malloc.c 2022-03-02 04:29:02.000000000 +0300 +++ seabios-1.16.2/src/malloc.c 2023-02-02 04:14:39.000000000 +0300 @@ -422,7 +422,8 @@ e820_add(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); // Populate temp high ram - u32 highram = 0; + u32 highram_start = 0; + u32 highram_size = 0; int i; for (i=e820_count-1; i>=0; i--) { struct e820entry *en = &e820_list[i]; @@ -432,11 +433,15 @@ if (en->type != E820_RAM || end > 0xffffffff) continue; u32 s = en->start, e = end; - if (!highram) { - u32 newe = ALIGN_DOWN(e - BUILD_MAX_HIGHTABLE, MALLOC_MIN_ALIGN); - if (newe <= e && newe >= s) { - highram = newe; - e = newe; + if (!highram_start) { + u32 new_max = ALIGN_DOWN(e - BUILD_MAX_HIGHTABLE, MALLOC_MIN_ALIGN); + u32 new_min = ALIGN_DOWN(e - BUILD_MIN_HIGHTABLE, MALLOC_MIN_ALIGN); + if (new_max <= e && new_max >= s + BUILD_MAX_HIGHTABLE) { + highram_start = e = new_max; + highram_size = BUILD_MAX_HIGHTABLE; + } else if (new_min <= e && new_min >= s) { + highram_start = e = new_min; + highram_size = BUILD_MIN_HIGHTABLE; } } alloc_add(&ZoneTmpHigh, s, e); @@ -444,9 +449,9 @@ // Populate regions alloc_add(&ZoneTmpLow, BUILD_STACK_ADDR, BUILD_EBDA_MINIMUM); - if (highram) { - alloc_add(&ZoneHigh, highram, highram + BUILD_MAX_HIGHTABLE); - e820_add(highram, BUILD_MAX_HIGHTABLE, E820_RESERVED); + if (highram_start) { + alloc_add(&ZoneHigh, highram_start, highram_start + highram_size); + e820_add(highram_start, highram_size, E820_RESERVED); } } diff -Nru seabios-1.16.0/.version seabios-1.16.2/.version --- seabios-1.16.0/.version 2022-03-02 05:09:22.000000000 +0300 +++ seabios-1.16.2/.version 2023-03-16 12:56:04.000000000 +0300 @@ -1 +1 @@ -1.16.0 +1.16.2