Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp2215786ybl; Thu, 9 Jan 2020 08:48:29 -0800 (PST) X-Google-Smtp-Source: APXvYqyMe9iN7+ncwmN9lR3W0mJHrhUyzJNqyvxEtjE0Ew2HIfxOQzAj9V4YBqNVTrGJEWuNTz2m X-Received: by 2002:a05:6808:4c7:: with SMTP id a7mr3874128oie.83.1578588509704; Thu, 09 Jan 2020 08:48:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578588509; cv=none; d=google.com; s=arc-20160816; b=Qm6Kye8tAsqRHGRKUdCLtvXbpOuYbWKTNG4nTdAu9Hv96izXwXUSDl1DKKFafZtphf AFqGsH/CCuQWv0a8oTyBwvCo0VtKIIdrVO2GDY91MNuRP+JdmUzUOoULsGF0qNS2J/8A WT+QixFlthBgdatB8fICPYuPefUO4gi5N1vG3bZbGney3Tq7M59NLpP0piDSMvpd9JD4 xE/zk1MFfao8qa4LClktpYC/3x+iWooysXahJbr9qbJe9fDcbWVw+JWw0Nw/iDx8lpAs 3TPnnoPtGHzocx/Nr4Bz3KoHumJ+vtvjm2gORpkhOvFEB+DqLcY3qfJ/YV4PmZngKBGE AZyQ== 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=5wHV7fLu1+idd5lVfa6Y08ed98hFBV7NTBA+k+ClsUc=; b=YWw2loHipEWMLNX9I8B64faQt4jpaYRBaOwdYWx1ux80lnV/0K7AVoTak294bUN/tB IwTuHbPp24XZiEgnAqLXm8wIgoJHSkA8oLYHmHFJcQd8QiD4OFkIbV3Nolvz5Cf+cVgh xWZau52ZTY01KhgnZ9ARIpj4tYnFEenLhMISsoapx9mdO4qryeYi+vOvJaERYjrFdiGf thL7sboV6cazAfQTagia9A6tOuHOlXlZg8R/3YdMoCnFO9j4XXMxRfLSXq8mQcYs0uYe wA4xItfaHYwIGeelplBVfUmclIXyi7LAFBm/iMX6kbMQZo1aVrRmvOfZCgHSokVkPHQW mwfw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=s8+lJx8X; 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=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l18si4338754oth.236.2020.01.09.08.48.16; Thu, 09 Jan 2020 08:48:29 -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=@linaro.org header.s=google header.b=s8+lJx8X; 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=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731403AbgAIOGC (ORCPT + 99 others); Thu, 9 Jan 2020 09:06:02 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:44267 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730033AbgAIOGC (ORCPT ); Thu, 9 Jan 2020 09:06:02 -0500 Received: by mail-wr1-f67.google.com with SMTP id q10so7488780wrm.11 for ; Thu, 09 Jan 2020 06:06:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=5wHV7fLu1+idd5lVfa6Y08ed98hFBV7NTBA+k+ClsUc=; b=s8+lJx8XPCKl1bu/IDbDXnGALgg5kCvFvoWSnaeATdrbv9UyIVL47+GxgeX7EZzEQ/ CEhTmb4J1Pub+C8EdKXf49I16Fg76XlSzshUSdokReGc4W0S8ZVzYFqtiu6lCgcX1v0v 7E4HEtIHMZHgjfItNNZY5avIw/0bEZMUGGEF7TMzZ/RgfvttxI9cWuBeYhFx2hgu/XWO kfFFJBqHxxshh+xkmV0vF8EJbO2L3D1woe3KT4K8YayKhNepIIXuq0Ub1ijiji2pBsEU YdfuBxcyX1Hx9AYsgEkDmu/VZVX7oP8GDALRix0uFaa8w1zZCpzKXBMqxHQj4aRhZClv b6HA== 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=5wHV7fLu1+idd5lVfa6Y08ed98hFBV7NTBA+k+ClsUc=; b=t/1OLsIl8gw0i0svx2HPAYJY5rcnJ4jFQ7gpTRHprPBdNrUMZR99v/LudJE7xIyGYb IK/5utKenFe0ULSv1QEbA6qUp47BuJxgcITgtfqe7RAq4qVCy49HQtsX3Gcp9DjfDv10 kRJKp7wCB4GUwjHoOMGj2lbNl4gArBn9kc8uG1pcftw4l7UxwhKEaKX4RPD9aC5JATA0 iKdsRwS77yZoGr3gXbO1nadc7G99fP8ujzt4DJZB3UNeNRyaTpF63FjXrGAxec/ziKqK m8Gsbe5SZLnhRkY227jTY6ExeYA8UfUazuki4IQ3H2uM6nkrRV6F2QdsA/VFu8MO0x0Z x/WQ== X-Gm-Message-State: APjAAAVhhxw1YRryAE0LAkysepDvDdfTT33JjqE+btt/disYhevBZo99 mkRriRLUiztNjxlnfbYKMvnNdA+Vcj0MK59+JUaXPw== X-Received: by 2002:a5d:43c7:: with SMTP id v7mr10620602wrr.32.1578578759741; Thu, 09 Jan 2020 06:05:59 -0800 (PST) MIME-Version: 1.0 References: <20191224044146.232713-1-saravanak@google.com> In-Reply-To: <20191224044146.232713-1-saravanak@google.com> From: Ard Biesheuvel Date: Thu, 9 Jan 2020 15:05:48 +0100 Message-ID: Subject: Re: [PATCH v2] efi: arm: defer probe of PCIe backed efifb on DT systems To: Saravana Kannan 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 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 > + .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 > + 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 Reviewed-by: Ard Biesheuvel but it still needs testing as well.