c687bc
From dfdf950e893c23e77c9dc0be18fca66ad195d260 Mon Sep 17 00:00:00 2001
c687bc
From: Greg Kurz <gkurz@redhat.com>
c687bc
Date: Wed, 10 Feb 2021 15:56:45 +0000
c687bc
Subject: [PATCH 2/2] spapr: Adjust firmware path of PCI devices
c687bc
MIME-Version: 1.0
c687bc
Content-Type: text/plain; charset=UTF-8
c687bc
Content-Transfer-Encoding: 8bit
c687bc
c687bc
RH-Author: Greg Kurz <gkurz@redhat.com>
c687bc
Message-id: <20210210165645.470195-2-gkurz@redhat.com>
c687bc
Patchwork-id: 101038
c687bc
O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] spapr: Adjust firmware path of PCI devices
c687bc
Bugzilla: 1912891
c687bc
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
c687bc
RH-Acked-by: David Gibson <dgibson@redhat.com>
c687bc
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
c687bc
c687bc
From: Greg Kurz <groug@kaod.org>
c687bc
c687bc
It is currently not possible to perform a strict boot from USB storage:
c687bc
c687bc
$ qemu-system-ppc64 -accel kvm -nodefaults -nographic -serial stdio \
c687bc
	-boot strict=on \
c687bc
	-device qemu-xhci \
c687bc
	-device usb-storage,drive=disk,bootindex=0 \
c687bc
	-blockdev driver=file,node-name=disk,filename=fedora-ppc64le.qcow2
c687bc
c687bc
SLOF **********************************************************************
c687bc
QEMU Starting
c687bc
 Build Date = Jul 17 2020 11:15:24
c687bc
 FW Version = git-e18ddad8516ff2cf
c687bc
 Press "s" to enter Open Firmware.
c687bc
c687bc
Populating /vdevice methods
c687bc
Populating /vdevice/vty@71000000
c687bc
Populating /vdevice/nvram@71000001
c687bc
Populating /pci@800000020000000
c687bc
                     00 0000 (D) : 1b36 000d    serial bus [ usb-xhci ]
c687bc
No NVRAM common partition, re-initializing...
c687bc
Scanning USB
c687bc
  XHCI: Initializing
c687bc
    USB Storage
c687bc
       SCSI: Looking for devices
c687bc
          101000000000000 DISK     : "QEMU     QEMU HARDDISK    2.5+"
c687bc
Using default console: /vdevice/vty@71000000
c687bc
c687bc
  Welcome to Open Firmware
c687bc
c687bc
  Copyright (c) 2004, 2017 IBM Corporation All rights reserved.
c687bc
  This program and the accompanying materials are made available
c687bc
  under the terms of the BSD License available at
c687bc
  http://www.opensource.org/licenses/bsd-license.php
c687bc
c687bc
Trying to load:  from: /pci@800000020000000/usb@0/storage@1/disk@101000000000000 ...
c687bc
E3405: No such device
c687bc
c687bc
E3407: Load failed
c687bc
c687bc
  Type 'boot' and press return to continue booting the system.
c687bc
  Type 'reset-all' and press return to reboot the system.
c687bc
c687bc
Ready!
c687bc
0 >
c687bc
c687bc
The device tree handed over by QEMU to SLOF indeed contains:
c687bc
c687bc
qemu,boot-list =
c687bc
	"/pci@800000020000000/usb@0/storage@1/disk@101000000000000 HALT";
c687bc
c687bc
but the device node is named usb-xhci@0, not usb@0.
c687bc
c687bc
This happens because the firmware names of PCI devices returned
c687bc
by get_boot_devices_list() come from pcibus_get_fw_dev_path(),
c687bc
while the sPAPR PHB code uses a different naming scheme for
c687bc
device nodes. This inconsistency has always been there but it was
c687bc
hidden for a long time because SLOF used to rename USB device
c687bc
nodes, until this commit, merged in QEMU 4.2.0 :
c687bc
c687bc
commit 85164ad4ed9960cac842fa4cc067c6b6699b0994
c687bc
Author: Alexey Kardashevskiy <aik@ozlabs.ru>
c687bc
Date:   Wed Sep 11 16:24:32 2019 +1000
c687bc
c687bc
    pseries: Update SLOF firmware image
c687bc
c687bc
    This fixes USB host bus adapter name in the device tree to match QEMU's
c687bc
    one.
c687bc
c687bc
    Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
c687bc
    Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
c687bc
c687bc
Fortunately, sPAPR implements the firmware path provider interface.
c687bc
This provides a way to override the default firmware paths.
c687bc
c687bc
Just factor out the sPAPR PHB naming logic from spapr_dt_pci_device()
c687bc
to a helper, and use it in the sPAPR firmware path provider hook.
c687bc
c687bc
Fixes: 85164ad4ed99 ("pseries: Update SLOF firmware image")
c687bc
Signed-off-by: Greg Kurz <groug@kaod.org>
c687bc
Message-Id: <20210122170157.246374-1-groug@kaod.org>
c687bc
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
c687bc
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
c687bc
(cherry picked from commit 040bdafce12f750816d879442014df2999a995c4)
c687bc
Signed-off-by: Greg Kurz <gkurz@redhat.com>
c687bc
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
c687bc
---
c687bc
 hw/ppc/spapr.c              |  5 +++++
