Skip to content

Commit

Permalink
Hyper-V: vPCI: Prepopulate device bars
Browse files Browse the repository at this point in the history
In recent Hyper-V releases on Windows Server 2022, vPCI code does not
initialize the last 4 bit of device bar registers. This behavior change
could result weird problems cuasing PCI code failure when configuring
bars.

Just write all 1's to those bars whose probed values are not the same
as current read ones. This seems to make Hyper-V vPCI and
pci_write_bar() to cooperate correctly on these releases.

Reported by:	khng@freebsd.org
Tested by:	khng@freebsd.org
MFC after:	2 weeks
Sponsored by:	Microsoft

(cherry picked from commit 75412a5)
(cherry picked from commit eabea1c700ad8eacb8dc780d8620b59ce72b2cf2)

Approved by:	so
Errata:		FreeBSD-EN-22:03.hyperv

(cherry picked from commit f1b8efb1b4ffc2182385d3f5cc26c37a4ad59026)
  • Loading branch information
Wei Hu authored and amotin committed Jan 12, 2022
1 parent 9c4b852 commit 5bd08f7
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions sys/dev/hyperv/pcib/vmbus_pcib.c
Expand Up @@ -1304,6 +1304,47 @@ _hv_pcifront_write_config(struct hv_pci_dev *hpdev, int where, int size,
}
}

/*
* The vPCI in some Hyper-V releases do not initialize the last 4
* bit of BAR registers. This could result weird problems causing PCI
* code fail to configure BAR correctly.
*
* Just write all 1's to those BARs whose probed values are not zero.
* This seems to make the Hyper-V vPCI and pci_write_bar() to cooperate
* correctly.
*/

static void
vmbus_pcib_prepopulate_bars(struct hv_pcibus *hbus)
{
struct hv_pci_dev *hpdev;
int i;

mtx_lock(&hbus->device_list_lock);
TAILQ_FOREACH(hpdev, &hbus->children, link) {
for (i = 0; i < 6; i++) {
/* Ignore empty bar */
if (hpdev->probed_bar[i] == 0)
continue;

uint32_t bar_val = 0;

_hv_pcifront_read_config(hpdev, PCIR_BAR(i),
4, &bar_val);

if (hpdev->probed_bar[i] != bar_val) {
if (bootverbose)
printf("vmbus_pcib: initialize bar %d "
"by writing all 1s\n", i);

_hv_pcifront_write_config(hpdev, PCIR_BAR(i),
4, 0xffffffff);
}
}
}
mtx_unlock(&hbus->device_list_lock);
}

static void
vmbus_pcib_set_detaching(void *arg, int pending __unused)
{
Expand Down Expand Up @@ -1425,6 +1466,8 @@ vmbus_pcib_attach(device_t dev)
if (ret)
goto vmbus_close;

vmbus_pcib_prepopulate_bars(hbus);

hbus->pci_bus = device_add_child(dev, "pci", -1);
if (!hbus->pci_bus) {
device_printf(dev, "failed to create pci bus\n");
Expand Down

0 comments on commit 5bd08f7

Please sign in to comment.