Currently, pci region on busses[0] may be migrate to

64-bit mmio space. this will cause a mistake to read/write

device config space

 

example:

A modern virtio device map to 64-bit mmio space will set

mode to VP_ACCESS_PCICFG, But the real device cap is

VIRTIO_PCI_CAP_COMMON_CFG, we can not access the cap

rightly.

 

If this is a virtio blk/scsi device as system disk, VM

will not be booted on the device.

 

A simple solution is make device use the 32-bit address

space as much as possible.

 

This patch changes the placement of the PCI bars.

 

[1] commit 0e21548b15e2 ("virtio: pci cfg access")

 

Signed-off-by: hulang <hulang13@huawei.com>

---

src/fw/pciinit.c | 16 +++++++++++++++-

1 file changed, 15 insertions(+), 1 deletion(-)

 

diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c

index b3e359d7..2e9544dc 100644

--- a/src/fw/pciinit.c

+++ b/src/fw/pciinit.c

@@ -1100,8 +1100,12 @@ static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r)

{

     struct hlist_node *n;

     struct pci_region_entry *entry;

+    u64 r_end = r->base + pci_region_sum(r)

+

     hlist_for_each_entry_safe(entry, n, &r->list, node) {

         u64 addr = r->base;

+        if (addr + entry->size >= r_end)

+            continue;

         r->base += entry->size;

         if (entry->bar == -1)

             // Update bus base address if entry is a bridge region

@@ -1114,6 +1118,8 @@ static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r)

 static void pci_bios_map_devices(struct pci_bus *busses)

{

+    int bus;

+

     if (pci_bios_init_root_regions_io(busses))

         panic("PCI: out of I/O address space\n");

@@ -1122,6 +1128,15 @@ static void pci_bios_map_devices(struct pci_bus *busses)

         struct pci_region r64_mem, r64_pref;

         r64_mem.list.first = NULL;

         r64_pref.list.first = NULL;

+

+        // try map pci region to 32bit

+        for (bus = 0; bus<=MaxPCIBus; bus++) {

+            int type;

+            for (type = 0; type < PCI_REGION_TYPE_COUNT; type++)

+                pci_region_map_entries(busses, &busses[bus].r[type]);

+        }

+

+        // map remaining pci region to 64bit

         pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_MEM],

                                          &r64_mem);

         pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_PREFMEM],

@@ -1166,7 +1181,6 @@ static void pci_bios_map_devices(struct pci_bus *busses)

         pcimem64_start = 0;

     }

     // Map regions on each device.

-    int bus;

     for (bus = 0; bus<=MaxPCIBus; bus++) {

         int type;

         for (type = 0; type < PCI_REGION_TYPE_COUNT; type++)

--

2.33.0

 

 

Best Regards£¡

ºú ÀË Hu Lang

»ªÎªÔƼÆË㹫˾ µÂ¿Æ Èí¼þ¿ª·¢¹¤³Ìʦ

Espace£ºh30028282

Mobile£º+86 18212092054

E-mail£º hulang11@huawei.com

www.fescoadecco.com

°ì¹«µØÖ·£ºº¼ÖÝÊбõ½­Çø½­Êç·»ªÎªÑо¿ËùZ6-4-B06R-087S