Unverified Commit 9ad7ca99 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!7011 v3 bugfix patches from OLK-5.10

Merge Pull Request from: @ci-robot 
 
PR sync from: Xiongfeng Wang <wangxiongfeng2@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/K3UXZHXMZC7UUVG747YFZQNMQWCJCQHT/ 
Guilherme G. Piccoli (2):
  x86/PCI: Export find_cap() to be used in early PCI code
  x86/quirks: Add parameter to clear MSIs early on boot


-- 
2.20.1
 
https://gitee.com/openeuler/kernel/issues/I8X2RA 
 
Link:https://gitee.com/openeuler/kernel/pulls/7011

 

Reviewed-by: default avatarWei Li <liwei391@huawei.com>
Signed-off-by: default avatarXie XiuQi <xiexiuqi@huawei.com>
parents 8c0dfc8b 52062ab0
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -4404,6 +4404,12 @@
		nomsi		[MSI] If the PCI_MSI kernel config parameter is
				enabled, this kernel boot option can be used to
				disable the use of MSI interrupts system-wide.
		clearmsi	[X86] Clears MSI/MSI-X enable bits early in boot
				time in order to avoid issues like adapters
				screaming irqs and preventing boot progress.
				Also, it enforces the PCI Local Bus spec
				rule that those bits should be 0 in system reset
				events (useful for kexec/kdump cases).
		noioapicquirk	[APIC] Disable all boot interrupt quirks.
				Safety option to keep boot IRQs enabled. This
				should never be necessary.
+2 −0
Original line number Diff line number Diff line
@@ -10,9 +10,11 @@
extern u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset);
extern u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset);
extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset);
extern u32 pci_early_find_cap(int bus, int slot, int func, int cap);
extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val);
extern void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val);
extern void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val);

extern unsigned int pci_early_clear_msi;
extern int early_pci_allowed(void);
#endif /* _ASM_X86_PCI_DIRECT_H */
+2 −28
Original line number Diff line number Diff line
@@ -136,32 +136,6 @@ static u32 __init allocate_aperture(void)
}


/* Find a PCI capability */
static u32 __init find_cap(int bus, int slot, int func, int cap)
{
	int bytes;
	u8 pos;

	if (!(read_pci_config_16(bus, slot, func, PCI_STATUS) &
						PCI_STATUS_CAP_LIST))
		return 0;

	pos = read_pci_config_byte(bus, slot, func, PCI_CAPABILITY_LIST);
	for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
		u8 id;

		pos &= ~3;
		id = read_pci_config_byte(bus, slot, func, pos+PCI_CAP_LIST_ID);
		if (id == 0xff)
			break;
		if (id == cap)
			return pos;
		pos = read_pci_config_byte(bus, slot, func,
						pos+PCI_CAP_LIST_NEXT);
	}
	return 0;
}

/* Read a standard AGPv3 bridge header */
static u32 __init read_agp(int bus, int slot, int func, int cap, u32 *order)
{
@@ -250,8 +224,8 @@ static u32 __init search_agp_bridge(u32 *order, int *valid_agp)
				case PCI_CLASS_BRIDGE_HOST:
				case PCI_CLASS_BRIDGE_OTHER: /* needed? */
					/* AGP bridge? */
					cap = find_cap(bus, slot, func,
							PCI_CAP_ID_AGP);
					cap = pci_early_find_cap(bus, slot,
						 func, PCI_CAP_ID_AGP);
					if (!cap)
						break;
					*valid_agp = 1;
+32 −0
Original line number Diff line number Diff line
@@ -29,6 +29,37 @@
#include <asm/irq_remapping.h>
#include <asm/early_ioremap.h>

static void __init early_pci_clear_msi(int bus, int slot, int func)
{
	int pos;
	u16 ctrl;

	if (likely(!pci_early_clear_msi))
		return;

	pr_info_once("Clearing MSI/MSI-X enable bits early in boot (quirk)\n");

	pos = pci_early_find_cap(bus, slot, func, PCI_CAP_ID_MSI);
	if (pos) {
		ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS);
		ctrl &= ~PCI_MSI_FLAGS_ENABLE;
		write_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS, ctrl);

		/* Read again to flush previous write */
		ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS);
	}

	pos = pci_early_find_cap(bus, slot, func, PCI_CAP_ID_MSIX);
	if (pos) {
		ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS);
		ctrl &= ~PCI_MSIX_FLAGS_ENABLE;
		write_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS, ctrl);

		/* Read again to flush previous write */
		ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS);
	}
}

static void __init fix_hypertransport_config(int num, int slot, int func)
{
	u32 htcfg;
@@ -728,6 +759,7 @@ static struct chipset early_qrk[] __initdata = {
		PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
	{ PCI_VENDOR_ID_BROADCOM, 0x4331,
	  PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
	{ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, early_pci_clear_msi},
	{}
};

+4 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ int noioapicreroute = 1;
#endif
int pcibios_last_bus = -1;
unsigned long pirq_table_addr;
unsigned int pci_early_clear_msi;
const struct pci_raw_ops *__read_mostly raw_pci_ops;
const struct pci_raw_ops *__read_mostly raw_pci_ext_ops;

@@ -614,6 +615,9 @@ char *__init pcibios_setup(char *str)
	} else if (!strcmp(str, "skip_isa_align")) {
		pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
		return NULL;
	} else if (!strcmp(str, "clearmsi")) {
		pci_early_clear_msi = 1;
		return NULL;
	} else if (!strcmp(str, "noioapicquirk")) {
		noioapicquirk = 1;
		return NULL;
Loading