提交 0591f31b 编写于 作者: M Marc Zyngier 提交者: Zheng Zengkai

irqchip/gic-v3: Fix GICR_CTLR.RWP polling

stable inclusion
from stable-v5.10.111
commit ff24114bb08d8b90edf2aff0a4fd0689523e6c17
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5GL1Z

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=ff24114bb08d8b90edf2aff0a4fd0689523e6c17

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

commit 0df66645 upstream.

It turns out that our polling of RWP is totally wrong when checking
for it in the redistributors, as we test the *distributor* bit index,
whereas it is a different bit number in the RDs... Oopsie boo.

This is embarassing. Not only because it is wrong, but also because
it took *8 years* to notice the blunder...

Just fix the damn thing.

Fixes: 021f6537 ("irqchip: gic-v3: Initial support for GICv3")
Signed-off-by: NMarc Zyngier <maz@kernel.org>
Cc: stable@vger.kernel.org
Reviewed-by: NAndre Przywara <andre.przywara@arm.com>
Reviewed-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Link: https://lore.kernel.org/r/20220315165034.794482-2-maz@kernel.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Reviewed-by: NWei Li <liwei391@huawei.com>
上级 14b1b102
...@@ -206,11 +206,11 @@ static inline void __iomem *gic_dist_base(struct irq_data *d) ...@@ -206,11 +206,11 @@ static inline void __iomem *gic_dist_base(struct irq_data *d)
} }
} }
static void gic_do_wait_for_rwp(void __iomem *base) static void gic_do_wait_for_rwp(void __iomem *base, u32 bit)
{ {
u32 count = 1000000; /* 1s! */ u32 count = 1000000; /* 1s! */
while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) { while (readl_relaxed(base + GICD_CTLR) & bit) {
count--; count--;
if (!count) { if (!count) {
pr_err_ratelimited("RWP timeout, gone fishing\n"); pr_err_ratelimited("RWP timeout, gone fishing\n");
...@@ -224,13 +224,13 @@ static void gic_do_wait_for_rwp(void __iomem *base) ...@@ -224,13 +224,13 @@ static void gic_do_wait_for_rwp(void __iomem *base)
/* Wait for completion of a distributor change */ /* Wait for completion of a distributor change */
static void gic_dist_wait_for_rwp(void) static void gic_dist_wait_for_rwp(void)
{ {
gic_do_wait_for_rwp(gic_data.dist_base); gic_do_wait_for_rwp(gic_data.dist_base, GICD_CTLR_RWP);
} }
/* Wait for completion of a redistributor change */ /* Wait for completion of a redistributor change */
static void gic_redist_wait_for_rwp(void) static void gic_redist_wait_for_rwp(void)
{ {
gic_do_wait_for_rwp(gic_data_rdist_rd_base()); gic_do_wait_for_rwp(gic_data_rdist_rd_base(), GICR_CTLR_RWP);
} }
#ifdef CONFIG_ARM64 #ifdef CONFIG_ARM64
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册