lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230904195724.633404-10-sui.jingfeng@linux.dev>
Date:   Tue,  5 Sep 2023 03:57:24 +0800
From:   Sui Jingfeng <sui.jingfeng@...ux.dev>
To:     Bjorn Helgaas <bhelgaas@...gle.com>
Cc:     amd-gfx@...ts.freedesktop.org, dri-devel@...ts.freedesktop.org,
        linux-kernel@...r.kernel.org, intel-gfx@...ts.freedesktop.org,
        nouveau@...ts.freedesktop.org, linux-pci@...r.kernel.org,
        Sui Jingfeng <suijingfeng@...ngson.cn>
Subject: [RFC,drm-misc-next v4 9/9] drm/gma500: Register as a VGA client by calling vga_client_register()

From: Sui Jingfeng <suijingfeng@...ngson.cn>

Because the display controller in N2000/D2000 series can be VGA-compatible,
so let's register gma500 as a VGA client, despite the firmware may alter
the PCI class code of IGD on a multiple GPU co-exist configuration. But
this commit no crime, because VGAARB only cares about VGA devices.

Noticed that the display controller in N2000/D2000 processor don't has a
valid VRAM BAR, the firmware put the EFI firmware framebuffer into the
stolen memory, so the commit <86fd887b7fe3> ("vgaarb: Don't default
exclusively to first video device with mem+io") is not effictive on such
a case. But the benefits of the stolen memory is that it will not suffer
from PCI resource relocation. Becase the stolen memory is carved out by
the firmware and reside in system RAM. Therefore, while at it, provided a
naive version of firmware framebuffer identification function and use the
new machanism just created.

Signed-off-by: Sui Jingfeng <suijingfeng@...ngson.cn>
---
 drivers/gpu/drm/gma500/psb_drv.c | 57 ++++++++++++++++++++++++++++++--
 1 file changed, 55 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 8b64f61ffaf9..eb95d030d981 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -14,7 +14,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
-
+#include <linux/vgaarb.h>
 #include <asm/set_memory.h>
 
 #include <acpi/video.h>
@@ -36,6 +36,11 @@
 #include "psb_irq.h"
 #include "psb_reg.h"
 
+static int gma500_modeset = -1;
+
+MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
+module_param_named(modeset, gma500_modeset, int, 0400);
+
 static const struct drm_driver driver;
 static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
 
@@ -446,6 +451,49 @@ static int gma_remove_conflicting_framebuffers(struct pci_dev *pdev,
 	return __aperture_remove_legacy_vga_devices(pdev);
 }
 
+static bool gma_contain_firmware_fb(u64 ap_start, u64 ap_end)
+{
+	u64 fb_start;
+	u64 fb_size;
+	u64 fb_end;
+
+	if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
+		fb_start = (u64)screen_info.ext_lfb_base << 32 | screen_info.lfb_base;
+	else
+		fb_start = screen_info.lfb_base;
+
+	fb_size = screen_info.lfb_size;
+	fb_end = fb_start + fb_size - 1;
+
+	/* No firmware framebuffer support */
+	if (!fb_start || !fb_size)
+		return false;
+
+	if (fb_start >= ap_start && fb_end <= ap_end)
+		return true;
+
+	return false;
+}
+
+static bool gma_want_to_be_primary(struct pci_dev *pdev)
+{
+	struct drm_device *drm = pci_get_drvdata(pdev);
+	struct drm_psb_private *priv = to_drm_psb_private(drm);
+	u64 vram_base = priv->stolen_base;
+	u64 vram_size = priv->vram_stolen_size;
+
+	if (gma500_modeset == 10)
+		return true;
+
+	/* Stolen memory are not going to be moved */
+	if (gma_contain_firmware_fb(vram_base, vram_base + vram_size)) {
+		drm_dbg(drm, "Contains firmware FB in the stolen memory\n");
+		return true;
+	}
+
+	return false;
+}
+
 static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct drm_psb_private *dev_priv;
@@ -475,6 +523,8 @@ static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (ret)
 		return ret;
 
+	vga_client_register(pdev, NULL, gma_want_to_be_primary);
+
 	psb_fbdev_setup(dev_priv);
 
 	return 0;
@@ -526,7 +576,10 @@ static struct pci_driver psb_pci_driver = {
 
 static int __init psb_init(void)
 {
-	if (drm_firmware_drivers_only())
+	if (drm_firmware_drivers_only() && (gma500_modeset == -1))
+		return -ENODEV;
+
+	if (!gma500_modeset)
 		return -ENODEV;
 
 	return pci_register_driver(&psb_pci_driver);
-- 
2.34.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