On Tue, Aug 20, 2024 at 04:36:05PM +0200, Andrea della Porta wrote: > The of_pci_set_address() function parse devicetree PCI range specifier s/parse/parses/ ? > assuming the address is 'sanitized' at the origin, i.e. without checking > whether the incoming address is 32 or 64 bit has specified in the flags. > In this way an address with no OF_PCI_ADDR_SPACE_MEM64 set in the flagss s/flagss/flags/ > could leak through and the upper 32 bits of the address will be set too, > and this violates the PCI specs stating that ion 32 bit address the upper s/ion/in/ > bit should be zero. I don't understand this code, so I'm probably missing something. It looks like the interesting path here is: of_pci_prop_ranges res = &pdev->resource[...]; for (j = 0; j < num; j++) { val64 = res[j].start; of_pci_set_address(..., val64, 0, flags, false); + if (OF_PCI_ADDR_SPACE_MEM64) + prop[1] = upper_32_bits(val64); + else + prop[1] = 0; OF_PCI_ADDR_SPACE_MEM64 tells us about the size of the PCI bus address, but the address (val64) is a CPU physical address, not a PCI bus address, so I don't understand why of_pci_set_address() should use OF_PCI_ADDR_SPACE_MEM64 to clear part of the CPU address. Add blank lines between paragraphs. > This could cause mapping translation mismatch on PCI devices (e.g. RP1) > that are expected to be addressed with a 64 bit address while advertising > a 32 bit address in the PCI config region. > Add a check in of_pci_set_address() to set upper 32 bits to zero in case > the address has no 64 bit flag set. Is this an indication of a DT error? Have you seen this cause a problem? If so, what does it look like to a user? I.e., how could a user find this patch if they saw a problem? > Signed-off-by: Andrea della Porta <andrea.porta@xxxxxxxx> > --- > drivers/pci/of_property.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c > index 5a0b98e69795..77865facdb4a 100644 > --- a/drivers/pci/of_property.c > +++ b/drivers/pci/of_property.c > @@ -60,7 +60,10 @@ static void of_pci_set_address(struct pci_dev *pdev, u32 *prop, u64 addr, > prop[0] |= flags | reg_num; > if (!reloc) { > prop[0] |= OF_PCI_ADDR_FIELD_NONRELOC; > - prop[1] = upper_32_bits(addr); > + if (FIELD_GET(OF_PCI_ADDR_FIELD_SS, flags) == OF_PCI_ADDR_SPACE_MEM64) > + prop[1] = upper_32_bits(addr); > + else > + prop[1] = 0; > prop[2] = lower_32_bits(addr); > } > } > -- > 2.35.3 >