Commit 30e4280b authored by Thomas Zimmermann's avatar Thomas Zimmermann Committed by dinglongwei
Browse files

firmware/sysfb: Create firmware device only for enabled PCI devices

mainline inclusion
from mainline-v6.9-rc1
commit 4e754597d603c642869be9bffbb0ef49bf5f7bb8
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAR4KI
CVE: CVE-2024-46698

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4e754597d603c642869be9bffbb0ef49bf5f7bb8



--------------------------------

Test if the firmware framebuffer's parent PCI device, if any, has
been enabled. If not, the firmware framebuffer is most likely not
working. Hence, do not create a device for the firmware framebuffer
on disabled PCI devices.

So far, efifb tracked the status of the PCI parent device internally
and did not bind if it was disabled. This patch implements the
functionality for all PCI-based firmware framebuffers.

v3:
	* make commit message more precise (Sui)
v2:
	* rework sysfb_pci_dev_is_enabled() (Javier)

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240212090736.11464-6-tzimmermann@suse.de


Signed-off-by: default avatardinglongwei <dinglongwei1@huawei.com>
parent 637a822c
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -70,15 +70,41 @@ void sysfb_disable(void)
}
EXPORT_SYMBOL_GPL(sysfb_disable);

#if defined(CONFIG_PCI)
static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
{
	/*
	 * TODO: Try to integrate this code into the PCI subsystem
	 */
	int ret;
	u16 command;

	ret = pci_read_config_word(pdev, PCI_COMMAND, &command);
	if (ret != PCIBIOS_SUCCESSFUL)
		return false;
	if (!(command & PCI_COMMAND_MEMORY))
		return false;
	return true;
}
#else
static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
{
	return false;
}
#endif

static __init struct device *sysfb_parent_dev(const struct screen_info *si)
{
	struct pci_dev *pdev;

	pdev = screen_info_pci_dev(si);
	if (IS_ERR(pdev))
	if (IS_ERR(pdev)) {
		return ERR_CAST(pdev);
	else if (pdev)
	} else if (pdev) {
		if (!sysfb_pci_dev_is_enabled(pdev))
			return ERR_PTR(-ENODEV);
		return &pdev->dev;
	}

	return NULL;
}
@@ -101,6 +127,8 @@ static __init int sysfb_init(void)
	sysfb_apply_efi_quirks();

	parent = sysfb_parent_dev(si);
	if (IS_ERR(parent))
		goto unlock_mutex;

	/* try to create a simple-framebuffer device */
	compatible = sysfb_parse_mode(si, &mode);