Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp2435249ybl; Thu, 9 Jan 2020 12:43:14 -0800 (PST) X-Google-Smtp-Source: APXvYqwoC903CpOsLcdJGZmp/ZVhsXHw20DPZICvDq4j9YHNmfTLl8Q+w7eh+KZhvf2rGzfdjKWO X-Received: by 2002:aca:d484:: with SMTP id l126mr4525122oig.114.1578602594136; Thu, 09 Jan 2020 12:43:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578602594; cv=none; d=google.com; s=arc-20160816; b=Wzxa51TBKqMm0yVr7FgpcYvkymMSBNxzUQ1/gXOMW/R7gkKU85wG/EjWq1cE+nje7k atP+6MmPKAHFb/BeANJ5LEuAGW/XQ57qRPsc80FKgDcoZvuqo/2i94kibTcVYHOhPyMn xzkJfgYxMtRdupI2APL73gk2uw3t+7Aq4k2vhIZUDBRMgvYnS7T4XJL2owqn82khjBoU +dzB41chtLMdyQSA8t9zqKtO4jdC/BhdpsBRt98Z40S94ToFJvDqVvrihwRxion/IPHx 03uMx3ZMTC88wTsDJ2yZ4+z0Y8uc/7nCm57TSdii/6SJQX+lIjUBzihexzCQHH6QnnqD YIaQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=LjrsEf49wxN7nbgg0ejb27fYAdliJCmtVPCHpdH/qLw=; b=cwOp7Pwel2jPiewfNfmvxLWMUDi24bNiYwByvJUbblX1pHcx8Mz/5/OfRtWBNa3YFo YxkFk04OuPUHGZQo6oFVhjMbgiQBL3HFXeSC6t4TVQa6+8fxQJjClhvysGbElrZEGweF l4s6Y9Xqm9ftPLMrpUBXxGb9l6ec5AWMm5lJMaaUgeT0Y4MyJUe0fiUPxvsgImxvaYAh FXL3kips2cPpm+WbdJ3r+DtC7oSnSviJX/EsvxzKDV5oZ4gYL/KARdrhr7vcNCEgM3Gi jfdRqnoveAToMXyyDsmTPIOB/MVX8Y0iiF8wHwwUo3OC3WgD8FE5r/noLZQMNeZN5n7o 3IFQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=nbsjGP0t; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p8si5717009otc.118.2020.01.09.12.43.01; Thu, 09 Jan 2020 12:43:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=nbsjGP0t; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388651AbgAISxY (ORCPT + 99 others); Thu, 9 Jan 2020 13:53:24 -0500 Received: from mail-oi1-f195.google.com ([209.85.167.195]:43627 "EHLO mail-oi1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729054AbgAISxY (ORCPT ); Thu, 9 Jan 2020 13:53:24 -0500 Received: by mail-oi1-f195.google.com with SMTP id p125so6773701oif.10 for ; Thu, 09 Jan 2020 10:53:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=LjrsEf49wxN7nbgg0ejb27fYAdliJCmtVPCHpdH/qLw=; b=nbsjGP0t5XsrJ4fFUnDPSRHA8/sLBXsgAlK+wM5pdnHzsZM29HqyVrjtamseVopALT r2jEHn31JnXHEnK5T4XuQl4kxmJpsXHEWdtsceXMEqBGBX9PlCkx6uYxDeq+PvvzbMxW mHnATg+LU3VBWvmENF9PfPxgBDlMri/JFVHitDKZX3aLhFeiHua0N0hTPT6TwYTJ5cn2 FxJh2s3Vlog8YwAYxR0aKCjpCaj+owJwnfZp8Os9I5khGXNf5u2v1oyhTixr7Exx14Zf Pz21n6JKf98cj1vqaZVvtrlTLY7U1lNoYT6air52s64WpvewD9zgNl7sbp7U4qocyt9j JPRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=LjrsEf49wxN7nbgg0ejb27fYAdliJCmtVPCHpdH/qLw=; b=AYhckl4kdvON+n4LRtLN+a4V0rIw6OSKMpM7sk79FQKJtxPPRHUGFOmK8diSQJ7a37 Zy+6UnlwakRHr7GouVsPwzsVrUfV387p8XemgwGYwv5FWAlxNCNc3OrkIv7oMA23n+sb T3dQ4nlJ1dmhQ+eKLm8hexKieY0xyYWwyThBFAtQZiEWp6L/hcPP7D/tESHWZrjaLGGe FJJ5FsABW2EozR9vqJNOHYH2pSKiMyogEF883SsmxmAxV+S8qC0GK5K/1U9MkyPeSV3i 2J/t5K+3JHhomH/TfndbC2A0bWAz/U8VhtQBRWb1G2rL8coxQeFUr/V2LXY/KKIcbomP sqPA== X-Gm-Message-State: APjAAAUyx9BJ/DSXHfMYhQJIV3sL/orJSwl3kyv40gdXNEuIuxh8NPCX Mr3zEuPmUd7jf+Kgc6d9wbEZpPSr3ypctiaDMpCLxA== X-Received: by 2002:aca:ea43:: with SMTP id i64mr4481440oih.30.1578596002690; Thu, 09 Jan 2020 10:53:22 -0800 (PST) MIME-Version: 1.0 References: <20191224044146.232713-1-saravanak@google.com> In-Reply-To: From: Saravana Kannan Date: Thu, 9 Jan 2020 10:52:46 -0800 Message-ID: Subject: Re: [PATCH v2] efi: arm: defer probe of PCIe backed efifb on DT systems To: Ard Biesheuvel Cc: Ard Biesheuvel , linux-arm-kernel , Will Deacon , Bjorn Helgaas , Greg Kroah-Hartman , Android Kernel Team , linux-efi , Linux Kernel Mailing List Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Jan 9, 2020 at 6:06 AM Ard Biesheuvel wrote: > > On Tue, 24 Dec 2019 at 05:41, Saravana Kannan wrote: > > > > From: Ard Biesheuvel > > > > The new of_devlink support breaks PCIe probing on ARM platforms booting > > via UEFI if the firmware exposes a EFI framebuffer that is backed by a > > PCI device. The reason is that the probing order gets reversed, > > resulting in a resource conflict on the framebuffer memory window when > > the PCIe probes last, causing it to give up entirely. > > > > Given that we rely on PCI quirks to deal with EFI framebuffers that get > > moved around in memory, we cannot simply drop the memory reservation, so > > instead, let's use the device link infrastructure to register this > > dependency, and force the probing to occur in the expected order. > > > > Cc: Greg Kroah-Hartman > > Signed-off-by: Ard Biesheuvel > > Co-developed-by: Saravana Kannan > > Signed-off-by: Saravana Kannan > > --- > > > > Hi Ard, > > > > I compile tested it and I think it should work. If you can actually run > > and test it, that'd be nice. > > > > You can also optimize find_pci_overlap_node() by caching the result if > > you think that's necessary. > > > > Right now this code will run always just like your code did. But once I > > rename of_devlink to fw_devlink, this code won't be run if fw_devlink is > > disabled. > > > > v1 -> v2: > > - Rewrote the device linking part to not depend on initcall ordering > > > > drivers/firmware/efi/arm-init.c | 106 ++++++++++++++++++++++++++++++-- > > 1 file changed, 102 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c > > index 904fa09e6a6b..8b789ff83af0 100644 > > --- a/drivers/firmware/efi/arm-init.c > > +++ b/drivers/firmware/efi/arm-init.c > > @@ -10,10 +10,12 @@ > > #define pr_fmt(fmt) "efi: " fmt > > > > #include > > +#include > > #include > > #include > > #include > > #include > > +#include > > #include > > #include > > #include > > @@ -276,15 +278,111 @@ void __init efi_init(void) > > efi_memmap_unmap(); > > } > > > > +static bool efifb_overlaps_pci_range(const struct of_pci_range *range) > > +{ > > + u64 fb_base = screen_info.lfb_base; > > + > > + if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) > > + fb_base |= (u64)(unsigned long)screen_info.ext_lfb_base << 32; > > + > > + return fb_base >= range->cpu_addr && > > + fb_base < (range->cpu_addr + range->size); > > +} > > + > > +static struct device_node *find_pci_overlap_node(void) > > +{ > > + struct device_node *np; > > + > > + for_each_node_by_type(np, "pci") { > > + struct of_pci_range_parser parser; > > + struct of_pci_range range; > > + int err; > > + > > + err = of_pci_range_parser_init(&parser, np); > > + if (err) { > > + pr_warn("of_pci_range_parser_init() failed: %d\n", err); > > + continue; > > + } > > + > > + for_each_of_pci_range(&parser, &range) > > + if (efifb_overlaps_pci_range(&range)) > > + return np; > > + } > > + return NULL; > > +} > > + > > +/* > > + * If the efifb framebuffer is backed by a PCI graphics controller, we have > > + * to ensure that this relation is expressed using a device link when > > + * running in DT mode, or the probe order may be reversed, resulting in a > > + * resource reservation conflict on the memory window that the efifb > > + * framebuffer steals from the PCIe host bridge. > > + */ > > +static int efifb_add_links(const struct fwnode_handle *fwnode, > > + struct device *dev) > > +{ > > + struct device_node *sup_np; > > + struct device *sup_dev; > > + > > + sup_np = find_pci_overlap_node(); > > + > > + /* > > + * If there's no PCI graphics controller backing the efifb, we are > > + * done here. > > + */ > > + if (!sup_np) > > + return 0; > > + > > + sup_dev = get_dev_from_fwnode(&sup_np->fwnode); > > + of_node_put(sup_np); > > + > > + /* > > + * Return -ENODEV if the PCI graphics controller device hasn't been > > + * registered yet. This ensures that efifb isn't allowed to probe > > + * and this function is retried again when new devices are > > + * registered. > > + */ > > + if (!sup_dev) > > + return -ENODEV; > > + > > + /* > > + * If this fails, retrying this function at a later point won't > > + * change anything. So, don't return an error after this. > > + */ > > + if (!device_link_add(dev, sup_dev, 0)) > > + dev_warn(dev, "device_link_add() failed\n"); > > + > > + put_device(sup_dev); > > + > > + return 0; > > +} > > + > > +static struct fwnode_operations efifb_fwnode_ops = { > > Please make this const Ack > > + .add_links = efifb_add_links, > > +}; > > + > > +static struct fwnode_handle efifb_fwnode = { > > + .ops = &efifb_fwnode_ops, > > +}; > > + > > static int __init register_gop_device(void) > > { > > - void *pd; > > + struct platform_device *pd; > > + int err; > > > > if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) > > return 0; > > > > - pd = platform_device_register_data(NULL, "efi-framebuffer", 0, > > - &screen_info, sizeof(screen_info)); > > - return PTR_ERR_OR_ZERO(pd); > > + pd = platform_device_alloc("efi-framebuffer", 0); > > + if (!pd) > > + return -ENOMEM; > > + > > Add > > if (IS_ENABLED(CONFIG_PCI)) > > here As in around the line below where I set the fwnode? Then it's going to warn about unused variable. Maybe I should just do the if (IS_ENABLED(CONFIG_PCI)) inside the add_links() function to short circuit it. Responding to your other email here. Adding ifdef CONFIG_PCI was my first inclination, but then those 2 functions are defined if CONFIG_OF_ADDRESS are defined and if not the stubs are always there. There's no #ifdef CONFIG_PCI around any of them AFAICT. So I'm confused about what's going on. > > + pd->dev.fwnode = &efifb_fwnode; > > + > > + err = platform_device_add_data(pd, &screen_info, sizeof(screen_info)); > > + if (err) > > + return err; > > + > > + return platform_device_add(pd); > > } > > subsys_initcall(register_gop_device); > > -- > > 2.24.1.735.g03f4e72817-goog > > > > With the changes above Yeah, will make them all. > > Reviewed-by: Ard Biesheuvel > Thanks! -Saravana