c687bc
 hw/ppc/spapr_pci.c          | 33 ++++++++++++++++++---------------
c687bc
 include/hw/pci-host/spapr.h |  2 ++
c687bc
 3 files changed, 25 insertions(+), 15 deletions(-)
c687bc
c687bc
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
c687bc
index 00b1ef075e..bee2299199 100644
c687bc
--- a/hw/ppc/spapr.c
c687bc
+++ b/hw/ppc/spapr.c
c687bc
@@ -3013,6 +3013,7 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
c687bc
     SCSIDevice *d = CAST(SCSIDevice,  dev, TYPE_SCSI_DEVICE);
c687bc
     SpaprPhbState *phb = CAST(SpaprPhbState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
c687bc
     VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON);
c687bc
+    PCIDevice *pcidev = CAST(PCIDevice, dev, TYPE_PCI_DEVICE);
c687bc
 
c687bc
     if (d) {
c687bc
         void *spapr = CAST(void, bus->parent, "spapr-vscsi");
c687bc
@@ -3086,6 +3087,10 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
c687bc
         return g_strdup_printf("pci@%x", PCI_SLOT(pcidev->devfn));
c687bc
     }
c687bc
 
c687bc
+    if (pcidev) {
c687bc
+        return spapr_pci_fw_dev_name(pcidev);
c687bc
+    }
c687bc
+
c687bc
     return NULL;
c687bc
 }
c687bc
 
c687bc
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
c687bc
index f6fbcf99ed..befa570aa8 100644
c687bc
--- a/hw/ppc/spapr_pci.c
c687bc
+++ b/hw/ppc/spapr_pci.c
c687bc
@@ -1348,15 +1348,29 @@ static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus *bus,
c687bc
     return offset;
c687bc
 }
c687bc
 
c687bc
+char *spapr_pci_fw_dev_name(PCIDevice *dev)
c687bc
+{
c687bc
+    const gchar *basename;
c687bc
+    int slot = PCI_SLOT(dev->devfn);
c687bc
+    int func = PCI_FUNC(dev->devfn);
c687bc
+    uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);
c687bc
+
c687bc
+    basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
c687bc
+                                  ccode & 0xff);
c687bc
+
c687bc
+    if (func != 0) {
c687bc
+        return g_strdup_printf("%s@%x,%x", basename, slot, func);
c687bc
+    } else {
c687bc
+        return g_strdup_printf("%s@%x", basename, slot);
c687bc
+    }
c687bc
+}
c687bc
+
c687bc
 /* create OF node for pci device and required OF DT properties */
c687bc
 static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
c687bc
                                void *fdt, int parent_offset)
c687bc
 {
c687bc
     int offset;
c687bc
-    const gchar *basename;
c687bc
-    gchar *nodename;
c687bc
-    int slot = PCI_SLOT(dev->devfn);
c687bc
-    int func = PCI_FUNC(dev->devfn);
c687bc
+    g_autofree gchar *nodename = spapr_pci_fw_dev_name(dev);
c687bc
     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
c687bc
     ResourceProps rp;
c687bc
     SpaprDrc *drc = drc_from_dev(sphb, dev);
c687bc
@@ -1373,19 +1387,8 @@ static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
c687bc
     uint32_t pci_status = pci_default_read_config(dev, PCI_STATUS, 2);
c687bc
     gchar *loc_code;
c687bc
 
c687bc
-    basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
c687bc
-                                  ccode & 0xff);
c687bc
-
c687bc
-    if (func != 0) {
c687bc
-        nodename = g_strdup_printf("%s@%x,%x", basename, slot, func);
c687bc
-    } else {
c687bc
-        nodename = g_strdup_printf("%s@%x", basename, slot);
c687bc
-    }
c687bc
-
c687bc
     _FDT(offset = fdt_add_subnode(fdt, parent_offset, nodename));
c687bc
 
c687bc
-    g_free(nodename);
c687bc
-
c687bc
     /* in accordance with PAPR+ v2.7 13.6.3, Table 181 */
c687bc
     _FDT(fdt_setprop_cell(fdt, offset, "vendor-id", vendor_id));
c687bc
     _FDT(fdt_setprop_cell(fdt, offset, "device-id", device_id));
c687bc
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
c687bc
index 8877ff51fb..9522db9047 100644
c687bc
--- a/include/hw/pci-host/spapr.h
c687bc
+++ b/include/hw/pci-host/spapr.h
c687bc
@@ -212,4 +212,6 @@ static inline unsigned spapr_phb_windows_supported(SpaprPhbState *sphb)
c687bc
     return sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
c687bc
 }
c687bc
 
c687bc
+char *spapr_pci_fw_dev_name(PCIDevice *dev);
c687bc
+
c687bc
 #endif /* PCI_HOST_SPAPR_H */
c687bc
-- 
c687bc
2.27.0
c687bc