* [PATCH 0/4] MIPS: sgi-ip32: CRIME 1.1 and MACE PCI fixes
@ 2026-10-21 19:24 Imre Kaloz
2026-10-21 19:24 ` [PATCH 1/4] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Imre Kaloz
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Imre Kaloz @ 2026-10-21 19:24 UTC (permalink / raw)
To: Thomas Bogendoerfer, linux-mips; +Cc: linux-kernel
This series fixes hangs and stale PIO reads on SGI O2 machines with a
CRIME 1.1 memory controller.
Patches 1-2 stop the MACE PCI code from issuing a bridge register
sequence that hangs the machine under DMA load: slot interrupts are
masked in CRIME and the bridge control register is left alone at run
time, as IRIX, OpenBSD and NetBSD do.
Patch 3 reports the real CRIME revision, which the current code
reads as 1 on both 1.1 and 1.4. Patch 4 fences PIO reads on CRIME
1.1, where a read that follows an aic7880 status register read within
a few microseconds returns stale data; the fence stays off on 1.4.
Patches 1-2 are independent of 3-4 and are marked for stable.
Tested on O2 systems with CRIME 1.1 and 1.4.
Imre Kaloz (4):
MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only
MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses
MIPS: sgi-ip32: Report the real CRIME revision
MIPS: sgi-ip32: Fence PIO reads on CRIME 1.1
arch/mips/include/asm/io.h | 11 +++++
arch/mips/include/asm/ip32/crime.h | 2 +-
.../include/asm/mach-generic/read-fence.h | 20 +++++++++
arch/mips/include/asm/mach-ip32/read-fence.h | 29 ++++++++++++
arch/mips/pci/ops-mace.c | 26 ++++++++---
arch/mips/pci/pci-ip32.c | 9 +++-
arch/mips/sgi-ip32/crime.c | 38 +++++++++++++---
arch/mips/sgi-ip32/ip32-irq.c | 45 ++-----------------
8 files changed, 123 insertions(+), 57 deletions(-)
create mode 100644 arch/mips/include/asm/mach-generic/read-fence.h
create mode 100644 arch/mips/include/asm/mach-ip32/read-fence.h
base-commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907
--
2.47.3
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/4] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only
2026-10-21 19:24 [PATCH 0/4] MIPS: sgi-ip32: CRIME 1.1 and MACE PCI fixes Imre Kaloz
@ 2026-10-21 19:24 ` Imre Kaloz
2026-11-05 15:25 ` Thomas Bogendoerfer
2026-10-21 19:24 ` [PATCH 2/4] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses Imre Kaloz
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Imre Kaloz @ 2026-10-21 19:24 UTC (permalink / raw)
To: Thomas Bogendoerfer, linux-mips; +Cc: linux-kernel, stable
Masking PCI interrupts in the MACE PCI control register overwrites the
error and arbitration enables set at init, and a read-modify-write can
hang CRIME 1.1 machines under DMA load. Enable the slot interrupts once
and mask them in CRIME.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
---
arch/mips/pci/pci-ip32.c | 7 ++++--
arch/mips/sgi-ip32/ip32-irq.c | 45 +++--------------------------------
2 files changed, 8 insertions(+), 44 deletions(-)
diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c
index 7ae89d0c7099..30aca6f76563 100644
--- a/arch/mips/pci/pci-ip32.c
+++ b/arch/mips/pci/pci-ip32.c
@@ -125,10 +125,13 @@ static int __init mace_init(void)
{
PCIBIOS_MIN_IO = 0x1000;
- /* Clear any outstanding errors and enable interrupts */
+ /*
+ * Clear any outstanding errors and enable interrupts. PCI interrupts
+ * are masked in CRIME, so the per-slot enables stay on.
+ */
mace->pci.error_addr = 0;
mace->pci.error = 0;
- mace->pci.control = 0xff008500;
+ mace->pci.control = 0xff0085ff;
printk("MACE PCI rev %d\n", mace->pci.rev);
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index 29d04468a06b..b9c72af481ed 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -160,38 +160,6 @@ static struct irq_chip crime_edge_interrupt = {
.irq_unmask = crime_enable_irq,
};
-/*
- * This is for MACE PCI interrupts. We can decrease bus traffic by masking
- * as close to the source as possible. This also means we can take the
- * next chunk of the CRIME register in one piece.
- */
-
-static unsigned long macepci_mask;
-
-static void enable_macepci_irq(struct irq_data *d)
-{
- macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
- mace->pci.control = macepci_mask;
- crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE);
- crime->imask = crime_mask;
-}
-
-static void disable_macepci_irq(struct irq_data *d)
-{
- crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE));
- crime->imask = crime_mask;
- flush_crime_bus();
- macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
- mace->pci.control = macepci_mask;
- flush_mace_bus();
-}
-
-static struct irq_chip ip32_macepci_interrupt = {
- .name = "IP32 MACE PCI",
- .irq_mask = disable_macepci_irq,
- .irq_unmask = enable_macepci_irq,
-};
-
/* This is used for MACE ISA interrupts. That means bits 4-6 in the
* CRIME register.
*/
@@ -299,8 +267,8 @@ static struct irq_chip ip32_maceisa_edge_interrupt = {
.irq_unmask = enable_maceisa_irq,
};
-/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
- * bits 0-3 and 7 in the CRIME register.
+/* This is used for regular non-ISA MACE interrupts. That means bits 0-3
+ * and 7-15 in the CRIME register.
*/
static void enable_mace_irq(struct irq_data *d)
@@ -436,20 +404,13 @@ void __init arch_init_irq(void)
mips_cpu_irq_init();
for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
switch (irq) {
- case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
+ case MACE_VID_IN1_IRQ ... MACEPCI_SHARED2_IRQ:
irq_set_chip_and_handler_name(irq,
&ip32_mace_interrupt,
handle_level_irq,
"level");
break;
- case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
- irq_set_chip_and_handler_name(irq,
- &ip32_macepci_interrupt,
- handle_level_irq,
- "level");
- break;
-
case CRIME_CPUERR_IRQ:
case CRIME_MEMERR_IRQ:
irq_set_chip_and_handler_name(irq,
--
2.47.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/4] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses
2026-10-21 19:24 [PATCH 0/4] MIPS: sgi-ip32: CRIME 1.1 and MACE PCI fixes Imre Kaloz
2026-10-21 19:24 ` [PATCH 1/4] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Imre Kaloz
@ 2026-10-21 19:24 ` Imre Kaloz
2026-11-05 15:26 ` Thomas Bogendoerfer
2026-10-21 19:24 ` [PATCH 3/4] MIPS: sgi-ip32: Report the real CRIME revision Imre Kaloz
2026-10-21 19:24 ` [PATCH 4/4] MIPS: sgi-ip32: Fence PIO reads on CRIME 1.1 Imre Kaloz
3 siblings, 1 reply; 10+ messages in thread
From: Imre Kaloz @ 2026-10-21 19:24 UTC (permalink / raw)
To: Thomas Bogendoerfer, linux-mips; +Cc: linux-kernel, stable
mace_pci_read_config() clears the master abort interrupt enable in the
MACE PCI control register around each config read. A register read
followed by two register writes can hang CRIME 1.1 under DMA load.
Ack master aborts in the error register instead, and follow every
write with a read so back-to-back accesses cannot form that sequence.
Fixes: c990081bf87b ("[MIPS] Fix IP32 breakage")
Cc: stable@vger.kernel.org
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
---
arch/mips/pci/ops-mace.c | 26 +++++++++++++++++++-------
arch/mips/pci/pci-ip32.c | 2 ++
2 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/arch/mips/pci/ops-mace.c b/arch/mips/pci/ops-mace.c
index 951d8070fb48..8827e5f2ea46 100644
--- a/arch/mips/pci/ops-mace.c
+++ b/arch/mips/pci/ops-mace.c
@@ -35,15 +35,27 @@ static inline int mkaddr(struct pci_bus *bus, unsigned int devfn,
(reg & 0xfc);
}
+/*
+ * On CRIME 1.1, a MACE PCI register read followed by two register writes
+ * can hang the machine under DMA load, so every register write in this
+ * file is followed by a read. Config cycles to empty slots end in a
+ * master abort; ack it with interrupts still off so the bridge error
+ * interrupt does not report it.
+ */
+static void mace_pci_ack_abort(void)
+{
+ u32 error = mace->pci.error;
+
+ if (error & MACEPCI_ERROR_MASTER_ABORT) {
+ mace->pci.error = error & ~MACEPCI_ERROR_MASTER_ABORT;
+ mace->pci.error;
+ }
+}
static int
mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int reg, int size, u32 *val)
{
- u32 control = mace->pci.control;
-
- /* disable master aborts interrupts during config read */
- mace->pci.control = control & ~MACEPCI_CONTROL_MAR_INT;
mace->pci.config_addr = mkaddr(bus, devfn, reg);
switch (size) {
case 1:
@@ -56,9 +68,7 @@ mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
*val = mace->pci.config_data.l;
break;
}
- /* ack possible master abort */
- mace->pci.error &= ~MACEPCI_ERROR_MASTER_ABORT;
- mace->pci.control = control;
+ mace_pci_ack_abort();
/*
* someone forgot to set the ultra bit for the onboard
* scsi chips; we fake it here
@@ -77,6 +87,7 @@ mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
int reg, int size, u32 val)
{
mace->pci.config_addr = mkaddr(bus, devfn, reg);
+ mace->pci.error;
switch (size) {
case 1:
mace->pci.config_data.b[(reg & 3) ^ 3] = val;
@@ -88,6 +99,7 @@ mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
mace->pci.config_data.l = val;
break;
}
+ mace_pci_ack_abort();
DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val);
diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c
index 30aca6f76563..41ec8453c865 100644
--- a/arch/mips/pci/pci-ip32.c
+++ b/arch/mips/pci/pci-ip32.c
@@ -77,6 +77,8 @@ static irqreturn_t macepci_error(int irq, void *dev)
}
mace->pci.error = flags;
+ /* follow the write with a read, see mace_pci_ack_abort() */
+ mace->pci.error;
return IRQ_HANDLED;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/4] MIPS: sgi-ip32: Report the real CRIME revision
2026-10-21 19:24 [PATCH 0/4] MIPS: sgi-ip32: CRIME 1.1 and MACE PCI fixes Imre Kaloz
2026-10-21 19:24 ` [PATCH 1/4] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Imre Kaloz
2026-10-21 19:24 ` [PATCH 2/4] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses Imre Kaloz
@ 2026-10-21 19:24 ` Imre Kaloz
2026-11-05 15:26 ` Thomas Bogendoerfer
2026-10-21 19:24 ` [PATCH 4/4] MIPS: sgi-ip32: Fence PIO reads on CRIME 1.1 Imre Kaloz
3 siblings, 1 reply; 10+ messages in thread
From: Imre Kaloz @ 2026-10-21 19:24 UTC (permalink / raw)
To: Thomas Bogendoerfer, linux-mips; +Cc: linux-kernel
CRIME_ID's low nibble reads 1 on both rev 1.1 and 1.4 chips, so it does
not give the revision. ID 0xa has it in bits 63:32, and ID 0xb is rev
1.5. Decode it, and drop the unused CRIME_ID_REV.
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
---
arch/mips/include/asm/ip32/crime.h | 2 +-
arch/mips/sgi-ip32/crime.c | 26 +++++++++++++++++++++-----
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/arch/mips/include/asm/ip32/crime.h b/arch/mips/include/asm/ip32/crime.h
index 16c94a27beba..8f87b15b772b 100644
--- a/arch/mips/include/asm/ip32/crime.h
+++ b/arch/mips/include/asm/ip32/crime.h
@@ -22,7 +22,7 @@ struct sgi_crime {
#define CRIME_ID_MASK 0xff
#define CRIME_ID_IDBITS 0xf0
#define CRIME_ID_IDVALUE 0xa0
-#define CRIME_ID_REV 0x0f
+#define CRIME_ID_IDVALUE_B 0xb0
#define CRIME_REV_PETTY 0x00
#define CRIME_REV_11 0x11
#define CRIME_REV_13 0x13
diff --git a/arch/mips/sgi-ip32/crime.c b/arch/mips/sgi-ip32/crime.c
index b8a0e4cfa9ce..a24424437c6b 100644
--- a/arch/mips/sgi-ip32/crime.c
+++ b/arch/mips/sgi-ip32/crime.c
@@ -27,7 +27,9 @@ EXPORT_SYMBOL_GPL(mace);
void __init crime_init(void)
{
- unsigned int id, rev;
+ static const char * const revs[] = { "1.1", "1.3", "1.4" };
+ const char *rev;
+ u64 id;
const int field = 2 * sizeof(unsigned long);
set_io_port_base((unsigned long) ioremap(MACEPCI_LOW_IO, 0x2000000));
@@ -35,10 +37,24 @@ void __init crime_init(void)
mace = ioremap(MACE_BASE, sizeof(struct sgi_mace));
id = crime->id;
- rev = id & CRIME_ID_REV;
- id = (id & CRIME_ID_IDBITS) >> 4;
- printk(KERN_INFO "CRIME id %1x rev %d at 0x%0*lx\n",
- id, rev, field, (unsigned long) CRIME_BASE);
+ /* The revision of ID 0xa is in the upper word; 0xb is rev 1.5. */
+ switch (id & CRIME_ID_IDBITS) {
+ case CRIME_ID_IDVALUE:
+ rev = revs[min_t(u64, id >> 32, ARRAY_SIZE(revs) - 1)];
+ break;
+ case CRIME_ID_IDVALUE_B:
+ rev = "1.5";
+ break;
+ case 0x00:
+ rev = "Petty";
+ break;
+ default:
+ rev = "?";
+ break;
+ }
+ pr_info("CRIME id %1x rev %s at 0x%0*lx\n",
+ (unsigned int)(id & CRIME_ID_IDBITS) >> 4, rev, field,
+ (unsigned long)CRIME_BASE);
}
irqreturn_t crime_memerr_intr(int irq, void *dev_id)
--
2.47.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/4] MIPS: sgi-ip32: Fence PIO reads on CRIME 1.1
2026-10-21 19:24 [PATCH 0/4] MIPS: sgi-ip32: CRIME 1.1 and MACE PCI fixes Imre Kaloz
` (2 preceding siblings ...)
2026-10-21 19:24 ` [PATCH 3/4] MIPS: sgi-ip32: Report the real CRIME revision Imre Kaloz
@ 2026-10-21 19:24 ` Imre Kaloz
2026-11-05 15:43 ` Thomas Bogendoerfer
3 siblings, 1 reply; 10+ messages in thread
From: Imre Kaloz @ 2026-10-21 19:24 UTC (permalink / raw)
To: Thomas Bogendoerfer, linux-mips; +Cc: linux-kernel
On CRIME 1.1, a MACE or PCI read within about 2us of a read of some PCI
registers (aic7880 HCNTRL, INTSTAT, ERROR) can return that read's data.
Under audio and SCSI DMA, repeating aic7xxx's ahc_pause(), register
read, ahc_unpause() hangs the machine; fenced, it runs clean, as
measured on an O2 with a CRIME 1.1. The next read can be an interrupt
handler's, so the fence follows the trigger.
Add a read hook to the MIPS accessors that, on CRIME 1.1, follows each
MMIO and port read by 5us with interrupts off. Other platforms compile
it out.
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
---
arch/mips/include/asm/io.h | 11 +++++++
.../include/asm/mach-generic/read-fence.h | 20 +++++++++++++
arch/mips/include/asm/mach-ip32/read-fence.h | 29 +++++++++++++++++++
arch/mips/sgi-ip32/crime.c | 12 ++++++++
4 files changed, 72 insertions(+)
create mode 100644 arch/mips/include/asm/mach-generic/read-fence.h
create mode 100644 arch/mips/include/asm/mach-ip32/read-fence.h
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 980187a83053..a5c49d319546 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -26,6 +26,7 @@
#include <asm/pgtable-bits.h>
#include <asm/string.h>
#include <mangle-port.h>
+#include <read-fence.h>
/*
* Raw operations are never swapped in software. OTOH values that raw
@@ -222,6 +223,8 @@ static inline void pfx##write##bwlq(type val, \
static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
{ \
volatile type *__mem; \
+ unsigned long __rflags; \
+ bool __fence; \
type __val; \
\
__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
@@ -229,6 +232,7 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
if (barrier) \
iobarrier_rw(); \
\
+ __fence = plat_read_fence_begin(&__rflags); \
if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
__val = *__mem; \
else if (cpu_has_64bits) { \
@@ -251,6 +255,8 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
__val = 0; \
BUG(); \
} \
+ if (__fence) \
+ plat_read_fence_end(__rflags); \
\
/* prevent prefetching of coherent DMA data prematurely */ \
if (!relax) \
@@ -283,6 +289,8 @@ static inline void pfx##out##bwlq(type val, unsigned long port) \
static inline type pfx##in##bwlq(unsigned long port) \
{ \
volatile type *__addr; \
+ unsigned long __rflags; \
+ bool __fence; \
type __val; \
\
__addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
@@ -292,7 +300,10 @@ static inline type pfx##in##bwlq(unsigned long port) \
if (barrier) \
iobarrier_rw(); \
\
+ __fence = plat_read_fence_begin(&__rflags); \
__val = *__addr; \
+ if (__fence) \
+ plat_read_fence_end(__rflags); \
\
/* prevent prefetching of coherent DMA data prematurely */ \
if (!relax) \
diff --git a/arch/mips/include/asm/mach-generic/read-fence.h b/arch/mips/include/asm/mach-generic/read-fence.h
new file mode 100644
index 000000000000..0147ed88bc01
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/read-fence.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MACH_GENERIC_READ_FENCE_H
+#define __ASM_MACH_GENERIC_READ_FENCE_H
+
+#include <linux/types.h>
+
+/*
+ * Called around every MMIO and port read; plat_read_fence_end() runs only
+ * when plat_read_fence_begin() returned true.
+ */
+static inline bool plat_read_fence_begin(unsigned long *flags)
+{
+ return false;
+}
+
+static inline void plat_read_fence_end(unsigned long flags)
+{
+}
+
+#endif /* __ASM_MACH_GENERIC_READ_FENCE_H */
diff --git a/arch/mips/include/asm/mach-ip32/read-fence.h b/arch/mips/include/asm/mach-ip32/read-fence.h
new file mode 100644
index 000000000000..7e3105af4c6f
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip32/read-fence.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MACH_IP32_READ_FENCE_H
+#define __ASM_MACH_IP32_READ_FENCE_H
+
+#include <linux/irqflags.h>
+#include <linux/types.h>
+
+extern bool crime_read_fence;
+void crime_read_fence_end(unsigned long flags);
+
+/*
+ * CRIME 1.1 can return a PCI read's data again to the next MACE or PCI
+ * read issued within about 2us, so each read is followed by 5us with
+ * interrupts off.
+ */
+static inline bool plat_read_fence_begin(unsigned long *flags)
+{
+ if (!crime_read_fence)
+ return false;
+ local_irq_save(*flags);
+ return true;
+}
+
+static inline void plat_read_fence_end(unsigned long flags)
+{
+ crime_read_fence_end(flags);
+}
+
+#endif /* __ASM_MACH_IP32_READ_FENCE_H */
diff --git a/arch/mips/sgi-ip32/crime.c b/arch/mips/sgi-ip32/crime.c
index a24424437c6b..0b94150fbec1 100644
--- a/arch/mips/sgi-ip32/crime.c
+++ b/arch/mips/sgi-ip32/crime.c
@@ -7,6 +7,7 @@
* Copyright (C) 2005 Ilya A. Volynets <ilya@total-knowledge.com>
*/
#include <linux/types.h>
+#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
@@ -25,6 +26,16 @@ struct sgi_mace __iomem *mace;
EXPORT_SYMBOL_GPL(mace);
+bool crime_read_fence __read_mostly;
+EXPORT_SYMBOL(crime_read_fence);
+
+void crime_read_fence_end(unsigned long flags)
+{
+ udelay(5);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(crime_read_fence_end);
+
void __init crime_init(void)
{
static const char * const revs[] = { "1.1", "1.3", "1.4" };
@@ -41,6 +52,7 @@ void __init crime_init(void)
switch (id & CRIME_ID_IDBITS) {
case CRIME_ID_IDVALUE:
rev = revs[min_t(u64, id >> 32, ARRAY_SIZE(revs) - 1)];
+ crime_read_fence = !(id >> 32);
break;
case CRIME_ID_IDVALUE_B:
rev = "1.5";
--
2.47.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only
2026-10-21 19:24 ` [PATCH 1/4] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Imre Kaloz
@ 2026-11-05 15:25 ` Thomas Bogendoerfer
0 siblings, 0 replies; 10+ messages in thread
From: Thomas Bogendoerfer @ 2026-11-05 15:25 UTC (permalink / raw)
To: Imre Kaloz; +Cc: linux-mips, linux-kernel, stable
On Wed, Oct 21, 2026 at 09:24:15PM +0200, Imre Kaloz wrote:
> Masking PCI interrupts in the MACE PCI control register overwrites the
> error and arbitration enables set at init, and a read-modify-write can
> hang CRIME 1.1 machines under DMA load. Enable the slot interrupts once
> and mask them in CRIME.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: stable@vger.kernel.org
> Signed-off-by: Imre Kaloz <kaloz@kernel.org>
> ---
> arch/mips/pci/pci-ip32.c | 7 ++++--
> arch/mips/sgi-ip32/ip32-irq.c | 45 +++--------------------------------
> 2 files changed, 8 insertions(+), 44 deletions(-)
applied to mips-fixes
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/4] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses
2026-10-21 19:24 ` [PATCH 2/4] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses Imre Kaloz
@ 2026-11-05 15:26 ` Thomas Bogendoerfer
0 siblings, 0 replies; 10+ messages in thread
From: Thomas Bogendoerfer @ 2026-11-05 15:26 UTC (permalink / raw)
To: Imre Kaloz; +Cc: linux-mips, linux-kernel, stable
On Wed, Oct 21, 2026 at 09:24:16PM +0200, Imre Kaloz wrote:
> mace_pci_read_config() clears the master abort interrupt enable in the
> MACE PCI control register around each config read. A register read
> followed by two register writes can hang CRIME 1.1 under DMA load.
>
> Ack master aborts in the error register instead, and follow every
> write with a read so back-to-back accesses cannot form that sequence.
>
> Fixes: c990081bf87b ("[MIPS] Fix IP32 breakage")
> Cc: stable@vger.kernel.org
> Signed-off-by: Imre Kaloz <kaloz@kernel.org>
> ---
> arch/mips/pci/ops-mace.c | 26 +++++++++++++++++++-------
> arch/mips/pci/pci-ip32.c | 2 ++
> 2 files changed, 21 insertions(+), 7 deletions(-)
applied to mips-fixes
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/4] MIPS: sgi-ip32: Report the real CRIME revision
2026-10-21 19:24 ` [PATCH 3/4] MIPS: sgi-ip32: Report the real CRIME revision Imre Kaloz
@ 2026-11-05 15:26 ` Thomas Bogendoerfer
0 siblings, 0 replies; 10+ messages in thread
From: Thomas Bogendoerfer @ 2026-11-05 15:26 UTC (permalink / raw)
To: Imre Kaloz; +Cc: linux-mips, linux-kernel
On Wed, Oct 21, 2026 at 09:24:17PM +0200, Imre Kaloz wrote:
> CRIME_ID's low nibble reads 1 on both rev 1.1 and 1.4 chips, so it does
> not give the revision. ID 0xa has it in bits 63:32, and ID 0xb is rev
> 1.5. Decode it, and drop the unused CRIME_ID_REV.
>
> Signed-off-by: Imre Kaloz <kaloz@kernel.org>
> ---
> arch/mips/include/asm/ip32/crime.h | 2 +-
> arch/mips/sgi-ip32/crime.c | 26 +++++++++++++++++++++-----
> 2 files changed, 22 insertions(+), 6 deletions(-)
applied to mips-fixes
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 4/4] MIPS: sgi-ip32: Fence PIO reads on CRIME 1.1
2026-10-21 19:24 ` [PATCH 4/4] MIPS: sgi-ip32: Fence PIO reads on CRIME 1.1 Imre Kaloz
@ 2026-11-05 15:43 ` Thomas Bogendoerfer
2026-11-05 19:40 ` Imre Kaloz
0 siblings, 1 reply; 10+ messages in thread
From: Thomas Bogendoerfer @ 2026-11-05 15:43 UTC (permalink / raw)
To: Imre Kaloz; +Cc: linux-mips, linux-kernel
On Wed, Oct 21, 2026 at 09:24:18PM +0200, Imre Kaloz wrote:
> On CRIME 1.1, a MACE or PCI read within about 2us of a read of some PCI
> registers (aic7880 HCNTRL, INTSTAT, ERROR) can return that read's data.
this reads strange, can you clarify what is happening ?
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 4/4] MIPS: sgi-ip32: Fence PIO reads on CRIME 1.1
2026-11-05 15:43 ` Thomas Bogendoerfer
@ 2026-11-05 19:40 ` Imre Kaloz
0 siblings, 0 replies; 10+ messages in thread
From: Imre Kaloz @ 2026-11-05 19:40 UTC (permalink / raw)
To: Thomas Bogendoerfer; +Cc: linux-mips, linux-kernel
On Thu, Nov 5, 2026, at 16:43, Thomas Bogendoerfer wrote:
> On Wed, Oct 21, 2026 at 09:24:18PM +0200, Imre Kaloz wrote:
>> On CRIME 1.1, a MACE or PCI read within about 2us of a read of some PCI
>> registers (aic7880 HCNTRL, INTSTAT, ERROR) can return that read's data.
>
> this reads strange, can you clarify what is happening ?
When the CPU reads one of those aic7880 registers and issues another
uncached load right after it, the second load sometimes returns the
first one's data instead of its own: readb() of HCNTRL returns 0x02,
and the readb() that follows returns 0x02 as well. The second read
does not have to go to the same chip; the other aic7880 and MACE's
MAC_CTRL get the stale data too.
It only shows up with audio and SCSI DMA running, a few hundred times
in 25 million read pairs. A gap of 2us between the two loads cures it,
masking interrupts alone does not. CRIME 1.4 does not do it, and IRIX
also delays around each PCI PIO read on CRIME 1.1.
I'll reword that paragraph in a v2.
Thanks,
Imre
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-11-05 19:41 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-21 19:24 [PATCH 0/4] MIPS: sgi-ip32: CRIME 1.1 and MACE PCI fixes Imre Kaloz
2026-10-21 19:24 ` [PATCH 1/4] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Imre Kaloz
2026-11-05 15:25 ` Thomas Bogendoerfer
2026-10-21 19:24 ` [PATCH 2/4] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses Imre Kaloz
2026-11-05 15:26 ` Thomas Bogendoerfer
2026-10-21 19:24 ` [PATCH 3/4] MIPS: sgi-ip32: Report the real CRIME revision Imre Kaloz
2026-11-05 15:26 ` Thomas Bogendoerfer
2026-10-21 19:24 ` [PATCH 4/4] MIPS: sgi-ip32: Fence PIO reads on CRIME 1.1 Imre Kaloz
2026-11-05 15:43 ` Thomas Bogendoerfer
2026-11-05 19:40 ` Imre Kaloz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox