PCI Express Base Spec r6.0 defines BAR size up to 8 EB (2^63 bytes), but supporting anything bigger than 128TB requires changes to pci_rebar_get_possible_sizes() to read the additional Capability bits from the Control register. Signed-off-by: Zhiyuan Dai <daizhiyuan@xxxxxxxxxxxxxx> --- drivers/pci/pci.c | 14 ++++++++++---- include/uapi/linux/pci_regs.h | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 661f98c6c63a..8903deb2d891 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3752,12 +3752,13 @@ static int pci_rebar_find_pos(struct pci_dev *pdev, int bar) * @bar: BAR to query * * Get the possible sizes of a resizable BAR as bitmask defined in the spec - * (bit 0=1MB, bit 19=512GB). Returns 0 if BAR isn't resizable. + * (bit 0=1MB, bit 43=8EB). Returns 0 if BAR isn't resizable. */ -u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar) +u64 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar) { int pos; - u32 cap; + u64 cap; + u32 cap2; pos = pci_rebar_find_pos(pdev, bar); if (pos < 0) @@ -3766,6 +3767,11 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar) pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap); cap = FIELD_GET(PCI_REBAR_CAP_SIZES, cap); + pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &cap2); + cap2 = FIELD_GET(PCI_REBAR_CTRL_CAP_SIZES, cap2); + + cap |= (cap2 << 32); + /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */ if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f && bar == 0 && cap == 0x700) @@ -3800,7 +3806,7 @@ int pci_rebar_get_current_size(struct pci_dev *pdev, int bar) * pci_rebar_set_size - set a new size for a BAR * @pdev: PCI device * @bar: BAR to set size to - * @size: new size as defined in the spec (0=1MB, 19=512GB) + * @size: new size as defined in the spec (0=1MB, 43=8EB) * * Set the new size of a BAR as defined in the spec. * Returns zero if resizing was successful, error code otherwise. diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 1601c7ed5fab..345f45264567 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -1013,13 +1013,14 @@ /* Resizable BARs */ #define PCI_REBAR_CAP 4 /* capability register */ -#define PCI_REBAR_CAP_SIZES 0x00FFFFF0 /* supported BAR sizes */ +#define PCI_REBAR_CAP_SIZES 0xFFFFFFF0 /* supported BAR sizes */ #define PCI_REBAR_CTRL 8 /* control register */ #define PCI_REBAR_CTRL_BAR_IDX 0x00000007 /* BAR index */ #define PCI_REBAR_CTRL_NBAR_MASK 0x000000E0 /* # of resizable BARs */ #define PCI_REBAR_CTRL_NBAR_SHIFT 5 /* shift for # of BARs */ #define PCI_REBAR_CTRL_BAR_SIZE 0x00001F00 /* BAR size */ #define PCI_REBAR_CTRL_BAR_SHIFT 8 /* shift for BAR size */ +#define PCI_REBAR_CTRL_CAP_SIZES 0xFFFF0000 /* supported BAR sizes */ /* Dynamic Power Allocation */ #define PCI_DPA_CAP 4 /* capability register */ -- 2.43.0