Received: by 2002:a05:6359:6284:b0:131:369:b2a3 with SMTP id se4csp4985255rwb; Tue, 8 Aug 2023 18:09:04 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGZrE3RMfQhgs70ZU86ajDuqqV7ObNCwSEWFcq57E9/q4xea+fsexbr5cfhceD614DjuOjk X-Received: by 2002:aa7:d912:0:b0:522:1e2f:99db with SMTP id a18-20020aa7d912000000b005221e2f99dbmr1337336edr.5.1691543344046; Tue, 08 Aug 2023 18:09:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691543344; cv=none; d=google.com; s=arc-20160816; b=LzzVG4dqkE9TQ3MKy7aK27n3/nqqfCbEAQPd4u+H0AQAAE84V1nHsKdd3Vb+Z0atF2 INRfPQdfAWitZT8Zg2CxOuRF1U1PFt8pfsGNJSxW+Y6nC5fXGyI/iUUjU06fNvhMS67b 9dL9PHuGHP0nTc4mWBLD75Wh7JtWuUL1qEVqqlH19dYhPvEwDYnPPnhbSDMF/cITtG9A WZDdG8kWWgiZXYHuoAQ+axh7umEewcsMlYF1TyhrbBQciDtDnME/YSG/L3derEOH4Iyq Fv0RFsc6jzQD/c7PSBIUWaBF/z2V+gHCJ+YwmEW1z7BtdKquQd53k0i5uGPhUjCrCao4 zdNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=noQeSrC40sd/EXkeg8fxahy+pA50ftyssyowKNSXpwM=; fh=zKhj6+xSEqABOWzFWt365x9j+71pDpY8YwR0FbB59ZY=; b=ALvQjn57PTpv91h6GBOUSpQmrTHjvEbEsD+DBBA08Y8PA8htvxWgDL1btN8YugPcpx z84a1z2PlRz/fANKU7Kc/x7kX4YERxupKwtFhhaDmY8pMnfqj1NRf9chjqWeeiW3nmp4 GQVYWayVUM0Rk5Qjk58XylrvwyDBzq20HadbS64iQ1U9j+I6Cjrrr2rTXhheWaRrzT+X i6vCvozrtwOyz1fc2cQ0lQ4oIGYOrSjnkmAnIkpu8CxE5HJpSD84OhXQNWWz2J5+Ffba M6VUHaBbrnEYdYGbIgIPdFk1w6ixzwccv7PXqfBZrBliTPNWxHywfcNKDa640PSD9SRR LzkQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=bmnuHOjN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m15-20020aa7c48f000000b0052275937198si7556416edq.628.2023.08.08.18.08.39; Tue, 08 Aug 2023 18:09:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=bmnuHOjN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230403AbjHHWeh (ORCPT + 99 others); Tue, 8 Aug 2023 18:34:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45276 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230433AbjHHWee (ORCPT ); Tue, 8 Aug 2023 18:34:34 -0400 Received: from out-71.mta1.migadu.com (out-71.mta1.migadu.com [IPv6:2001:41d0:203:375::47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D25E6FE for ; Tue, 8 Aug 2023 15:34:32 -0700 (PDT) X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1691534069; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=noQeSrC40sd/EXkeg8fxahy+pA50ftyssyowKNSXpwM=; b=bmnuHOjNxAVhqjQOMstFLbhvA7AheHtRPdPVazLBqkBj17xtd3uGnHL/K2InWr0ptnzDFD ObY6ZX76LkF1kTuK4SxezbX0dBOd2wGgTr9nMpWDU3JDp173MGKw9ID+4bBl63G0cBZc7O hT1KYhpjhwPNNTyUYGFhYaX3lUZEIYA= From: Sui Jingfeng To: Bjorn Helgaas Cc: Dave Airlie , Daniel Vetter , linux-pci@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Sui Jingfeng , Mario Limonciello Subject: [PATCH v2 03/11] PCI/VGA: Deal with VGA class devices Date: Wed, 9 Aug 2023 06:34:04 +0800 Message-Id: <20230808223412.1743176-4-sui.jingfeng@linux.dev> In-Reply-To: <20230808223412.1743176-1-sui.jingfeng@linux.dev> References: <20230808223412.1743176-1-sui.jingfeng@linux.dev> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sui Jingfeng vgaarb only cares about PCI(e) VGA devices (pdev->class == 0x0300XX) Currently, hence we only need to add VGA devices has its class code equals to 0x0300 to the arbiter. To keep align with the previous behavior. we ignore the programming interface byte (the least significant 8 bits) intentionally. After apply this patch, We will filter the unqualified devices out in the vga_arb_device_init() function. While the current implementation is to search all PCI devices in a system, this is not efficient. This also means that deleting a PCI device no longer needs to walk the list. Note that the major contribution of this patch is optimization. Reviewed-by: Mario Limonciello Signed-off-by: Sui Jingfeng --- drivers/pci/vgaarb.c | 68 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c index c1bc6c983932..8742a51d450f 100644 --- a/drivers/pci/vgaarb.c +++ b/drivers/pci/vgaarb.c @@ -754,10 +754,6 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev) struct pci_dev *bridge; u16 cmd; - /* Only deal with VGA class devices */ - if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) - return false; - /* Allocate structure */ vgadev = kzalloc(sizeof(struct vga_device), GFP_KERNEL); if (vgadev == NULL) { @@ -1493,6 +1489,42 @@ static void vga_arbiter_notify_clients(void) spin_unlock_irqrestore(&vga_lock, flags); } +/* + * The PCI Class Code spec implies that only VGA devices with programming + * interface 0x00 can depend on the legacy VGA address range. VGA devices + * with programming interface 0x01 are 8514-compatible controllers. Since + * VGA devices with programming interface 0x00 is VGA compatible, the 'vga' + * suffix here should refer to the VGA-compatible devices after a strict + * reading of that specification. But considering the fact that there + * probably don't has a 8514-compatible controller that could be used with + * upstream kernel anymore, we would like to just ignore the programming + * interface byte. + * + * Besides, there do exist non VGA-compatible display controllers in the + * world and hardware vendors may abandon the old VGA standard someday. + * The meaning of 'vga' suffix here may change to evolve with time. + * + * A strict understanding of 'vga' certainly should be VGA-compatible, While + * a relaxed understanding of 'vga' would be PCI devices that are able to + * display. Currently, we just keep aligned to the previous behavior. + * Deal with VGA class devices. + */ +static bool pci_dev_is_vga(struct pci_dev *pdev) +{ + if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) + return true; + + /* + * The PCI_CLASS_NOT_DEFINED_VGA is defined to provide backward + * compatibility for devices that were built before the class code + * field was defined. + */ + if ((pdev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA) + return true; + + return false; +} + static int pci_notify(struct notifier_block *nb, unsigned long action, void *data) { @@ -1502,6 +1534,9 @@ static int pci_notify(struct notifier_block *nb, unsigned long action, vgaarb_dbg(dev, "%s\n", __func__); + if (!pci_dev_is_vga(pdev)) + return 0; + /* For now we're only intereted in devices added and removed. I didn't * test this thing here, so someone needs to double check for the * cases of hotplugable vga cards. */ @@ -1534,8 +1569,8 @@ static struct miscdevice vga_arb_device = { static int __init vga_arb_device_init(void) { + struct pci_dev *pdev = NULL; int rc; - struct pci_dev *pdev; rc = misc_register(&vga_arb_device); if (rc < 0) @@ -1543,13 +1578,22 @@ static int __init vga_arb_device_init(void) bus_register_notifier(&pci_bus_type, &pci_notifier); - /* We add all PCI devices satisfying VGA class in the arbiter by - * default */ - pdev = NULL; - while ((pdev = - pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, - PCI_ANY_ID, pdev)) != NULL) - vga_arbiter_add_pci_device(pdev); + /* + * We add all PCI devices satisfying VGA class in the arbiter + * by default, but we ignore the programming interface byte + * intentionally. + */ + do { + pdev = pci_get_class_masked(PCI_CLASS_DISPLAY_VGA << 8, 0xFFFF00, pdev); + if (pdev && pci_dev_is_vga(pdev)) + vga_arbiter_add_pci_device(pdev); + } while (pdev); + + do { + pdev = pci_get_class_masked(PCI_CLASS_NOT_DEFINED_VGA << 8, 0xFFFF00, pdev); + if (pdev && pci_dev_is_vga(pdev)) + vga_arbiter_add_pci_device(pdev); + } while (pdev); pr_info("loaded\n"); return rc; -- 2.34.1