From e35b279d96ff7453cfb257508d056d67d6879e27 Mon Sep 17 00:00:00 2001 From: Wenhui Fan Date: Tue, 18 Feb 2025 14:53:15 +0800 Subject: [PATCH 1/3] EDAC/mce_amd: Add LS and IF mce types for Hygon family 18h model 7h hygon inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IBN1VZ CVE: NA --------------------------- The error types are changed in LS and IF machine check control registers of Hygon family 18h model 7h processors, so add support to get the correct error types in smca error decoding process. Signed-off-by: Wenhui Fan --- drivers/edac/mce_amd.c | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c index b39fb9932bed..be0ec09f9389 100644 --- a/drivers/edac/mce_amd.c +++ b/drivers/edac/mce_amd.c @@ -168,6 +168,33 @@ static const char * const smca_ls_mce_desc[] = { "L2 Fill Data error", }; +/* Hygon Model7h Scalable MCA LS error strings */ +static const char * const smca_ls_mce_hygon_desc[] = { + "Load queue parity error", + "Store queue parity error", + "Miss address buffer payload parity error", + "Level 1 TLB parity error", + "DC Tag error type 5", + "DC Tag error type 6", + "DC Tag error type 1", + "Internal error type 1", + "Internal error type 2", + "System Read Data Error 0", + "System Read Data Error 1", + "System Read Data Error 2", + "System Read Data Error 3", + "DC Tag error type 2", + "DC Data error type 1 and poison consumption", + "DC Data error type 2", + "DC Data error type 3", + "DC Tag error type 4", + "Level 2 TLB parity error", + "PDC parity error", + "DC Tag error type 3", + "DC Tag error type 5", + "L2 Fill Data error", +}; + static const char * const smca_ls2_mce_desc[] = { "An ECC error was detected on a data cache read by a probe or victimization", "An ECC error or L2 poison was detected on a data cache read by a load", @@ -217,6 +244,31 @@ static const char * const smca_if_mce_desc[] = { "CT MCE", }; +/* Hygon Model7h Scalable MCA IF error strings */ +static const char * const smca_if_mce_hygon_desc[] = { + "Op Cache Microtag Probe Port Parity Error", + "IC Microtag or Full Tag Multi-hit Error", + "IC Full Tag Parity Error", + "IC Data Array Parity Error", + "Decoupling Queue PhysAddr Parity Error", + "L0 ITLB Parity Error", + "L1 ITLB Parity Error", + "L2 ITLB Parity Error", + "BPQ 0 Snoop Parity Error", + "BPQ 1 Snoop Parity Error", + "BPQ 2 Snoop Parity Error", + "BPQ 3 Snoop Parity Error", + "L1 BTB Multi-Match Error", + "L2 BTB Multi-Match Error", + "L2 Cache Response Poison Error", + "System Read Data Error", + "Hardware Assertion Error", + "L1-TLB Multi-Hit", + "L2-TLB Multi-Hit", + "BSR Parity Error", + "CT MCE", +}; + static const char * const smca_l2_mce_desc[] = { "L2M Tag Multiple-Way-Hit error", "L2M Tag or State Array ECC Error", @@ -1432,6 +1484,16 @@ static int __init mce_amd_init(void) out: pr_info("MCE: In-kernel MCE decoding enabled.\n"); + if (c->x86_vendor == X86_VENDOR_HYGON && + c->x86_model >= 0x7 && c->x86_model <= 0xf) { + smca_mce_descs[SMCA_LS].descs = smca_ls_mce_hygon_desc; + smca_mce_descs[SMCA_LS].num_descs = ARRAY_SIZE(smca_ls_mce_hygon_desc); + smca_mce_descs[SMCA_IF].descs = smca_if_mce_hygon_desc; + smca_mce_descs[SMCA_IF].num_descs = ARRAY_SIZE(smca_if_mce_hygon_desc); + pr_info("MCE: Hygon Fam%xh Model%xh smca mce descs setup.\n", + c->x86, c->x86_model); + } + mce_register_decode_chain(&amd_mce_dec_nb); return 0; -- Gitee From 1ffbf544ef7741a083a6e3dd00e3e03027c10a64 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 2 Feb 2023 17:04:58 +0200 Subject: [PATCH 2/3] xhci: add helpers for enabling and disabling interrupters mainline inclusion from mainline-v6.3-rc1 commit 52dd0483e822d097fd6f522af2438a9b6f6eb0a9 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICJVXA CVE: NA Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=52dd0483e822d097fd6f522af2438a9b6f6eb0a9 ---------------------------------------------------------------------- Simple helpers to set and clear the IE (interrupter enable) bit for an interrupter. Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20230202150505.618915-5-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: yang-yulong <528553518@qq.com> --- drivers/usb/host/xhci.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ed52cc9e4df8..4a05a9dcb2fe 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -294,6 +294,32 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci) xhci_info(xhci, "Fault detected\n"); } +static int xhci_enable_interrupter(struct xhci_hcd *xhci) +{ + u32 iman; + + if (!xhci || !xhci->ir_set) + return -EINVAL; + + iman = readl(&xhci->ir_set->irq_pending); + writel(ER_IRQ_ENABLE(iman), &xhci->ir_set->irq_pending); + + return 0; +} + +static int xhci_disable_interrupter(struct xhci_hcd *xhci) +{ + u32 iman; + + if (!xhci || !xhci->ir_set) + return -EINVAL; + + iman = readl(&xhci->ir_set->irq_pending); + writel(ER_IRQ_DISABLE(iman), &xhci->ir_set->irq_pending); + + return 0; +} + #ifdef CONFIG_USB_PCI /* * Set up MSI -- Gitee From a33d599ef88a887a7cf3d1d874c225462c9e6782 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 10 Apr 2025 18:18:27 +0300 Subject: [PATCH 3/3] xhci: Limit time spent with xHC interrupts disabled during bus resume mainline inclusion from mainline-v6.15-rc1 commit bea5892d0ed274e03655223d1977cf59f9aff2f2 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICJVXA CVE: NA Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bea5892d0ed274e03655223d1977cf59f9aff2f2 ---------------------------------------------------------------------- Current xhci bus resume implementation prevents xHC host from generating interrupts during high-speed USB 2 and super-speed USB 3 bus resume. Only reason to disable interrupts during bus resume would be to prevent the interrupt handler from interfering with the resume process of USB 2 ports. Host initiated resume of USB 2 ports is done in two stages. The xhci driver first transitions the port from 'U3' to 'Resume' state, then wait in Resume for 20ms, and finally moves port to U0 state. xhci driver can't prevent interrupts by keeping the xhci spinlock due to this 20ms sleep. Limit interrupt disabling to the USB 2 port resume case only. resuming USB 2 ports in bus resume is only done in special cases where USB 2 ports had to be forced to suspend during bus suspend. The current way of preventing interrupts by clearing the 'Interrupt Enable' (INTE) bit in USBCMD register won't prevent the Interrupter registers 'Interrupt Pending' (IP), 'Event Handler Busy' (EHB) and USBSTS register Event Interrupt (EINT) bits from being set. New interrupts can't be issued before those bits are properly clered. Disable interrupts by clearing the interrupter register 'Interrupt Enable' (IE) bit instead. This way IP, EHB and INTE won't be set before IE is enabled again and a new interrupt is triggered. Fixes: 52dd0483e822 ("xhci: add helpers for enabling and disabling interrupters") Reported-by: Devyn Liu Closes: https://lore.kernel.org/linux-usb/b1a9e2d51b4d4ff7a304f77c5be8164e@huawei.com/ Cc: stable@vger.kernel.org Tested-by: Devyn Liu Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250410151828.2868740-6-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: lujunhua Signed-off-by: yang-yulong <528553518@qq.com> --- drivers/usb/host/xhci-hub.c | 30 ++++++++++++++++-------------- drivers/usb/host/xhci.c | 4 ++-- drivers/usb/host/xhci.h | 2 ++ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index e92f920256b2..44c6dc82644b 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1773,9 +1773,10 @@ int xhci_bus_resume(struct usb_hcd *hcd) int slot_id; int sret; u32 next_state; - u32 temp, portsc; + u32 portsc; struct xhci_hub *rhub; struct xhci_port **ports; + bool disabled_irq = false; rhub = xhci_get_rhub(hcd); ports = rhub->ports; @@ -1791,17 +1792,20 @@ int xhci_bus_resume(struct usb_hcd *hcd) return -ESHUTDOWN; } - /* delay the irqs */ - temp = readl(&xhci->op_regs->command); - temp &= ~CMD_EIE; - writel(temp, &xhci->op_regs->command); - /* bus specific resume for ports we suspended at bus_suspend */ - if (hcd->speed >= HCD_USB3) + if (hcd->speed >= HCD_USB3) { next_state = XDEV_U0; - else + } else { next_state = XDEV_RESUME; - + if (bus_state->bus_suspended) { + /* + * prevent port event interrupts from interfering + * with usb2 port resume process + */ + xhci_disable_interrupter(xhci); + disabled_irq = true; + } + } port_index = max_ports; while (port_index--) { portsc = readl(ports[port_index]->addr); @@ -1870,11 +1874,9 @@ int xhci_bus_resume(struct usb_hcd *hcd) (void) readl(&xhci->op_regs->command); bus_state->next_statechange = jiffies + msecs_to_jiffies(5); - /* re-enable irqs */ - temp = readl(&xhci->op_regs->command); - temp |= CMD_EIE; - writel(temp, &xhci->op_regs->command); - temp = readl(&xhci->op_regs->command); + /* re-enable interrupter */ + if (disabled_irq) + xhci_enable_interrupter(xhci); spin_unlock_irqrestore(&xhci->lock, flags); return 0; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 4a05a9dcb2fe..8608f3598ad9 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -294,7 +294,7 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci) xhci_info(xhci, "Fault detected\n"); } -static int xhci_enable_interrupter(struct xhci_hcd *xhci) +int xhci_enable_interrupter(struct xhci_hcd *xhci) { u32 iman; @@ -307,7 +307,7 @@ static int xhci_enable_interrupter(struct xhci_hcd *xhci) return 0; } -static int xhci_disable_interrupter(struct xhci_hcd *xhci) +int xhci_disable_interrupter(struct xhci_hcd *xhci) { u32 iman; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index d82c90e73726..e4fa4300bee0 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -2121,6 +2121,8 @@ int xhci_alloc_tt_info(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_device *hdev, struct usb_tt *tt, gfp_t mem_flags); +int xhci_enable_interrupter(struct xhci_hcd *xhci); +int xhci_disable_interrupter(struct xhci_hcd *xhci); /* xHCI ring, segment, TRB, and TD functions */ dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb); -- Gitee