Created
January 9, 2022 00:22
-
-
Save Keno/8d1b61166248fd594484835657b8c6ed to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- nv-pci.c 2022-01-08 23:12:19.137095516 +0000 | |
+++ /usr/src/nvidia-495.46/nvidia/nv-pci.c 2022-01-09 00:05:21.323360921 +0000 | |
@@ -217,7 +217,78 @@ | |
+#define NV_GPU_BAR1 1 | |
+static int nv_resize_pcie_bars(struct pci_dev *pci_dev) { | |
+ struct pci_host_bridge *host; | |
+ u16 cmd; | |
+ int r, old_size, requested_size; | |
+ int ret = 0; | |
+ | |
+ // Check if BAR1 has PCIe rebar capabilities | |
+ u32 sizes = pci_rebar_get_possible_sizes(pci_dev, NV_GPU_BAR1); | |
+ if (sizes == 0) { | |
+ /* ReBAR not available. Nothing to do. */ | |
+ return 0; | |
+ } | |
+ | |
+ /* Try to resize the BAR to the largest supported size */ | |
+ requested_size = fls(sizes) - 1; | |
+ | |
+ /* If the kernel will refuse us, don't even try to resize, | |
+ but give an informative error */ | |
+ host = pci_find_host_bridge(pci_dev->bus); | |
+ if (host->preserve_config) { | |
+ nv_printf(NV_DBG_INFO, "NVRM: Not resizing BAR because the firmware forbids moving windows.\n"); | |
+ return 0; | |
+ } | |
+ | |
+ nv_printf(NV_DBG_INFO, "NVRM: %04x:%02x:%02x.%x: Attempting to resize BAR1.\n", | |
+ NV_PCI_DOMAIN_NUMBER(pci_dev), NV_PCI_BUS_NUMBER(pci_dev), | |
+ NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn)); | |
+ | |
+ /* Disable memory decoding - required by the kernel APIs */ | |
+ pci_read_config_word(pci_dev, PCI_COMMAND, &cmd); | |
+ pci_write_config_word(pci_dev, PCI_COMMAND, cmd & ~PCI_COMMAND_MEMORY); | |
+ | |
+ /* Release BAR1 */ | |
+ pci_release_resource(pci_dev, NV_GPU_BAR1); | |
+ | |
+ /* Save the current size, just in case things go wrong */ | |
+ old_size = fls(pci_resource_len(pci_dev, NV_GPU_BAR1)) >> 20; | |
+ | |
+resize: | |
+ /* Attempt to resize BAR1 to the largest supported size */ | |
+ r = pci_resize_resource(pci_dev, NV_GPU_BAR1, requested_size); | |
+ | |
+ if (r) { | |
+ if (r == -ENOSPC) | |
+ nv_printf(NV_DBG_ERRORS, "NVRM: No address space to allocate resized BAR1.\n"); | |
+ else if (r) | |
+ nv_printf(NV_DBG_ERRORS, "NVRM: BAR resizing failed with error `%d`.\n", r); | |
+ | |
+ /* Re-attempt assignment of PCIe resources */ | |
+ pci_assign_unassigned_bus_resources(pci_dev->bus); | |
+ } | |
+ if (pci_resource_flags(pci_dev, NV_GPU_BAR1) & IORESOURCE_UNSET) { | |
+ if (requested_size != old_size) { | |
+ /* Try to get the BAR back with the original size */ | |
+ requested_size = old_size; | |
+ goto resize; | |
+ } | |
+ /* Something went horribly wrong and the kernel didn't manage to re-allocate BAR1. | |
+ This is unlikely (because we had space before), but can happen. */ | |
+ nv_printf(NV_DBG_ERRORS, "NVRM: FATAL: Failed to re-allocate BAR1.\n"); | |
+ ret = -ENODEV; | |
+ goto done; | |
+ } | |
+ | |
+done: | |
+ /* Re-enable memory decoding */ | |
+ pci_write_config_word(pci_dev, PCI_COMMAND, cmd); | |
+ | |
+ return ret; | |
+} | |
/* find nvidia devices and set initial state */ | |
static int | |
@@ -428,6 +499,11 @@ | |
goto failed; | |
} | |
+ if (!nv_resize_pcie_bars(pci_dev)) { | |
+ nv_printf(NV_DBG_ERRORS, | |
+ "NVRM: Fatal Error while attempting to resize PCIe BARs.\n"); | |
+ } | |
+ | |
NV_KMALLOC(nvl, sizeof(nv_linux_state_t)); | |
if (nvl == NULL) | |
{ | |
@@ -470,6 +546,7 @@ | |
nvl->gpu_wakeup_callback_needed = NV_TRUE; | |
INIT_LIST_HEAD(&nvl->open_files); | |
+ | |
for (i = 0, j = 0; i < NVRM_PCICFG_NUM_BARS && j < NV_GPU_NUM_BARS; i++) | |
{ | |
if ((NV_PCI_RESOURCE_VALID(pci_dev, i)) && |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment