From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit 4775bc63f880 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
--------------------------
As we are about to change the registers that are used by the driver, start by adding build-time checks to ensure that we always handle all registers and access modes.
Suggested-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-2-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm/include/asm/arch_timer.h | 12 ++++++++++++ arch/arm64/include/asm/arch_timer.h | 13 ++++++++++++- drivers/clocksource/arm_arch_timer.c | 8 ++++++++ 3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index 99175812d903..a5d27cff28fa 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -34,6 +34,8 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) case ARCH_TIMER_REG_TVAL: asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); break; + default: + BUILD_BUG(); } } else if (access == ARCH_TIMER_VIRT_ACCESS) { switch (reg) { @@ -43,7 +45,11 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) case ARCH_TIMER_REG_TVAL: asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val)); break; + default: + BUILD_BUG(); } + } else { + BUILD_BUG(); }
isb(); @@ -62,6 +68,8 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) case ARCH_TIMER_REG_TVAL: asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); break; + default: + BUILD_BUG(); } } else if (access == ARCH_TIMER_VIRT_ACCESS) { switch (reg) { @@ -71,7 +79,11 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) case ARCH_TIMER_REG_TVAL: asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val)); break; + default: + BUILD_BUG(); } + } else { + BUILD_BUG(); }
return val; diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index ce37c14f9417..7dfb7c6261bb 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -112,6 +112,8 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) case ARCH_TIMER_REG_TVAL: write_sysreg(val, cntp_tval_el0); break; + default: + BUILD_BUG(); } } else if (access == ARCH_TIMER_VIRT_ACCESS) { switch (reg) { @@ -121,7 +123,11 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) case ARCH_TIMER_REG_TVAL: write_sysreg(val, cntv_tval_el0); break; + default: + BUILD_BUG(); } + } else { + BUILD_BUG(); }
isb(); @@ -136,6 +142,8 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) return read_sysreg(cntp_ctl_el0); case ARCH_TIMER_REG_TVAL: return arch_timer_reg_read_stable(cntp_tval_el0); + default: + BUILD_BUG(); } } else if (access == ARCH_TIMER_VIRT_ACCESS) { switch (reg) { @@ -143,10 +151,13 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) return read_sysreg(cntv_ctl_el0); case ARCH_TIMER_REG_TVAL: return arch_timer_reg_read_stable(cntv_tval_el0); + default: + BUILD_BUG(); } }
- BUG(); + BUILD_BUG(); + unreachable(); }
static inline u32 arch_timer_get_cntfrq(void) diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 3ea1c22314f9..f3c65e5181ec 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -103,6 +103,8 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val, case ARCH_TIMER_REG_TVAL: writel_relaxed(val, timer->base + CNTP_TVAL); break; + default: + BUILD_BUG(); } } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) { struct arch_timer *timer = to_arch_timer(clk); @@ -113,6 +115,8 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val, case ARCH_TIMER_REG_TVAL: writel_relaxed(val, timer->base + CNTV_TVAL); break; + default: + BUILD_BUG(); } } else { arch_timer_reg_write_cp15(access, reg, val); @@ -134,6 +138,8 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, case ARCH_TIMER_REG_TVAL: val = readl_relaxed(timer->base + CNTP_TVAL); break; + default: + BUILD_BUG(); } } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) { struct arch_timer *timer = to_arch_timer(clk); @@ -144,6 +150,8 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, case ARCH_TIMER_REG_TVAL: val = readl_relaxed(timer->base + CNTV_TVAL); break; + default: + BUILD_BUG(); } } else { val = arch_timer_reg_read_cp15(access, reg);
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit d72689988d67 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
The arch timer driver never reads the various TVAL registers, only writes to them. It is thus pointless to provide accessors for them and to implement errata workarounds.
Drop these read-side accessors, and add a couple of BUG() statements for the time being. These statements will be removed further down the line.
Reviewed-by: Oliver Upton oupton@google.com Reviewed-by: Mark Rutland mark.rutland@arm.com Tested-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-3-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm/include/asm/arch_timer.h | 6 ---- arch/arm64/include/asm/arch_timer.h | 17 ----------- drivers/clocksource/arm_arch_timer.c | 44 ---------------------------- 3 files changed, 67 deletions(-)
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index a5d27cff28fa..7d757085c61a 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -65,9 +65,6 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) case ARCH_TIMER_REG_CTRL: asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val)); break; - case ARCH_TIMER_REG_TVAL: - asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); - break; default: BUILD_BUG(); } @@ -76,9 +73,6 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) case ARCH_TIMER_REG_CTRL: asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val)); break; - case ARCH_TIMER_REG_TVAL: - asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val)); - break; default: BUILD_BUG(); } diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 7dfb7c6261bb..a57c0fb7ab02 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -52,8 +52,6 @@ struct arch_timer_erratum_workaround { enum arch_timer_erratum_match_type match_type; const void *id; const char *desc; - u32 (*read_cntp_tval_el0)(void); - u32 (*read_cntv_tval_el0)(void); u64 (*read_cntpct_el0)(void); u64 (*read_cntvct_el0)(void); int (*set_next_event_phys)(unsigned long, struct clock_event_device *); @@ -64,17 +62,6 @@ struct arch_timer_erratum_workaround { DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround);
-/* inline sysreg accessors that make erratum_handler() work */ -static inline notrace u32 arch_timer_read_cntp_tval_el0(void) -{ - return read_sysreg(cntp_tval_el0); -} - -static inline notrace u32 arch_timer_read_cntv_tval_el0(void) -{ - return read_sysreg(cntv_tval_el0); -} - static inline notrace u64 arch_timer_read_cntpct_el0(void) { return read_sysreg(cntpct_el0); @@ -140,8 +127,6 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) switch (reg) { case ARCH_TIMER_REG_CTRL: return read_sysreg(cntp_ctl_el0); - case ARCH_TIMER_REG_TVAL: - return arch_timer_reg_read_stable(cntp_tval_el0); default: BUILD_BUG(); } @@ -149,8 +134,6 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) switch (reg) { case ARCH_TIMER_REG_CTRL: return read_sysreg(cntv_ctl_el0); - case ARCH_TIMER_REG_TVAL: - return arch_timer_reg_read_stable(cntv_tval_el0); default: BUILD_BUG(); } diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index f3c65e5181ec..b481596ef3cd 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -135,9 +135,6 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, case ARCH_TIMER_REG_CTRL: val = readl_relaxed(timer->base + CNTP_CTL); break; - case ARCH_TIMER_REG_TVAL: - val = readl_relaxed(timer->base + CNTP_TVAL); - break; default: BUILD_BUG(); } @@ -147,9 +144,6 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, case ARCH_TIMER_REG_CTRL: val = readl_relaxed(timer->base + CNTV_CTL); break; - case ARCH_TIMER_REG_TVAL: - val = readl_relaxed(timer->base + CNTV_TVAL); - break; default: BUILD_BUG(); } @@ -237,16 +231,6 @@ struct ate_acpi_oem_info { _new; \ })
-static u32 notrace fsl_a008585_read_cntp_tval_el0(void) -{ - return __fsl_a008585_read_reg(cntp_tval_el0); -} - -static u32 notrace fsl_a008585_read_cntv_tval_el0(void) -{ - return __fsl_a008585_read_reg(cntv_tval_el0); -} - static u64 notrace fsl_a008585_read_cntpct_el0(void) { return __fsl_a008585_read_reg(cntpct_el0); @@ -283,16 +267,6 @@ static u64 notrace fsl_a008585_read_cntvct_el0(void) _new; \ })
-static u32 notrace hisi_161010101_read_cntp_tval_el0(void) -{ - return __hisi_161010101_read_reg(cntp_tval_el0); -} - -static u32 notrace hisi_161010101_read_cntv_tval_el0(void) -{ - return __hisi_161010101_read_reg(cntv_tval_el0); -} - static u64 notrace hisi_161010101_read_cntpct_el0(void) { return __hisi_161010101_read_reg(cntpct_el0); @@ -377,16 +351,6 @@ static u64 notrace sun50i_a64_read_cntvct_el0(void) { return __sun50i_a64_read_reg(cntvct_el0); } - -static u32 notrace sun50i_a64_read_cntp_tval_el0(void) -{ - return read_sysreg(cntp_cval_el0) - sun50i_a64_read_cntpct_el0(); -} - -static u32 notrace sun50i_a64_read_cntv_tval_el0(void) -{ - return read_sysreg(cntv_cval_el0) - sun50i_a64_read_cntvct_el0(); -} #endif
#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND @@ -436,8 +400,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .match_type = ate_match_dt, .id = "fsl,erratum-a008585", .desc = "Freescale erratum a005858", - .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0, - .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0, .read_cntpct_el0 = fsl_a008585_read_cntpct_el0, .read_cntvct_el0 = fsl_a008585_read_cntvct_el0, .set_next_event_phys = erratum_set_next_event_tval_phys, @@ -449,8 +411,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .match_type = ate_match_dt, .id = "hisilicon,erratum-161010101", .desc = "HiSilicon erratum 161010101", - .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0, - .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0, .read_cntpct_el0 = hisi_161010101_read_cntpct_el0, .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, .set_next_event_phys = erratum_set_next_event_tval_phys, @@ -460,8 +420,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .match_type = ate_match_acpi_oem_info, .id = hisi_161010101_oem_info, .desc = "HiSilicon erratum 161010101", - .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0, - .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0, .read_cntpct_el0 = hisi_161010101_read_cntpct_el0, .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, .set_next_event_phys = erratum_set_next_event_tval_phys, @@ -482,8 +440,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .match_type = ate_match_dt, .id = "allwinner,erratum-unknown1", .desc = "Allwinner erratum UNKNOWN1", - .read_cntp_tval_el0 = sun50i_a64_read_cntp_tval_el0, - .read_cntv_tval_el0 = sun50i_a64_read_cntv_tval_el0, .read_cntpct_el0 = sun50i_a64_read_cntpct_el0, .read_cntvct_el0 = sun50i_a64_read_cntvct_el0, .set_next_event_phys = erratum_set_next_event_tval_phys,
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit 1e8d929231cf category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
The various accessors for the timer sysreg and MMIO registers are currently hardwired to 32bit. However, we are about to introduce the use of the CVAL registers, which require a 64bit access.
Upgrade the write side of the accessors to take a 64bit value (the read side is left untouched as we don't plan to ever read back any of these registers).
No functional change expected.
Reviewed-by: Oliver Upton oupton@google.com Reviewed-by: Mark Rutland mark.rutland@arm.com Tested-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-4-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm/include/asm/arch_timer.h | 10 +++++----- arch/arm64/include/asm/arch_timer.h | 2 +- drivers/clocksource/arm_arch_timer.c | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index 7d757085c61a..1482e70da7d3 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -24,15 +24,15 @@ int arch_timer_arch_init(void); * the code. At least it does so with a recent GCC (4.6.3). */ static __always_inline -void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) +void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) { if (access == ARCH_TIMER_PHYS_ACCESS) { switch (reg) { case ARCH_TIMER_REG_CTRL: - asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val)); + asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val)); break; case ARCH_TIMER_REG_TVAL: - asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); + asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" ((u32)val)); break; default: BUILD_BUG(); @@ -40,10 +40,10 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) } else if (access == ARCH_TIMER_VIRT_ACCESS) { switch (reg) { case ARCH_TIMER_REG_CTRL: - asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val)); + asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val)); break; case ARCH_TIMER_REG_TVAL: - asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val)); + asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" ((u32)val)); break; default: BUILD_BUG(); diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index a57c0fb7ab02..6b6ce6f0d914 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -89,7 +89,7 @@ static inline notrace u64 arch_timer_read_cntvct_el0(void) * the code. */ static __always_inline -void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) +void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) { if (access == ARCH_TIMER_PHYS_ACCESS) { switch (reg) { diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index b481596ef3cd..2e2fa49d3531 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -91,17 +91,17 @@ early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg); */
static __always_inline -void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val, +void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val, struct clock_event_device *clk) { if (access == ARCH_TIMER_MEM_PHYS_ACCESS) { struct arch_timer *timer = to_arch_timer(clk); switch (reg) { case ARCH_TIMER_REG_CTRL: - writel_relaxed(val, timer->base + CNTP_CTL); + writel_relaxed((u32)val, timer->base + CNTP_CTL); break; case ARCH_TIMER_REG_TVAL: - writel_relaxed(val, timer->base + CNTP_TVAL); + writel_relaxed((u32)val, timer->base + CNTP_TVAL); break; default: BUILD_BUG(); @@ -110,10 +110,10 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val, struct arch_timer *timer = to_arch_timer(clk); switch (reg) { case ARCH_TIMER_REG_CTRL: - writel_relaxed(val, timer->base + CNTV_CTL); + writel_relaxed((u32)val, timer->base + CNTV_CTL); break; case ARCH_TIMER_REG_TVAL: - writel_relaxed(val, timer->base + CNTV_TVAL); + writel_relaxed((u32)val, timer->base + CNTV_TVAL); break; default: BUILD_BUG();
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit a38b71b0833e category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
In order to cope better with high frequency counters, move the programming of the timers from the countdown timer (TVAL) over to the comparator (CVAL).
The programming model is slightly different, as we now need to read the current counter value to have an absolute deadline instead of a relative one.
There is a small overhead to this change, which we will address in the following patches.
Reviewed-by: Oliver Upton oupton@google.com Reviewed-by: Mark Rutland mark.rutland@arm.com Tested-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-5-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm/include/asm/arch_timer.h | 8 ++++---- arch/arm64/include/asm/arch_timer.h | 10 +++++----- drivers/clocksource/arm_arch_timer.c | 26 +++++++++++++++++++++++--- include/clocksource/arm_arch_timer.h | 1 + 4 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index 1482e70da7d3..a9b2b721c7f9 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -31,8 +31,8 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) case ARCH_TIMER_REG_CTRL: asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val)); break; - case ARCH_TIMER_REG_TVAL: - asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" ((u32)val)); + case ARCH_TIMER_REG_CVAL: + asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val)); break; default: BUILD_BUG(); @@ -42,8 +42,8 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) case ARCH_TIMER_REG_CTRL: asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val)); break; - case ARCH_TIMER_REG_TVAL: - asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" ((u32)val)); + case ARCH_TIMER_REG_CVAL: + asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val)); break; default: BUILD_BUG(); diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 6b6ce6f0d914..53aee93d1c93 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -96,8 +96,8 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) case ARCH_TIMER_REG_CTRL: write_sysreg(val, cntp_ctl_el0); break; - case ARCH_TIMER_REG_TVAL: - write_sysreg(val, cntp_tval_el0); + case ARCH_TIMER_REG_CVAL: + write_sysreg(val, cntp_cval_el0); break; default: BUILD_BUG(); @@ -107,8 +107,8 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) case ARCH_TIMER_REG_CTRL: write_sysreg(val, cntv_ctl_el0); break; - case ARCH_TIMER_REG_TVAL: - write_sysreg(val, cntv_tval_el0); + case ARCH_TIMER_REG_CVAL: + write_sysreg(val, cntv_cval_el0); break; default: BUILD_BUG(); @@ -121,7 +121,7 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) }
static __always_inline -u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) +u64 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) { if (access == ARCH_TIMER_PHYS_ACCESS) { switch (reg) { diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 2e2fa49d3531..e94ef4ff0a2e 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -690,10 +690,18 @@ static __always_inline void set_next_event(const int access, unsigned long evt, struct clock_event_device *clk) { unsigned long ctrl; + u64 cnt; + ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); ctrl |= ARCH_TIMER_CTRL_ENABLE; ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; - arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk); + + if (access == ARCH_TIMER_PHYS_ACCESS) + cnt = __arch_counter_get_cntpct(); + else + cnt = __arch_counter_get_cntvct(); + + arch_timer_reg_write(access, ARCH_TIMER_REG_CVAL, evt + cnt, clk); arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); }
@@ -711,17 +719,29 @@ static int arch_timer_set_next_event_phys(unsigned long evt, return 0; }
+static __always_inline void set_next_event_mem(const int access, unsigned long evt, + struct clock_event_device *clk) +{ + unsigned long ctrl; + ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); + ctrl |= ARCH_TIMER_CTRL_ENABLE; + ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; + + arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk); + arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); +} + static int arch_timer_set_next_event_virt_mem(unsigned long evt, struct clock_event_device *clk) { - set_next_event(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk); + set_next_event_mem(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk); return 0; }
static int arch_timer_set_next_event_phys_mem(unsigned long evt, struct clock_event_device *clk) { - set_next_event(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk); + set_next_event_mem(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk); return 0; }
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h index 1d68d5613dae..1bc46dd857b0 100644 --- a/include/clocksource/arm_arch_timer.h +++ b/include/clocksource/arm_arch_timer.h @@ -25,6 +25,7 @@ enum arch_timer_reg { ARCH_TIMER_REG_CTRL, ARCH_TIMER_REG_TVAL, + ARCH_TIMER_REG_CVAL, };
enum arch_timer_ppi_nr {
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit ac9ef4f24cb2 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
The '_tval' name in the erratum handling function names doesn't make much sense anymore (and they were using CVAL the first place).
Drop the _tval tag.
Reviewed-by: Oliver Upton oupton@google.com Reviewed-by: Mark Rutland mark.rutland@arm.com Tested-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-6-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/clocksource/arm_arch_timer.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index e94ef4ff0a2e..035e108bcee3 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -359,7 +359,7 @@ EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
static atomic_t timer_unstable_counter_workaround_in_use = ATOMIC_INIT(0);
-static void erratum_set_next_event_tval_generic(const int access, unsigned long evt, +static void erratum_set_next_event_generic(const int access, unsigned long evt, struct clock_event_device *clk) { unsigned long ctrl; @@ -380,17 +380,17 @@ static void erratum_set_next_event_tval_generic(const int access, unsigned long arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); }
-static __maybe_unused int erratum_set_next_event_tval_virt(unsigned long evt, +static __maybe_unused int erratum_set_next_event_virt(unsigned long evt, struct clock_event_device *clk) { - erratum_set_next_event_tval_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk); + erratum_set_next_event_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk); return 0; }
-static __maybe_unused int erratum_set_next_event_tval_phys(unsigned long evt, +static __maybe_unused int erratum_set_next_event_phys(unsigned long evt, struct clock_event_device *clk) { - erratum_set_next_event_tval_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk); + erratum_set_next_event_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk); return 0; }
@@ -402,8 +402,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .desc = "Freescale erratum a005858", .read_cntpct_el0 = fsl_a008585_read_cntpct_el0, .read_cntvct_el0 = fsl_a008585_read_cntvct_el0, - .set_next_event_phys = erratum_set_next_event_tval_phys, - .set_next_event_virt = erratum_set_next_event_tval_virt, + .set_next_event_phys = erratum_set_next_event_phys, + .set_next_event_virt = erratum_set_next_event_virt, }, #endif #ifdef CONFIG_HISILICON_ERRATUM_161010101 @@ -413,8 +413,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .desc = "HiSilicon erratum 161010101", .read_cntpct_el0 = hisi_161010101_read_cntpct_el0, .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, - .set_next_event_phys = erratum_set_next_event_tval_phys, - .set_next_event_virt = erratum_set_next_event_tval_virt, + .set_next_event_phys = erratum_set_next_event_phys, + .set_next_event_virt = erratum_set_next_event_virt, }, { .match_type = ate_match_acpi_oem_info, @@ -422,8 +422,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .desc = "HiSilicon erratum 161010101", .read_cntpct_el0 = hisi_161010101_read_cntpct_el0, .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, - .set_next_event_phys = erratum_set_next_event_tval_phys, - .set_next_event_virt = erratum_set_next_event_tval_virt, + .set_next_event_phys = erratum_set_next_event_phys, + .set_next_event_virt = erratum_set_next_event_virt, }, #endif #ifdef CONFIG_ARM64_ERRATUM_858921 @@ -442,8 +442,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .desc = "Allwinner erratum UNKNOWN1", .read_cntpct_el0 = sun50i_a64_read_cntpct_el0, .read_cntvct_el0 = sun50i_a64_read_cntvct_el0, - .set_next_event_phys = erratum_set_next_event_tval_phys, - .set_next_event_virt = erratum_set_next_event_tval_virt, + .set_next_event_phys = erratum_set_next_event_phys, + .set_next_event_virt = erratum_set_next_event_virt, }, #endif #ifdef CONFIG_ARM64_ERRATUM_1418040
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit 72f47a3f0ea4 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
The MMIO timer base address gets published after we have registered the callbacks and the interrupt handler, which is... a bit dangerous.
Fix this by moving the base address publication to the point where we register the timer, and expose a pointer to the timer structure itself rather than a naked value.
Reviewed-by: Oliver Upton oupton@google.com Reviewed-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-7-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org
Conflicts: drivers/clocksource/arm_arch_timer.c [fix conflicts caused by extra '__ro_after_init'] Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/clocksource/arm_arch_timer.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 035e108bcee3..cfcdc4b24ee4 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -51,13 +51,13 @@
static unsigned arch_timers_present __initdata;
-static void __iomem *arch_counter_base; - struct arch_timer { void __iomem *base; struct clock_event_device evt; };
+static struct arch_timer *arch_timer_mem __ro_after_init; + #define to_arch_timer(e) container_of(e, struct arch_timer, evt)
static u32 arch_timer_rate; @@ -972,9 +972,9 @@ static u64 arch_counter_get_cntvct_mem(void) u32 vct_lo, vct_hi, tmp_hi;
do { - vct_hi = readl_relaxed(arch_counter_base + CNTVCT_HI); - vct_lo = readl_relaxed(arch_counter_base + CNTVCT_LO); - tmp_hi = readl_relaxed(arch_counter_base + CNTVCT_HI); + vct_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI); + vct_lo = readl_relaxed(arch_timer_mem->base + CNTVCT_LO); + tmp_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI); } while (vct_hi != tmp_hi);
return ((u64) vct_hi << 32) | vct_lo; @@ -1167,25 +1167,25 @@ static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq) { int ret; irq_handler_t func; - struct arch_timer *t;
- t = kzalloc(sizeof(*t), GFP_KERNEL); - if (!t) + arch_timer_mem = kzalloc(sizeof(*arch_timer_mem), GFP_KERNEL); + if (!arch_timer_mem) return -ENOMEM;
- t->base = base; - t->evt.irq = irq; - __arch_timer_setup(ARCH_TIMER_TYPE_MEM, &t->evt); + arch_timer_mem->base = base; + arch_timer_mem->evt.irq = irq; + __arch_timer_setup(ARCH_TIMER_TYPE_MEM, &arch_timer_mem->evt);
if (arch_timer_mem_use_virtual) func = arch_timer_handler_virt_mem; else func = arch_timer_handler_phys_mem;
- ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &t->evt); + ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &arch_timer_mem->evt); if (ret) { pr_err("Failed to request mem timer irq\n"); - kfree(t); + kfree(arch_timer_mem); + arch_timer_mem = NULL; }
return ret; @@ -1433,7 +1433,6 @@ arch_timer_mem_frame_register(struct arch_timer_mem_frame *frame) return ret; }
- arch_counter_base = base; arch_timers_present |= ARCH_TIMER_TYPE_MEM;
return 0;
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit 8b82c4f883a7 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
Similarily to the sysreg-based timer, move the MMIO over to using the CVAL registers instead of TVAL. Note that there is no warranty that the 64bit MMIO access will be atomic, but the timer is always disabled at the point where we program CVAL.
Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-8-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm/include/asm/arch_timer.h | 1 + drivers/clocksource/arm_arch_timer.c | 50 +++++++++++++++++++++------- 2 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index a9b2b721c7f9..9f4b895b78f7 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -7,6 +7,7 @@ #include <asm/hwcap.h> #include <linux/clocksource.h> #include <linux/init.h> +#include <linux/io-64-nonatomic-lo-hi.h> #include <linux/types.h>
#include <clocksource/arm_arch_timer.h> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index cfcdc4b24ee4..e3a946a237ab 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -41,11 +41,13 @@ #define CNTACR_RWVT BIT(4) #define CNTACR_RWPT BIT(5)
-#define CNTVCT_LO 0x08 -#define CNTVCT_HI 0x0c +#define CNTVCT_LO 0x00 +#define CNTPCT_LO 0x08 #define CNTFRQ 0x10 +#define CNTP_CVAL_LO 0x20 #define CNTP_TVAL 0x28 #define CNTP_CTL 0x2c +#define CNTV_CVAL_LO 0x30 #define CNTV_TVAL 0x38 #define CNTV_CTL 0x3c
@@ -103,6 +105,13 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val, case ARCH_TIMER_REG_TVAL: writel_relaxed((u32)val, timer->base + CNTP_TVAL); break; + case ARCH_TIMER_REG_CVAL: + /* + * Not guaranteed to be atomic, so the timer + * must be disabled at this point. + */ + writeq_relaxed(val, timer->base + CNTP_CVAL_LO); + break; default: BUILD_BUG(); } @@ -115,6 +124,10 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val, case ARCH_TIMER_REG_TVAL: writel_relaxed((u32)val, timer->base + CNTV_TVAL); break; + case ARCH_TIMER_REG_CVAL: + /* Same restriction as above */ + writeq_relaxed(val, timer->base + CNTV_CVAL_LO); + break; default: BUILD_BUG(); } @@ -719,15 +732,36 @@ static int arch_timer_set_next_event_phys(unsigned long evt, return 0; }
+static u64 arch_counter_get_cnt_mem(struct arch_timer *t, int offset_lo) +{ + u32 cnt_lo, cnt_hi, tmp_hi; + + do { + cnt_hi = readl_relaxed(t->base + offset_lo + 4); + cnt_lo = readl_relaxed(t->base + offset_lo); + tmp_hi = readl_relaxed(t->base + offset_lo + 4); + } while (cnt_hi != tmp_hi); + + return ((u64) cnt_hi << 32) | cnt_lo; +} + static __always_inline void set_next_event_mem(const int access, unsigned long evt, struct clock_event_device *clk) { + struct arch_timer *timer = to_arch_timer(clk); unsigned long ctrl; + u64 cnt; + ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); ctrl |= ARCH_TIMER_CTRL_ENABLE; ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
- arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk); + if (access == ARCH_TIMER_MEM_VIRT_ACCESS) + cnt = arch_counter_get_cnt_mem(timer, CNTVCT_LO); + else + cnt = arch_counter_get_cnt_mem(timer, CNTPCT_LO); + + arch_timer_reg_write(access, ARCH_TIMER_REG_CVAL, evt + cnt, clk); arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); }
@@ -969,15 +1003,7 @@ bool arch_timer_evtstrm_available(void)
static u64 arch_counter_get_cntvct_mem(void) { - u32 vct_lo, vct_hi, tmp_hi; - - do { - vct_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI); - vct_lo = readl_relaxed(arch_timer_mem->base + CNTVCT_LO); - tmp_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI); - } while (vct_hi != tmp_hi); - - return ((u64) vct_hi << 32) | vct_lo; + return arch_counter_get_cnt_mem(arch_timer_mem, CNTVCT_LO); }
static struct arch_timer_kvm_info arch_timer_kvm_info;
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit 30aa08da35e0 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
Proudly tell the code code that we have a timer able to handle 56 bits deltas.
Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-9-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/clocksource/arm_arch_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index e3a946a237ab..ba04d03a7172 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -833,7 +833,7 @@ static void __arch_timer_setup(unsigned type,
clk->set_state_shutdown(clk);
- clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff); + clockevents_config_and_register(clk, arch_timer_rate, 0xf, CLOCKSOURCE_MASK(56)); }
static void arch_timer_evtstrm_enable(int divider)
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit 012f18850452 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
The Applied Micro XGene-1 SoC has a busted implementation of the CVAL register: it looks like it is based on TVAL instead of the other way around. The net effect of this implementation blunder is that the maximum deadline you can program in the timer is 32bit wide.
Use a MIDR check to notice the broken CPU, and reduce the width of the timer to 32bit.
Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-10-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/clocksource/arm_arch_timer.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index ba04d03a7172..2fba11b4c5ee 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -779,9 +779,32 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt, return 0; }
+static u64 __arch_timer_check_delta(void) +{ +#ifdef CONFIG_ARM64 + const struct midr_range broken_cval_midrs[] = { + /* + * XGene-1 implements CVAL in terms of TVAL, meaning + * that the maximum timer range is 32bit. Shame on them. + */ + MIDR_ALL_VERSIONS(MIDR_CPU_MODEL(ARM_CPU_IMP_APM, + APM_CPU_PART_POTENZA)), + {}, + }; + + if (is_midr_in_range_list(read_cpuid_id(), broken_cval_midrs)) { + pr_warn_once("Broken CNTx_CVAL_EL1, limiting width to 32bits"); + return CLOCKSOURCE_MASK(32); + } +#endif + return CLOCKSOURCE_MASK(56); +} + static void __arch_timer_setup(unsigned type, struct clock_event_device *clk) { + u64 max_delta; + clk->features = CLOCK_EVT_FEAT_ONESHOT;
if (type == ARCH_TIMER_TYPE_CP15) { @@ -813,6 +836,7 @@ static void __arch_timer_setup(unsigned type, }
clk->set_next_event = sne; + max_delta = __arch_timer_check_delta(); } else { clk->features |= CLOCK_EVT_FEAT_DYNIRQ; clk->name = "arch_mem_timer"; @@ -829,11 +853,13 @@ static void __arch_timer_setup(unsigned type, clk->set_next_event = arch_timer_set_next_event_phys_mem; } + + max_delta = CLOCKSOURCE_MASK(56); }
clk->set_state_shutdown(clk);
- clockevents_config_and_register(clk, arch_timer_rate, 0xf, CLOCKSOURCE_MASK(56)); + clockevents_config_and_register(clk, arch_timer_rate, 0xf, max_delta); }
static void arch_timer_evtstrm_enable(int divider)
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit 41f8d02a6a55 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
TVAL usage is now long gone, get rid of the leftovers.
Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-11-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/clocksource/arm_arch_timer.c | 8 -------- include/clocksource/arm_arch_timer.h | 1 - 2 files changed, 9 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 2fba11b4c5ee..27d2d93df3f8 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -45,10 +45,8 @@ #define CNTPCT_LO 0x08 #define CNTFRQ 0x10 #define CNTP_CVAL_LO 0x20 -#define CNTP_TVAL 0x28 #define CNTP_CTL 0x2c #define CNTV_CVAL_LO 0x30 -#define CNTV_TVAL 0x38 #define CNTV_CTL 0x3c
static unsigned arch_timers_present __initdata; @@ -102,9 +100,6 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val, case ARCH_TIMER_REG_CTRL: writel_relaxed((u32)val, timer->base + CNTP_CTL); break; - case ARCH_TIMER_REG_TVAL: - writel_relaxed((u32)val, timer->base + CNTP_TVAL); - break; case ARCH_TIMER_REG_CVAL: /* * Not guaranteed to be atomic, so the timer @@ -121,9 +116,6 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val, case ARCH_TIMER_REG_CTRL: writel_relaxed((u32)val, timer->base + CNTV_CTL); break; - case ARCH_TIMER_REG_TVAL: - writel_relaxed((u32)val, timer->base + CNTV_TVAL); - break; case ARCH_TIMER_REG_CVAL: /* Same restriction as above */ writeq_relaxed(val, timer->base + CNTV_CVAL_LO); diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h index 1bc46dd857b0..6b085710ec68 100644 --- a/include/clocksource/arm_arch_timer.h +++ b/include/clocksource/arm_arch_timer.h @@ -24,7 +24,6 @@
enum arch_timer_reg { ARCH_TIMER_REG_CTRL, - ARCH_TIMER_REG_TVAL, ARCH_TIMER_REG_CVAL, };
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit ec8f7f3342c8 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
Switching from TVAL to CVAL has a small drawback: we need an ISB before reading the counter. We cannot get rid of it, but we can instead remove the one that comes just after writing to CVAL.
This reduces the number of ISBs from 3 to 2 when programming the timer.
Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-12-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm/include/asm/arch_timer.h | 4 ++-- arch/arm64/include/asm/arch_timer.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index 9f4b895b78f7..bb129b6d2366 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -31,6 +31,7 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) switch (reg) { case ARCH_TIMER_REG_CTRL: asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val)); + isb(); break; case ARCH_TIMER_REG_CVAL: asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val)); @@ -42,6 +43,7 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) switch (reg) { case ARCH_TIMER_REG_CTRL: asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val)); + isb(); break; case ARCH_TIMER_REG_CVAL: asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val)); @@ -52,8 +54,6 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) } else { BUILD_BUG(); } - - isb(); }
static __always_inline diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 53aee93d1c93..b05018c907d5 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -95,6 +95,7 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) switch (reg) { case ARCH_TIMER_REG_CTRL: write_sysreg(val, cntp_ctl_el0); + isb(); break; case ARCH_TIMER_REG_CVAL: write_sysreg(val, cntp_cval_el0); @@ -106,6 +107,7 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) switch (reg) { case ARCH_TIMER_REG_CTRL: write_sysreg(val, cntv_ctl_el0); + isb(); break; case ARCH_TIMER_REG_CVAL: write_sysreg(val, cntv_cval_el0); @@ -116,8 +118,6 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val) } else { BUILD_BUG(); } - - isb(); }
static __always_inline
From: Oliver Upton oupton@google.com
mainline inclusion from mainline-v5.16-rc1 commit c1153d52c414 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
Unfortunately, the architecture provides no means to determine the bit width of the system counter. However, we do know the following from the specification:
- the system counter is at least 56 bits wide - Roll-over time of not less than 40 years
To date, the arch timer driver has depended on the first property, assuming any system counter to be 56 bits wide and masking off the rest. However, combining a narrow clocksource mask with a high frequency counter could result in prematurely wrapping the system counter by a significant margin. For example, a 56 bit wide, 1GHz system counter would wrap in a mere 2.28 years!
This is a problem for two reasons: v8.6+ implementations are required to provide a 64 bit, 1GHz system counter. Furthermore, before v8.6, implementers may select a counter frequency of their choosing.
Fix the issue by deriving a valid clock mask based on the second property from above. Set the floor at 56 bits, since we know no system counter is narrower than that.
[maz: fixed width computation not to lose the last bit, added max delta generation for the timer]
Suggested-by: Marc Zyngier maz@kernel.org Signed-off-by: Oliver Upton oupton@google.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20210807191428.3488948-1-oupton@google.com Link: https://lore.kernel.org/r/20211017124225.3018098-13-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/clocksource/arm_arch_timer.c | 34 ++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 27d2d93df3f8..447e2a688113 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -49,6 +49,12 @@ #define CNTV_CVAL_LO 0x30 #define CNTV_CTL 0x3c
+/* + * The minimum amount of time a generic counter is guaranteed to not roll over + * (40 years) + */ +#define MIN_ROLLOVER_SECS (40ULL * 365 * 24 * 3600) + static unsigned arch_timers_present __initdata;
struct arch_timer { @@ -86,6 +92,22 @@ static int __init early_evtstrm_cfg(char *buf) } early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
+/* + * Makes an educated guess at a valid counter width based on the Generic Timer + * specification. Of note: + * 1) the system counter is at least 56 bits wide + * 2) a roll-over time of not less than 40 years + * + * See 'ARM DDI 0487G.a D11.1.2 ("The system counter")' for more details. + */ +static int arch_counter_get_width(void) +{ + u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_rate; + + /* guarantee the returned width is within the valid range */ + return clamp_val(ilog2(min_cycles - 1) + 1, 56, 64); +} + /* * Architected system timer support. */ @@ -202,13 +224,11 @@ static struct clocksource clocksource_counter = { .name = "arch_sys_counter", .rating = 400, .read = arch_counter_read, - .mask = CLOCKSOURCE_MASK(56), .flags = CLOCK_SOURCE_IS_CONTINUOUS, };
static struct cyclecounter cyclecounter __ro_after_init = { .read = arch_counter_read_cc, - .mask = CLOCKSOURCE_MASK(56), };
struct ate_acpi_oem_info { @@ -789,7 +809,7 @@ static u64 __arch_timer_check_delta(void) return CLOCKSOURCE_MASK(32); } #endif - return CLOCKSOURCE_MASK(56); + return CLOCKSOURCE_MASK(arch_counter_get_width()); }
static void __arch_timer_setup(unsigned type, @@ -1034,6 +1054,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_register(unsigned type) { u64 start_count; + int width;
/* Register the CP15 based counter if we have one */ if (type & ARCH_TIMER_TYPE_CP15) { @@ -1060,6 +1081,10 @@ static void __init arch_counter_register(unsigned type) arch_timer_read_counter = arch_counter_get_cntvct_mem; }
+ width = arch_counter_get_width(); + clocksource_counter.mask = CLOCKSOURCE_MASK(width); + cyclecounter.mask = CLOCKSOURCE_MASK(width); + if (!arch_counter_suspend_stop) clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; start_count = arch_timer_read_counter(); @@ -1069,8 +1094,7 @@ static void __init arch_counter_register(unsigned type) timecounter_init(&arch_timer_kvm_info.timecounter, &cyclecounter, start_count);
- /* 56 bits minimum, so we assume worst case rollover */ - sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate); + sched_clock_register(arch_timer_read_counter, width, arch_timer_rate); }
static void arch_timer_stop(struct clock_event_device *clk)
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit db26f8f2da92 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
We currently handle synchronisation when workarounds are enabled by having an ISB in the __arch_counter_get_cnt?ct_stable() helpers.
While this works, this prevents us from relaxing this synchronisation.
Instead, move it closer to the point where the synchronisation is actually needed. Further patches will subsequently relax this.
Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-14-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/include/asm/arch_timer.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index b05018c907d5..637bb985a330 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -32,7 +32,7 @@ ({ \ const struct arch_timer_erratum_workaround *__wa; \ __wa = __this_cpu_read(timer_unstable_counter_workaround); \ - (__wa && __wa->h) ? __wa->h : arch_timer_##h; \ + (__wa && __wa->h) ? ({ isb(); __wa->h;}) : arch_timer_##h; \ })
#else @@ -64,11 +64,13 @@ DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
static inline notrace u64 arch_timer_read_cntpct_el0(void) { + isb(); return read_sysreg(cntpct_el0); }
static inline notrace u64 arch_timer_read_cntvct_el0(void) { + isb(); return read_sysreg(cntvct_el0); }
@@ -163,7 +165,6 @@ static __always_inline u64 __arch_counter_get_cntpct_stable(void) { u64 cnt;
- isb(); cnt = arch_timer_reg_read_stable(cntpct_el0); arch_counter_enforce_ordering(cnt); return cnt; @@ -183,7 +184,6 @@ static __always_inline u64 __arch_counter_get_cntvct_stable(void) { u64 cnt;
- isb(); cnt = arch_timer_reg_read_stable(cntvct_el0); arch_counter_enforce_ordering(cnt); return cnt;
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit fdf865988b5a category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
Add a new capability to detect the Enhanced Counter Virtualization feature (FEAT_ECV).
Reviewed-by: Oliver Upton oupton@google.com Acked-by: Will Deacon will@kernel.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-15-maz@kernel.org Signed-off-by: Will Deacon will@kernel.org
Conflicts: arch/arm64/tools/cpucaps [ignore modification in 'arch/arm64/tools/cpucaps' because we don't have this file. Add the modification in arch/arm64/include/asm/cpucaps.h] Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/include/asm/cpucaps.h | 1 + arch/arm64/kernel/cpufeature.c | 10 ++++++++++ 2 files changed, 11 insertions(+)
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index c58a1919bfc9..49b5310ad02d 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -71,6 +71,7 @@ #define ARM64_CLEARPAGE_STNP 61 #define ARM64_HAS_TWED 62 #define ARM64_WORKAROUND_HISILICON_1980005 63 +#define ARM64_HAS_ECV 64
#define ARM64_NCAPS 80
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 4e934aca9f53..d267f00a9b71 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1803,6 +1803,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .sign = FTR_UNSIGNED, .min_field_value = 1, }, + { + .desc = "Enhanced Counter Virtualization", + .capability = ARM64_HAS_ECV, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = has_cpuid_feature, + .sys_reg = SYS_ID_AA64MMFR0_EL1, + .field_pos = ID_AA64MMFR0_ECV_SHIFT, + .sign = FTR_UNSIGNED, + .min_field_value = 1, + }, #ifdef CONFIG_ARM64_PAN { .desc = "Privileged Access Never",
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit 9ee840a96042 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
CNTPCTSS_EL0 and CNTVCTSS_EL0 are alternatives to the usual CNTPCT_EL0 and CNTVCT_EL0 that do not require a previous ISB to be synchronised (SS stands for Self-Synchronising).
Use the ARM64_HAS_ECV capability to control alternative sequences that switch to these low(er)-cost primitives. Note that the counter access in the VDSO is for now left alone until we decide whether we want to allow this.
Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-16-maz@kernel.org Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/include/asm/arch_timer.h | 32 +++++++++++++++++++++-------- arch/arm64/include/asm/sysreg.h | 3 +++ 2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 637bb985a330..fe829b641650 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -64,14 +64,26 @@ DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
static inline notrace u64 arch_timer_read_cntpct_el0(void) { - isb(); - return read_sysreg(cntpct_el0); + u64 cnt; + + asm volatile(ALTERNATIVE("isb\n mrs %0, cntpct_el0", + "nop\n" __mrs_s("%0", SYS_CNTPCTSS_EL0), + ARM64_HAS_ECV) + : "=r" (cnt)); + + return cnt; }
static inline notrace u64 arch_timer_read_cntvct_el0(void) { - isb(); - return read_sysreg(cntvct_el0); + u64 cnt; + + asm volatile(ALTERNATIVE("isb\n mrs %0, cntvct_el0", + "nop\n" __mrs_s("%0", SYS_CNTVCTSS_EL0), + ARM64_HAS_ECV) + : "=r" (cnt)); + + return cnt; }
#define arch_timer_reg_read_stable(reg) \ @@ -174,8 +186,10 @@ static __always_inline u64 __arch_counter_get_cntpct(void) { u64 cnt;
- isb(); - cnt = read_sysreg(cntpct_el0); + asm volatile(ALTERNATIVE("isb\n mrs %0, cntpct_el0", + "nop\n" __mrs_s("%0", SYS_CNTPCTSS_EL0), + ARM64_HAS_ECV) + : "=r" (cnt)); arch_counter_enforce_ordering(cnt); return cnt; } @@ -193,8 +207,10 @@ static __always_inline u64 __arch_counter_get_cntvct(void) { u64 cnt;
- isb(); - cnt = read_sysreg(cntvct_el0); + asm volatile(ALTERNATIVE("isb\n mrs %0, cntvct_el0", + "nop\n" __mrs_s("%0", SYS_CNTVCTSS_EL0), + ARM64_HAS_ECV) + : "=r" (cnt)); arch_counter_enforce_ordering(cnt); return cnt; } diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 5a9ff0d216dc..bc5547727b02 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -450,6 +450,9 @@
#define SYS_CNTFRQ_EL0 sys_reg(3, 3, 14, 0, 0)
+#define SYS_CNTPCTSS_EL0 sys_reg(3, 3, 14, 0, 5) +#define SYS_CNTVCTSS_EL0 sys_reg(3, 3, 14, 0, 6) + #define SYS_CNTP_TVAL_EL0 sys_reg(3, 3, 14, 2, 0) #define SYS_CNTP_CTL_EL0 sys_reg(3, 3, 14, 2, 1) #define SYS_CNTP_CVAL_EL0 sys_reg(3, 3, 14, 2, 2)
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit ae976f063b60 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
Since CNTVCTSS obey the same control bits as CNTVCT, add the necessary decoding to the hook table. Note that there is no known user of this at the moment.
Acked-by: Will Deacon will@kernel.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-17-maz@kernel.org Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/include/asm/esr.h | 6 ++++++ arch/arm64/kernel/traps.c | 11 +++++++++++ 2 files changed, 17 insertions(+)
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 4a76f566e44f..d7638b528c97 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -227,6 +227,9 @@ #define ESR_ELx_SYS64_ISS_SYS_CNTVCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \ ESR_ELx_SYS64_ISS_DIR_READ)
+#define ESR_ELx_SYS64_ISS_SYS_CNTVCTSS (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 6, 14, 0) | \ + ESR_ELx_SYS64_ISS_DIR_READ) + #define ESR_ELx_SYS64_ISS_SYS_CNTFRQ (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 0, 14, 0) | \ ESR_ELx_SYS64_ISS_DIR_READ)
@@ -317,6 +320,9 @@ #define ESR_ELx_CP15_64_ISS_SYS_CNTVCT (ESR_ELx_CP15_64_ISS_SYS_VAL(1, 14) | \ ESR_ELx_CP15_64_ISS_DIR_READ)
+#define ESR_ELx_CP15_64_ISS_SYS_CNTVCTSS (ESR_ELx_CP15_64_ISS_SYS_VAL(9, 14) | \ + ESR_ELx_CP15_64_ISS_DIR_READ) + #define ESR_ELx_CP15_32_ISS_SYS_CNTFRQ (ESR_ELx_CP15_32_ISS_SYS_VAL(0, 0, 14, 0) |\ ESR_ELx_CP15_32_ISS_DIR_READ)
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index ce8055679269..7c05bcf29013 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -562,6 +562,12 @@ static const struct sys64_hook sys64_hooks[] = { .esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCT, .handler = cntvct_read_handler, }, + { + /* Trap read access to CNTVCTSS_EL0 */ + .esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK, + .esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCTSS, + .handler = cntvct_read_handler, + }, { /* Trap read access to CNTFRQ_EL0 */ .esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK, @@ -638,6 +644,11 @@ static const struct sys64_hook cp15_64_hooks[] = { .esr_val = ESR_ELx_CP15_64_ISS_SYS_CNTVCT, .handler = compat_cntvct_read_handler, }, + { + .esr_mask = ESR_ELx_CP15_64_ISS_SYS_MASK, + .esr_val = ESR_ELx_CP15_64_ISS_SYS_CNTVCTSS, + .handler = compat_cntvct_read_handler, + }, {}, };
From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit fee29f008aa3 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
Since userspace can make use of the CNTVSS_EL0 instruction, expose it via a HWCAP.
Suggested-by: Will Deacon will@kernel.org Acked-by: Will Deacon will@kernel.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-18-maz@kernel.org Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- Documentation/arm64/cpu-feature-registers.rst | 12 ++++++++++-- Documentation/arm64/elf_hwcaps.rst | 4 ++++ arch/arm64/include/asm/hwcap.h | 1 + arch/arm64/include/uapi/asm/hwcap.h | 1 + arch/arm64/kernel/cpufeature.c | 3 ++- arch/arm64/kernel/cpuinfo.c | 1 + 6 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/Documentation/arm64/cpu-feature-registers.rst b/Documentation/arm64/cpu-feature-registers.rst index 328e0c454fbd..9f9b8fd06089 100644 --- a/Documentation/arm64/cpu-feature-registers.rst +++ b/Documentation/arm64/cpu-feature-registers.rst @@ -235,7 +235,15 @@ infrastructure: | DPB | [3-0] | y | +------------------------------+---------+---------+
- 6) ID_AA64MMFR2_EL1 - Memory model feature register 2 + 6) ID_AA64MMFR0_EL1 - Memory model feature register 0 + + +------------------------------+---------+---------+ + | Name | bits | visible | + +------------------------------+---------+---------+ + | ECV | [63-60] | y | + +------------------------------+---------+---------+ + + 7) ID_AA64MMFR2_EL1 - Memory model feature register 2
+------------------------------+---------+---------+ | Name | bits | visible | @@ -243,7 +251,7 @@ infrastructure: | AT | [35-32] | y | +------------------------------+---------+---------+
- 7) ID_AA64ZFR0_EL1 - SVE feature ID register 0 + 8) ID_AA64ZFR0_EL1 - SVE feature ID register 0
+------------------------------+---------+---------+ | Name | bits | visible | diff --git a/Documentation/arm64/elf_hwcaps.rst b/Documentation/arm64/elf_hwcaps.rst index bbd9cf54db6c..95e66bd7dd17 100644 --- a/Documentation/arm64/elf_hwcaps.rst +++ b/Documentation/arm64/elf_hwcaps.rst @@ -245,6 +245,10 @@ HWCAP2_MTE Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0010, as described by Documentation/arm64/memory-tagging-extension.rst.
+HWCAP2_ECV + + Functionality implied by ID_AA64MMFR0_EL1.ECV == 0b0001. + 4. Unused AT_HWCAP bits -----------------------
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h index c9c6aa1c4b54..be9cb527b309 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -105,6 +105,7 @@ #define KERNEL_HWCAP_RNG __khwcap2_feature(RNG) #define KERNEL_HWCAP_BTI __khwcap2_feature(BTI) #define KERNEL_HWCAP_MTE __khwcap2_feature(MTE) +#define KERNEL_HWCAP_ECV __khwcap2_feature(ECV)
/* * This yields a mask that user programs can use to figure out what diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h index b8f41aa234ee..7b23b16f21ce 100644 --- a/arch/arm64/include/uapi/asm/hwcap.h +++ b/arch/arm64/include/uapi/asm/hwcap.h @@ -75,5 +75,6 @@ #define HWCAP2_RNG (1 << 16) #define HWCAP2_BTI (1 << 17) #define HWCAP2_MTE (1 << 18) +#define HWCAP2_ECV (1 << 19)
#endif /* _UAPI__ASM_HWCAP_H */ diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index d267f00a9b71..3e6fe8befc63 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -259,7 +259,7 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = { };
static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_ECV_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_ECV_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_FGT_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_EXS_SHIFT, 4, 0), /* @@ -2361,6 +2361,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { #ifdef CONFIG_ARM64_MTE HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE), #endif /* CONFIG_ARM64_MTE */ + HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV), {}, };
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index 1b5ee494488a..50bbce672a3c 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -94,6 +94,7 @@ static const char *const hwcap_str[] = { [KERNEL_HWCAP_RNG] = "rng", [KERNEL_HWCAP_BTI] = "bti", [KERNEL_HWCAP_MTE] = "mte", + [KERNEL_HWCAP_ECV] = "ecv", };
#ifdef CONFIG_AARCH32_EL0
From: Ionela Voinescu ionela.voinescu@arm.com
mainline inclusion from mainline-v5.11-rc1 commit 4b9cf23c179a category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QGH5 CVE: NA
----------------------
In preparation for other uses of Activity Monitors (AMU) cycle counters, place counter read functionality in generic functions that can reused: read_corecnt() and read_constcnt().
As a result, implement update_freq_counters_refs() to replace init_cpu_freq_invariance_counters() and both initialise and update the per-cpu reference variables.
Signed-off-by: Ionela Voinescu ionela.voinescu@arm.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Cc: Will Deacon will@kernel.org Link: https://lore.kernel.org/r/20201106125334.21570-2-ionela.voinescu@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/include/asm/cpufeature.h | 5 +++++ arch/arm64/include/asm/topology.h | 4 +++- arch/arm64/kernel/cpufeature.c | 5 +---- arch/arm64/kernel/topology.c | 23 ++++++++++++++--------- 4 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 2f9258371bb8..925881e32559 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -769,6 +769,11 @@ static inline bool cpu_has_hw_af(void) #ifdef CONFIG_ARM64_AMU_EXTN /* Check whether the cpu supports the Activity Monitors Unit (AMU) */ extern bool cpu_has_amu_feat(int cpu); +#else +static inline bool cpu_has_amu_feat(int cpu) +{ + return false; +} #endif
static inline unsigned int get_vmid_bits(u64 mmfr1) diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h index 11a465243f66..3b8dca4eb08d 100644 --- a/arch/arm64/include/asm/topology.h +++ b/arch/arm64/include/asm/topology.h @@ -16,12 +16,14 @@ int pcibus_to_node(struct pci_bus *bus);
#include <linux/arch_topology.h>
+void update_freq_counters_refs(void); +void topology_scale_freq_tick(void); + #ifdef CONFIG_ARM64_AMU_EXTN /* * Replace task scheduler's default counter-based * frequency-invariance scale factor setting. */ -void topology_scale_freq_tick(void); #define arch_scale_freq_tick topology_scale_freq_tick #endif /* CONFIG_ARM64_AMU_EXTN */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 3e6fe8befc63..04a8bffae5f9 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1568,16 +1568,13 @@ bool cpu_has_amu_feat(int cpu) return cpumask_test_cpu(cpu, &amu_cpus); }
-/* Initialize the use of AMU counters for frequency invariance */ -extern void init_cpu_freq_invariance_counters(void); - static void cpu_amu_enable(struct arm64_cpu_capabilities const *cap) { if (has_cpuid_feature(cap, SCOPE_LOCAL_CPU)) { pr_info("detected CPU%d: Activity Monitors Unit (AMU)\n", smp_processor_id()); cpumask_set_cpu(smp_processor_id(), &amu_cpus); - init_cpu_freq_invariance_counters(); + update_freq_counters_refs(); } }
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index a80fcb6dd88a..bfdb4acda4ba 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -137,6 +137,12 @@ int __init parse_acpi_topology(void) #endif
#ifdef CONFIG_ARM64_AMU_EXTN +#define read_corecnt() read_sysreg_s(SYS_AMEVCNTR0_CORE_EL0) +#define read_constcnt() read_sysreg_s(SYS_AMEVCNTR0_CONST_EL0) +#else +#define read_corecnt() (0UL) +#define read_constcnt() (0UL) +#endif
#undef pr_fmt #define pr_fmt(fmt) "AMU: " fmt @@ -146,13 +152,10 @@ static DEFINE_PER_CPU(u64, arch_const_cycles_prev); static DEFINE_PER_CPU(u64, arch_core_cycles_prev); static cpumask_var_t amu_fie_cpus;
-/* Initialize counter reference per-cpu variables for the current CPU */ -void init_cpu_freq_invariance_counters(void) +void update_freq_counters_refs(void) { - this_cpu_write(arch_core_cycles_prev, - read_sysreg_s(SYS_AMEVCNTR0_CORE_EL0)); - this_cpu_write(arch_const_cycles_prev, - read_sysreg_s(SYS_AMEVCNTR0_CONST_EL0)); + this_cpu_write(arch_core_cycles_prev, read_corecnt()); + this_cpu_write(arch_const_cycles_prev, read_constcnt()); }
static int validate_cpu_freq_invariance_counters(int cpu) @@ -293,11 +296,14 @@ void topology_scale_freq_tick(void) if (!cpumask_test_cpu(cpu, amu_fie_cpus)) return;
- const_cnt = read_sysreg_s(SYS_AMEVCNTR0_CONST_EL0); - core_cnt = read_sysreg_s(SYS_AMEVCNTR0_CORE_EL0); prev_const_cnt = this_cpu_read(arch_const_cycles_prev); prev_core_cnt = this_cpu_read(arch_core_cycles_prev);
+ update_freq_counters_refs(); + + const_cnt = this_cpu_read(arch_const_cycles_prev); + core_cnt = this_cpu_read(arch_core_cycles_prev); + if (unlikely(core_cnt <= prev_core_cnt || const_cnt <= prev_const_cnt)) goto store_and_exit; @@ -322,4 +328,3 @@ void topology_scale_freq_tick(void) this_cpu_write(arch_core_cycles_prev, core_cnt); this_cpu_write(arch_const_cycles_prev, const_cnt); } -#endif /* CONFIG_ARM64_AMU_EXTN */
From: Ionela Voinescu ionela.voinescu@arm.com
mainline inclusion from mainline-v5.11-rc1 commit bc3b6562a1ac category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QGH5 CVE: NA
----------------------
In order for the counter validation function to be reused, split validate_cpu_freq_invariance_counters() into: - freq_counters_valid(cpu) - check cpu for valid cycle counters - freq_inv_set_max_ratio(int cpu, u64 max_rate, u64 ref_rate) - generic function that sets the normalization ratio used by topology_scale_freq_tick()
Signed-off-by: Ionela Voinescu ionela.voinescu@arm.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Cc: Will Deacon will@kernel.org Link: https://lore.kernel.org/r/20201106125334.21570-3-ionela.voinescu@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/kernel/topology.c | 44 +++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index bfdb4acda4ba..dd2dabbfbc89 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -158,45 +158,49 @@ void update_freq_counters_refs(void) this_cpu_write(arch_const_cycles_prev, read_constcnt()); }
-static int validate_cpu_freq_invariance_counters(int cpu) +static inline bool freq_counters_valid(int cpu) { - u64 max_freq_hz, ratio; - if (!cpu_has_amu_feat(cpu)) { pr_debug("CPU%d: counters are not supported.\n", cpu); - return -EINVAL; + return false; }
if (unlikely(!per_cpu(arch_const_cycles_prev, cpu) || !per_cpu(arch_core_cycles_prev, cpu))) { pr_debug("CPU%d: cycle counters are not enabled.\n", cpu); - return -EINVAL; + return false; }
- /* Convert maximum frequency from KHz to Hz and validate */ - max_freq_hz = cpufreq_get_hw_max_freq(cpu) * 1000; - if (unlikely(!max_freq_hz)) { - pr_debug("CPU%d: invalid maximum frequency.\n", cpu); + return true; +} + +static int freq_inv_set_max_ratio(int cpu, u64 max_rate, u64 ref_rate) +{ + u64 ratio; + + if (unlikely(!max_rate || !ref_rate)) { + pr_debug("CPU%d: invalid maximum or reference frequency.\n", + cpu); return -EINVAL; }
/* * Pre-compute the fixed ratio between the frequency of the constant - * counter and the maximum frequency of the CPU. + * reference counter and the maximum frequency of the CPU. * - * const_freq - * arch_max_freq_scale = ---------------- * SCHED_CAPACITY_SCALE² - * cpuinfo_max_freq + * ref_rate + * arch_max_freq_scale = ---------- * SCHED_CAPACITY_SCALE² + * max_rate * * We use a factor of 2 * SCHED_CAPACITY_SHIFT -> SCHED_CAPACITY_SCALE² * in order to ensure a good resolution for arch_max_freq_scale for - * very low arch timer frequencies (down to the KHz range which should + * very low reference frequencies (down to the KHz range which should * be unlikely). */ - ratio = (u64)arch_timer_get_rate() << (2 * SCHED_CAPACITY_SHIFT); - ratio = div64_u64(ratio, max_freq_hz); + ratio = ref_rate << (2 * SCHED_CAPACITY_SHIFT); + ratio = div64_u64(ratio, max_rate); if (!ratio) { - WARN_ONCE(1, "System timer frequency too low.\n"); + WARN_ONCE(1, "Reference frequency too low.\n"); return -EINVAL; }
@@ -243,8 +247,12 @@ static int __init init_amu_fie(void) }
for_each_present_cpu(cpu) { - if (validate_cpu_freq_invariance_counters(cpu)) + if (!freq_counters_valid(cpu) || + freq_inv_set_max_ratio(cpu, + cpufreq_get_hw_max_freq(cpu) * 1000, + arch_timer_get_rate())) continue; + cpumask_set_cpu(cpu, valid_cpus); have_policy |= enable_policy_freq_counters(cpu, valid_cpus); }
From: Ionela Voinescu ionela.voinescu@arm.com
mainline inclusion from mainline-v5.11-rc1 commit 68c5debcc06d category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QGH5 CVE: NA
----------------------
If Activity Monitors (AMUs) are present, two of the counters can be used to implement support for CPPC's (Collaborative Processor Performance Control) delivered and reference performance monitoring functionality using FFH (Functional Fixed Hardware).
Given that counters for a certain CPU can only be read from that CPU, while FFH operations can be called from any CPU for any of the CPUs, use smp_call_function_single() to provide the requested values.
Therefore, depending on the register addresses, the following values are returned: - 0x0 (DeliveredPerformanceCounterRegister): AMU core counter - 0x1 (ReferencePerformanceCounterRegister): AMU constant counter
The use of Activity Monitors is hidden behind the generic cpu_read_{corecnt,constcnt}() functions.
Read functionality for these two registers represents the only current FFH support for CPPC. Read operations for other register values or write operation for all registers are unsupported. Therefore, keep CPPC's FFH unsupported if no CPUs have valid AMU frequency counters. For this purpose, the get_cpu_with_amu_feat() is introduced.
Signed-off-by: Ionela Voinescu ionela.voinescu@arm.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Cc: Will Deacon will@kernel.org Link: https://lore.kernel.org/r/20201106125334.21570-4-ionela.voinescu@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com
[wangxiongfeng: A usecase is as follows.] Name(_CPC, Package() { 23, // NumEntries 3, // Revision 100, // Highest Performance - Fixed 100MHz 100, // Nominal Performance - Fixed 100MHz 1, // Lowest Nonlinear Performance 1, // Lowest Performance ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Guaranteed Performance Register ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Desired Perf Register ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Minimum Performance Register ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Maximum Performance Register ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Performance Red. Tolerance Register ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Time Window Register ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Counter Wraparound Time ResourceTemplate(){Register(FFixedHW, 0x40, 0, 1, 0x4)}, // Reference Performance Counter Register ResourceTemplate(){Register(FFixedHW, 0x40, 0, 0, 0x4)}, // Delivered Performance Counter Register ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Performance Ltd Register ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // CPPC Enable Register ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Autonomous Selection Enable ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Autonomous Activity Window Register ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, // Energy Performance Preference Register 100, // Reference Performance - Fixed 100MHz 1, // Lowest Frequency 100, // Nominal Frequency - Fixed 100MHz })
Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/include/asm/cpufeature.h | 3 ++ arch/arm64/kernel/cpufeature.c | 10 +++++ arch/arm64/kernel/topology.c | 64 +++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 925881e32559..55be75bd3f02 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -776,6 +776,9 @@ static inline bool cpu_has_amu_feat(int cpu) } #endif
+/* Get a cpu that supports the Activity Monitors Unit (AMU) */ +extern int get_cpu_with_amu_feat(void); + static inline unsigned int get_vmid_bits(u64 mmfr1) { int vmid_bits; diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 04a8bffae5f9..04a9cf3d5ea9 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1568,6 +1568,11 @@ bool cpu_has_amu_feat(int cpu) return cpumask_test_cpu(cpu, &amu_cpus); }
+int get_cpu_with_amu_feat(void) +{ + return cpumask_any(&amu_cpus); +} + static void cpu_amu_enable(struct arm64_cpu_capabilities const *cap) { if (has_cpuid_feature(cap, SCOPE_LOCAL_CPU)) { @@ -1596,6 +1601,11 @@ static bool has_amu(const struct arm64_cpu_capabilities *cap,
return true; } +#else +int get_cpu_with_amu_feat(void) +{ + return nr_cpu_ids; +} #endif
#ifdef CONFIG_ARM64_VHE diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index dd2dabbfbc89..f8d9ddc38550 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -160,6 +160,9 @@ void update_freq_counters_refs(void)
static inline bool freq_counters_valid(int cpu) { + if ((cpu >= nr_cpu_ids) || !cpumask_test_cpu(cpu, cpu_present_mask)) + return false; + if (!cpu_has_amu_feat(cpu)) { pr_debug("CPU%d: counters are not supported.\n", cpu); return false; @@ -336,3 +339,64 @@ void topology_scale_freq_tick(void) this_cpu_write(arch_core_cycles_prev, core_cnt); this_cpu_write(arch_const_cycles_prev, const_cnt); } + +#ifdef CONFIG_ACPI_CPPC_LIB +#include <acpi/cppc_acpi.h> + +static void cpu_read_corecnt(void *val) +{ + *(u64 *)val = read_corecnt(); +} + +static void cpu_read_constcnt(void *val) +{ + *(u64 *)val = read_constcnt(); +} + +static inline +int counters_read_on_cpu(int cpu, smp_call_func_t func, u64 *val) +{ + if (!cpu_has_amu_feat(cpu)) + return -EOPNOTSUPP; + + smp_call_function_single(cpu, func, val, 1); + + return 0; +} + +/* + * Refer to drivers/acpi/cppc_acpi.c for the description of the functions + * below. + */ +bool cpc_ffh_supported(void) +{ + return freq_counters_valid(get_cpu_with_amu_feat()); +} + +int cpc_read_ffh(int cpu, struct cpc_reg *reg, u64 *val) +{ + int ret = -EOPNOTSUPP; + + switch ((u64)reg->address) { + case 0x0: + ret = counters_read_on_cpu(cpu, cpu_read_corecnt, val); + break; + case 0x1: + ret = counters_read_on_cpu(cpu, cpu_read_constcnt, val); + break; + } + + if (!ret) { + *val &= GENMASK_ULL(reg->bit_offset + reg->bit_width - 1, + reg->bit_offset); + *val >>= reg->bit_offset; + } + + return ret; +} + +int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val) +{ + return -EOPNOTSUPP; +} +#endif /* CONFIG_ACPI_CPPC_LIB */
From: Ionela Voinescu ionela.voinescu@arm.com
mainline inclusion from mainline-v5.11-rc1 commit 74490422522d category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QGH5 CVE: NA
----------------------
Given that smp_call_function_single() can deadlock when interrupts are disabled, abort the SMP call if irqs_disabled(). This scenario is currently not possible given the function's uses, but safeguard this for potential future uses.
Signed-off-by: Ionela Voinescu ionela.voinescu@arm.com Cc: Will Deacon will@kernel.org Acked-by: Mark Rutland mark.rutland@arm.com Link: https://lore.kernel.org/r/20201113155328.4194-1-ionela.voinescu@arm.com [catalin.marinas@arm.com: modified following Mark's comment] Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/kernel/topology.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index f8d9ddc38550..6f1a8edd79ef 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -356,9 +356,16 @@ static void cpu_read_constcnt(void *val) static inline int counters_read_on_cpu(int cpu, smp_call_func_t func, u64 *val) { + /* + * Abort call on counterless CPU or when interrupts are + * disabled - can lead to deadlock in smp sync call. + */ if (!cpu_has_amu_feat(cpu)) return -EOPNOTSUPP;
+ if (WARN_ON_ONCE(irqs_disabled())) + return -EPERM; + smp_call_function_single(cpu, func, val, 1);
return 0;
From: Ard Biesheuvel ardb@kernel.org
mainline inclusion from mainline-v5.12-rc1 commit 67c6bb56b649 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOJF CVE: NA
----------------------
The ARM architected TRNG firmware interface, described in ARM spec DEN0098, define an ARM SMCCC based interface to a true random number generator, provided by firmware.
Add the definitions of the SMCCC functions as defined by the spec.
Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Andre Przywara andre.przywara@arm.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Reviewed-by: Sudeep Holla sudeep.holla@arm.com Link: https://lore.kernel.org/r/20210106103453.152275-2-andre.przywara@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- include/linux/arm-smccc.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index 42c73106acb1..1df33aaea17e 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -102,6 +102,37 @@ ARM_SMCCC_OWNER_STANDARD_HYP, \ 0x21)
+/* TRNG entropy source calls (defined by ARM DEN0098) */ +#define ARM_SMCCC_TRNG_VERSION \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_STANDARD, \ + 0x50) + +#define ARM_SMCCC_TRNG_FEATURES \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_STANDARD, \ + 0x51) + +#define ARM_SMCCC_TRNG_GET_UUID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_STANDARD, \ + 0x52) + +#define ARM_SMCCC_TRNG_RND32 \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_STANDARD, \ + 0x53) + +#define ARM_SMCCC_TRNG_RND64 \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_STANDARD, \ + 0x53) + /* * Return codes defined in ARM DEN 0070A * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
From: Andre Przywara andre.przywara@arm.com
mainline inclusion from mainline-v5.12-rc1 commit a37e31fc97ef category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOJF CVE: NA
----------------------
The ARM DEN0098 document describe an SMCCC based firmware service to deliver hardware generated random numbers. Its existence is advertised according to the SMCCC v1.1 specification.
Add a (dummy) call to probe functions implemented in each architecture (ARM and arm64), to determine the existence of this interface. For now this return false, but this will be overwritten by each architecture's support patch.
Signed-off-by: Andre Przywara andre.przywara@arm.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Reviewed-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm/include/asm/archrandom.h | 10 ++++++++++ arch/arm64/include/asm/archrandom.h | 12 ++++++++++++ drivers/firmware/smccc/smccc.c | 6 ++++++ 3 files changed, 28 insertions(+) create mode 100644 arch/arm/include/asm/archrandom.h
diff --git a/arch/arm/include/asm/archrandom.h b/arch/arm/include/asm/archrandom.h new file mode 100644 index 000000000000..a8e84ca5c2ee --- /dev/null +++ b/arch/arm/include/asm/archrandom.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ARCHRANDOM_H +#define _ASM_ARCHRANDOM_H + +static inline bool __init smccc_probe_trng(void) +{ + return false; +} + +#endif /* _ASM_ARCHRANDOM_H */ diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h index ffb1a40d5475..abe07c21da8e 100644 --- a/arch/arm64/include/asm/archrandom.h +++ b/arch/arm64/include/asm/archrandom.h @@ -8,6 +8,11 @@ #include <linux/kernel.h> #include <asm/cpufeature.h>
+static inline bool __init smccc_probe_trng(void) +{ + return false; +} + static inline bool __arm64_rndr(unsigned long *v) { bool ok; @@ -79,5 +84,12 @@ arch_get_random_seed_long_early(unsigned long *v) } #define arch_get_random_seed_long_early arch_get_random_seed_long_early
+#else /* !CONFIG_ARCH_RANDOM */ + +static inline bool __init smccc_probe_trng(void) +{ + return false; +} + #endif /* CONFIG_ARCH_RANDOM */ #endif /* _ASM_ARCHRANDOM_H */ diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c index 00c88b809c0c..d52bfc5ed5e4 100644 --- a/drivers/firmware/smccc/smccc.c +++ b/drivers/firmware/smccc/smccc.c @@ -5,16 +5,22 @@
#define pr_fmt(fmt) "smccc: " fmt
+#include <linux/cache.h> #include <linux/init.h> #include <linux/arm-smccc.h> +#include <asm/archrandom.h>
static u32 smccc_version = ARM_SMCCC_VERSION_1_0; static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE;
+bool __ro_after_init smccc_trng_available = false; + void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit) { smccc_version = version; smccc_conduit = conduit; + + smccc_trng_available = smccc_probe_trng(); }
enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void)
From: Andre Przywara andre.przywara@arm.com
mainline inclusion from mainline-v5.12-rc1 commit 38db987316a3 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOJF CVE: NA
----------------------
The ARM architected TRNG firmware interface, described in ARM spec DEN0098, defines an ARM SMCCC based interface to a true random number generator, provided by firmware. This can be discovered via the SMCCC >=v1.1 interface, and provides up to 192 bits of entropy per call.
Hook this SMC call into arm64's arch_get_random_*() implementation, coming to the rescue when the CPU does not implement the ARM v8.5 RNG system registers.
For the detection, we piggy back on the PSCI/SMCCC discovery (which gives us the conduit to use (hvc/smc)), then try to call the ARM_SMCCC_TRNG_VERSION function, which returns -1 if this interface is not implemented.
Reviewed-by: Mark Brown broonie@kernel.org Signed-off-by: Andre Przywara andre.przywara@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/include/asm/archrandom.h | 72 ++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h index abe07c21da8e..09e43272ccb0 100644 --- a/arch/arm64/include/asm/archrandom.h +++ b/arch/arm64/include/asm/archrandom.h @@ -4,13 +4,24 @@
#ifdef CONFIG_ARCH_RANDOM
+#include <linux/arm-smccc.h> #include <linux/bug.h> #include <linux/kernel.h> #include <asm/cpufeature.h>
+#define ARM_SMCCC_TRNG_MIN_VERSION 0x10000UL + +extern bool smccc_trng_available; + static inline bool __init smccc_probe_trng(void) { - return false; + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_VERSION, &res); + if ((s32)res.a0 < 0) + return false; + + return res.a0 >= ARM_SMCCC_TRNG_MIN_VERSION; }
static inline bool __arm64_rndr(unsigned long *v) @@ -43,26 +54,55 @@ static inline bool __must_check arch_get_random_int(unsigned int *v)
static inline bool __must_check arch_get_random_seed_long(unsigned long *v) { + struct arm_smccc_res res; + + /* + * We prefer the SMCCC call, since its semantics (return actual + * hardware backed entropy) is closer to the idea behind this + * function here than what even the RNDRSS register provides + * (the output of a pseudo RNG freshly seeded by a TRNG). + */ + if (smccc_trng_available) { + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 64, &res); + if ((int)res.a0 >= 0) { + *v = res.a3; + return true; + } + } + /* * Only support the generic interface after we have detected * the system wide capability, avoiding complexity with the * cpufeature code and with potential scheduling between CPUs * with and without the feature. */ - if (!cpus_have_const_cap(ARM64_HAS_RNG)) - return false; + if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v)) + return true;
- return __arm64_rndr(v); + return false; }
- static inline bool __must_check arch_get_random_seed_int(unsigned int *v) { + struct arm_smccc_res res; unsigned long val; - bool ok = arch_get_random_seed_long(&val);
- *v = val; - return ok; + if (smccc_trng_available) { + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 32, &res); + if ((int)res.a0 >= 0) { + *v = res.a3 & GENMASK(31, 0); + return true; + } + } + + if (cpus_have_const_cap(ARM64_HAS_RNG)) { + if (__arm64_rndr(&val)) { + *v = val; + return true; + } + } + + return false; }
static inline bool __init __early_cpu_has_rndr(void) @@ -77,10 +117,20 @@ arch_get_random_seed_long_early(unsigned long *v) { WARN_ON(system_state != SYSTEM_BOOTING);
- if (!__early_cpu_has_rndr()) - return false; + if (smccc_trng_available) { + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 64, &res); + if ((int)res.a0 >= 0) { + *v = res.a3; + return true; + } + }
- return __arm64_rndr(v); + if (__early_cpu_has_rndr() && __arm64_rndr(v)) + return true; + + return false; } #define arch_get_random_seed_long_early arch_get_random_seed_long_early
From: Ard Biesheuvel ardb@kernel.org
mainline inclusion from mainline-v5.12-rc1 commit a8e190cdae1b category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOJF CVE: NA
----------------------
Provide a hypervisor implementation of the ARM architected TRNG firmware interface described in ARM spec DEN0098. All function IDs are implemented, including both 32-bit and 64-bit versions of the TRNG_RND service, which is the centerpiece of the API.
The API is backed by the kernel's entropy pool only, to avoid guests draining more precious direct entropy sources.
Signed-off-by: Ard Biesheuvel ardb@kernel.org [Andre: minor fixes, drop arch_get_random() usage] Signed-off-by: Andre Przywara andre.przywara@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20210106103453.152275-6-andre.przywara@arm.com
Conflicts: arch/arm64/include/asm/kvm_host.h arch/arm64/kvm/Makefile arch/arm64/kvm/hypercalls.c [wangxiongfeng: fix conflicts caused by context mismatch.] Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/include/asm/kvm_host.h | 2 + arch/arm64/kvm/Makefile | 2 +- arch/arm64/kvm/hypercalls.c | 6 +++ arch/arm64/kvm/trng.c | 85 +++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/kvm/trng.c
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 93cdc5a2fc97..7e8deca33a02 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -704,6 +704,8 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); #define kvm_vcpu_has_pmu(vcpu) \ (test_bit(KVM_ARM_VCPU_PMU_V3, (vcpu)->arch.features))
+int kvm_trng_call(struct kvm_vcpu *vcpu); + #ifdef CONFIG_ARM64_TWED #define use_twed() (has_twed() && twed_enable) extern bool twed_enable; diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 928065a7bae9..02612bfbbde7 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -16,7 +16,7 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ inject_fault.o regmap.o va_layout.o handle_exit.o \ guest.o debug.o reset.o sys_regs.o \ vgic-sys-reg-v3.o fpsimd.o pmu.o \ - aarch32.o arch_timer.o \ + aarch32.o arch_timer.o trng.o\ hisi_cpu_model.o \ vgic/vgic.o vgic/vgic-init.o \ vgic/vgic-irqfd.o vgic/vgic-v2.o \ diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 02f38b3f8912..10d91047d38a 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -91,6 +91,12 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) case ARM_SMCCC_HV_PV_SCHED_KICK_CPU: val = kvm_pvsched_kick_vcpu(vcpu); break; + case ARM_SMCCC_TRNG_VERSION: + case ARM_SMCCC_TRNG_FEATURES: + case ARM_SMCCC_TRNG_GET_UUID: + case ARM_SMCCC_TRNG_RND32: + case ARM_SMCCC_TRNG_RND64: + return kvm_trng_call(vcpu); default: return kvm_psci_call(vcpu); } diff --git a/arch/arm64/kvm/trng.c b/arch/arm64/kvm/trng.c new file mode 100644 index 000000000000..99bdd7103c9c --- /dev/null +++ b/arch/arm64/kvm/trng.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2020 Arm Ltd. + +#include <linux/arm-smccc.h> +#include <linux/kvm_host.h> + +#include <asm/kvm_emulate.h> + +#include <kvm/arm_hypercalls.h> + +#define ARM_SMCCC_TRNG_VERSION_1_0 0x10000UL + +/* Those values are deliberately separate from the generic SMCCC definitions. */ +#define TRNG_SUCCESS 0UL +#define TRNG_NOT_SUPPORTED ((unsigned long)-1) +#define TRNG_INVALID_PARAMETER ((unsigned long)-2) +#define TRNG_NO_ENTROPY ((unsigned long)-3) + +#define TRNG_MAX_BITS64 192 + +static const uuid_t arm_smc_trng_uuid __aligned(4) = UUID_INIT( + 0x0d21e000, 0x4384, 0x11eb, 0x80, 0x70, 0x52, 0x44, 0x55, 0x4e, 0x5a, 0x4c); + +static int kvm_trng_do_rnd(struct kvm_vcpu *vcpu, int size) +{ + DECLARE_BITMAP(bits, TRNG_MAX_BITS64); + u32 num_bits = smccc_get_arg1(vcpu); + int i; + + if (num_bits > 3 * size) { + smccc_set_retval(vcpu, TRNG_INVALID_PARAMETER, 0, 0, 0); + return 1; + } + + /* get as many bits as we need to fulfil the request */ + for (i = 0; i < DIV_ROUND_UP(num_bits, BITS_PER_LONG); i++) + bits[i] = get_random_long(); + + bitmap_clear(bits, num_bits, TRNG_MAX_BITS64 - num_bits); + + if (size == 32) + smccc_set_retval(vcpu, TRNG_SUCCESS, lower_32_bits(bits[1]), + upper_32_bits(bits[0]), lower_32_bits(bits[0])); + else + smccc_set_retval(vcpu, TRNG_SUCCESS, bits[2], bits[1], bits[0]); + + memzero_explicit(bits, sizeof(bits)); + return 1; +} + +int kvm_trng_call(struct kvm_vcpu *vcpu) +{ + const __le32 *u = (__le32 *)arm_smc_trng_uuid.b; + u32 func_id = smccc_get_function(vcpu); + unsigned long val = TRNG_NOT_SUPPORTED; + int size = 64; + + switch (func_id) { + case ARM_SMCCC_TRNG_VERSION: + val = ARM_SMCCC_TRNG_VERSION_1_0; + break; + case ARM_SMCCC_TRNG_FEATURES: + switch (smccc_get_arg1(vcpu)) { + case ARM_SMCCC_TRNG_VERSION: + case ARM_SMCCC_TRNG_FEATURES: + case ARM_SMCCC_TRNG_GET_UUID: + case ARM_SMCCC_TRNG_RND32: + case ARM_SMCCC_TRNG_RND64: + val = TRNG_SUCCESS; + } + break; + case ARM_SMCCC_TRNG_GET_UUID: + smccc_set_retval(vcpu, le32_to_cpu(u[0]), le32_to_cpu(u[1]), + le32_to_cpu(u[2]), le32_to_cpu(u[3])); + return 1; + case ARM_SMCCC_TRNG_RND32: + size = 32; + fallthrough; + case ARM_SMCCC_TRNG_RND64: + return kvm_trng_do_rnd(vcpu, size); + } + + smccc_set_retval(vcpu, val, 0, 0, 0); + return 1; +}
From: Mark Brown broonie@kernel.org
mainline inclusion from mainline-v5.14-rc1 commit cfa7ff959a78 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QPMK CVE: NA
----------------------
SMCCC v1.2 requires that all SVE state be preserved over SMC calls which introduces substantial overhead in the common case where there is no SVE state in the registers. To avoid this SMCCC v1.3 introduces a flag which allows the caller to say that there is no state that needs to be preserved in the registers. Make use of this flag, setting it if the SMCCC version indicates support for it and the TIF_ flags indicate that there is no live SVE state in the registers, this avoids placing any constraints on when SMCCC calls can be done or triggering extra saving and reloading of SVE register state in the kernel.
This would be straightforward enough except for the rather entertaining inline assembly we use to do SMCCC v1.1 calls to allow us to take advantage of the limited number of registers it clobbers. Deal with this by having a function which we call immediately before issuing the SMCCC call to make our checks and set the flag. Using alternatives the overhead if SVE is supported but not detected at runtime can be reduced to a single NOP.
Signed-off-by: Mark Brown broonie@kernel.org Reviewed-by: Ard Biesheuvel ardb@kernel.org Reviewed-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20210603184118.15090-1-broonie@kernel.org Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/kernel/smccc-call.S | 26 ++++++++++++++++++++++++++ drivers/firmware/smccc/smccc.c | 4 ++++ include/linux/arm-smccc.h | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S index d62447964ed9..0d0a03dd0488 100644 --- a/arch/arm64/kernel/smccc-call.S +++ b/arch/arm64/kernel/smccc-call.S @@ -7,8 +7,34 @@
#include <asm/asm-offsets.h> #include <asm/assembler.h> +#include <asm/thread_info.h> + +/* + * If we have SMCCC v1.3 and (as is likely) no SVE state in + * the registers then set the SMCCC hint bit to say there's no + * need to preserve it. Do this by directly adjusting the SMCCC + * function value which is already stored in x0 ready to be called. + */ +SYM_FUNC_START(__arm_smccc_sve_check) + + ldr_l x16, smccc_has_sve_hint + cbz x16, 2f + + get_current_task x16 + ldr x16, [x16, #TSK_TI_FLAGS] + tbnz x16, #TIF_FOREIGN_FPSTATE, 1f // Any live FP state? + tbnz x16, #TIF_SVE, 2f // Does that state include SVE? + +1: orr x0, x0, ARM_SMCCC_1_3_SVE_HINT + +2: ret +SYM_FUNC_END(__arm_smccc_sve_check) +EXPORT_SYMBOL(__arm_smccc_sve_check)
.macro SMCCC instr +alternative_if ARM64_SVE + bl __arm_smccc_sve_check +alternative_else_nop_endif \instr #0 ldr x4, [sp] stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c index d52bfc5ed5e4..6a6a5b0700a8 100644 --- a/drivers/firmware/smccc/smccc.c +++ b/drivers/firmware/smccc/smccc.c @@ -14,6 +14,7 @@ static u32 smccc_version = ARM_SMCCC_VERSION_1_0; static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE;
bool __ro_after_init smccc_trng_available = false; +u64 __ro_after_init smccc_has_sve_hint = false;
void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit) { @@ -21,6 +22,9 @@ void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit) smccc_conduit = conduit;
smccc_trng_available = smccc_probe_trng(); + if (IS_ENABLED(CONFIG_ARM64_SVE) && + smccc_version >= ARM_SMCCC_VERSION_1_3) + smccc_has_sve_hint = true; }
enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void) diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index 1df33aaea17e..5491c6d46e3a 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -61,6 +61,9 @@ #define ARM_SMCCC_VERSION_1_0 0x10000 #define ARM_SMCCC_VERSION_1_1 0x10001 #define ARM_SMCCC_VERSION_1_2 0x10002 +#define ARM_SMCCC_VERSION_1_3 0x10003 + +#define ARM_SMCCC_1_3_SVE_HINT 0x10000
#define ARM_SMCCC_VERSION_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ @@ -175,6 +178,8 @@ u32 arm_smccc_get_version(void);
void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
+extern u64 smccc_has_sve_hint; + /** * struct arm_smccc_res - Result from SMC/HVC call * @a0-a3 result values from registers 0 to 3 @@ -199,6 +204,15 @@ struct arm_smccc_quirk { } state; };
+/** + * __arm_smccc_sve_check() - Set the SVE hint bit when doing SMC calls + * + * Sets the SMCCC hint bit to indicate if there is live state in the SVE + * registers, this modifies x0 in place and should never be called from C + * code. + */ +asmlinkage unsigned long __arm_smccc_sve_check(unsigned long x0); + /** * __arm_smccc_smc() - make SMC calls * @a0-a7: arguments passed in registers 0 to 7 @@ -256,6 +270,20 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
#endif
+/* nVHE hypervisor doesn't have a current thread so needs separate checks */ +#if defined(CONFIG_ARM64_SVE) && !defined(__KVM_NVHE_HYPERVISOR__) + +#define SMCCC_SVE_CHECK ALTERNATIVE("nop \n", "bl __arm_smccc_sve_check \n", \ + ARM64_SVE) +#define smccc_sve_clobbers "x16", "x30", "cc", + +#else + +#define SMCCC_SVE_CHECK +#define smccc_sve_clobbers + +#endif + #define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
#define __count_args(...) \ @@ -323,7 +351,7 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
#define ___constraints(count) \ : __constraint_read_ ## count \ - : "memory" + : smccc_sve_clobbers "memory" #define __constraints(count) ___constraints(count)
/* @@ -338,7 +366,8 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, register unsigned long r2 asm("r2"); \ register unsigned long r3 asm("r3"); \ __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \ - asm volatile(inst "\n" : \ + asm volatile(SMCCC_SVE_CHECK \ + inst "\n" : \ "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \ __constraints(__count_args(__VA_ARGS__))); \ if (___res) \
From: Jean-Philippe Brucker jean-philippe@linaro.org
mainline inclusion from mainline-v5.14-rc3 commit a7c3acca5380 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QPMK CVE: NA
----------------------
Commit cfa7ff959a78 ("arm64: smccc: Support SMCCC v1.3 SVE register saving hint") added a call to __arm_smccc_sve_check() which clobbers the lr (register x30), causing __arm_smccc_hvc() to return to itself and crash. Save lr on the stack before calling __arm_smccc_sve_check(). Save the frame pointer (x29) to complete the frame record, and adjust the offsets used to access stack parameters.
Acked-by: Ard Biesheuvel ardb@kernel.org Acked-by: Mark Brown broonie@kernel.org Fixes: cfa7ff959a78 ("arm64: smccc: Support SMCCC v1.3 SVE register saving hint") Signed-off-by: Jean-Philippe Brucker jean-philippe@linaro.org Link: https://lore.kernel.org/r/20210721071834.69130-1-jean-philippe@linaro.org Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/kernel/smccc-call.S | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S index 0d0a03dd0488..8f2de507b0af 100644 --- a/arch/arm64/kernel/smccc-call.S +++ b/arch/arm64/kernel/smccc-call.S @@ -32,20 +32,23 @@ SYM_FUNC_END(__arm_smccc_sve_check) EXPORT_SYMBOL(__arm_smccc_sve_check)
.macro SMCCC instr + stp x29, x30, [sp, #-16]! + mov x29, sp alternative_if ARM64_SVE bl __arm_smccc_sve_check alternative_else_nop_endif \instr #0 - ldr x4, [sp] + ldr x4, [sp, #16] stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] - ldr x4, [sp, #8] + ldr x4, [sp, #24] cbz x4, 1f /* no quirk structure */ ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS] cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6 b.ne 1f str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] -1: ret +1: ldp x29, x30, [sp], #16 + ret .endm
/*
From: Mark Rutland mark.rutland@arm.com
mainline inclusion from mainline-v5.11-rc1 commit 2ffac9e3fdbd category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QUF2 CVE: NA
----------------------
Let's make SCTLR_ELx initialization a bit clearer by using meaningful names for the initialization values, following the same scheme for SCTLR_EL1 and SCTLR_EL2.
These definitions will be used more widely in subsequent patches.
There should be no functional change as a result of this patch.
Signed-off-by: Mark Rutland mark.rutland@arm.com Cc: Christoph Hellwig hch@lst.de Cc: James Morse james.morse@arm.com Cc: Will Deacon will@kernel.org Link: https://lore.kernel.org/r/20201113124937.20574-5-mark.rutland@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/include/asm/sysreg.h | 18 ++++++++++++------ arch/arm64/kernel/head.S | 6 +++--- arch/arm64/mm/proc.S | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index bc5547727b02..48a7c79a9f5d 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -589,6 +589,9 @@ #define ENDIAN_SET_EL2 0 #endif
+#define INIT_SCTLR_EL2_MMU_OFF \ + (SCTLR_EL2_RES1 | ENDIAN_SET_EL2) + /* SCTLR_EL1 specific flags. */ #define SCTLR_EL1_ATA0 (BIT(42))
@@ -622,12 +625,15 @@ #define ENDIAN_SET_EL1 0 #endif
-#define SCTLR_EL1_SET (SCTLR_ELx_M | SCTLR_ELx_C | SCTLR_ELx_SA |\ - SCTLR_EL1_SA0 | SCTLR_EL1_SED | SCTLR_ELx_I |\ - SCTLR_EL1_DZE | SCTLR_EL1_UCT |\ - SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN |\ - SCTLR_ELx_ITFSB| SCTLR_ELx_ATA | SCTLR_EL1_ATA0 |\ - ENDIAN_SET_EL1 | SCTLR_EL1_UCI | SCTLR_EL1_RES1) +#define INIT_SCTLR_EL1_MMU_OFF \ + (ENDIAN_SET_EL1 | SCTLR_EL1_RES1) + +#define INIT_SCTLR_EL1_MMU_ON \ + (SCTLR_ELx_M | SCTLR_ELx_C | SCTLR_ELx_SA | SCTLR_EL1_SA0 | \ + SCTLR_EL1_SED | SCTLR_ELx_I | SCTLR_EL1_DZE | SCTLR_EL1_UCT | \ + SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN | SCTLR_ELx_ITFSB | \ + SCTLR_ELx_ATA | SCTLR_EL1_ATA0 | ENDIAN_SET_EL1 | SCTLR_EL1_UCI | \ + SCTLR_EL1_RES1)
/* MAIR_ELx memory attributes (used by Linux) */ #define MAIR_ATTR_DEVICE_nGnRnE UL(0x00) diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 0f5b677d1ca7..e4ba7c189bb2 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -494,13 +494,13 @@ SYM_FUNC_START(el2_setup) mrs x0, CurrentEL cmp x0, #CurrentEL_EL2 b.eq 1f - mov_q x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1) + mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr sctlr_el1, x0 mov w0, #BOOT_CPU_MODE_EL1 // This cpu booted in EL1 isb ret
-1: mov_q x0, (SCTLR_EL2_RES1 | ENDIAN_SET_EL2) +1: mov_q x0, INIT_SCTLR_EL2_MMU_OFF msr sctlr_el2, x0
#ifdef CONFIG_ARM64_VHE @@ -621,7 +621,7 @@ SYM_INNER_LABEL(install_el2_stub, SYM_L_LOCAL) * requires no configuration, and all non-hyp-specific EL2 setup * will be done via the _EL1 system register aliases in __cpu_setup. */ - mov_q x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1) + mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr sctlr_el1, x0
/* Coprocessor traps. */ diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index aacc7eab9b2f..a3fdc71c01eb 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -501,6 +501,6 @@ SYM_FUNC_START(__cpu_setup) /* * Prepare SCTLR */ - mov_q x0, SCTLR_EL1_SET + mov_q x0, INIT_SCTLR_EL1_MMU_ON ret // return to head.S SYM_FUNC_END(__cpu_setup)
From: Vladimir Murzin vladimir.murzin@arm.com
mainline inclusion from mainline-v5.13-rc1 commit 18107f8a2df6 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QUF2 CVE: NA
----------------------
Enhanced Privileged Access Never (EPAN) allows Privileged Access Never to be used with Execute-only mappings.
Absence of such support was a reason for 24cecc377463 ("arm64: Revert support for execute-only user mappings"). Thus now it can be revisited and re-enabled.
Cc: Kees Cook keescook@chromium.org Signed-off-by: Vladimir Murzin vladimir.murzin@arm.com Acked-by: Will Deacon will@kernel.org Link: https://lore.kernel.org/r/20210312173811.58284-2-vladimir.murzin@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com
Conflicts: arch/arm64/Kconfig arch/arm64/include/asm/cpucaps.h [wangxiongfeng: fix conflicts caused by context mismatch.] Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/Kconfig | 17 +++++++++++++++ arch/arm64/include/asm/cpucaps.h | 1 + arch/arm64/include/asm/pgtable-prot.h | 5 +++-- arch/arm64/include/asm/pgtable.h | 31 ++++++++++++++++++++------- arch/arm64/include/asm/sysreg.h | 3 ++- arch/arm64/kernel/cpufeature.c | 12 +++++++++++ arch/arm64/mm/fault.c | 18 +++++++++++++++- mm/mmap.c | 6 ++++++ 8 files changed, 81 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 405e5ce460ce..2cab963563d9 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1156,6 +1156,9 @@ config ARCH_WANT_HUGE_PMD_SHARE config ARCH_HAS_CACHE_LINE_SIZE def_bool y
+config ARCH_HAS_FILTER_PGPROT + def_bool y + config ARCH_ENABLE_SPLIT_PMD_PTLOCK def_bool y if PGTABLE_LEVELS > 2
@@ -1836,6 +1839,20 @@ config ARM64_TWED
endmenu
+menu "ARMv8.7 architectural features" + +config ARM64_EPAN + bool "Enable support for Enhanced Privileged Access Never (EPAN)" + default y + depends on ARM64_PAN + help + Enhanced Privileged Access Never (EPAN) allows Privileged + Access Never to be used with Execute-only mappings. + + The feature is detected at runtime, and will remain disabled + if the cpu does not implement the feature. +endmenu + config ARM64_SVE bool "ARM Scalable Vector Extension support" default y diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index 49b5310ad02d..e088c161372c 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -72,6 +72,7 @@ #define ARM64_HAS_TWED 62 #define ARM64_WORKAROUND_HISILICON_1980005 63 #define ARM64_HAS_ECV 64 +#define ARM64_HAS_EPAN 65
#define ARM64_NCAPS 80
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index 9a65fb528110..fab2f573f7a4 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -87,12 +87,13 @@ extern bool arm64_use_ng_mappings; #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE) #define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) #define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN) +#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
#define __P000 PAGE_NONE #define __P001 PAGE_READONLY #define __P010 PAGE_READONLY #define __P011 PAGE_READONLY -#define __P100 PAGE_READONLY_EXEC +#define __P100 PAGE_EXECONLY #define __P101 PAGE_READONLY_EXEC #define __P110 PAGE_READONLY_EXEC #define __P111 PAGE_READONLY_EXEC @@ -101,7 +102,7 @@ extern bool arm64_use_ng_mappings; #define __S001 PAGE_READONLY #define __S010 PAGE_SHARED #define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY_EXEC +#define __S100 PAGE_EXECONLY #define __S101 PAGE_READONLY_EXEC #define __S110 PAGE_SHARED_EXEC #define __S111 PAGE_SHARED_EXEC diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 90b154501d70..daed33697d98 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -119,11 +119,12 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys) #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte))
#define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) +/* + * Execute-only user mappings do not have the PTE_USER bit set. All valid + * kernel mappings have the PTE_UXN bit set. + */ #define pte_valid_not_user(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) -#define pte_valid_user(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) - + ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN)) /* * Could the pte be present in the TLB? We must check mm_tlb_flush_pending * so that we don't erroneously return false for pages that have been @@ -136,12 +137,14 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys) (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte))
/* - * p??_access_permitted() is true for valid user mappings (subject to the - * write permission check). PROT_NONE mappings do not have the PTE_VALID bit - * set. + * p??_access_permitted() is true for valid user mappings (PTE_USER + * bit set, subject to the write permission check). For execute-only + * mappings, like PROT_EXEC with EPAN (both PTE_USER and PTE_UXN bits + * not set) must return false. PROT_NONE mappings do not have the + * PTE_VALID bit set. */ #define pte_access_permitted(pte, write) \ - (pte_valid_user(pte) && (!(write) || pte_write(pte))) + (((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) && (!(write) || pte_write(pte))) #define pmd_access_permitted(pmd, write) \ (pte_access_permitted(pmd_pte(pmd), (write))) #define pud_access_permitted(pud, write) \ @@ -987,6 +990,18 @@ static inline bool arch_faults_on_old_pte(void) } #define arch_faults_on_old_pte arch_faults_on_old_pte
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot) +{ + if (cpus_have_const_cap(ARM64_HAS_EPAN)) + return prot; + + if (pgprot_val(prot) != pgprot_val(PAGE_EXECONLY)) + return prot; + + return PAGE_READONLY_EXEC; +} + + #endif /* !__ASSEMBLY__ */
#endif /* __ASM_PGTABLE_H */ diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 48a7c79a9f5d..3e4b53b75267 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -593,6 +593,7 @@ (SCTLR_EL2_RES1 | ENDIAN_SET_EL2)
/* SCTLR_EL1 specific flags. */ +#define SCTLR_EL1_EPAN (BIT(57)) #define SCTLR_EL1_ATA0 (BIT(42))
#define SCTLR_EL1_TCF0_SHIFT 38 @@ -633,7 +634,7 @@ SCTLR_EL1_SED | SCTLR_ELx_I | SCTLR_EL1_DZE | SCTLR_EL1_UCT | \ SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN | SCTLR_ELx_ITFSB | \ SCTLR_ELx_ATA | SCTLR_EL1_ATA0 | ENDIAN_SET_EL1 | SCTLR_EL1_UCI | \ - SCTLR_EL1_RES1) + SCTLR_EL1_EPAN | SCTLR_EL1_RES1)
/* MAIR_ELx memory attributes (used by Linux) */ #define MAIR_ATTR_DEVICE_nGnRnE UL(0x00) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 04a9cf3d5ea9..d1f521f092a4 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1833,6 +1833,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .cpu_enable = cpu_enable_pan, }, #endif /* CONFIG_ARM64_PAN */ +#ifdef CONFIG_ARM64_EPAN + { + .desc = "Enhanced Privileged Access Never", + .capability = ARM64_HAS_EPAN, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = has_cpuid_feature, + .sys_reg = SYS_ID_AA64MMFR1_EL1, + .field_pos = ID_AA64MMFR1_PAN_SHIFT, + .sign = FTR_UNSIGNED, + .min_field_value = 3, + }, +#endif /* CONFIG_ARM64_EPAN */ #ifdef CONFIG_ARM64_LSE_ATOMICS { .desc = "LSE atomic instructions", diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 8f4ceab2fa35..22d96efe1925 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -458,7 +458,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, const struct fault_info *inf; struct mm_struct *mm = current->mm; vm_fault_t fault; - unsigned long vm_flags = VM_ACCESS_FLAGS; + unsigned long vm_flags; unsigned int mm_flags = FAULT_FLAG_DEFAULT;
if (kprobe_page_fault(regs, esr)) @@ -474,12 +474,28 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, if (user_mode(regs)) mm_flags |= FAULT_FLAG_USER;
+ /* + * vm_flags tells us what bits we must have in vma->vm_flags + * for the fault to be benign, __do_page_fault() would check + * vma->vm_flags & vm_flags and returns an error if the + * intersection is empty + */ if (is_el0_instruction_abort(esr)) { + /* It was exec fault */ vm_flags = VM_EXEC; mm_flags |= FAULT_FLAG_INSTRUCTION; } else if (is_write_abort(esr)) { + /* It was write fault */ vm_flags = VM_WRITE; mm_flags |= FAULT_FLAG_WRITE; + } else { + /* It was read fault */ + vm_flags = VM_READ; + /* Write implies read */ + vm_flags |= VM_WRITE; + /* If EPAN is absent then exec implies read */ + if (!cpus_have_const_cap(ARM64_HAS_EPAN)) + vm_flags |= VM_EXEC; }
if (is_ttbr0_addr(addr) && is_el1_permission_fault(addr, esr, regs)) { diff --git a/mm/mmap.c b/mm/mmap.c index 36ef4c2b93a9..5c9b27aa337d 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -95,6 +95,12 @@ static void unmap_region(struct mm_struct *mm, * MAP_PRIVATE r: (no) no r: (yes) yes r: (no) yes r: (no) yes * w: (no) no w: (no) no w: (copy) copy w: (no) no * x: (no) no x: (no) yes x: (no) yes x: (yes) yes + * + * On arm64, PROT_EXEC has the following behaviour for both MAP_SHARED and + * MAP_PRIVATE (with Enhanced PAN supported): + * r: (no) no + * w: (no) no + * x: (yes) yes */ pgprot_t protection_map[16] __ro_after_init = { __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
From: Xiongfeng Wang wangxiongfeng2@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QUF2
---------------------------
Enable CONFIG_ARM64_EPAN for ARM64 architecture by default.
Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- arch/arm64/configs/openeuler_defconfig | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index dfbfa10a6097..771eb45cb362 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -466,6 +466,12 @@ CONFIG_ARM64_E0PD=y CONFIG_ARCH_RANDOM=y # end of ARMv8.5 architectural features
+# +# ARMv8.7 architectural features +# +CONFIG_ARM64_EPAN=y +# end of ARMv8.7 architectural features + CONFIG_ARM64_SVE=y CONFIG_ARM64_MODULE_PLTS=y CONFIG_ARM64_PSEUDO_NMI=y
From: Nathan Fontenot nathan.fontenot@amd.com
mainline inclusion from mainline-5.12-rc1-dontuse commit 629d512d682de2259179046e2364f1f1ff4232e3 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QQWF
--------------------------------
The msr_pstate union struct named fam17h_bits is misleading since this is the struct to use for all families >= 0x17, not just for family 0x17. Rename the bits structs to be 'pstate' (for pre family 17h CPUs) and 'pstatedef' (for CPUs since fam 17h) to align closer with PPR/BDKG (1) naming.
There are no functional changes as part of this update.
1: AMD Processor Programming Reference (PPR) and BIOS and Kernel Developer's Guide (BKDG) available at: http://developer.amd.com/resources/developer-guides-manuals
Signed-off-by: Nathan Fontenot nathan.fontenot@amd.com Reviewed-by: Robert Richter rrichter@amd.com Reviewed-by: skhan@linuxfoundation.org Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: qinyu qinyu16@huawei.com Reviewed-by: Chao Liu liuchao173@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- tools/power/cpupower/utils/helpers/amd.c | 26 +++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index 7c4f83a8c973..34368436bbd6 100644 --- a/tools/power/cpupower/utils/helpers/amd.c +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -13,7 +13,8 @@ #define MSR_AMD_PSTATE 0xc0010064 #define MSR_AMD_PSTATE_LIMIT 0xc0010061
-union msr_pstate { +union core_pstate { + /* pre fam 17h: */ struct { unsigned fid:6; unsigned did:3; @@ -26,7 +27,8 @@ union msr_pstate { unsigned idddiv:2; unsigned res3:21; unsigned en:1; - } bits; + } pstate; + /* since fam 17h: */ struct { unsigned fid:8; unsigned did:6; @@ -35,36 +37,36 @@ union msr_pstate { unsigned idddiv:2; unsigned res1:31; unsigned en:1; - } fam17h_bits; + } pstatedef; unsigned long long val; };
-static int get_did(int family, union msr_pstate pstate) +static int get_did(int family, union core_pstate pstate) { int t;
if (family == 0x12) t = pstate.val & 0xf; else if (family == 0x17 || family == 0x18) - t = pstate.fam17h_bits.did; + t = pstate.pstatedef.did; else - t = pstate.bits.did; + t = pstate.pstate.did;
return t; }
-static int get_cof(int family, union msr_pstate pstate) +static int get_cof(int family, union core_pstate pstate) { int t; int fid, did, cof;
did = get_did(family, pstate); if (family == 0x17 || family == 0x18) { - fid = pstate.fam17h_bits.fid; + fid = pstate.pstatedef.fid; cof = 200 * fid / did; } else { t = 0x10; - fid = pstate.bits.fid; + fid = pstate.pstate.fid; if (family == 0x11) t = 0x8; cof = (100 * (fid + t)) >> did; @@ -89,7 +91,7 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, int boost_states, unsigned long *pstates, int *no) { int i, psmax, pscur; - union msr_pstate pstate; + union core_pstate pstate; unsigned long long val;
/* Only read out frequencies from HW when CPU might be boostable @@ -119,9 +121,9 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, } if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val)) return -1; - if ((cpu_family == 0x17) && (!pstate.fam17h_bits.en)) + if ((cpu_family == 0x17) && (!pstate.pstatedef.en)) continue; - else if (!pstate.bits.en) + else if (!pstate.pstate.en) continue;
pstates[i] = get_cof(cpu_family, pstate);
From: Robert Richter rrichter@amd.com
mainline inclusion from mainline-5.12-rc1-dontuse commit 7a136a8fcd7ef14c63d07667e81c4dcac77e0a13 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QQWF
--------------------------------
The name is Core Performance Boost (CPB) for the cpuid flag. Correct cpuid caps flag to use this name (instead of CBP).
Signed-off-by: Robert Richter rrichter@amd.com Signed-off-by: Nathan Fontenot nathan.fontenot@amd.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: qinyu qinyu16@huawei.com Reviewed-by: Chao Liu liuchao173@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- tools/power/cpupower/utils/helpers/cpuid.c | 2 +- tools/power/cpupower/utils/helpers/helpers.h | 2 +- tools/power/cpupower/utils/helpers/misc.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index 73bfafc60e9b..f9a66a430b72 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -130,7 +130,7 @@ int get_cpu_info(struct cpupower_cpu_info *cpu_info) cpu_info->vendor == X86_VENDOR_HYGON) { if (ext_cpuid_level >= 0x80000007 && (cpuid_edx(0x80000007) & (1 << 9))) - cpu_info->caps |= CPUPOWER_CAP_AMD_CBP; + cpu_info->caps |= CPUPOWER_CAP_AMD_CPB;
if (ext_cpuid_level >= 0x80000008 && cpuid_ebx(0x80000008) & (1 << 4)) diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index c258eeccd05f..cfd5004b0b5c 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -64,7 +64,7 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
#define CPUPOWER_CAP_INV_TSC 0x00000001 #define CPUPOWER_CAP_APERF 0x00000002 -#define CPUPOWER_CAP_AMD_CBP 0x00000004 +#define CPUPOWER_CAP_AMD_CPB 0x00000004 #define CPUPOWER_CAP_PERF_BIAS 0x00000008 #define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010 #define CPUPOWER_CAP_IS_SNB 0x00000020 diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c index f406adc40bad..3113e551bd8a 100644 --- a/tools/power/cpupower/utils/helpers/misc.c +++ b/tools/power/cpupower/utils/helpers/misc.c @@ -18,7 +18,7 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, if (ret) return ret;
- if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CBP) { + if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB) { *support = 1;
/* AMD Family 0x17 does not utilize PCI D18F4 like prior
From: Nathan Fontenot nathan.fontenot@amd.com
mainline inclusion from mainline-5.12-rc1-dontuse commit a0255a76bf3a78d322adfe4eb4e73eb83998f61a category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QQWF
--------------------------------
Add a check in get_cpu_info() for the ability to read frequencies from hardware and set the CPUPOWER_CAP_AMD_HW_PSTATE cpuid flag. The cpuid flag is set when CPUID_80000007_EDX[7] is set, which is all families >= 10h. The check excludes family 14h because HW pstate reporting was not implemented on family 14h.
This is intended to reduce family checks in the main code paths.
Signed-off-by: Nathan Fontenot nathan.fontenot@amd.com Reviewed-by: Robert Richter rrichter@amd.com Reviewed-by: skhan@linuxfoundation.org Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: qinyu qinyu16@huawei.com Reviewed-by: Chao Liu liuchao173@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- tools/power/cpupower/utils/helpers/amd.c | 9 ++++----- tools/power/cpupower/utils/helpers/cpuid.c | 12 +++++++++--- tools/power/cpupower/utils/helpers/helpers.h | 1 + 3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index 34368436bbd6..8b69c7ff639a 100644 --- a/tools/power/cpupower/utils/helpers/amd.c +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -94,11 +94,10 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, union core_pstate pstate; unsigned long long val;
- /* Only read out frequencies from HW when CPU might be boostable - to keep the code as short and clean as possible. - Otherwise frequencies are exported via ACPI tables. - */ - if (cpu_family < 0x10 || cpu_family == 0x14) + /* Only read out frequencies from HW if HW Pstate is supported, + * otherwise frequencies are exported via ACPI tables. + */ + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_HW_PSTATE)) return -1;
if (read_msr(cpu, MSR_AMD_PSTATE_LIMIT, &val)) diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index f9a66a430b72..d577220a193b 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -128,9 +128,15 @@ int get_cpu_info(struct cpupower_cpu_info *cpu_info) /* AMD or Hygon Boost state enable/disable register */ if (cpu_info->vendor == X86_VENDOR_AMD || cpu_info->vendor == X86_VENDOR_HYGON) { - if (ext_cpuid_level >= 0x80000007 && - (cpuid_edx(0x80000007) & (1 << 9))) - cpu_info->caps |= CPUPOWER_CAP_AMD_CPB; + if (ext_cpuid_level >= 0x80000007) { + if (cpuid_edx(0x80000007) & (1 << 9)) + cpu_info->caps |= CPUPOWER_CAP_AMD_CPB; + + if ((cpuid_edx(0x80000007) & (1 << 7)) && + cpu_info->family != 0x14) + /* HW pstate was not implemented in family 0x14 */ + cpu_info->caps |= CPUPOWER_CAP_AMD_HW_PSTATE; + }
if (ext_cpuid_level >= 0x80000008 && cpuid_ebx(0x80000008) & (1 << 4)) diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index cfd5004b0b5c..da3f22e5c388 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -70,6 +70,7 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, #define CPUPOWER_CAP_IS_SNB 0x00000020 #define CPUPOWER_CAP_INTEL_IDA 0x00000040 #define CPUPOWER_CAP_AMD_RDPRU 0x00000080 +#define CPUPOWER_CAP_AMD_HW_PSTATE 0x00000100
#define CPUPOWER_AMD_CPBDIS 0x02000000
From: Nathan Fontenot nathan.fontenot@amd.com
mainline inclusion from mainline-5.12-rc1-dontuse commit 1421de7919cd082bad692626937f055f367586ba category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QQWF
--------------------------------
The pscur variable is set but not uused, just remove it.
This may have previsously been set to validate the MSR_AMD_PSTATE_STATUS MSR. With the addition of the CPUPOWER_CAP_AMD_HW_PSTATE cap flag this is no longer needed since the cpuid bit to enable this cap flag also validates that the MSR_AMD_PSTATE_STATUS MSR is present.
Signed-off-by: Nathan Fontenot nathan.fontenot@amd.com Reviewed-by: Robert Richter rrichter@amd.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: qinyu qinyu16@huawei.com Reviewed-by: Chao Liu liuchao173@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- tools/power/cpupower/utils/helpers/amd.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index 8b69c7ff639a..fc2ac1e6bfb2 100644 --- a/tools/power/cpupower/utils/helpers/amd.c +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -90,7 +90,7 @@ static int get_cof(int family, union core_pstate pstate) int decode_pstates(unsigned int cpu, unsigned int cpu_family, int boost_states, unsigned long *pstates, int *no) { - int i, psmax, pscur; + int i, psmax; union core_pstate pstate; unsigned long long val;
@@ -104,13 +104,6 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, return -1;
psmax = (val >> 4) & 0x7; - - if (read_msr(cpu, MSR_AMD_PSTATE_STATUS, &val)) - return -1; - - pscur = val & 0x7; - - pscur += boost_states; psmax += boost_states; for (i = 0; i <= psmax; i++) { if (i >= MAX_HW_PSTATES) {
From: Nathan Fontenot nathan.fontenot@amd.com
mainline inclusion from mainline-5.12-rc1-dontuse commit 23765b82a808da416b70b41d711468e723531e6a category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QQWF
--------------------------------
The family checks in get_cof() and get_did() need to use the correct MSR format depending on the family. Add a cpupower capability for using the pstatedef (family 17h and newer) to control this instead of direct family checks.
Signed-off-by: Nathan Fontenot nathan.fontenot@amd.com Reviewed-by: Robert Richter rrichter@amd.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: qinyu qinyu16@huawei.com Reviewed-by: Chao Liu liuchao173@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- tools/power/cpupower/utils/helpers/amd.c | 8 ++++---- tools/power/cpupower/utils/helpers/cpuid.c | 6 +++++- tools/power/cpupower/utils/helpers/helpers.h | 1 + 3 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index fc2ac1e6bfb2..b4731daa6820 100644 --- a/tools/power/cpupower/utils/helpers/amd.c +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -45,10 +45,10 @@ static int get_did(int family, union core_pstate pstate) { int t;
- if (family == 0x12) - t = pstate.val & 0xf; - else if (family == 0x17 || family == 0x18) + if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF) t = pstate.pstatedef.did; + else if (family == 0x12) + t = pstate.val & 0xf; else t = pstate.pstate.did;
@@ -61,7 +61,7 @@ static int get_cof(int family, union core_pstate pstate) int fid, did, cof;
did = get_did(family, pstate); - if (family == 0x17 || family == 0x18) { + if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF) { fid = pstate.pstatedef.fid; cof = 200 * fid / did; } else { diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index d577220a193b..db2e88ceb67b 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -133,9 +133,13 @@ int get_cpu_info(struct cpupower_cpu_info *cpu_info) cpu_info->caps |= CPUPOWER_CAP_AMD_CPB;
if ((cpuid_edx(0x80000007) & (1 << 7)) && - cpu_info->family != 0x14) + cpu_info->family != 0x14) { /* HW pstate was not implemented in family 0x14 */ cpu_info->caps |= CPUPOWER_CAP_AMD_HW_PSTATE; + + if (cpu_info->family >= 0x17) + cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATEDEF; + } }
if (ext_cpuid_level >= 0x80000008 && diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index da3f22e5c388..8b07ac1d99ef 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -71,6 +71,7 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, #define CPUPOWER_CAP_INTEL_IDA 0x00000040 #define CPUPOWER_CAP_AMD_RDPRU 0x00000080 #define CPUPOWER_CAP_AMD_HW_PSTATE 0x00000100 +#define CPUPOWER_CAP_AMD_PSTATEDEF 0x00000200
#define CPUPOWER_AMD_CPBDIS 0x02000000
From: Nathan Fontenot nathan.fontenot@amd.com
mainline inclusion from mainline-5.12-rc1-dontuse commit 56a85eebebdba62ebf6c46bd957949cc6e926aa0 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QQWF
--------------------------------
The enabled bit (bit 63) is common for all families so we can remove the multiple enabled checks based on family and have a common check for HW pstate enabled.
Signed-off-by: Nathan Fontenot nathan.fontenot@amd.com Reviewed-by: Robert Richter rrichter@amd.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: qinyu qinyu16@huawei.com Reviewed-by: Chao Liu liuchao173@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- tools/power/cpupower/utils/helpers/amd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index b4731daa6820..216240e2b771 100644 --- a/tools/power/cpupower/utils/helpers/amd.c +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -113,9 +113,9 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, } if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val)) return -1; - if ((cpu_family == 0x17) && (!pstate.pstatedef.en)) - continue; - else if (!pstate.pstate.en) + + /* The enabled bit (bit 63) is common for all families */ + if (!pstate.pstatedef.en) continue;
pstates[i] = get_cof(cpu_family, pstate);
From: Nathan Fontenot nathan.fontenot@amd.com
mainline inclusion from mainline-5.12-rc1-dontuse commit d1abc4e996d7784ce4d56749e4b5ca8ff23b1e0f category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QQWF
--------------------------------
The decode_pstates() routine no longer uses the CPU family and the caleed routines (get_cof() and get_did()) can grab the family from the global cpupower_cpu_info struct. These update removes passing the family arg to all these routines.
Signed-off-by: Nathan Fontenot nathan.fontenot@amd.com Reviewed-by: Robert Richter rrichter@amd.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: qinyu qinyu16@huawei.com Reviewed-by: Chao Liu liuchao173@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- tools/power/cpupower/utils/cpufreq-info.c | 3 +-- tools/power/cpupower/utils/helpers/amd.c | 19 +++++++++---------- tools/power/cpupower/utils/helpers/helpers.h | 9 ++++----- 3 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c index 6efc0f6b1b11..f9895e31ff5a 100644 --- a/tools/power/cpupower/utils/cpufreq-info.c +++ b/tools/power/cpupower/utils/cpufreq-info.c @@ -186,8 +186,7 @@ static int get_boost_mode_x86(unsigned int cpu) if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD && cpupower_cpu_info.family >= 0x10) || cpupower_cpu_info.vendor == X86_VENDOR_HYGON) { - ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states, - pstates, &pstate_no); + ret = decode_pstates(cpu, b_states, pstates, &pstate_no); if (ret) return ret;
diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index 216240e2b771..97f2c857048e 100644 --- a/tools/power/cpupower/utils/helpers/amd.c +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -41,13 +41,13 @@ union core_pstate { unsigned long long val; };
-static int get_did(int family, union core_pstate pstate) +static int get_did(union core_pstate pstate) { int t;
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF) t = pstate.pstatedef.did; - else if (family == 0x12) + else if (cpupower_cpu_info.family == 0x12) t = pstate.val & 0xf; else t = pstate.pstate.did; @@ -55,19 +55,19 @@ static int get_did(int family, union core_pstate pstate) return t; }
-static int get_cof(int family, union core_pstate pstate) +static int get_cof(union core_pstate pstate) { int t; int fid, did, cof;
- did = get_did(family, pstate); + did = get_did(pstate); if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF) { fid = pstate.pstatedef.fid; cof = 200 * fid / did; } else { t = 0x10; fid = pstate.pstate.fid; - if (family == 0x11) + if (cpupower_cpu_info.family == 0x11) t = 0x8; cof = (100 * (fid + t)) >> did; } @@ -76,8 +76,7 @@ static int get_cof(int family, union core_pstate pstate)
/* Needs: * cpu -> the cpu that gets evaluated - * cpu_family -> The cpu's family (0x10, 0x12,...) - * boots_states -> how much boost states the machines support + * boost_states -> how much boost states the machines support * * Fills up: * pstates -> a pointer to an array of size MAX_HW_PSTATES @@ -87,8 +86,8 @@ static int get_cof(int family, union core_pstate pstate) * * returns zero on success, -1 on failure */ -int decode_pstates(unsigned int cpu, unsigned int cpu_family, - int boost_states, unsigned long *pstates, int *no) +int decode_pstates(unsigned int cpu, int boost_states, + unsigned long *pstates, int *no) { int i, psmax; union core_pstate pstate; @@ -118,7 +117,7 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, if (!pstate.pstatedef.en) continue;
- pstates[i] = get_cof(cpu_family, pstate); + pstates[i] = get_cof(pstate); } *no = i; return 0; diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 8b07ac1d99ef..19ea196458f1 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -125,8 +125,8 @@ extern struct pci_dev *pci_slot_func_init(struct pci_access **pacc,
/* AMD HW pstate decoding **************************/
-extern int decode_pstates(unsigned int cpu, unsigned int cpu_family, - int boost_states, unsigned long *pstates, int *no); +extern int decode_pstates(unsigned int cpu, int boost_states, + unsigned long *pstates, int *no);
/* AMD HW pstate decoding **************************/
@@ -143,9 +143,8 @@ unsigned int cpuid_edx(unsigned int op); /* cpuid and cpuinfo helpers **************************/ /* X86 ONLY ********************************************/ #else -static inline int decode_pstates(unsigned int cpu, unsigned int cpu_family, - int boost_states, unsigned long *pstates, - int *no) +static inline int decode_pstates(unsigned int cpu, int boost_states, + unsigned long *pstates, int *no) { return -1; };
static inline int read_msr(int cpu, unsigned int idx, unsigned long long *val)
From: Nathan Fontenot nathan.fontenot@amd.com
mainline inclusion from mainline-5.12-rc1-dontuse commit 3a3ecfdb605cc8d98988012a4f88c34b4d220c21 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QQWF
--------------------------------
Remove the family check for accessing the MSR_AMD_HWCR MSR and replace it with a cpupower cap flag.
This update also allows for the removal of the local cpupower_cpu_info variable in cpufreq_has_boost_support() since we no longer need it to check the family.
Signed-off-by: Nathan Fontenot nathan.fontenot@amd.com Reviewed-by: Robert Richter rrichter@amd.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: qinyu qinyu16@huawei.com Reviewed-by: Chao Liu liuchao173@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- tools/power/cpupower/utils/helpers/cpuid.c | 6 +++++- tools/power/cpupower/utils/helpers/helpers.h | 1 + tools/power/cpupower/utils/helpers/misc.c | 7 +------ 3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index db2e88ceb67b..72eb43593180 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -129,9 +129,13 @@ int get_cpu_info(struct cpupower_cpu_info *cpu_info) if (cpu_info->vendor == X86_VENDOR_AMD || cpu_info->vendor == X86_VENDOR_HYGON) { if (ext_cpuid_level >= 0x80000007) { - if (cpuid_edx(0x80000007) & (1 << 9)) + if (cpuid_edx(0x80000007) & (1 << 9)) { cpu_info->caps |= CPUPOWER_CAP_AMD_CPB;
+ if (cpu_info->family >= 0x17) + cpu_info->caps |= CPUPOWER_CAP_AMD_CPB_MSR; + } + if ((cpuid_edx(0x80000007) & (1 << 7)) && cpu_info->family != 0x14) { /* HW pstate was not implemented in family 0x14 */ diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 19ea196458f1..9fb75b768b62 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -72,6 +72,7 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, #define CPUPOWER_CAP_AMD_RDPRU 0x00000080 #define CPUPOWER_CAP_AMD_HW_PSTATE 0x00000100 #define CPUPOWER_CAP_AMD_PSTATEDEF 0x00000200 +#define CPUPOWER_CAP_AMD_CPB_MSR 0x00000400
#define CPUPOWER_AMD_CPBDIS 0x02000000
diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c index 3113e551bd8a..34c6627ed2b2 100644 --- a/tools/power/cpupower/utils/helpers/misc.c +++ b/tools/power/cpupower/utils/helpers/misc.c @@ -8,16 +8,11 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, int *states) { - struct cpupower_cpu_info cpu_info; int ret; unsigned long long val;
*support = *active = *states = 0;
- ret = get_cpu_info(&cpu_info); - if (ret) - return ret; - if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB) { *support = 1;
@@ -26,7 +21,7 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, * has Hardware determined variable increments instead. */
- if (cpu_info.family == 0x17 || cpu_info.family == 0x18) { + if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB_MSR) { if (!read_msr(cpu, MSR_AMD_HWCR, &val)) { if (!(val & CPUPOWER_AMD_CPBDIS)) *active = 1;
From: Zhenguo Yao yaozhenguo1@gmail.com
mainline inclusion from mainline-v5.16-rc1 commit b5389086ad7be0453c55e0069a89856d1fbdf605 category: feature bugzilla: 186043, https://gitee.com/openeuler/kernel/issues/I4QSF4 CVE: NA
--------------------------------
We can specify the number of hugepages to allocate at boot. But the hugepages is balanced in all nodes at present. In some scenarios, we only need hugepages in one node. For example: DPDK needs hugepages which are in the same node as NIC.
If DPDK needs four hugepages of 1G size in node1 and system has 16 numa nodes we must reserve 64 hugepages on the kernel cmdline. But only four hugepages are used. The others should be free after boot. If the system memory is low(for example: 64G), it will be an impossible task.
So extend the hugepages parameter to support specifying hugepages on a specific node. For example add following parameter:
hugepagesz=1G hugepages=0:1,1:3
It will allocate 1 hugepage in node0 and 3 hugepages in node1.
Link: https://lkml.kernel.org/r/20211005054729.86457-1-yaozhenguo1@gmail.com Signed-off-by: Zhenguo Yao yaozhenguo1@gmail.com Reviewed-by: Mike Kravetz mike.kravetz@oracle.com Cc: Zhenguo Yao yaozhenguo1@gmail.com Cc: Dan Carpenter dan.carpenter@oracle.com Cc: Nathan Chancellor nathan@kernel.org Cc: Michael Ellerman mpe@ellerman.id.au Cc: Benjamin Herrenschmidt benh@kernel.crashing.org Cc: Paul Mackerras paulus@samba.org Cc: Jonathan Corbet corbet@lwn.net Cc: Mike Rapoport rppt@kernel.org Cc: Matthew Wilcox (Oracle) willy@infradead.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Conflicts: mm/hugetlb.c Signed-off-by: Liu Shixin liushixin2@huawei.com Reviewed-by: Kefeng Wangwangkefeng.wang@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- .../admin-guide/kernel-parameters.txt | 8 +- Documentation/admin-guide/mm/hugetlbpage.rst | 12 +- arch/powerpc/mm/hugetlbpage.c | 9 +- include/linux/hugetlb.h | 6 +- mm/hugetlb.c | 153 +++++++++++++++--- 5 files changed, 155 insertions(+), 33 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 64be32ba4373..5a0a68b35bb1 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1563,9 +1563,11 @@ the number of pages of hugepagesz to be allocated. If this is the first HugeTLB parameter on the command line, it specifies the number of pages to allocate for - the default huge page size. See also - Documentation/admin-guide/mm/hugetlbpage.rst. - Format: <integer> + the default huge page size. If using node format, the + number of pages to allocate per-node can be specified. + See also Documentation/admin-guide/mm/hugetlbpage.rst. + Format: <integer> or (node format) + <node>:<integer>[,<node>:<integer>]
hugepagesz= [HW] The size of the HugeTLB pages. This is used in diff --git a/Documentation/admin-guide/mm/hugetlbpage.rst b/Documentation/admin-guide/mm/hugetlbpage.rst index 8abaeb144e44..d70828c07658 100644 --- a/Documentation/admin-guide/mm/hugetlbpage.rst +++ b/Documentation/admin-guide/mm/hugetlbpage.rst @@ -128,7 +128,9 @@ hugepages implicitly specifies the number of huge pages of default size to allocate. If the number of huge pages of default size is implicitly specified, it can not be overwritten by a hugepagesz,hugepages - parameter pair for the default size. + parameter pair for the default size. This parameter also has a + node format. The node format specifies the number of huge pages + to allocate on specific nodes.
For example, on an architecture with 2M default huge page size::
@@ -138,6 +140,14 @@ hugepages indicating that the hugepages=512 parameter is ignored. If a hugepages parameter is preceded by an invalid hugepagesz parameter, it will be ignored. + + Node format example:: + + hugepagesz=2M hugepages=0:1,1:2 + + It will allocate 1 2M hugepage on node0 and 2 2M hugepages on node1. + If the node number is invalid, the parameter will be ignored. + default_hugepagesz Specify the default huge page size. This parameter can only be specified once on the command line. default_hugepagesz can diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 36c3800769fb..a1417c865b6d 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -228,17 +228,22 @@ int __init pseries_alloc_bootmem_huge_page(struct hstate *hstate) m->hstate = hstate; return 1; } + +bool __init hugetlb_node_alloc_supported(void) +{ + return false; +} #endif
-int __init alloc_bootmem_huge_page(struct hstate *h) +int __init alloc_bootmem_huge_page(struct hstate *h, int nid) {
#ifdef CONFIG_PPC_BOOK3S_64 if (firmware_has_feature(FW_FEATURE_LPAR) && !radix_enabled()) return pseries_alloc_bootmem_huge_page(h); #endif - return __alloc_bootmem_huge_page(h); + return __alloc_bootmem_huge_page(h, nid); }
#ifndef CONFIG_PPC_BOOK3S_64 diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 50101bbdb7cf..61c38e6c6c43 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -583,6 +583,7 @@ struct hstate { unsigned long nr_overcommit_huge_pages; struct list_head hugepage_activelist; struct list_head hugepage_freelists[MAX_NUMNODES]; + unsigned int max_huge_pages_node[MAX_NUMNODES]; unsigned int nr_huge_pages_node[MAX_NUMNODES]; unsigned int free_huge_pages_node[MAX_NUMNODES]; unsigned int surplus_huge_pages_node[MAX_NUMNODES]; @@ -652,8 +653,9 @@ static inline int hugetlb_insert_hugepage_pte_by_pa(struct mm_struct *mm, #endif
/* arch callback */ -int __init __alloc_bootmem_huge_page(struct hstate *h); -int __init alloc_bootmem_huge_page(struct hstate *h); +int __init __alloc_bootmem_huge_page(struct hstate *h, int nid); +int __init alloc_bootmem_huge_page(struct hstate *h, int nid); +bool __init hugetlb_node_alloc_supported(void);
void __init hugetlb_add_hstate(unsigned order); bool __init arch_hugetlb_valid_size(unsigned long size); diff --git a/mm/hugetlb.c b/mm/hugetlb.c index c9b6f063fde1..558dc08a90b7 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -68,6 +68,7 @@ static struct hstate * __initdata parsed_hstate; static unsigned long __initdata default_hstate_max_huge_pages; static bool __initdata parsed_valid_hugepagesz = true; static bool __initdata parsed_default_hugepagesz; +static unsigned int default_hugepages_in_node[MAX_NUMNODES] __initdata; /* * Protects updates to hugepage_freelists, hugepage_activelist, nr_huge_pages, * free_huge_pages, and surplus_huge_pages. @@ -2590,33 +2591,39 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, return ERR_PTR(-ENOSPC); }
-int alloc_bootmem_huge_page(struct hstate *h) +int alloc_bootmem_huge_page(struct hstate *h, int nid) __attribute__ ((weak, alias("__alloc_bootmem_huge_page"))); -int __alloc_bootmem_huge_page(struct hstate *h) +int __alloc_bootmem_huge_page(struct hstate *h, int nid) { - struct huge_bootmem_page *m; + struct huge_bootmem_page *m = NULL; /* initialize for clang */ int nr_nodes, node;
+ if (nid >= nr_online_nodes) + return 0; + /* do node specific alloc */ + if (nid != NUMA_NO_NODE) { + m = memblock_alloc_try_nid_raw(huge_page_size(h), huge_page_size(h), + 0, MEMBLOCK_ALLOC_ACCESSIBLE, nid); + if (!m) + return 0; + goto found; + } + /* allocate from next node when distributing huge pages */ for_each_node_mask_to_alloc(h, nr_nodes, node, &node_states[N_MEMORY]) { - void *addr; - - addr = memblock_alloc_try_nid_raw( + m = memblock_alloc_try_nid_raw( huge_page_size(h), huge_page_size(h), 0, MEMBLOCK_ALLOC_ACCESSIBLE, node); - if (addr) { - /* - * Use the beginning of the huge page to store the - * huge_bootmem_page struct (until gather_bootmem - * puts them into the mem_map). - */ - m = addr; - goto found; - } + /* + * Use the beginning of the huge page to store the + * huge_bootmem_page struct (until gather_bootmem + * puts them into the mem_map). + */ + if (!m) + return 0; + goto found; } - return 0;
found: - BUG_ON(!IS_ALIGNED(virt_to_phys(m), huge_page_size(h))); /* Put them into a private list first because mem_map is not up yet */ INIT_LIST_HEAD(&m->list); list_add(&m->list, &huge_boot_pages); @@ -2656,12 +2663,61 @@ static void __init gather_bootmem_prealloc(void) cond_resched(); } } +static void __init hugetlb_hstate_alloc_pages_onenode(struct hstate *h, int nid) +{ + unsigned long i; + char buf[32]; + + for (i = 0; i < h->max_huge_pages_node[nid]; ++i) { + if (hstate_is_gigantic(h)) { + if (!alloc_bootmem_huge_page(h, nid)) + break; + } else { + struct page *page; + gfp_t gfp_mask = htlb_alloc_mask(h) | __GFP_THISNODE; + + page = alloc_fresh_huge_page(h, gfp_mask, nid, + &node_states[N_MEMORY], NULL); + if (!page) + break; + put_page(page); /* free it into the hugepage allocator */ + } + cond_resched(); + } + if (i == h->max_huge_pages_node[nid]) + return; + + string_get_size(huge_page_size(h), 1, STRING_UNITS_2, buf, 32); + pr_warn("HugeTLB: allocating %u of page size %s failed node%d. Only allocated %lu hugepages.\n", + h->max_huge_pages_node[nid], buf, nid, i); + h->max_huge_pages -= (h->max_huge_pages_node[nid] - i); + h->max_huge_pages_node[nid] = i; +}
static void __init hugetlb_hstate_alloc_pages(struct hstate *h) { unsigned long i; nodemask_t *node_alloc_noretry; + bool node_specific_alloc = false;
+ /* skip gigantic hugepages allocation if hugetlb_cma enabled */ + if (hstate_is_gigantic(h) && hugetlb_cma_size) { + pr_warn_once("HugeTLB: hugetlb_cma is enabled, skip boot time allocation\n"); + return; + } + + /* do node specific alloc */ + for (i = 0; i < nr_online_nodes; i++) { + if (h->max_huge_pages_node[i] > 0) { + hugetlb_hstate_alloc_pages_onenode(h, i); + node_specific_alloc = true; + } + } + + if (node_specific_alloc) + return; + + /* below will do all node balanced alloc */ if (!hstate_is_gigantic(h)) { /* * Bit mask controlling how hard we retry per-node allocations. @@ -2682,11 +2738,7 @@ static void __init hugetlb_hstate_alloc_pages(struct hstate *h)
for (i = 0; i < h->max_huge_pages; ++i) { if (hstate_is_gigantic(h)) { - if (hugetlb_cma_size) { - pr_warn_once("HugeTLB: hugetlb_cma is enabled, skip boot time allocation\n"); - goto free; - } - if (!alloc_bootmem_huge_page(h)) + if (!alloc_bootmem_huge_page(h, NUMA_NO_NODE)) break; } else if (!alloc_pool_huge_page(h, &node_states[N_MEMORY], @@ -2702,7 +2754,6 @@ static void __init hugetlb_hstate_alloc_pages(struct hstate *h) h->max_huge_pages, buf, i); h->max_huge_pages = i; } -free: kfree(node_alloc_noretry); }
@@ -3392,6 +3443,10 @@ static int __init hugetlb_init(void) } default_hstate.max_huge_pages = default_hstate_max_huge_pages; + + for (i = 0; i < nr_online_nodes; i++) + default_hstate.max_huge_pages_node[i] = + default_hugepages_in_node[i]; } }
@@ -3454,6 +3509,10 @@ void __init hugetlb_add_hstate(unsigned int order) parsed_hstate = h; }
+bool __init __weak hugetlb_node_alloc_supported(void) +{ + return true; +} /* * hugepages command line processing * hugepages normally follows a valid hugepagsz or default_hugepagsz @@ -3465,6 +3524,10 @@ static int __init hugepages_setup(char *s) { unsigned long *mhp; static unsigned long *last_mhp; + int node = NUMA_NO_NODE; + int count; + unsigned long tmp; + char *p = s;
if (!parsed_valid_hugepagesz) { pr_warn("HugeTLB: hugepages=%s does not follow a valid hugepagesz, ignoring\n", s); @@ -3488,8 +3551,40 @@ static int __init hugepages_setup(char *s) return 0; }
- if (sscanf(s, "%lu", mhp) <= 0) - *mhp = 0; + while (*p) { + count = 0; + if (sscanf(p, "%lu%n", &tmp, &count) != 1) + goto invalid; + /* Parameter is node format */ + if (p[count] == ':') { + if (!hugetlb_node_alloc_supported()) { + pr_warn("HugeTLB: architecture can't support node specific alloc, ignoring!\n"); + return 0; + } + node = tmp; + p += count + 1; + if (node < 0 || node >= nr_online_nodes) + goto invalid; + /* Parse hugepages */ + if (sscanf(p, "%lu%n", &tmp, &count) != 1) + goto invalid; + if (!hugetlb_max_hstate) + default_hugepages_in_node[node] = tmp; + else + parsed_hstate->max_huge_pages_node[node] = tmp; + *mhp += tmp; + /* Go to parse next node*/ + if (p[count] == ',') + p += count + 1; + else + break; + } else { + if (p != s) + goto invalid; + *mhp = tmp; + break; + } + }
/* * Global state is always initialized later in hugetlb_init. @@ -3502,6 +3597,10 @@ static int __init hugepages_setup(char *s) last_mhp = mhp;
return 1; + +invalid: + pr_warn("HugeTLB: Invalid hugepages parameter %s\n", p); + return 0; } __setup("hugepages=", hugepages_setup);
@@ -3563,6 +3662,7 @@ __setup("hugepagesz=", hugepagesz_setup); static int __init default_hugepagesz_setup(char *s) { unsigned long size; + int i;
parsed_valid_hugepagesz = false; if (parsed_default_hugepagesz) { @@ -3591,6 +3691,9 @@ static int __init default_hugepagesz_setup(char *s) */ if (default_hstate_max_huge_pages) { default_hstate.max_huge_pages = default_hstate_max_huge_pages; + for (i = 0; i < nr_online_nodes; i++) + default_hstate.max_huge_pages_node[i] = + default_hugepages_in_node[i]; if (hstate_is_gigantic(&default_hstate)) hugetlb_hstate_alloc_pages(&default_hstate); default_hstate_max_huge_pages = 0;
From: Zhenguo Yao yaozhenguo1@gmail.com
mainline inclusion from mainline-v5.16-rc5 commit 4178158ef8cadeb0ee86639749ce2b33ad75f770 category: bugfix bugzilla: 186043, https://gitee.com/openeuler/kernel/issues/I4QSF4 CVE: NA
--------------------------------
Preallocation of gigantic pages can't work bacause of commit b5389086ad7b ("hugetlbfs: extend the definition of hugepages parameter to support node allocation"). When nid is NUMA_NO_NODE(-1), alloc_bootmem_huge_page will always return without doing allocation. Fix this by adding more check.
Link: https://lkml.kernel.org/r/20211129133803.15653-1-yaozhenguo1@gmail.com Fixes: b5389086ad7b ("hugetlbfs: extend the definition of hugepages parameter to support node allocation") Signed-off-by: Zhenguo Yao yaozhenguo1@gmail.com Reviewed-by: Mike Kravetz mike.kravetz@oracle.com Tested-by: Maxim Levitsky mlevitsk@redhat.com Reviewed-by: Muchun Song songmuchun@bytedance.com Reviewed-by: Baolin Wang baolin.wang@linux.alibaba.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Liu Shixin liushixin2@huawei.com Reviewed-by: Kefeng Wangwangkefeng.wang@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- mm/hugetlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 558dc08a90b7..219bf083dc8a 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2598,7 +2598,7 @@ int __alloc_bootmem_huge_page(struct hstate *h, int nid) struct huge_bootmem_page *m = NULL; /* initialize for clang */ int nr_nodes, node;
- if (nid >= nr_online_nodes) + if (nid != NUMA_NO_NODE && nid >= nr_online_nodes) return 0; /* do node specific alloc */ if (nid != NUMA_NO_NODE) {
From: Yangyang Li liyangyang20@huawei.com
mainline inclusion from mainline-v5.14-rc5 commit 8b436a99cd70 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=8b4...
---------------------------------------------------------------------
If hns_roce_cmd_use_events() fails then it means that the poll_sem is not obtained, but the poll_sem is released in hns_roce_cmd_use_polling(), this will cause an unlock problem.
This is the static checker warning: drivers/infiniband/hw/hns/hns_roce_main.c:926 hns_roce_init() error: double unlocked '&hr_dev->cmd.poll_sem' (orig line 879)
Event mode and polling mode are mutually exclusive and resources are separated, so there is no need to process polling mode resources in event mode.
The initial mode of cmd is polling mode, so even if cmd fails to switch to event mode, it is not necessary to switch to polling mode.
Fixes: a389d016c030 ("RDMA/hns: Enable all CMDQ context") Fixes: 3d50503b3b33 ("RDMA/hns: Optimize cmd init and mode selection for hip08") Link: https://lore.kernel.org/r/1627887374-20019-1-git-send-email-liangwenpeng@hua... Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Yangyang Li liyangyang20@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Reviewed-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yixing Liu liuyixing1@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_cmd.c | 7 +++---- drivers/infiniband/hw/hns/hns_roce_main.c | 4 +--- 2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.c b/drivers/infiniband/hw/hns/hns_roce_cmd.c index 37fdc4a38f02..3fa152f7b5ee 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cmd.c +++ b/drivers/infiniband/hw/hns/hns_roce_cmd.c @@ -212,8 +212,10 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev)
hr_cmd->context = kcalloc(hr_cmd->max_cmds, sizeof(*hr_cmd->context), GFP_KERNEL); - if (!hr_cmd->context) + if (!hr_cmd->context) { + hr_dev->cmd_mod = 0; return -ENOMEM; + }
for (i = 0; i < hr_cmd->max_cmds; ++i) { hr_cmd->context[i].token = i; @@ -227,7 +229,6 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev) spin_lock_init(&hr_cmd->context_lock);
hr_cmd->use_events = 1; - down(&hr_cmd->poll_sem);
return 0; } @@ -238,8 +239,6 @@ void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev)
kfree(hr_cmd->context); hr_cmd->use_events = 0; - - up(&hr_cmd->poll_sem); }
struct hns_roce_cmd_mailbox * diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 19e040a437bb..f5c753a90db4 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -972,11 +972,9 @@ int hns_roce_init(struct hns_roce_dev *hr_dev)
if (hr_dev->cmd_mod) { ret = hns_roce_cmd_use_events(hr_dev); - if (ret) { + if (ret) dev_warn(dev, "Cmd event mode failed, set back to poll!\n"); - hns_roce_cmd_use_polling(hr_dev); - } }
ret = hns_roce_init_hem(hr_dev);
From: Leon Romanovsky leonro@nvidia.com
mainline inclusion from mainline-v5.15-rc1 commit e66e49592b69 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=e66...
---------------------------------------------------------------------
QP attributes that were supplied by IB/core already have all parameters set when they are passed to the driver. The drivers are not supposed to change anything in struct ib_qp_init_attr.
Fixes: 66d86e529dd5 ("RDMA/hns: Add UD support for HIP09") Link: https://lore.kernel.org/r/5987138875e8ade9aa339d4db6e1bd9694ed4591.162704018... Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_qp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 1fda9617f91e..00d1f44f91b9 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -1233,14 +1233,8 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd, if (!hr_qp) return ERR_PTR(-ENOMEM);
- if (init_attr->qp_type == IB_QPT_XRC_INI) - init_attr->recv_cq = NULL; - - if (init_attr->qp_type == IB_QPT_XRC_TGT) { + if (init_attr->qp_type == IB_QPT_XRC_TGT) hr_qp->xrcdn = to_hr_xrcd(init_attr->xrcd)->xrcdn; - init_attr->recv_cq = NULL; - init_attr->send_cq = NULL; - }
if (init_attr->qp_type == IB_QPT_GSI) { hr_qp->port = init_attr->port_num - 1;
From: Lang Cheng chenglang@huawei.com
mainline inclusion from mainline-0110a1ed0e80 commit v5.15-rc1 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=011...
---------------------------------------------------------------------
CMDQ support un-interrupt mode only, and firmware ignores this mode flag, so remove it.
Fixes: a04ff739f2a9 ("RDMA/hns: Add command queue support for hip08 RoCE driver") Link: https://lore.kernel.org/r/1629539607-33217-2-git-send-email-liangwenpeng@hua... Signed-off-by: Lang Cheng chenglang@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 21 +++++++-------------- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 20 +++++++------------- 2 files changed, 14 insertions(+), 27 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index e60a8f9b0348..62c113bf1ff4 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -1258,8 +1258,7 @@ static void hns_roce_cmq_setup_basic_desc(struct hns_roce_cmq_desc *desc, { memset((void *)desc, 0, sizeof(struct hns_roce_cmq_desc)); desc->opcode = cpu_to_le16(opcode); - desc->flag = - cpu_to_le16(HNS_ROCE_CMD_FLAG_NO_INTR | HNS_ROCE_CMD_FLAG_IN); + desc->flag = cpu_to_le16(HNS_ROCE_CMD_FLAG_IN); if (is_read) desc->flag |= cpu_to_le16(HNS_ROCE_CMD_FLAG_WR); else @@ -1298,16 +1297,11 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev, /* Write to hardware */ roce_write(hr_dev, ROCEE_TX_CMQ_PI_REG, csq->head);
- /* If the command is sync, wait for the firmware to write back, - * if multi descriptors to be sent, use the first one to check - */ - if (le16_to_cpu(desc->flag) & HNS_ROCE_CMD_FLAG_NO_INTR) { - do { - if (hns_roce_cmq_csq_done(hr_dev)) - break; - udelay(1); - } while (++timeout < priv->cmq.tx_timeout); - } + do { + if (hns_roce_cmq_csq_done(hr_dev)) + break; + udelay(1); + } while (++timeout < priv->cmq.tx_timeout);
if (hns_roce_cmq_csq_done(hr_dev)) { for (ret = 0, i = 0; i < num; i++) { @@ -1771,8 +1765,7 @@ static int __hns_roce_set_vf_switch_param(struct hns_roce_dev *hr_dev, if (ret) return ret;
- desc.flag = - cpu_to_le16(HNS_ROCE_CMD_FLAG_NO_INTR | HNS_ROCE_CMD_FLAG_IN); + desc.flag = cpu_to_le16(HNS_ROCE_CMD_FLAG_IN); desc.flag &= cpu_to_le16(~HNS_ROCE_CMD_FLAG_WR); roce_set_bit(swt->cfg, VF_SWITCH_DATA_CFG_ALW_LPBK_S, 1); roce_set_bit(swt->cfg, VF_SWITCH_DATA_CFG_ALW_LCL_LPBK_S, 0); diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h index b8a09d411e2e..54c1223d63d8 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -129,19 +129,13 @@
#define HNS_ROCE_V2_TABLE_CHUNK_SIZE (1 << 18)
-#define HNS_ROCE_CMD_FLAG_IN_VALID_SHIFT 0 -#define HNS_ROCE_CMD_FLAG_OUT_VALID_SHIFT 1 -#define HNS_ROCE_CMD_FLAG_NEXT_SHIFT 2 -#define HNS_ROCE_CMD_FLAG_WR_OR_RD_SHIFT 3 -#define HNS_ROCE_CMD_FLAG_NO_INTR_SHIFT 4 -#define HNS_ROCE_CMD_FLAG_ERR_INTR_SHIFT 5 - -#define HNS_ROCE_CMD_FLAG_IN BIT(HNS_ROCE_CMD_FLAG_IN_VALID_SHIFT) -#define HNS_ROCE_CMD_FLAG_OUT BIT(HNS_ROCE_CMD_FLAG_OUT_VALID_SHIFT) -#define HNS_ROCE_CMD_FLAG_NEXT BIT(HNS_ROCE_CMD_FLAG_NEXT_SHIFT) -#define HNS_ROCE_CMD_FLAG_WR BIT(HNS_ROCE_CMD_FLAG_WR_OR_RD_SHIFT) -#define HNS_ROCE_CMD_FLAG_NO_INTR BIT(HNS_ROCE_CMD_FLAG_NO_INTR_SHIFT) -#define HNS_ROCE_CMD_FLAG_ERR_INTR BIT(HNS_ROCE_CMD_FLAG_ERR_INTR_SHIFT) +enum { + HNS_ROCE_CMD_FLAG_IN = BIT(0), + HNS_ROCE_CMD_FLAG_OUT = BIT(1), + HNS_ROCE_CMD_FLAG_NEXT = BIT(2), + HNS_ROCE_CMD_FLAG_WR = BIT(3), + HNS_ROCE_CMD_FLAG_ERR_INTR = BIT(5), +};
#define HNS_ROCE_CMQ_DESC_NUM_S 3
From: Lang Cheng chenglang@huawei.com
mainline inclusion from mainline-v5.15-rc1 commit f8c549afd1e7 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4O23M CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=f8c...
---------------------------------------------------------------------
The ownerbit mode is for external card mode. Make it controlled by the firmware.
Fixes: aba457ca890c ("RDMA/hns: Support owner mode doorbell") Link: https://lore.kernel.org/r/1629539607-33217-4-git-send-email-liangwenpeng@hua... Signed-off-by: Lang Cheng chenglang@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 62c113bf1ff4..8c0c57eca8d5 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4100,6 +4100,9 @@ static void modify_qp_reset_to_init(struct ib_qp *ibqp, if (hr_qp->en_flags & HNS_ROCE_QP_CAP_RQ_RECORD_DB) hr_reg_enable(context, QPC_RQ_RECORD_EN);
+ if (hr_qp->en_flags & HNS_ROCE_QP_CAP_OWNER_DB) + hr_reg_enable(context, QPC_OWNER_MODE); + hr_reg_write(context, QPC_RQ_DB_RECORD_ADDR_L, lower_32_bits(hr_qp->rdb.dma) >> 1); hr_reg_write(context, QPC_RQ_DB_RECORD_ADDR_H,
From: Yangyang Li liyangyang20@huawei.com
mainline inclusion from mainline-v5.15-rc1 commit c4f11b36f817 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=c4f...
---------------------------------------------------------------------
Switch srq index allocation and release from hns' own bitmap interface to IDA interface.
Link: https://lore.kernel.org/r/1629336980-17499-3-git-send-email-liangwenpeng@hua... Signed-off-by: Yangyang Li liyangyang20@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yixing Liu liuyixing1@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_alloc.c | 2 +- drivers/infiniband/hw/hns/hns_roce_device.h | 5 ++-- drivers/infiniband/hw/hns/hns_roce_main.c | 17 +------------ drivers/infiniband/hw/hns/hns_roce_srq.c | 28 ++++++++++----------- 4 files changed, 18 insertions(+), 34 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_alloc.c b/drivers/infiniband/hw/hns/hns_roce_alloc.c index 85b2e352f9be..7afae02acda7 100644 --- a/drivers/infiniband/hw/hns/hns_roce_alloc.c +++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c @@ -256,7 +256,7 @@ void hns_roce_cleanup_bitmap(struct hns_roce_dev *hr_dev) ida_destroy(&hr_dev->xrcd_ida.ida);
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SRQ) - hns_roce_cleanup_srq_table(hr_dev); + ida_destroy(&hr_dev->srq_table.srq_ida.ida); hns_roce_cleanup_qp_table(hr_dev); hns_roce_cleanup_cq_table(hr_dev); ida_destroy(&hr_dev->mr_table.mtpt_ida.ida); diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index c9188879693e..2dafc1b66d8a 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -494,7 +494,7 @@ struct hns_roce_cq_table { };
struct hns_roce_srq_table { - struct hns_roce_bitmap bitmap; + struct hns_roce_ida srq_ida; struct xarray xa; struct hns_roce_hem_table table; }; @@ -1100,13 +1100,12 @@ void hns_roce_init_pd_table(struct hns_roce_dev *hr_dev); void hns_roce_init_mr_table(struct hns_roce_dev *hr_dev); void hns_roce_init_cq_table(struct hns_roce_dev *hr_dev); void hns_roce_init_qp_table(struct hns_roce_dev *hr_dev); -int hns_roce_init_srq_table(struct hns_roce_dev *hr_dev); +void hns_roce_init_srq_table(struct hns_roce_dev *hr_dev); void hns_roce_init_xrcd_table(struct hns_roce_dev *hr_dev);
void hns_roce_cleanup_eq_table(struct hns_roce_dev *hr_dev); void hns_roce_cleanup_cq_table(struct hns_roce_dev *hr_dev); void hns_roce_cleanup_qp_table(struct hns_roce_dev *hr_dev); -void hns_roce_cleanup_srq_table(struct hns_roce_dev *hr_dev);
int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj); void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj); diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index f5c753a90db4..58200d0730bf 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -867,26 +867,11 @@ static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev) hns_roce_init_qp_table(hr_dev);
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SRQ) { - ret = hns_roce_init_srq_table(hr_dev); - if (ret) { - dev_err(dev, - "Failed to init share receive queue table.\n"); - goto err_qp_table_free; - } + hns_roce_init_srq_table(hr_dev); }
return 0;
-err_qp_table_free: - hns_roce_cleanup_qp_table(hr_dev); - hns_roce_cleanup_cq_table(hr_dev); - ida_destroy(&hr_dev->mr_table.mtpt_ida.ida); - - if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC) - ida_destroy(&hr_dev->xrcd_ida.ida); - - ida_destroy(&hr_dev->pd_ida.ida); - err_uar_table_free: ida_destroy(&hr_dev->uar_ida.ida); return ret; diff --git a/drivers/infiniband/hw/hns/hns_roce_srq.c b/drivers/infiniband/hw/hns/hns_roce_srq.c index e6b487053e60..5672f588c4dc 100644 --- a/drivers/infiniband/hw/hns/hns_roce_srq.c +++ b/drivers/infiniband/hw/hns/hns_roce_srq.c @@ -80,15 +80,19 @@ static int hns_roce_hw_destroy_srq(struct hns_roce_dev *dev, static int alloc_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq) { struct hns_roce_srq_table *srq_table = &hr_dev->srq_table; + struct hns_roce_ida *srq_ida = &hr_dev->srq_table.srq_ida; struct ib_device *ibdev = &hr_dev->ib_dev; struct hns_roce_cmd_mailbox *mailbox; int ret; + int id;
- ret = hns_roce_bitmap_alloc(&srq_table->bitmap, &srq->srqn); - if (ret) { - ibdev_err(ibdev, "failed to alloc SRQ number.\n"); + id = ida_alloc_range(&srq_ida->ida, srq_ida->min, srq_ida->max, + GFP_KERNEL); + if (id < 0) { + ibdev_err(ibdev, "failed to alloc srq(%d).\n", id); return -ENOMEM; } + srq->srqn = (unsigned long)id;
ret = hns_roce_table_get(hr_dev, &srq_table->table, srq->srqn); if (ret) { @@ -132,7 +136,7 @@ static int alloc_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq) err_put: hns_roce_table_put(hr_dev, &srq_table->table, srq->srqn); err_out: - hns_roce_bitmap_free(&srq_table->bitmap, srq->srqn); + ida_free(&srq_ida->ida, id);
return ret; } @@ -154,7 +158,7 @@ static void free_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq) wait_for_completion(&srq->free);
hns_roce_table_put(hr_dev, &srq_table->table, srq->srqn); - hns_roce_bitmap_free(&srq_table->bitmap, srq->srqn); + ida_free(&srq_table->srq_ida.ida, (int)srq->srqn); }
static int alloc_srq_idx(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq, @@ -440,18 +444,14 @@ int hns_roce_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata) return 0; }
-int hns_roce_init_srq_table(struct hns_roce_dev *hr_dev) +void hns_roce_init_srq_table(struct hns_roce_dev *hr_dev) { struct hns_roce_srq_table *srq_table = &hr_dev->srq_table; + struct hns_roce_ida *srq_ida = &srq_table->srq_ida;
xa_init(&srq_table->xa);
- return hns_roce_bitmap_init(&srq_table->bitmap, hr_dev->caps.num_srqs, - hr_dev->caps.num_srqs - 1, - hr_dev->caps.reserved_srqs, 0); -} - -void hns_roce_cleanup_srq_table(struct hns_roce_dev *hr_dev) -{ - hns_roce_bitmap_cleanup(&hr_dev->srq_table.bitmap); + ida_init(&srq_ida->ida); + srq_ida->max = hr_dev->caps.num_srqs - 1; + srq_ida->min = hr_dev->caps.reserved_srqs; }
From: Yangyang Li liyangyang20@huawei.com
mainline inclusion from mainline-v5.15-rc1 commit f0a64199195e category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=f0a...
---------------------------------------------------------------------
The resources that use the hns bitmap interface: qp, cq, mr, pd, xrcd, uar, srq, have been changed to IDA interfaces, and the unused hns' own bitmap interfaces need to be deleted.
Link: https://lore.kernel.org/r/1629336980-17499-4-git-send-email-liangwenpeng@hua... Signed-off-by: Yangyang Li liyangyang20@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yixing Liu liuyixing1@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_alloc.c | 70 --------------------- drivers/infiniband/hw/hns/hns_roce_device.h | 5 -- 2 files changed, 75 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_alloc.c b/drivers/infiniband/hw/hns/hns_roce_alloc.c index 7afae02acda7..1a9da5c84183 100644 --- a/drivers/infiniband/hw/hns/hns_roce_alloc.c +++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c @@ -35,76 +35,6 @@ #include <rdma/ib_umem.h> #include "hns_roce_device.h"
-int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj) -{ - int ret = 0; - - spin_lock(&bitmap->lock); - *obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last); - if (*obj >= bitmap->max) { - bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) - & bitmap->mask; - *obj = find_first_zero_bit(bitmap->table, bitmap->max); - } - - if (*obj < bitmap->max) { - set_bit(*obj, bitmap->table); - bitmap->last = (*obj + 1); - if (bitmap->last == bitmap->max) - bitmap->last = 0; - *obj |= bitmap->top; - } else { - ret = -EINVAL; - } - - spin_unlock(&bitmap->lock); - - return ret; -} - -void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj) -{ - obj &= bitmap->max + bitmap->reserved_top - 1; - - spin_lock(&bitmap->lock); - clear_bit(obj, bitmap->table); - - bitmap->last = min(bitmap->last, obj); - bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) - & bitmap->mask; - spin_unlock(&bitmap->lock); -} - -int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask, - u32 reserved_bot, u32 reserved_top) -{ - u32 i; - - if (num != roundup_pow_of_two(num)) - return -EINVAL; - - bitmap->last = 0; - bitmap->top = 0; - bitmap->max = num - reserved_top; - bitmap->mask = mask; - bitmap->reserved_top = reserved_top; - spin_lock_init(&bitmap->lock); - bitmap->table = kcalloc(BITS_TO_LONGS(bitmap->max), sizeof(long), - GFP_KERNEL); - if (!bitmap->table) - return -ENOMEM; - - for (i = 0; i < reserved_bot; ++i) - set_bit(i, bitmap->table); - - return 0; -} - -void hns_roce_bitmap_cleanup(struct hns_roce_bitmap *bitmap) -{ - kfree(bitmap->table); -} - void hns_roce_buf_free(struct hns_roce_dev *hr_dev, struct hns_roce_buf *buf) { struct hns_roce_buf_list *trunks; diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 2dafc1b66d8a..e1d4cc3ecc76 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -1107,11 +1107,6 @@ void hns_roce_cleanup_eq_table(struct hns_roce_dev *hr_dev); void hns_roce_cleanup_cq_table(struct hns_roce_dev *hr_dev); void hns_roce_cleanup_qp_table(struct hns_roce_dev *hr_dev);
-int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj); -void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj); -int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask, - u32 reserved_bot, u32 resetrved_top); -void hns_roce_bitmap_cleanup(struct hns_roce_bitmap *bitmap); void hns_roce_cleanup_bitmap(struct hns_roce_dev *hr_dev);
int hns_roce_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
From: Yixing Liu liuyixing1@huawei.com
mainline inclusion from mainline-v5.15-rc1 commit 9bed8a70716b category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=9be...
---------------------------------------------------------------------
In RNR NAK screnario, according to the specification, when no credit is available, only the first fragment of the send request can be sent. The LSN(Limit Sequence Number) field should be 0 or the entire packet will be resent.
Fixes: 926a01dc000d ("RDMA/hns: Add QP operations support for hip08 SoC") Link: https://lore.kernel.org/r/1629883169-2306-1-git-send-email-liangwenpeng@huaw... Signed-off-by: Yixing Liu liuyixing1@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 8c0c57eca8d5..da6e0cde381d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4475,9 +4475,6 @@ static int modify_qp_rtr_to_rts(struct ib_qp *ibqp,
hr_reg_clear(qpc_mask, QPC_CHECK_FLG);
- hr_reg_write(context, QPC_LSN, 0x100); - hr_reg_clear(qpc_mask, QPC_LSN); - hr_reg_clear(qpc_mask, QPC_V2_IRRL_HEAD);
return 0;
From: Junxian Huang huangjunxian4@hisilicon.com
mainline inclusion from mainline-v5.15-rc1 commit 4303e61264c4 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=430...
---------------------------------------------------------------------
dip_idx is associated with qp_num whose data type is u32. However, dip_idx is incorrectly defined as u8 data in the hns_roce_dip struct, which leads to data truncation during value assignment.
Fixes: f91696f2f053 ("RDMA/hns: Support congestion control type selection according to the FW") Link: https://lore.kernel.org/r/1629884592-23424-2-git-send-email-liangwenpeng@hua... Signed-off-by: Junxian Huang huangjunxian4@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h index 54c1223d63d8..0b91a1a57aa0 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -1441,7 +1441,7 @@ struct hns_roce_v2_priv {
struct hns_roce_dip { u8 dgid[GID_LEN_V2]; - u8 dip_idx; + u32 dip_idx; struct list_head node; /* all dips are on a list */ };
From: Junxian Huang huangjunxian4@hisilicon.com
mainline inclusion from mainline-v5.15-rc1 commit 074f315fc54a category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=074...
---------------------------------------------------------------------
When the dgid-dip_idx mapping relationship exists, dip should be assigned.
Fixes: f91696f2f053 ("RDMA/hns: Support congestion control type selection according to the FW") Link: https://lore.kernel.org/r/1629884592-23424-3-git-send-email-liangwenpeng@hua... Signed-off-by: Junxian Huang huangjunxian4@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index da6e0cde381d..cff1a73c4be7 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4500,8 +4500,10 @@ static int get_dip_ctx_idx(struct ib_qp *ibqp, const struct ib_qp_attr *attr, spin_lock_irqsave(&hr_dev->dip_list_lock, flags);
list_for_each_entry(hr_dip, &hr_dev->dip_list, node) { - if (!memcmp(grh->dgid.raw, hr_dip->dgid, 16)) + if (!memcmp(grh->dgid.raw, hr_dip->dgid, 16)) { + *dip_idx = hr_dip->dip_idx; goto out; + } }
/* If no dgid is found, a new dip and a mapping between dgid and
From: Junxian Huang huangjunxian4@hisilicon.com
mainline inclusion from mainline-v5.15-rc1 commit eb653eda1e91 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=eb6...
---------------------------------------------------------------------
dip_idx and dgid should be a one-to-one mapping relationship, but when qp_num loops back to the start number, it may happen that two different dgid are assiociated to the same dip_idx incorrectly.
One solution is to store the qp_num that is not assigned to dip_idx in an array. When a dip_idx needs to be allocated to a new dgid, an spare qp_num is extracted and assigned to dip_idx.
Fixes: f91696f2f053 ("RDMA/hns: Support congestion control type selection according to the FW") Link: https://lore.kernel.org/r/1629884592-23424-4-git-send-email-liangwenpeng@hua... Signed-off-by: Junxian Huang huangjunxian4@hisilicon.com Signed-off-by: Yangyang Li liyangyang20@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_device.h | 9 ++++++++- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 9 ++++++++- drivers/infiniband/hw/hns/hns_roce_main.c | 8 ++++++-- drivers/infiniband/hw/hns/hns_roce_qp.c | 10 +++++++++- 4 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index e1d4cc3ecc76..3066bb4008ca 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -476,6 +476,12 @@ struct hns_roce_bank { u32 next; /* Next ID to allocate. */ };
+struct hns_roce_idx_table { + u32 *spare_idx; + u32 head; + u32 tail; +}; + struct hns_roce_qp_table { struct hns_roce_hem_table qp_table; struct hns_roce_hem_table irrl_table; @@ -484,6 +490,7 @@ struct hns_roce_qp_table { struct mutex scc_mutex; struct hns_roce_bank bank[HNS_ROCE_QP_BANK_NUM]; struct mutex bank_mutex; + struct hns_roce_idx_table idx_table; };
struct hns_roce_cq_table { @@ -1099,7 +1106,7 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, void hns_roce_init_pd_table(struct hns_roce_dev *hr_dev); void hns_roce_init_mr_table(struct hns_roce_dev *hr_dev); void hns_roce_init_cq_table(struct hns_roce_dev *hr_dev); -void hns_roce_init_qp_table(struct hns_roce_dev *hr_dev); +int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev); void hns_roce_init_srq_table(struct hns_roce_dev *hr_dev); void hns_roce_init_xrcd_table(struct hns_roce_dev *hr_dev);
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index cff1a73c4be7..ab0623d45b78 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4493,12 +4493,18 @@ static int get_dip_ctx_idx(struct ib_qp *ibqp, const struct ib_qp_attr *attr, { const struct ib_global_route *grh = rdma_ah_read_grh(&attr->ah_attr); struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); + u32 *spare_idx = hr_dev->qp_table.idx_table.spare_idx; + u32 *head = &hr_dev->qp_table.idx_table.head; + u32 *tail = &hr_dev->qp_table.idx_table.tail; struct hns_roce_dip *hr_dip; unsigned long flags; int ret = 0;
spin_lock_irqsave(&hr_dev->dip_list_lock, flags);
+ spare_idx[*tail] = ibqp->qp_num; + *tail = (*tail == hr_dev->caps.num_qps - 1) ? 0 : (*tail + 1); + list_for_each_entry(hr_dip, &hr_dev->dip_list, node) { if (!memcmp(grh->dgid.raw, hr_dip->dgid, 16)) { *dip_idx = hr_dip->dip_idx; @@ -4516,7 +4522,8 @@ static int get_dip_ctx_idx(struct ib_qp *ibqp, const struct ib_qp_attr *attr, }
memcpy(hr_dip->dgid, grh->dgid.raw, sizeof(grh->dgid.raw)); - hr_dip->dip_idx = *dip_idx = ibqp->qp_num; + hr_dip->dip_idx = *dip_idx = spare_idx[*head]; + *head = (*head == hr_dev->caps.num_qps - 1) ? 0 : (*head + 1); list_add_tail(&hr_dip->node, &hr_dev->dip_list);
out: diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 58200d0730bf..0fb42051273e 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -855,6 +855,12 @@ static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev) goto err_uar_table_free; }
+ ret = hns_roce_init_qp_table(hr_dev); + if (ret) { + dev_err(dev, "Failed to init qp_table.\n"); + goto err_uar_table_free; + } + hns_roce_init_pd_table(hr_dev);
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC) @@ -864,8 +870,6 @@ static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev)
hns_roce_init_cq_table(hr_dev);
- hns_roce_init_qp_table(hr_dev); - if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SRQ) { hns_roce_init_srq_table(hr_dev); } diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 00d1f44f91b9..6342b27ba90c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -1476,12 +1476,17 @@ bool hns_roce_wq_overflow(struct hns_roce_wq *hr_wq, u32 nreq, return cur + nreq >= hr_wq->wqe_cnt; }
-void hns_roce_init_qp_table(struct hns_roce_dev *hr_dev) +int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev) { struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; unsigned int reserved_from_bot; unsigned int i;
+ qp_table->idx_table.spare_idx = kcalloc(hr_dev->caps.num_qps, + sizeof(u32), GFP_KERNEL); + if (!qp_table->idx_table.spare_idx) + return -ENOMEM; + mutex_init(&qp_table->scc_mutex); mutex_init(&qp_table->bank_mutex); xa_init(&hr_dev->qp_table_xa); @@ -1499,6 +1504,8 @@ void hns_roce_init_qp_table(struct hns_roce_dev *hr_dev) HNS_ROCE_QP_BANK_NUM - 1; hr_dev->qp_table.bank[i].next = hr_dev->qp_table.bank[i].min; } + + return 0; }
void hns_roce_cleanup_qp_table(struct hns_roce_dev *hr_dev) @@ -1507,4 +1514,5 @@ void hns_roce_cleanup_qp_table(struct hns_roce_dev *hr_dev)
for (i = 0; i < HNS_ROCE_QP_BANK_NUM; i++) ida_destroy(&hr_dev->qp_table.bank[i].ida); + kfree(hr_dev->qp_table.idx_table.spare_idx); }
From: Wenpeng Liang liangwenpeng@huawei.com
mainline inclusion from mainline-v5.15-rc1 commit e788a3cd5787 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=e78...
---------------------------------------------------------------------
The bit width of dqpn is 24 bits, using u8 will cause truncation error.
Fixes: 926a01dc000d ("RDMA/hns: Add QP operations support for hip08 SoC") Link: https://lore.kernel.org/r/1629985056-57004-2-git-send-email-liangwenpeng@hua... Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index ab0623d45b78..faaca96eee12 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -5119,7 +5119,7 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
qp_attr->rq_psn = hr_reg_read(&context, QPC_RX_REQ_EPSN); qp_attr->sq_psn = (u32)hr_reg_read(&context, QPC_SQ_CUR_PSN); - qp_attr->dest_qp_num = (u8)hr_reg_read(&context, QPC_DQPN); + qp_attr->dest_qp_num = hr_reg_read(&context, QPC_DQPN); qp_attr->qp_access_flags = ((hr_reg_read(&context, QPC_RRE)) << V2_QP_RRE_S) | ((hr_reg_read(&context, QPC_RWE)) << V2_QP_RWE_S) |
From: Wenpeng Liang liangwenpeng@huawei.com
mainline inclusion from mainline-v5.15-rc1 commit fe164fc8d7b2 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=fe1...
---------------------------------------------------------------------
According to the IB specification, the destination qpn is allowed to be filled into the qpc only when the qp transitions from Init to RTR, so this code is unused.
Link: https://lore.kernel.org/r/1629985056-57004-4-git-send-email-liangwenpeng@hua... Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index faaca96eee12..d9bd2c721578 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4135,8 +4135,6 @@ static void modify_qp_init_to_init(struct ib_qp *ibqp, struct hns_roce_v2_qp_context *context, struct hns_roce_v2_qp_context *qpc_mask) { - struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); - /* * In v2 engine, software pass context and context mask to hardware * when modifying qp. If software need modify some fields in context, @@ -4161,11 +4159,6 @@ static void modify_qp_init_to_init(struct ib_qp *ibqp, hr_reg_write(context, QPC_SRQN, to_hr_srq(ibqp->srq)->srqn); hr_reg_clear(qpc_mask, QPC_SRQN); } - - if (attr_mask & IB_QP_DEST_QPN) { - hr_reg_write(context, QPC_DQPN, hr_qp->qpn); - hr_reg_clear(qpc_mask, QPC_DQPN); - } }
static int config_qp_rq_buf(struct hns_roce_dev *hr_dev,
From: Wenpeng Liang liangwenpeng@huawei.com
mainline inclusion from mainline-v5.15-rc1 commit 7fac71691b61 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=7fa...
---------------------------------------------------------------------
It should first alloc workqueue and request irq, and finally enable irq.
Link: https://lore.kernel.org/r/1629985056-57004-6-git-send-email-liangwenpeng@hua... Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 29 ++++++++++------------ 1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index d9bd2c721578..3b2909e746ef 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -6103,35 +6103,32 @@ static int hns_roce_v2_init_eq_table(struct hns_roce_dev *hr_dev)
ret = hns_roce_v2_create_eq(hr_dev, eq, eq_cmd); if (ret) { - dev_err(dev, "eq create failed.\n"); + dev_err(dev, "failed to create eq.\n"); goto err_create_eq_fail; } }
- /* enable irq */ - hns_roce_v2_int_mask_enable(hr_dev, eq_num, EQ_ENABLE); + hr_dev->irq_workq = alloc_ordered_workqueue("hns_roce_irq_workq", 0); + if (!hr_dev->irq_workq) { + dev_err(dev, "failed to create irq workqueue.\n"); + ret = -ENOMEM; + goto err_create_eq_fail; + }
- ret = __hns_roce_request_irq(hr_dev, irq_num, comp_num, - aeq_num, other_num); + ret = __hns_roce_request_irq(hr_dev, irq_num, comp_num, aeq_num, + other_num); if (ret) { - dev_err(dev, "Request irq failed.\n"); + dev_err(dev, "failed to request irq.\n"); goto err_request_irq_fail; }
- hr_dev->irq_workq = alloc_ordered_workqueue("hns_roce_irq_workq", 0); - if (!hr_dev->irq_workq) { - dev_err(dev, "Create irq workqueue failed!\n"); - ret = -ENOMEM; - goto err_create_wq_fail; - } + /* enable irq */ + hns_roce_v2_int_mask_enable(hr_dev, eq_num, EQ_ENABLE);
return 0;
-err_create_wq_fail: - __hns_roce_free_irq(hr_dev); - err_request_irq_fail: - hns_roce_v2_int_mask_enable(hr_dev, eq_num, EQ_DISABLE); + destroy_workqueue(hr_dev->irq_workq);
err_create_eq_fail: for (i -= 1; i >= 0; i--)
From: Xinhao Liu liuxinhao5@hisilicon.com
mainline inclusion from mainline-v5.15-rc1 commit 1a0182785a6d category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=1a0...
---------------------------------------------------------------------
Just delete unnecessary blank lines.
Link: https://lore.kernel.org/r/1629985056-57004-8-git-send-email-liangwenpeng@hua... Signed-off-by: Xinhao Liu liuxinhao5@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 -- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 1 - drivers/infiniband/hw/hns/hns_roce_qp.c | 1 - 3 files changed, 4 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 3b2909e746ef..556a89965e38 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -5209,7 +5209,6 @@ static int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev,
if (send_cq && send_cq != recv_cq) __hns_roce_v2_cq_clean(send_cq, hr_qp->qpn, NULL); - }
hns_roce_qp_remove(hr_dev, hr_qp); @@ -6349,7 +6348,6 @@ static int hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
handle->rinfo.instance_state = HNS_ROCE_STATE_INITED;
- return 0;
reset_chk_err: diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h index 0b91a1a57aa0..4d904d5e82be 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -1407,7 +1407,6 @@ struct hns_roce_cmq_desc { __le32 rsv[4]; } func_info; }; - };
struct hns_roce_v2_cmq_ring { diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 6342b27ba90c..065df146b883 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -697,7 +697,6 @@ static int alloc_rq_inline_buf(struct hns_roce_qp *hr_qp, /* allocate recv inline buf */ wqe_list = kcalloc(wqe_cnt, sizeof(struct hns_roce_rinl_wqe), GFP_KERNEL); - if (!wqe_list) goto err;
From: Jason Gunthorpe jgg@nvidia.com
mainline inclusion from mainline-v5.15-rc4 commit 14351f08ed5c category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=143...
---------------------------------------------------------------------
gcc 8.3 and 5.4 throw this:
In function 'modify_qp_init_to_rtr', ././include/linux/compiler_types.h:322:38: error: call to '__compiletime_assert_1859' declared with attribute error: FIELD_PREP: value too large for the field _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) [..] drivers/infiniband/hw/hns/hns_roce_common.h:91:52: note: in expansion of macro 'FIELD_PREP' *((__le32 *)ptr + (field_h) / 32) |= cpu_to_le32(FIELD_PREP( \ ^~~~~~~~~~ drivers/infiniband/hw/hns/hns_roce_common.h:95:39: note: in expansion of macro '_hr_reg_write' #define hr_reg_write(ptr, field, val) _hr_reg_write(ptr, field, val) ^~~~~~~~~~~~~ drivers/infiniband/hw/hns/hns_roce_hw_v2.c:4412:2: note: in expansion of macro 'hr_reg_write' hr_reg_write(context, QPC_LP_PKTN_INI, lp_pktn_ini);
Because gcc has miscalculated the constantness of lp_pktn_ini:
mtu = ib_mtu_enum_to_int(ib_mtu); if (WARN_ON(mtu < 0)) [..] lp_pktn_ini = ilog2(MAX_LP_MSG_LEN / mtu);
Since mtu is limited to {256,512,1024,2048,4096} lp_pktn_ini is between 4 and 8 which is compatible with the 4 bit field in the FIELD_PREP.
Work around this broken compiler by adding a 'can never be true' constraint on lp_pktn_ini's value which clears out the problem.
Fixes: f0cb411aad23 ("RDMA/hns: Use new interface to modify QP context") Link: https://lore.kernel.org/r/0-v1-c773ecb137bc+11f-hns_gcc8_jgg@nvidia.com Reported-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 556a89965e38..6016ffae19ae 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4389,7 +4389,12 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, hr_qp->path_mtu = ib_mtu;
mtu = ib_mtu_enum_to_int(ib_mtu); - if (WARN_ON(mtu < 0)) + if (WARN_ON(mtu <= 0)) + return -EINVAL; +#define MAX_LP_MSG_LEN 65536 + /* MTU * (2 ^ LP_PKTN_INI) shouldn't be bigger than 64KB */ + lp_pktn_ini = ilog2(MAX_LP_MSG_LEN / mtu); + if (WARN_ON(lp_pktn_ini >= 0xF)) return -EINVAL;
if (attr_mask & IB_QP_PATH_MTU) { @@ -4397,10 +4402,6 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, hr_reg_clear(qpc_mask, QPC_MTU); }
-#define MAX_LP_MSG_LEN 65536 - /* MTU * (2 ^ LP_PKTN_INI) shouldn't be bigger than 64KB */ - lp_pktn_ini = ilog2(MAX_LP_MSG_LEN / mtu); - hr_reg_write(context, QPC_LP_PKTN_INI, lp_pktn_ini); hr_reg_clear(qpc_mask, QPC_LP_PKTN_INI);
From: Wenpeng Liang liangwenpeng@huawei.com
mainline inclusion from mainline-v5.15-rc4 commit cc26aee10058 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=cc2...
---------------------------------------------------------------------
The size of CQE is different for different versions of hardware, so the driver needs to specify the size of CQE explicitly.
Fixes: 09a5f210f67e ("RDMA/hns: Add support for CQE in size of 64 Bytes") Link: https://lore.kernel.org/r/20210927125557.15031-2-liangwenpeng@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 6016ffae19ae..925ca904aa49 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -3291,7 +3291,7 @@ static void __hns_roce_v2_cq_clean(struct hns_roce_cq *hr_cq, u32 qpn, dest = get_cqe_v2(hr_cq, (prod_index + nfreed) & hr_cq->ib_cq.cqe); owner_bit = hr_reg_read(dest, CQE_OWNER); - memcpy(dest, cqe, sizeof(*cqe)); + memcpy(dest, cqe, hr_cq->cqe_size); hr_reg_write(dest, CQE_OWNER, owner_bit); } }
From: Wenpeng Liang liangwenpeng@huawei.com
mainline inclusion from mainline-v5.15-rc4 commit e671f0ecfece category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=e67...
---------------------------------------------------------------------
If the CQE size of the user space is not the size supported by the hardware, the creation of CQ should be stopped.
Fixes: 09a5f210f67e ("RDMA/hns: Add support for CQE in size of 64 Bytes") Link: https://lore.kernel.org/r/20210927125557.15031-3-liangwenpeng@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_cq.c | 31 ++++++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index 9d376879dccc..65e1e6126d95 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -325,19 +325,30 @@ static void set_cq_param(struct hns_roce_cq *hr_cq, u32 cq_entries, int vector, INIT_LIST_HEAD(&hr_cq->rq_list); }
-static void set_cqe_size(struct hns_roce_cq *hr_cq, struct ib_udata *udata, - struct hns_roce_ib_create_cq *ucmd) +static int set_cqe_size(struct hns_roce_cq *hr_cq, struct ib_udata *udata, + struct hns_roce_ib_create_cq *ucmd) { struct hns_roce_dev *hr_dev = to_hr_dev(hr_cq->ib_cq.device);
- if (udata) { - if (udata->inlen >= offsetofend(typeof(*ucmd), cqe_size)) - hr_cq->cqe_size = ucmd->cqe_size; - else - hr_cq->cqe_size = HNS_ROCE_V2_CQE_SIZE; - } else { + if (!udata) { hr_cq->cqe_size = hr_dev->caps.cqe_sz; + return 0; + } + + if (udata->inlen >= offsetofend(typeof(*ucmd), cqe_size)) { + if (ucmd->cqe_size != HNS_ROCE_V2_CQE_SIZE && + ucmd->cqe_size != HNS_ROCE_V3_CQE_SIZE) { + ibdev_err(&hr_dev->ib_dev, + "invalid cqe size %u.\n", ucmd->cqe_size); + return -EINVAL; + } + + hr_cq->cqe_size = ucmd->cqe_size; + } else { + hr_cq->cqe_size = HNS_ROCE_V2_CQE_SIZE; } + + return 0; }
int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr, @@ -366,7 +377,9 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,
set_cq_param(hr_cq, attr->cqe, attr->comp_vector, &ucmd);
- set_cqe_size(hr_cq, udata, &ucmd); + ret = set_cqe_size(hr_cq, udata, &ucmd); + if (ret) + return ret;
ret = alloc_cq_buf(hr_dev, hr_cq, udata, ucmd.buf_addr); if (ret) {
From: Cai Huoqing caihuoqing@baidu.com
mainline inclusion from mainline-v5.15-rc5 commit 9a33f3980978 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=9a3...
---------------------------------------------------------------------
Replacing kmalloc/kfree/dma_map_single/dma_unmap_single() with dma_alloc_coherent/dma_free_coherent() helps to reduce code size, and simplify the code, and coherent DMA will not clear the cache every time.
The SOC that this driver supports does not have incoherent DMA, so this makes the code follow the DMA API properly with no performance impact. Currently there are missing dma sync calls around the DMA transfers.
Link: https://lore.kernel.org/r/20210926061116.282-1-caihuoqing@baidu.com Signed-off-by: Cai Huoqing caihuoqing@baidu.com Reviewed-by: Wenpeng Liang liangwenpeng@huawei.com Tested-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 925ca904aa49..7ba5e215d621 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -1175,32 +1175,22 @@ static int hns_roce_alloc_cmq_desc(struct hns_roce_dev *hr_dev, { int size = ring->desc_num * sizeof(struct hns_roce_cmq_desc);
- ring->desc = kzalloc(size, GFP_KERNEL); + ring->desc = dma_alloc_coherent(hr_dev->dev, size, + &ring->desc_dma_addr, GFP_KERNEL); if (!ring->desc) return -ENOMEM;
- ring->desc_dma_addr = dma_map_single(hr_dev->dev, ring->desc, size, - DMA_BIDIRECTIONAL); - if (dma_mapping_error(hr_dev->dev, ring->desc_dma_addr)) { - ring->desc_dma_addr = 0; - kfree(ring->desc); - ring->desc = NULL; - - return -ENOMEM; - } - return 0; }
static void hns_roce_free_cmq_desc(struct hns_roce_dev *hr_dev, struct hns_roce_v2_cmq_ring *ring) { - dma_unmap_single(hr_dev->dev, ring->desc_dma_addr, - ring->desc_num * sizeof(struct hns_roce_cmq_desc), - DMA_BIDIRECTIONAL); + dma_free_coherent(hr_dev->dev, + ring->desc_num * sizeof(struct hns_roce_cmq_desc), + ring->desc, ring->desc_dma_addr);
ring->desc_dma_addr = 0; - kfree(ring->desc); }
static int init_csq(struct hns_roce_dev *hr_dev,
From: Jakub Kicinski kuba@kernel.org
mainline inclusion from mainline-v5.15-rc5 commit fd92213e9af3 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=fd9...
---------------------------------------------------------------------
netdev->dev_addr will become const soon, make sure drivers propagate the qualifier.
Link: https://lore.kernel.org/r/20211019182604.1441387-4-kuba@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Reviewed-by: Leon Romanovsky leonro@nvidia.com Acked-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/bnxt_re/qplib_res.c | 2 +- drivers/infiniband/hw/bnxt_re/qplib_res.h | 2 +- drivers/infiniband/hw/bnxt_re/qplib_sp.c | 6 +++--- drivers/infiniband/hw/bnxt_re/qplib_sp.h | 5 +++-- drivers/infiniband/hw/hfi1/ipoib_main.c | 2 +- drivers/infiniband/hw/hns/hns_roce_device.h | 3 ++- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 6 +++--- drivers/infiniband/hw/hns/hns_roce_main.c | 3 ++- drivers/infiniband/hw/usnic/usnic_fwd.c | 2 +- drivers/infiniband/hw/usnic/usnic_fwd.h | 2 +- 10 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c index 754dcebeb4ca..a9c2359b0d07 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_res.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c @@ -572,7 +572,7 @@ int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res, }
/* GUID */ -void bnxt_qplib_get_guid(u8 *dev_addr, u8 *guid) +void bnxt_qplib_get_guid(const u8 *dev_addr, u8 *guid) { u8 mac[ETH_ALEN];
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.h b/drivers/infiniband/hw/bnxt_re/qplib_res.h index 58bad6f78456..a531024fcc17 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_res.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h @@ -351,7 +351,7 @@ void bnxt_qplib_free_hwq(struct bnxt_qplib_res *res, struct bnxt_qplib_hwq *hwq); int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, struct bnxt_qplib_hwq_attr *hwq_attr); -void bnxt_qplib_get_guid(u8 *dev_addr, u8 *guid); +void bnxt_qplib_get_guid(const u8 *dev_addr, u8 *guid); int bnxt_qplib_alloc_pd(struct bnxt_qplib_pd_tbl *pd_tbl, struct bnxt_qplib_pd *pd); int bnxt_qplib_dealloc_pd(struct bnxt_qplib_res *res, diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c index 64d44f51db4b..167d416a380b 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c @@ -275,8 +275,8 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl, }
int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl, - struct bnxt_qplib_gid *gid, u8 *smac, u16 vlan_id, - bool update, u32 *index) + struct bnxt_qplib_gid *gid, const u8 *smac, + u16 vlan_id, bool update, u32 *index) { struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl, struct bnxt_qplib_res, @@ -367,7 +367,7 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
int bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl, struct bnxt_qplib_gid *gid, u16 gid_idx, - u8 *smac) + const u8 *smac) { struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl, struct bnxt_qplib_res, diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h index 967890cd81f2..39ef6fae0662 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h @@ -227,10 +227,11 @@ int bnxt_qplib_get_sgid(struct bnxt_qplib_res *res, int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl, struct bnxt_qplib_gid *gid, u16 vlan_id, bool update); int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl, - struct bnxt_qplib_gid *gid, u8 *mac, u16 vlan_id, + struct bnxt_qplib_gid *gid, const u8 *mac, u16 vlan_id, bool update, u32 *index); int bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl, - struct bnxt_qplib_gid *gid, u16 gid_idx, u8 *smac); + struct bnxt_qplib_gid *gid, u16 gid_idx, + const u8 *smac); int bnxt_qplib_get_pkey(struct bnxt_qplib_res *res, struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 index, u16 *pkey); diff --git a/drivers/infiniband/hw/hfi1/ipoib_main.c b/drivers/infiniband/hw/hfi1/ipoib_main.c index 9f71b9d706bd..a1cce33f97de 100644 --- a/drivers/infiniband/hw/hfi1/ipoib_main.c +++ b/drivers/infiniband/hw/hfi1/ipoib_main.c @@ -11,7 +11,7 @@ #include "ipoib.h" #include "hfi.h"
-static u32 qpn_from_mac(u8 *mac_arr) +static u32 qpn_from_mac(const u8 *mac_arr) { return (u32)mac_arr[1] << 16 | mac_arr[2] << 8 | mac_arr[3]; } diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 3066bb4008ca..0fb4f363b997 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -859,7 +859,8 @@ struct hns_roce_hw { bool (*chk_mbox_avail)(struct hns_roce_dev *hr_dev, bool *is_busy); int (*set_gid)(struct hns_roce_dev *hr_dev, int gid_index, const union ib_gid *gid, const struct ib_gid_attr *attr); - int (*set_mac)(struct hns_roce_dev *hr_dev, u8 phy_port, u8 *addr); + int (*set_mac)(struct hns_roce_dev *hr_dev, u8 phy_port, + const u8 *addr); int (*write_mtpt)(struct hns_roce_dev *hr_dev, void *mb_buf, struct hns_roce_mr *mr); int (*rereg_write_mtpt)(struct hns_roce_dev *hr_dev, diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 7ba5e215d621..23a0eafe518b 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -2975,7 +2975,7 @@ static int hns_roce_v2_set_gid(struct hns_roce_dev *hr_dev, int gid_index, }
static int hns_roce_v2_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port, - u8 *addr) + const u8 *addr) { struct hns_roce_cmq_desc desc; struct hns_roce_cfg_smac_tb *smac_tb = @@ -4300,10 +4300,10 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, dma_addr_t trrl_ba; dma_addr_t irrl_ba; enum ib_mtu ib_mtu; + const u8 *smac; u8 lp_pktn_ini; u64 *mtts; u8 *dmac; - u8 *smac; int mtu; int port; int ret; @@ -4356,7 +4356,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
port = (attr_mask & IB_QP_PORT) ? (attr->port_num - 1) : hr_qp->port;
- smac = (u8 *)hr_dev->dev_addr[port]; + smac = (const u8 *)hr_dev->dev_addr[port]; dmac = (u8 *)attr->ah_attr.roce.dmac; /* when dmac equals smac or loop_idc is 1, it should loopback */ if (ether_addr_equal_unaligned(dmac, smac) || diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 0fb42051273e..8946aa8a1f3c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -41,7 +41,8 @@ #include "hns_roce_device.h" #include "hns_roce_hem.h"
-static int hns_roce_set_mac(struct hns_roce_dev *hr_dev, u8 port, u8 *addr) +static int hns_roce_set_mac(struct hns_roce_dev *hr_dev, u32 port, + const u8 *addr) { u8 phy_port; u32 i; diff --git a/drivers/infiniband/hw/usnic/usnic_fwd.c b/drivers/infiniband/hw/usnic/usnic_fwd.c index 398c4c00b932..18a70850b738 100644 --- a/drivers/infiniband/hw/usnic/usnic_fwd.c +++ b/drivers/infiniband/hw/usnic/usnic_fwd.c @@ -103,7 +103,7 @@ void usnic_fwd_dev_free(struct usnic_fwd_dev *ufdev) kfree(ufdev); }
-void usnic_fwd_set_mac(struct usnic_fwd_dev *ufdev, char mac[ETH_ALEN]) +void usnic_fwd_set_mac(struct usnic_fwd_dev *ufdev, const char mac[ETH_ALEN]) { spin_lock(&ufdev->lock); memcpy(&ufdev->mac, mac, sizeof(ufdev->mac)); diff --git a/drivers/infiniband/hw/usnic/usnic_fwd.h b/drivers/infiniband/hw/usnic/usnic_fwd.h index f0b71d593da5..a91200886922 100644 --- a/drivers/infiniband/hw/usnic/usnic_fwd.h +++ b/drivers/infiniband/hw/usnic/usnic_fwd.h @@ -74,7 +74,7 @@ struct usnic_filter_action { struct usnic_fwd_dev *usnic_fwd_dev_alloc(struct pci_dev *pdev); void usnic_fwd_dev_free(struct usnic_fwd_dev *ufdev);
-void usnic_fwd_set_mac(struct usnic_fwd_dev *ufdev, char mac[ETH_ALEN]); +void usnic_fwd_set_mac(struct usnic_fwd_dev *ufdev, const char mac[ETH_ALEN]); void usnic_fwd_add_ipaddr(struct usnic_fwd_dev *ufdev, __be32 inaddr); void usnic_fwd_del_ipaddr(struct usnic_fwd_dev *ufdev); void usnic_fwd_carrier_up(struct usnic_fwd_dev *ufdev);
From: Haoyue Xu xuhaoyue1@hisilicon.com
mainline inclusion from mainline-v5.15-rc6 commit fd92213e9af3 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=571...
---------------------------------------------------------------------
We set the init CQ status to ARMED before. As a result, an unexpected CEQE would be reported. Therefore, the init CQ status should be set to no_armed rather than REG_NXT_CEQE.
Fixes: a5073d6054f7 ("RDMA/hns: Add eq support of hip08") Link: https://lore.kernel.org/r/20211029095846.26732-1-liangwenpeng@huawei.com Signed-off-by: Haoyue Xu xuhaoyue1@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 23a0eafe518b..ecd7db65c6f1 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -3310,7 +3310,7 @@ static void hns_roce_v2_write_cqc(struct hns_roce_dev *hr_dev, memset(cq_context, 0, sizeof(*cq_context));
hr_reg_write(cq_context, CQC_CQ_ST, V2_CQ_STATE_VALID); - hr_reg_write(cq_context, CQC_ARM_ST, REG_NXT_CEQE); + hr_reg_write(cq_context, CQC_ARM_ST, NO_ARMED); hr_reg_write(cq_context, CQC_SHIFT, ilog2(hr_cq->cq_depth)); hr_reg_write(cq_context, CQC_CEQN, hr_cq->vector); hr_reg_write(cq_context, CQC_CQN, hr_cq->cqn);
From: Yixing Liu liuyixing1@huawei.com
mainline inclusion from mainline-v5.15-rc6 commit 0e60778efb07 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=0e6...
---------------------------------------------------------------------
The upper limit of MAX_LP_MSG_LEN on HIP08 is 64K, and the upper limit on HIP09 is 16K. Regardless of whether it is HIP08 or HIP09, only 16K will be used. In order to ensure compatibility, it is unified to 16K.
Setting MAX_LP_MSG_LEN to 16K will not cause performance loss on HIP08.
Fixes: fbed9d2be292 ("RDMA/hns: Fix configuration of ack_req_freq in QPC") Link: https://lore.kernel.org/r/20211029100537.27299-1-liangwenpeng@huawei.com Signed-off-by: Yixing Liu liuyixing1@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index ecd7db65c6f1..e30936189d9a 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4381,8 +4381,8 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, mtu = ib_mtu_enum_to_int(ib_mtu); if (WARN_ON(mtu <= 0)) return -EINVAL; -#define MAX_LP_MSG_LEN 65536 - /* MTU * (2 ^ LP_PKTN_INI) shouldn't be bigger than 64KB */ +#define MAX_LP_MSG_LEN 16384 + /* MTU * (2 ^ LP_PKTN_INI) shouldn't be bigger than 16KB */ lp_pktn_ini = ilog2(MAX_LP_MSG_LEN / mtu); if (WARN_ON(lp_pktn_ini >= 0xF)) return -EINVAL;
From: Kamal Heib kamalheib1@gmail.com
mainline inclusion from mainline-v5.16-rc2 commit 2a67fcfa0db6 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=2a6...
---------------------------------------------------------------------
Before query pkey, make sure that the queried index is valid.
Fixes: 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver") Link: https://lore.kernel.org/r/20211117145954.123893-1-kamalheib1@gmail.com Signed-off-by: Kamal Heib kamalheib1@gmail.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_main.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 8946aa8a1f3c..8aa0af069042 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -266,6 +266,9 @@ static enum rdma_link_layer hns_roce_get_link_layer(struct ib_device *device, static int hns_roce_query_pkey(struct ib_device *ib_dev, u8 port, u16 index, u16 *pkey) { + if (index > 0) + return -EINVAL; + *pkey = PKEY_ID;
return 0;
From: Xinhao Liu liuxinhao5@hisilicon.com
mainline inclusion from mainline-v5.16-rc2 commit 994baacc6b4a category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=994...
---------------------------------------------------------------------
The hex printf format should be "0xff" instead of "ff".
Link: https://lore.kernel.org/r/20211119140208.40416-2-liangwenpeng@huawei.com Signed-off-by: Xinhao Liu liuxinhao5@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_cmd.c | 10 +++++----- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.c b/drivers/infiniband/hw/hns/hns_roce_cmd.c index 3fa152f7b5ee..4b693d542ace 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cmd.c +++ b/drivers/infiniband/hw/hns/hns_roce_cmd.c @@ -60,7 +60,7 @@ static int __hns_roce_cmd_mbox_poll(struct hns_roce_dev *hr_dev, u64 in_param, CMD_POLL_TOKEN, 0); if (ret) { dev_err_ratelimited(hr_dev->dev, - "failed to post mailbox %x in poll mode, ret = %d.\n", + "failed to post mailbox 0x%x in poll mode, ret = %d.\n", op, ret); return ret; } @@ -90,7 +90,7 @@ void hns_roce_cmd_event(struct hns_roce_dev *hr_dev, u16 token, u8 status,
if (unlikely(token != context->token)) { dev_err_ratelimited(hr_dev->dev, - "[cmd] invalid ae token %x,context token is %x!\n", + "[cmd] invalid ae token 0x%x, context token is 0x%x.\n", token, context->token); return; } @@ -129,14 +129,14 @@ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param, context->token, 1); if (ret) { dev_err_ratelimited(dev, - "failed to post mailbox %x in event mode, ret = %d.\n", + "failed to post mailbox 0x%x in event mode, ret = %d.\n", op, ret); goto out; }
if (!wait_for_completion_timeout(&context->done, msecs_to_jiffies(timeout))) { - dev_err_ratelimited(dev, "[cmd] token %x mailbox %x timeout.\n", + dev_err_ratelimited(dev, "[cmd] token 0x%x mailbox 0x%x timeout.\n", context->token, op); ret = -EBUSY; goto out; @@ -144,7 +144,7 @@ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param,
ret = context->result; if (ret) - dev_err_ratelimited(dev, "[cmd] token %x mailbox %x error %d\n", + dev_err_ratelimited(dev, "[cmd] token 0x%x mailbox 0x%x error %d.\n", context->token, op, ret);
out: diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index e30936189d9a..c98c682c9cb7 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -1305,7 +1305,7 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev, continue;
dev_err_ratelimited(hr_dev->dev, - "Cmdq IO error, opcode = %x, return = %x\n", + "Cmdq IO error, opcode = 0x%x, return = 0x%x.\n", desc->opcode, desc_ret); ret = -EIO; }
From: Xinhao Liu liuxinhao5@hisilicon.com
mainline inclusion from mainline-v5.16-rc2 commit ea393549a3e1 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=ea3...
---------------------------------------------------------------------
The print format should be consistent with the variable type.
Link: https://lore.kernel.org/r/20211119140208.40416-3-liangwenpeng@huawei.com Signed-off-by: Xinhao Liu liuxinhao5@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index c98c682c9cb7..8daf1b9af4af 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -1312,7 +1312,7 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev, } else { /* FW/HW reset or incorrect number of desc */ tail = roce_read(hr_dev, ROCEE_TX_CMQ_CI_REG); - dev_warn(hr_dev->dev, "CMDQ move tail from %d to %d\n", + dev_warn(hr_dev->dev, "CMDQ move tail from %u to %u.\n", csq->head, tail); csq->head = tail;
@@ -4715,7 +4715,7 @@ static int hns_roce_v2_set_path(struct ib_qp *ibqp, hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr); if (unlikely(hr_qp->sl > MAX_SERVICE_LEVEL)) { ibdev_err(ibdev, - "failed to fill QPC, sl (%d) shouldn't be larger than %d.\n", + "failed to fill QPC, sl (%u) shouldn't be larger than %d.\n", hr_qp->sl, MAX_SERVICE_LEVEL); return -EINVAL; } @@ -5820,7 +5820,7 @@ static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev, int eqn) 0, HNS_ROCE_CMD_DESTROY_AEQC, HNS_ROCE_CMD_TIMEOUT_MSECS); if (ret) - dev_err(dev, "[mailbox cmd] destroy eqc(%d) failed.\n", eqn); + dev_err(dev, "[mailbox cmd] destroy eqc(%u) failed.\n", eqn); }
static void free_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
From: Xinhao Liu liuxinhao5@hisilicon.com
mainline inclusion from mainline-v5.16-rc2 commit 3aecfc3802d8 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=3ae...
---------------------------------------------------------------------
There should be a space between the code and the comment on the right.
Link: https://lore.kernel.org/r/20211119140208.40416-4-liangwenpeng@huawei.com Signed-off-by: Xinhao Liu liuxinhao5@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_device.h | 22 ++++++++++----------- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +- drivers/infiniband/hw/hns/hns_roce_mr.c | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 0fb4f363b997..592cc416f28d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -322,10 +322,10 @@ struct hns_roce_mr { u64 size; /* Address range of MR */ u32 key; /* Key of MR */ u32 pd; /* PD num of MR */ - u32 access; /* Access permission of MR */ + u32 access; /* Access permission of MR */ int enabled; /* MR's active status */ - int type; /* MR's register type */ - u32 pbl_hop_num; /* multi-hop number */ + int type; /* MR's register type */ + u32 pbl_hop_num; /* multi-hop number */ struct hns_roce_mtr pbl_mtr; u32 npages; dma_addr_t *page_list; @@ -343,16 +343,16 @@ struct hns_roce_wq { u32 max_gs; u32 rsv_sge; int offset; - int wqe_shift; /* WQE size */ + int wqe_shift; /* WQE size */ u32 head; u32 tail; void __iomem *db_reg; };
struct hns_roce_sge { - unsigned int sge_cnt; /* SGE num */ + unsigned int sge_cnt; /* SGE num */ int offset; - int sge_shift; /* SGE size */ + int sge_shift; /* SGE size */ };
struct hns_roce_buf_list { @@ -629,9 +629,9 @@ struct hns_roce_qp { unsigned long flush_flag; struct hns_roce_work flush_work; struct hns_roce_rinl_buf rq_inl_buf; - struct list_head node; /* all qps are on a list */ - struct list_head rq_node; /* all recv qps are on a list */ - struct list_head sq_node; /* all send qps are on a list */ + struct list_head node; /* all qps are on a list */ + struct list_head rq_node; /* all recv qps are on a list */ + struct list_head sq_node; /* all send qps are on a list */ struct hns_user_mmap_entry *dwqe_mmap_entry; };
@@ -804,7 +804,7 @@ struct hns_roce_caps { u32 cqc_timer_ba_pg_sz; u32 cqc_timer_buf_pg_sz; u32 cqc_timer_hop_num; - u32 cqe_ba_pg_sz; /* page_size = 4K*(2^cqe_ba_pg_sz) */ + u32 cqe_ba_pg_sz; /* page_size = 4K*(2^cqe_ba_pg_sz) */ u32 cqe_buf_pg_sz; u32 cqe_hop_num; u32 srqwqe_ba_pg_sz; @@ -823,7 +823,7 @@ struct hns_roce_caps { u32 gmv_hop_num; u32 sl_num; u32 llm_buf_pg_sz; - u32 chunk_sz; /* chunk size in non multihop mode */ + u32 chunk_sz; /* chunk size in non multihop mode */ u64 flags; u16 default_ceq_max_cnt; u16 default_ceq_period; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h index 4d904d5e82be..6858b939de63 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -1441,7 +1441,7 @@ struct hns_roce_v2_priv { struct hns_roce_dip { u8 dgid[GID_LEN_V2]; u32 dip_idx; - struct list_head node; /* all dips are on a list */ + struct list_head node; /* all dips are on a list */ };
#define HNS_ROCE_AEQ_DEFAULT_BURST_NUM 0x0 diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c index 504b75f7f551..ad3149ee1086 100644 --- a/drivers/infiniband/hw/hns/hns_roce_mr.c +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c @@ -80,7 +80,7 @@ static int alloc_mr_key(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr) return -ENOMEM; }
- mr->key = hw_index_to_key(id); /* MR key */ + mr->key = hw_index_to_key(id); /* MR key */
err = hns_roce_table_get(hr_dev, &hr_dev->mr_table.mtpt_table, (unsigned long)id);
From: Xinhao Liu liuxinhao5@hisilicon.com
mainline inclusion from mainline-v5.16-rc2 commit d147583ec8d0 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=d14...
---------------------------------------------------------------------
The type of the variable participating in the shift operation should be an unsigned type instead of a signed type.
Link: https://lore.kernel.org/r/20211119140208.40416-5-liangwenpeng@huawei.com Signed-off-by: Xinhao Liu liuxinhao5@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_device.h | 18 +++++++++--------- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- drivers/infiniband/hw/hns/hns_roce_mr.c | 8 ++++---- drivers/infiniband/hw/hns/hns_roce_qp.c | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 592cc416f28d..8bea6de7f955 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -342,8 +342,8 @@ struct hns_roce_wq { u32 wqe_cnt; /* WQE num */ u32 max_gs; u32 rsv_sge; - int offset; - int wqe_shift; /* WQE size */ + u32 offset; + u32 wqe_shift; /* WQE size */ u32 head; u32 tail; void __iomem *db_reg; @@ -351,8 +351,8 @@ struct hns_roce_wq {
struct hns_roce_sge { unsigned int sge_cnt; /* SGE num */ - int offset; - int sge_shift; /* SGE size */ + u32 offset; + u32 sge_shift; /* SGE size */ };
struct hns_roce_buf_list { @@ -435,7 +435,7 @@ struct hns_roce_cq {
struct hns_roce_idx_que { struct hns_roce_mtr mtr; - int entry_shift; + u32 entry_shift; unsigned long *bitmap; u32 head; u32 tail; @@ -447,7 +447,7 @@ struct hns_roce_srq { u32 wqe_cnt; int max_gs; u32 rsv_sge; - int wqe_shift; + u32 wqe_shift; u32 cqn; u32 xrcdn; void __iomem *db_reg; @@ -716,7 +716,7 @@ struct hns_roce_caps { u32 reserved_qps; int num_qpc_timer; int num_cqc_timer; - int num_srqs; + u32 num_srqs; u32 max_wqes; u32 max_srq_wrs; u32 max_srq_sges; @@ -730,7 +730,7 @@ struct hns_roce_caps { u32 min_cqes; u32 min_wqes; u32 reserved_cqs; - int reserved_srqs; + u32 reserved_srqs; int num_aeq_vectors; int num_comp_vectors; int num_other_vectors; @@ -1094,7 +1094,7 @@ void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev); /* hns roce hw need current block and next block addr from mtt */ #define MTT_MIN_COUNT 2 int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, - int offset, u64 *mtt_buf, int mtt_max, u64 *base_addr); + u32 offset, u64 *mtt_buf, int mtt_max, u64 *base_addr); int hns_roce_mtr_create(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, struct hns_roce_buf_attr *buf_attr, unsigned int page_shift, struct ib_udata *udata, diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 8daf1b9af4af..f7ac17524414 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -5806,7 +5806,7 @@ static void hns_roce_v2_int_mask_enable(struct hns_roce_dev *hr_dev, roce_write(hr_dev, ROCEE_VF_ABN_INT_CFG_REG, enable_flag); }
-static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev, int eqn) +static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev, u32 eqn) { struct device *dev = hr_dev->dev; int ret; diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c index ad3149ee1086..44e0ee3b5b6c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_mr.c +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c @@ -812,11 +812,11 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, }
int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, - int offset, u64 *mtt_buf, int mtt_max, u64 *base_addr) + u32 offset, u64 *mtt_buf, int mtt_max, u64 *base_addr) { struct hns_roce_hem_cfg *cfg = &mtr->hem_cfg; int mtt_count, left; - int start_index; + u32 start_index; int total = 0; __le64 *mtts; u32 npage; @@ -869,10 +869,10 @@ int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, static int mtr_init_buf_cfg(struct hns_roce_dev *hr_dev, struct hns_roce_buf_attr *attr, struct hns_roce_hem_cfg *cfg, - unsigned int *buf_page_shift, int unalinged_size) + unsigned int *buf_page_shift, u64 unalinged_size) { struct hns_roce_buf_region *r; - int first_region_padding; + u64 first_region_padding; int page_cnt, region_cnt; unsigned int page_shift; size_t buf_size; diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 065df146b883..1099963db1b6 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -1437,7 +1437,7 @@ void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq, } }
-static inline void *get_wqe(struct hns_roce_qp *hr_qp, int offset) +static inline void *get_wqe(struct hns_roce_qp *hr_qp, u32 offset) { return hns_roce_buf_offset(hr_qp->mtr.kmem, offset); }
From: Xinhao Liu liuxinhao@huawei.com
mainline inclusion from mainline-v5.16-rc2 commit 6cb6a6cbcd7f category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=6cb...
---------------------------------------------------------------------
Each member of Array[][] should be initialized on a separate line.
Link: https://lore.kernel.org/r/20211119140208.40416-7-liangwenpeng@huawei.com Signed-off-by: Xinhao Liu liuxinhao@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index f7ac17524414..3d64963c5f2d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4744,7 +4744,8 @@ static bool check_qp_state(enum ib_qp_state cur_state, [IB_QPS_ERR] = true }, [IB_QPS_SQD] = {}, [IB_QPS_SQE] = {}, - [IB_QPS_ERR] = { [IB_QPS_RESET] = true, [IB_QPS_ERR] = true } + [IB_QPS_ERR] = { [IB_QPS_RESET] = true, + [IB_QPS_ERR] = true } };
return sm[cur_state][new_state];
From: Yixing Liu liuyixing1@huawei.com
mainline inclusion from mainline-v5.16-rc2 commit 31835593763c category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=318...
---------------------------------------------------------------------
These macros are no longer used, so remove them.
Link: https://lore.kernel.org/r/20211119140208.40416-9-liangwenpeng@huawei.com Signed-off-by: Yixing Liu liuyixing1@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 16 ---------------- 1 file changed, 16 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h index 6858b939de63..fddb9bc3c14c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -35,26 +35,15 @@
#include <linux/bitops.h>
-#define HNS_ROCE_VF_QPC_BT_NUM 256 -#define HNS_ROCE_VF_SCCC_BT_NUM 64 -#define HNS_ROCE_VF_SRQC_BT_NUM 64 -#define HNS_ROCE_VF_CQC_BT_NUM 64 -#define HNS_ROCE_VF_MPT_BT_NUM 64 -#define HNS_ROCE_VF_SMAC_NUM 32 -#define HNS_ROCE_VF_SL_NUM 8 -#define HNS_ROCE_VF_GMV_BT_NUM 256 - #define HNS_ROCE_V2_MAX_QP_NUM 0x1000 #define HNS_ROCE_V2_MAX_QPC_TIMER_NUM 0x200 #define HNS_ROCE_V2_MAX_WQE_NUM 0x8000 -#define HNS_ROCE_V2_MAX_SRQ 0x100000 #define HNS_ROCE_V2_MAX_SRQ_WR 0x8000 #define HNS_ROCE_V2_MAX_SRQ_SGE 64 #define HNS_ROCE_V2_MAX_CQ_NUM 0x100000 #define HNS_ROCE_V2_MAX_CQC_TIMER_NUM 0x100 #define HNS_ROCE_V2_MAX_SRQ_NUM 0x100000 #define HNS_ROCE_V2_MAX_CQE_NUM 0x400000 -#define HNS_ROCE_V2_MAX_SRQWQE_NUM 0x8000 #define HNS_ROCE_V2_MAX_RQ_SGE_NUM 64 #define HNS_ROCE_V2_MAX_SQ_SGE_NUM 64 #define HNS_ROCE_V2_MAX_EXTEND_SGE_NUM 0x200000 @@ -63,13 +52,10 @@ #define HNS_ROCE_V2_MAX_RC_INL_INN_SZ 32 #define HNS_ROCE_V2_UAR_NUM 256 #define HNS_ROCE_V2_PHY_UAR_NUM 1 -#define HNS_ROCE_V2_MAX_IRQ_NUM 65 -#define HNS_ROCE_V2_COMP_VEC_NUM 63 #define HNS_ROCE_V2_AEQE_VEC_NUM 1 #define HNS_ROCE_V2_ABNORMAL_VEC_NUM 1 #define HNS_ROCE_V2_MAX_MTPT_NUM 0x100000 #define HNS_ROCE_V2_MAX_MTT_SEGS 0x1000000 -#define HNS_ROCE_V2_MAX_CQE_SEGS 0x1000000 #define HNS_ROCE_V2_MAX_SRQWQE_SEGS 0x1000000 #define HNS_ROCE_V2_MAX_IDX_SEGS 0x1000000 #define HNS_ROCE_V2_MAX_PD_NUM 0x1000000 @@ -81,7 +67,6 @@ #define HNS_ROCE_V2_MAX_RQ_DESC_SZ 16 #define HNS_ROCE_V2_MAX_SRQ_DESC_SZ 64 #define HNS_ROCE_V2_IRRL_ENTRY_SZ 64 -#define HNS_ROCE_V2_TRRL_ENTRY_SZ 48 #define HNS_ROCE_V2_EXT_ATOMIC_TRRL_ENTRY_SZ 100 #define HNS_ROCE_V2_CQC_ENTRY_SZ 64 #define HNS_ROCE_V2_SRQC_ENTRY_SZ 64 @@ -103,7 +88,6 @@ #define HNS_ROCE_INVALID_LKEY 0x0 #define HNS_ROCE_INVALID_SGE_LENGTH 0x80000000 #define HNS_ROCE_CMQ_TX_TIMEOUT 30000 -#define HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE 2 #define HNS_ROCE_V2_RSV_QPS 8
#define HNS_ROCE_V2_HW_RST_TIMEOUT 1000
From: Xinhao Liu liuxinhao5@hisilicon.com
mainline inclusion from mainline-v5.16-rc2 commit 9c3631d17054 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=9c3...
---------------------------------------------------------------------
Don't use unintelligible constants.
Link: https://lore.kernel.org/r/20211119140208.40416-10-liangwenpeng@huawei.com Signed-off-by: Xinhao Liu liuxinhao5@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 3d64963c5f2d..5d8aff81af33 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -678,6 +678,7 @@ static void hns_roce_write512(struct hns_roce_dev *hr_dev, u64 *val, static void write_dwqe(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp, void *wqe) { +#define HNS_ROCE_SL_SHIFT 2 struct hns_roce_v2_rc_send_wqe *rc_sq_wqe = wqe;
/* All kinds of DirectWQE have the same header field layout */ @@ -685,7 +686,8 @@ static void write_dwqe(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp, roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_DB_SL_L_M, V2_RC_SEND_WQE_BYTE_4_DB_SL_L_S, qp->sl); roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_DB_SL_H_M, - V2_RC_SEND_WQE_BYTE_4_DB_SL_H_S, qp->sl >> 2); + V2_RC_SEND_WQE_BYTE_4_DB_SL_H_S, + qp->sl >> HNS_ROCE_SL_SHIFT); roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_WQE_INDEX_M, V2_RC_SEND_WQE_BYTE_4_WQE_INDEX_S, qp->sq.head);
From: Wenpeng Liang liangwenpeng@huawei.com
mainline inclusion from mainline-v5.16-rc6 commit 8a3fa72f4b38 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=8a3...
---------------------------------------------------------------------
HIP09 EQ does not support level 2 addressing.
Link: https://lore.kernel.org/r/20211231101341.45759-3-liangwenpeng@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 ++- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 5d8aff81af33..ba9cabc22a54 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -2123,7 +2123,6 @@ static void apply_func_caps(struct hns_roce_dev *hr_dev) caps->cqc_timer_entry_sz = HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ; caps->mtt_entry_sz = HNS_ROCE_V2_MTT_ENTRY_SZ;
- caps->eqe_hop_num = HNS_ROCE_EQE_HOP_NUM; caps->pbl_hop_num = HNS_ROCE_PBL_HOP_NUM; caps->qpc_timer_hop_num = HNS_ROCE_HOP_NUM_0; caps->cqc_timer_hop_num = HNS_ROCE_HOP_NUM_0; @@ -2140,6 +2139,7 @@ static void apply_func_caps(struct hns_roce_dev *hr_dev) (u32)priv->handle->rinfo.num_vectors - 2);
if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) { + caps->eqe_hop_num = HNS_ROCE_V3_EQE_HOP_NUM; caps->ceqe_size = HNS_ROCE_V3_EQE_SIZE; caps->aeqe_size = HNS_ROCE_V3_EQE_SIZE;
@@ -2160,6 +2160,7 @@ static void apply_func_caps(struct hns_roce_dev *hr_dev) } else { u32 func_num = max_t(u32, 1, hr_dev->func_num);
+ caps->eqe_hop_num = HNS_ROCE_V2_EQE_HOP_NUM; caps->ceqe_size = HNS_ROCE_CEQE_SIZE; caps->aeqe_size = HNS_ROCE_AEQE_SIZE; caps->gid_table_len[0] /= func_num; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h index fddb9bc3c14c..e9a73c34389b 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -101,12 +101,14 @@ #define HNS_ROCE_CQE_HOP_NUM 1 #define HNS_ROCE_SRQWQE_HOP_NUM 1 #define HNS_ROCE_PBL_HOP_NUM 2 -#define HNS_ROCE_EQE_HOP_NUM 2 #define HNS_ROCE_IDX_HOP_NUM 1 #define HNS_ROCE_SQWQE_HOP_NUM 2 #define HNS_ROCE_EXT_SGE_HOP_NUM 1 #define HNS_ROCE_RQWQE_HOP_NUM 2
+#define HNS_ROCE_V2_EQE_HOP_NUM 2 +#define HNS_ROCE_V3_EQE_HOP_NUM 1 + #define HNS_ROCE_BA_PG_SZ_SUPPORTED_256K 6 #define HNS_ROCE_BA_PG_SZ_SUPPORTED_16K 2 #define HNS_ROCE_V2_GID_INDEX_NUM 16
From: Zhu Yanjun yanjun.zhu@linux.dev
mainline inclusion from mainline-v5.16-rc6 commit 18451db82ef7 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=184...
---------------------------------------------------------------------
Calculate and set UDP source port based on the flow label. If flow label is not defined in GRH then calculate it based on lqpn/rqpn.
Link: https://lore.kernel.org/r/20220106180359.2915060-2-yanjun.zhu@linux.dev Signed-off-by: Zhu Yanjun yanjun.zhu@linux.dev Reviewed-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- include/rdma/ib_verbs.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 3ca7f7c3740a..5aa21b454afc 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -4722,4 +4722,22 @@ static inline u32 rdma_calc_flow_label(u32 lqpn, u32 rqpn)
return (u32)(v & IB_GRH_FLOWLABEL_MASK); } + +/** + * rdma_get_udp_sport - Calculate and set UDP source port based on the flow + * label. If flow label is not defined in GRH then + * calculate it based on lqpn/rqpn. + * + * @fl: flow label from GRH + * @lqpn: local qp number + * @rqpn: remote qp number + */ +static inline u16 rdma_get_udp_sport(u32 fl, u32 lqpn, u32 rqpn) +{ + if (!fl) + fl = rdma_calc_flow_label(lqpn, rqpn); + + return rdma_flow_label_to_udp_sport(fl); +} + #endif /* IB_VERBS_H */
From: Zhu Yanjun yanjun.zhu@linux.dev
mainline inclusion from mainline-v5.16-rc6 commit 93f8df548187 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QOTS CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?id=93f...
---------------------------------------------------------------------
Several drivers have the same function xxx_get_udp_sport. So this function is moved to ib_verbs.h.
Link: https://lore.kernel.org/r/20220106180359.2915060-3-yanjun.zhu@linux.dev Signed-off-by: Zhu Yanjun yanjun.zhu@linux.dev Reviewed-by: Leon Romanovsky leonro@nvidia.com Acked-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com sigend-off-by: Guofeng Yue yueguofeng@hisilicon.com
Reviewed-by: Yangyang Li liyangyang20@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index ba9cabc22a54..587b46ddecfc 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4467,14 +4467,6 @@ static int modify_qp_rtr_to_rts(struct ib_qp *ibqp, return 0; }
-static inline u16 get_udp_sport(u32 fl, u32 lqpn, u32 rqpn) -{ - if (!fl) - fl = rdma_calc_flow_label(lqpn, rqpn); - - return rdma_flow_label_to_udp_sport(fl); -} - static int get_dip_ctx_idx(struct ib_qp *ibqp, const struct ib_qp_attr *attr, u32 *dip_idx) { @@ -4691,8 +4683,9 @@ static int hns_roce_v2_set_path(struct ib_qp *ibqp, }
hr_reg_write(context, QPC_UDPSPN, - is_udp ? get_udp_sport(grh->flow_label, ibqp->qp_num, - attr->dest_qp_num) : 0); + is_udp ? rdma_get_udp_sport(grh->flow_label, ibqp->qp_num, + attr->dest_qp_num) : + 0);
hr_reg_clear(qpc_mask, QPC_UDPSPN);
From: Yanling Song songyl@ramaxel.com
Ramaxel inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4P01N CVE: NA
Remove unused functions about ceq since the code just defined but never used in the driver.
Signed-off-by: Yanling Song songyl@ramaxel.com Reviewed-by: Yang Gan yanggan@ramaxel.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- .../net/ethernet/ramaxel/spnic/hw/sphw_eqs.c | 97 ------------------- .../net/ethernet/ramaxel/spnic/hw/sphw_hwif.c | 27 +----- .../net/ethernet/ramaxel/spnic/hw/sphw_mbox.c | 18 ---- .../net/ethernet/ramaxel/spnic/hw/sphw_mbox.h | 2 - 4 files changed, 1 insertion(+), 143 deletions(-)
diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_eqs.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_eqs.c index e0c84c5bcc58..8f71d9de76c1 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_eqs.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_eqs.c @@ -595,43 +595,6 @@ static bool eq_irq_handler(void *data) return uncompleted; }
-static struct sphw_eq *find_eq(struct sphw_hwdev *hwdev, int msix_entry_idx) -{ - struct sphw_aeqs *aeqs = hwdev->aeqs; - struct sphw_ceqs *ceqs = hwdev->ceqs; - int i; - - for (i = 0; i < aeqs->num_aeqs; i++) { - struct sphw_eq *eq = &aeqs->aeq[i]; - - if (eq->eq_irq.msix_entry_idx == msix_entry_idx) - return eq; - } - - for (i = 0; i < ceqs->num_ceqs; i++) { - struct sphw_eq *eq = &ceqs->ceq[i]; - - if (eq->eq_irq.msix_entry_idx == msix_entry_idx) - return eq; - } - - return NULL; -} - -/* for windows */ -bool sphw_eq_intr_handler(void *hwdev, int msix_entry_idx) -{ - struct sphw_eq *eq; - - eq = find_eq(hwdev, msix_entry_idx); - if (!eq) { - pr_err("Can't find eq in eq interrupt handler\n"); - return false; - } - - return eq_irq_handler(eq); -} - /** * eq_irq_work - eq work for the event * @work: the work that is associated with the eq @@ -1312,63 +1275,3 @@ void sphw_dump_ceq_info(struct sphw_hwdev *hwdev) jiffies_to_msecs(jiffies - eq->soft_intr_jif)); } } - -int sphw_get_ceq_info(void *hwdev, u16 q_id, struct sphw_ceq_info *ceq_info) -{ - struct sphw_hwdev *dev = hwdev; - struct sphw_eq *eq = NULL; - - if (!hwdev || !ceq_info) - return -EINVAL; - - if (q_id >= dev->ceqs->num_ceqs) - return -EINVAL; - - eq = &dev->ceqs->ceq[q_id]; - ceq_info->q_len = eq->eq_len; - ceq_info->num_pages = eq->num_pages; - ceq_info->page_size = eq->page_size; - ceq_info->num_elem_in_pg = eq->num_elem_in_pg; - ceq_info->elem_size = eq->elem_size; - sdk_info(dev->dev_hdl, "get_ceq_info: qid=0x%x page_size=%ul\n", - q_id, eq->page_size); - - return 0; -} - -int sphw_get_ceq_page_phy_addr(void *hwdev, u16 q_id, u16 page_idx, u64 *page_phy_addr) -{ - struct sphw_hwdev *dev = hwdev; - struct sphw_eq *eq = NULL; - - if (!hwdev || !page_phy_addr) - return -EINVAL; - - if (q_id >= dev->ceqs->num_ceqs) - return -EINVAL; - - eq = &dev->ceqs->ceq[q_id]; - *page_phy_addr = eq->eq_pages[page_idx].align_paddr; - sdk_info(dev->dev_hdl, "ceq_page_phy_addr: 0x%llx page_idx=%u\n", - eq->eq_pages[page_idx].align_paddr, page_idx); - - return 0; -} - -int sphw_set_ceq_irq_disable(void *hwdev, u16 q_id) -{ - struct sphw_hwdev *dev = hwdev; - struct sphw_eq *ceq = NULL; - - if (!hwdev) - return -EINVAL; - - if (q_id >= dev->ceqs->num_ceqs) - return -EINVAL; - - ceq = &dev->ceqs->ceq[q_id]; - - sphw_set_msix_state(ceq->hwdev, ceq->eq_irq.msix_entry_idx, SPHW_MSIX_DISABLE); - - return 0; -} diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwif.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwif.c index 7230ce2f0778..fbb1128957f0 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwif.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwif.c @@ -338,32 +338,6 @@ void sphw_disable_doorbell(struct sphw_hwif *hwif) sphw_hwif_write_reg(hwif, addr, attr4); }
-void sphw_enable_outbound(struct sphw_hwif *hwif) -{ - u32 addr, attr5; - - addr = SPHW_CSR_FUNC_ATTR5_ADDR; - attr5 = sphw_hwif_read_reg(hwif, addr); - - attr5 = SPHW_AF5_CLEAR(attr5, OUTBOUND_CTRL); - attr5 |= SPHW_AF5_SET(ENABLE_OUTBOUND, OUTBOUND_CTRL); - - sphw_hwif_write_reg(hwif, addr, attr5); -} - -void sphw_disable_outbound(struct sphw_hwif *hwif) -{ - u32 addr, attr5; - - addr = SPHW_CSR_FUNC_ATTR5_ADDR; - attr5 = sphw_hwif_read_reg(hwif, addr); - - attr5 = SPHW_AF5_CLEAR(attr5, OUTBOUND_CTRL); - attr5 |= SPHW_AF5_SET(DISABLE_OUTBOUND, OUTBOUND_CTRL); - - sphw_hwif_write_reg(hwif, addr, attr5); -} - /** * set_ppf - try to set hwif as ppf and set the type of hwif in this case * @hwif: the hardware interface of a pci function device @@ -441,6 +415,7 @@ static int init_db_area_idx(struct sphw_free_db_area *free_db_area, u64 db_dwqe_ } free_db_area->db_max_areas = db_max_areas; spin_lock_init(&free_db_area->idx_lock); + return 0; }
diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.c index edaef57a6b32..672882190907 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.c @@ -1458,24 +1458,6 @@ int sphw_mbox_to_vf(void *hwdev, u16 vf_id, u8 mod, u16 cmd, void *buf_in, u16 i in_size, buf_out, out_size, timeout, channel); }
-int sphw_mbox_set_channel_status(struct sphw_hwdev *hwdev, u16 channel, bool enable) -{ - if (channel >= SPHW_CHANNEL_MAX) { - sdk_err(hwdev->dev_hdl, "Invalid channel id: 0x%x\n", channel); - return -EINVAL; - } - - if (enable) - clear_bit(channel, &hwdev->func_to_func->channel_stop); - else - set_bit(channel, &hwdev->func_to_func->channel_stop); - - sdk_info(hwdev->dev_hdl, "%s mbox channel 0x%x\n", - enable ? "Enable" : "Disable", channel); - - return 0; -} - void sphw_mbox_enable_channel_lock(struct sphw_hwdev *hwdev, bool enable) { hwdev->func_to_func->lock_channel_en = enable; diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.h index 1a7e0dff0965..9aebee1c088a 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.h @@ -266,8 +266,6 @@ int sphw_mbox_ppf_to_host(void *hwdev, u8 mod, u16 cmd, u8 host_id,
int sphw_mbox_init_host_msg_channel(struct sphw_hwdev *hwdev);
-int sphw_mbox_set_channel_status(struct sphw_hwdev *hwdev, u16 channel, bool enable); - void sphw_mbox_enable_channel_lock(struct sphw_hwdev *hwdev, bool enable);
#endif
From: Yanling Song songyl@ramaxel.com
Ramaxel inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4P01N CVE: NA
Delete all functions about clp hardware channels since the driver does not use clp hardware channel.
Signed-off-by: Yanling Song songyl@ramaxel.com Reviewed-by: Yang Gan yanggan@ramaxel.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- .../net/ethernet/ramaxel/spnic/hw/sphw_csr.h | 13 - .../net/ethernet/ramaxel/spnic/hw/sphw_hw.h | 2 - .../ethernet/ramaxel/spnic/hw/sphw_hwdev.c | 30 -- .../ethernet/ramaxel/spnic/hw/sphw_hwdev.h | 1 - .../net/ethernet/ramaxel/spnic/hw/sphw_mgmt.c | 487 ------------------ .../net/ethernet/ramaxel/spnic/hw/sphw_mgmt.h | 50 -- .../net/ethernet/ramaxel/spnic/hw/sphw_mt.h | 1 - 7 files changed, 584 deletions(-)
diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_csr.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_csr.h index 3d84e1ef2fa3..d283c1456615 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_csr.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_csr.h @@ -39,19 +39,6 @@ (SPHW_CFG_REGS_FLAG + 0x0108) #define SPHW_FUNC_CSR_MAILBOX_RESULT_L_OFF \ (SPHW_CFG_REGS_FLAG + 0x010C) -/*CLP registers*/ -#define SPHW_BAR3_CLP_BASE_ADDR (SPHW_MGMT_REGS_FLAG + 0x0000) - -#define SPHW_UCPU_CLP_SIZE_REG (SPHW_HOST_CSR_BASE_ADDR + 0x40) -#define SPHW_UCPU_CLP_REQBASE_REG (SPHW_HOST_CSR_BASE_ADDR + 0x44) -#define SPHW_UCPU_CLP_RSPBASE_REG (SPHW_HOST_CSR_BASE_ADDR + 0x48) -#define SPHW_UCPU_CLP_REQ_REG (SPHW_HOST_CSR_BASE_ADDR + 0x4c) -#define SPHW_UCPU_CLP_RSP_REG (SPHW_HOST_CSR_BASE_ADDR + 0x50) -#define SPHW_CLP_REG(member) (SPHW_UCPU_CLP_##member##_REG) - -#define SPHW_CLP_REQ_DATA SPHW_BAR3_CLP_BASE_ADDR -#define SPHW_CLP_RSP_DATA (SPHW_BAR3_CLP_BASE_ADDR + 0x1000) -#define SPHW_CLP_DATA(member) (SPHW_CLP_##member##_DATA)
#define SPHW_PPF_ELECTION_OFFSET 0x0 #define SPHW_MPF_ELECTION_OFFSET 0x20 diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw.h index 74607ff24f09..41945efe86d8 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw.h @@ -482,8 +482,6 @@ int sphw_mbox_to_pf(void *hwdev, u8 mod, u16 cmd, void *buf_in, u16 in_size, voi int sphw_mbox_to_vf(void *hwdev, u16 vf_id, u8 mod, u16 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size, u32 timeout, u16 channel);
-int sphw_clp_to_mgmt(void *hwdev, u8 mod, u16 cmd, const void *buf_in, - u16 in_size, void *buf_out, u16 *out_size); /** * @brief sphw_cmdq_async - cmdq asynchronous message * @param hwdev: device pointer to hwdev diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.c index fc7d101a7fe3..8eda93a5c5bd 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.c @@ -455,28 +455,6 @@ static int init_ceqs_msix_attr(struct sphw_hwdev *hwdev) return 0; }
-static int sphw_comm_clp_to_mgmt_init(struct sphw_hwdev *hwdev) -{ - int err; - - if (sphw_func_type(hwdev) == TYPE_VF) - return 0; - - err = sphw_clp_pf_to_mgmt_init(hwdev); - if (err) - return err; - - return 0; -} - -static void sphw_comm_clp_to_mgmt_free(struct sphw_hwdev *hwdev) -{ - if (sphw_func_type(hwdev) == TYPE_VF) - return; - - sphw_clp_pf_to_mgmt_free(hwdev); -} - static int sphw_comm_aeqs_init(struct sphw_hwdev *hwdev) { struct irq_info aeq_irqs[SPHW_MAX_AEQS] = {{0} }; @@ -777,15 +755,8 @@ static int init_pf_mgmt_channel(struct sphw_hwdev *hwdev) { int err;
- err = sphw_comm_clp_to_mgmt_init(hwdev); - if (err) { - sdk_err(hwdev->dev_hdl, "Failed to init clp\n"); - return err; - } - err = sphw_comm_pf_to_mgmt_init(hwdev); if (err) { - sphw_comm_clp_to_mgmt_free(hwdev); sdk_err(hwdev->dev_hdl, "Failed to init pf to mgmt\n"); return err; } @@ -795,7 +766,6 @@ static int init_pf_mgmt_channel(struct sphw_hwdev *hwdev)
static void free_pf_mgmt_channel(struct sphw_hwdev *hwdev) { - sphw_comm_clp_to_mgmt_free(hwdev); sphw_comm_pf_to_mgmt_free(hwdev); }
diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.h index bf0b93d9a4d2..83f9a6630c8b 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.h @@ -55,7 +55,6 @@ struct sphw_hwdev { struct sphw_ceqs *ceqs; struct sphw_mbox *func_to_func; struct sphw_msg_pf_to_mgmt *pf_to_mgmt; - struct sphw_clp_pf_to_mgmt *clp_pf_to_mgmt;
void *cqm_hdl; struct mqm_addr_trans_tbl_info mqm_att; diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt.c index f885ca8ce761..01e88535a0ab 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt.c @@ -174,28 +174,6 @@ static void prepare_header(struct sphw_msg_pf_to_mgmt *pf_to_mgmt, SPHW_MSG_HEADER_SET(msg_id, MSG_ID); }
-static void clp_prepare_header(struct sphw_hwdev *hwdev, u64 *header, - u16 msg_len, u8 mod, - enum sphw_msg_ack_type ack_type, - enum sphw_msg_direction_type direction, - enum sphw_mgmt_cmd cmd, u32 msg_id) -{ - struct sphw_hwif *hwif = hwdev->hwif; - - *header = SPHW_MSG_HEADER_SET(msg_len, MSG_LEN) | - SPHW_MSG_HEADER_SET(mod, MODULE) | - SPHW_MSG_HEADER_SET(msg_len, SEG_LEN) | - SPHW_MSG_HEADER_SET(ack_type, NO_ACK) | - SPHW_MSG_HEADER_SET(SPHW_DATA_INLINE, DATA_TYPE) | - SPHW_MSG_HEADER_SET(0, SEQID) | - SPHW_MSG_HEADER_SET(SPHW_API_CHAIN_AEQ_ID, AEQ_ID) | - SPHW_MSG_HEADER_SET(LAST_SEGMENT, LAST) | - SPHW_MSG_HEADER_SET(direction, DIRECTION) | - SPHW_MSG_HEADER_SET(cmd, CMD) | - SPHW_MSG_HEADER_SET(hwif->attr.func_global_idx, SRC_GLB_FUNC_IDX) | - SPHW_MSG_HEADER_SET(msg_id, MSG_ID); -} - /** * prepare_mgmt_cmd - prepare the mgmt command * @mgmt_cmd: pointer to the command to prepare @@ -515,8 +493,6 @@ static void mgmt_recv_msg_handler(struct sphw_msg_pf_to_mgmt *pf_to_mgmt, goto resp; }
- /* TO DO some message need to ack first*/ - pf_to_mgmt->recv_mgmt_msg_cb[tmp_mod](pf_to_mgmt->hwdev, pf_to_mgmt->recv_mgmt_msg_data[tmp_mod], cmd, buf_in, in_size, buf_out, &out_size); @@ -917,466 +893,3 @@ int sphw_api_cmd_write_nack(void *hwdev, u8 dest, const void *cmd, u16 size)
return sphw_api_cmd_write(chain, dest, cmd, size); } - -static int get_clp_reg(void *hwdev, enum clp_data_type data_type, - enum clp_reg_type reg_type, u32 *reg_addr) -{ - struct sphw_hwdev *dev = hwdev; - u32 offset; - - offset = SPHW_CLP_REG_GAP * sphw_pcie_itf_id(dev); - - switch (reg_type) { - case SPHW_CLP_BA_HOST: - *reg_addr = (data_type == SPHW_CLP_REQ_HOST) ? - SPHW_CLP_REG(REQBASE) : - SPHW_CLP_REG(RSPBASE); - break; - - case SPHW_CLP_SIZE_HOST: - *reg_addr = SPHW_CLP_REG(SIZE); - break; - - case SPHW_CLP_LEN_HOST: - *reg_addr = (data_type == SPHW_CLP_REQ_HOST) ? - SPHW_CLP_REG(REQ) : SPHW_CLP_REG(RSP); - break; - - case SPHW_CLP_START_REQ_HOST: - *reg_addr = SPHW_CLP_REG(REQ); - break; - - case SPHW_CLP_READY_RSP_HOST: - *reg_addr = SPHW_CLP_REG(RSP); - break; - - default: - *reg_addr = 0; - break; - } - if (*reg_addr == 0) - return -EINVAL; - - *reg_addr += offset; - - return 0; -} - -static inline int clp_param_valid(struct sphw_hwdev *hwdev, - enum clp_data_type data_type, - enum clp_reg_type reg_type) -{ - if (data_type == SPHW_CLP_REQ_HOST && - reg_type == SPHW_CLP_READY_RSP_HOST) - return -EINVAL; - - if (data_type == SPHW_CLP_RSP_HOST && - reg_type == SPHW_CLP_START_REQ_HOST) - return -EINVAL; - - return 0; -} - -static u32 get_clp_reg_value(struct sphw_hwdev *hwdev, - enum clp_data_type data_type, - enum clp_reg_type reg_type, u32 reg_addr) -{ - u32 value; - - value = sphw_hwif_read_reg(hwdev->hwif, reg_addr); - - switch (reg_type) { - case SPHW_CLP_BA_HOST: - value = ((value >> SPHW_CLP_OFFSET(BASE)) & - SPHW_CLP_MASK(BASE)); - break; - - case SPHW_CLP_SIZE_HOST: - if (data_type == SPHW_CLP_REQ_HOST) - value = ((value >> SPHW_CLP_OFFSET(REQ_SIZE)) & - SPHW_CLP_MASK(SIZE)); - else - value = ((value >> SPHW_CLP_OFFSET(RSP_SIZE)) & - SPHW_CLP_MASK(SIZE)); - break; - - case SPHW_CLP_LEN_HOST: - value = ((value >> SPHW_CLP_OFFSET(LEN)) & - SPHW_CLP_MASK(LEN)); - break; - - case SPHW_CLP_START_REQ_HOST: - value = ((value >> SPHW_CLP_OFFSET(START)) & - SPHW_CLP_MASK(START)); - break; - - case SPHW_CLP_READY_RSP_HOST: - value = ((value >> SPHW_CLP_OFFSET(READY)) & - SPHW_CLP_MASK(READY)); - break; - - default: - break; - } - - return value; -} - -static int sphw_read_clp_reg(struct sphw_hwdev *hwdev, enum clp_data_type data_type, - enum clp_reg_type reg_type, u32 *read_value) -{ - u32 reg_addr; - int err; - - err = clp_param_valid(hwdev, data_type, reg_type); - if (err) - return err; - - err = get_clp_reg(hwdev, data_type, reg_type, ®_addr); - if (err) - return err; - - *read_value = get_clp_reg_value(hwdev, data_type, reg_type, reg_addr); - - return 0; -} - -static int check_data_type(enum clp_data_type data_type, enum clp_reg_type reg_type) -{ - if (data_type == SPHW_CLP_REQ_HOST && - reg_type == SPHW_CLP_READY_RSP_HOST) - return -EINVAL; - if (data_type == SPHW_CLP_RSP_HOST && - reg_type == SPHW_CLP_START_REQ_HOST) - return -EINVAL; - - return 0; -} - -static int check_reg_value(enum clp_reg_type reg_type, u32 value) -{ - if (reg_type == SPHW_CLP_BA_HOST && - value > SPHW_CLP_SRAM_BASE_REG_MAX) - return -EINVAL; - - if (reg_type == SPHW_CLP_SIZE_HOST && - value > SPHW_CLP_SRAM_SIZE_REG_MAX) - return -EINVAL; - - if (reg_type == SPHW_CLP_LEN_HOST && - value > SPHW_CLP_LEN_REG_MAX) - return -EINVAL; - - if ((reg_type == SPHW_CLP_START_REQ_HOST || - reg_type == SPHW_CLP_READY_RSP_HOST) && - value > SPHW_CLP_START_OR_READY_REG_MAX) - return -EINVAL; - - return 0; -} - -static int sphw_check_clp_init_status(struct sphw_hwdev *hwdev) -{ - int err; - u32 reg_value = 0; - - err = sphw_read_clp_reg(hwdev, SPHW_CLP_REQ_HOST, SPHW_CLP_BA_HOST, ®_value); - if (err || !reg_value) { - sdk_err(hwdev->dev_hdl, "Wrong req ba value: 0x%x\n", - reg_value); - return -EINVAL; - } - - err = sphw_read_clp_reg(hwdev, SPHW_CLP_RSP_HOST, SPHW_CLP_BA_HOST, ®_value); - if (err || !reg_value) { - sdk_err(hwdev->dev_hdl, "Wrong rsp ba value: 0x%x\n", - reg_value); - return -EINVAL; - } - - err = sphw_read_clp_reg(hwdev, SPHW_CLP_REQ_HOST, SPHW_CLP_SIZE_HOST, ®_value); - if (err || !reg_value) { - sdk_err(hwdev->dev_hdl, "Wrong req size\n"); - return -EINVAL; - } - - err = sphw_read_clp_reg(hwdev, SPHW_CLP_RSP_HOST, SPHW_CLP_SIZE_HOST, ®_value); - if (err || !reg_value) { - sdk_err(hwdev->dev_hdl, "Wrong rsp size\n"); - return -EINVAL; - } - - return 0; -} - -static void sphw_write_clp_reg(struct sphw_hwdev *hwdev, enum clp_data_type data_type, - enum clp_reg_type reg_type, u32 value) -{ - u32 reg_addr, reg_value; - - if (check_data_type(data_type, reg_type)) - return; - - if (check_reg_value(reg_type, value)) - return; - - if (get_clp_reg(hwdev, data_type, reg_type, ®_addr)) - return; - - reg_value = sphw_hwif_read_reg(hwdev->hwif, reg_addr); - - switch (reg_type) { - case SPHW_CLP_LEN_HOST: - reg_value = reg_value & - (~(SPHW_CLP_MASK(LEN) << SPHW_CLP_OFFSET(LEN))); - reg_value = reg_value | (value << SPHW_CLP_OFFSET(LEN)); - break; - - case SPHW_CLP_START_REQ_HOST: - reg_value = reg_value & - (~(SPHW_CLP_MASK(START) << - SPHW_CLP_OFFSET(START))); - reg_value = reg_value | (value << SPHW_CLP_OFFSET(START)); - break; - - case SPHW_CLP_READY_RSP_HOST: - reg_value = reg_value & - (~(SPHW_CLP_MASK(READY) << - SPHW_CLP_OFFSET(READY))); - reg_value = reg_value | (value << SPHW_CLP_OFFSET(READY)); - break; - - default: - return; - } - - sphw_hwif_write_reg(hwdev->hwif, reg_addr, reg_value); -} - -static int sphw_read_clp_data(struct sphw_hwdev *hwdev, void *buf_out, u16 *out_size) -{ - int err; - u32 reg = SPHW_CLP_DATA(RSP); - u32 ready, delay_cnt; - u32 *ptr = (u32 *)buf_out; - u32 temp_out_size = 0; - - err = sphw_read_clp_reg(hwdev, SPHW_CLP_RSP_HOST, SPHW_CLP_READY_RSP_HOST, &ready); - if (err) - return err; - - delay_cnt = 0; - while (ready == 0) { - usleep_range(9000, 10000); - delay_cnt++; - err = sphw_read_clp_reg(hwdev, SPHW_CLP_RSP_HOST, SPHW_CLP_READY_RSP_HOST, &ready); - if (err || delay_cnt > SPHW_CLP_DELAY_CNT_MAX) { - sdk_err(hwdev->dev_hdl, "Timeout with delay_cnt: %u\n", - delay_cnt); - return -EINVAL; - } - } - - err = sphw_read_clp_reg(hwdev, SPHW_CLP_RSP_HOST, SPHW_CLP_LEN_HOST, &temp_out_size); - if (err) - return err; - - if (temp_out_size > SPHW_CLP_SRAM_SIZE_REG_MAX || !temp_out_size) { - sdk_err(hwdev->dev_hdl, "Invalid temp_out_size: %u\n", - temp_out_size); - return -EINVAL; - } - - *out_size = (u16)temp_out_size; - for (; temp_out_size > 0; temp_out_size--) { - *ptr = sphw_hwif_read_reg(hwdev->hwif, reg); - ptr++; - /* read 4 bytes every time */ - reg = reg + 4; - } - - sphw_write_clp_reg(hwdev, SPHW_CLP_RSP_HOST, SPHW_CLP_READY_RSP_HOST, (u32)0x0); - sphw_write_clp_reg(hwdev, SPHW_CLP_RSP_HOST, SPHW_CLP_LEN_HOST, (u32)0x0); - - return 0; -} - -static int sphw_write_clp_data(struct sphw_hwdev *hwdev, void *buf_in, u16 in_size) -{ - int err; - u32 reg = SPHW_CLP_DATA(REQ); - u32 start = 1; - u32 delay_cnt = 0; - u32 *ptr = (u32 *)buf_in; - - err = sphw_read_clp_reg(hwdev, SPHW_CLP_REQ_HOST, SPHW_CLP_START_REQ_HOST, &start); - if (err) - return err; - - while (start == 1) { - usleep_range(9000, 10000); - delay_cnt++; - err = sphw_read_clp_reg(hwdev, SPHW_CLP_REQ_HOST, SPHW_CLP_START_REQ_HOST, &start); - if (err || delay_cnt > SPHW_CLP_DELAY_CNT_MAX) - return -EINVAL; - } - - sphw_write_clp_reg(hwdev, SPHW_CLP_REQ_HOST, SPHW_CLP_LEN_HOST, in_size); - sphw_write_clp_reg(hwdev, SPHW_CLP_REQ_HOST, SPHW_CLP_START_REQ_HOST, (u32)0x1); - - for (; in_size > 0; in_size--) { - sphw_hwif_write_reg(hwdev->hwif, reg, *ptr); - ptr++; - reg = reg + 4; - } - - return 0; -} - -static void sphw_clear_clp_data(struct sphw_hwdev *hwdev, enum clp_data_type data_type) -{ - u32 reg = (data_type == SPHW_CLP_REQ_HOST) ? - SPHW_CLP_DATA(REQ) : SPHW_CLP_DATA(RSP); - u32 count = SPHW_CLP_INPUT_BUF_LEN_HOST / SPHW_CLP_DATA_UNIT_HOST; - - for (; count > 0; count--) { - sphw_hwif_write_reg(hwdev->hwif, reg, 0x0); - reg = reg + 4; - } -} - -int sphw_pf_clp_to_mgmt(void *hwdev, u8 mod, u16 cmd, const void *buf_in, - u16 in_size, void *buf_out, u16 *out_size) -{ - struct sphw_clp_pf_to_mgmt *clp_pf_to_mgmt; - struct sphw_hwdev *dev = hwdev; - u64 header; - u16 real_size; - u8 *clp_msg_buf; - int err; - - clp_pf_to_mgmt = ((struct sphw_hwdev *)hwdev)->clp_pf_to_mgmt; - clp_msg_buf = clp_pf_to_mgmt->clp_msg_buf; - - /* 4 bytes alignment */ - if (in_size % SPHW_CLP_DATA_UNIT_HOST) - real_size = (in_size + (u16)sizeof(header) + SPHW_CLP_DATA_UNIT_HOST); - else - real_size = in_size + (u16)sizeof(header); - real_size = real_size / SPHW_CLP_DATA_UNIT_HOST; - - if (real_size > (SPHW_CLP_INPUT_BUF_LEN_HOST / SPHW_CLP_DATA_UNIT_HOST)) { - sdk_err(dev->dev_hdl, "Invalid real_size: %u\n", real_size); - return -EINVAL; - } - down(&clp_pf_to_mgmt->clp_msg_lock); - - err = sphw_check_clp_init_status(dev); - if (err) { - sdk_err(dev->dev_hdl, "Check clp init status failed\n"); - up(&clp_pf_to_mgmt->clp_msg_lock); - return err; - } - - sphw_clear_clp_data(dev, SPHW_CLP_RSP_HOST); - sphw_write_clp_reg(dev, SPHW_CLP_RSP_HOST, SPHW_CLP_READY_RSP_HOST, 0x0); - - /* Send request */ - memset(clp_msg_buf, 0x0, SPHW_CLP_INPUT_BUF_LEN_HOST); - clp_prepare_header(dev, &header, in_size, mod, 0, 0, cmd, 0); - - memcpy(clp_msg_buf, &header, sizeof(header)); - clp_msg_buf += sizeof(header); - memcpy(clp_msg_buf, buf_in, in_size); - - clp_msg_buf = clp_pf_to_mgmt->clp_msg_buf; - - sphw_clear_clp_data(dev, SPHW_CLP_REQ_HOST); - err = sphw_write_clp_data(hwdev, clp_pf_to_mgmt->clp_msg_buf, real_size); - if (err) { - sdk_err(dev->dev_hdl, "Send clp request failed\n"); - up(&clp_pf_to_mgmt->clp_msg_lock); - return -EINVAL; - } - - /* Get response */ - clp_msg_buf = clp_pf_to_mgmt->clp_msg_buf; - memset(clp_msg_buf, 0x0, SPHW_CLP_INPUT_BUF_LEN_HOST); - err = sphw_read_clp_data(hwdev, clp_msg_buf, &real_size); - sphw_clear_clp_data(dev, SPHW_CLP_RSP_HOST); - if (err) { - sdk_err(dev->dev_hdl, "Read clp response failed\n"); - up(&clp_pf_to_mgmt->clp_msg_lock); - return -EINVAL; - } - - real_size = (u16)((real_size * SPHW_CLP_DATA_UNIT_HOST) & 0xffff); - if (real_size <= sizeof(header) || real_size > SPHW_CLP_INPUT_BUF_LEN_HOST) { - sdk_err(dev->dev_hdl, "Invalid response size: %u", real_size); - up(&clp_pf_to_mgmt->clp_msg_lock); - return -EINVAL; - } - real_size = real_size - sizeof(header); - if (real_size != *out_size) { - sdk_err(dev->dev_hdl, "Invalid real_size:%u, out_size: %u\n", - real_size, *out_size); - up(&clp_pf_to_mgmt->clp_msg_lock); - return -EINVAL; - } - - memcpy(buf_out, (clp_msg_buf + sizeof(header)), real_size); - up(&clp_pf_to_mgmt->clp_msg_lock); - - return 0; -} - -int sphw_clp_to_mgmt(void *hwdev, u8 mod, u16 cmd, const void *buf_in, - u16 in_size, void *buf_out, u16 *out_size) - -{ - struct sphw_hwdev *dev = hwdev; - int err; - - if (!dev) - return -EINVAL; - - if (!dev->chip_present_flag) - return -EPERM; - - if (sphw_func_type(hwdev) == TYPE_VF) - return -EINVAL; - - err = sphw_pf_clp_to_mgmt(dev, mod, cmd, buf_in, in_size, buf_out, - out_size); - - return err; -} - -int sphw_clp_pf_to_mgmt_init(struct sphw_hwdev *hwdev) -{ - struct sphw_clp_pf_to_mgmt *clp_pf_to_mgmt; - - clp_pf_to_mgmt = kzalloc(sizeof(*clp_pf_to_mgmt), GFP_KERNEL); - if (!clp_pf_to_mgmt) - return -ENOMEM; - - clp_pf_to_mgmt->clp_msg_buf = kzalloc(SPHW_CLP_INPUT_BUF_LEN_HOST, - GFP_KERNEL); - if (!clp_pf_to_mgmt->clp_msg_buf) { - kfree(clp_pf_to_mgmt); - return -ENOMEM; - } - sema_init(&clp_pf_to_mgmt->clp_msg_lock, 1); - - hwdev->clp_pf_to_mgmt = clp_pf_to_mgmt; - - return 0; -} - -void sphw_clp_pf_to_mgmt_free(struct sphw_hwdev *hwdev) -{ - struct sphw_clp_pf_to_mgmt *clp_pf_to_mgmt = hwdev->clp_pf_to_mgmt; - - kfree(clp_pf_to_mgmt->clp_msg_buf); - kfree(clp_pf_to_mgmt); -} diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt.h index c6f63f935ea5..802336bd5cb1 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt.h @@ -6,44 +6,6 @@
#define SPHW_MGMT_WQ_NAME "sphw_mgmt"
-#define SPHW_CLP_REG_GAP 0x20 -#define SPHW_CLP_INPUT_BUF_LEN_HOST 4096UL -#define SPHW_CLP_DATA_UNIT_HOST 4UL - -enum clp_data_type { - SPHW_CLP_REQ_HOST = 0, - SPHW_CLP_RSP_HOST = 1 -}; - -enum clp_reg_type { - SPHW_CLP_BA_HOST = 0, - SPHW_CLP_SIZE_HOST = 1, - SPHW_CLP_LEN_HOST = 2, - SPHW_CLP_START_REQ_HOST = 3, - SPHW_CLP_READY_RSP_HOST = 4 -}; - -#define SPHW_CLP_REQ_SIZE_OFFSET 0 -#define SPHW_CLP_RSP_SIZE_OFFSET 16 -#define SPHW_CLP_BASE_OFFSET 0 -#define SPHW_CLP_LEN_OFFSET 0 -#define SPHW_CLP_START_OFFSET 31 -#define SPHW_CLP_READY_OFFSET 31 -#define SPHW_CLP_OFFSET(member) (SPHW_CLP_##member##_OFFSET) - -#define SPHW_CLP_SIZE_MASK 0x7ffUL -#define SPHW_CLP_BASE_MASK 0x7ffffffUL -#define SPHW_CLP_LEN_MASK 0x7ffUL -#define SPHW_CLP_START_MASK 0x1UL -#define SPHW_CLP_READY_MASK 0x1UL -#define SPHW_CLP_MASK(member) (SPHW_CLP_##member##_MASK) - -#define SPHW_CLP_DELAY_CNT_MAX 200UL -#define SPHW_CLP_SRAM_SIZE_REG_MAX 0x3ff -#define SPHW_CLP_SRAM_BASE_REG_MAX 0x7ffffff -#define SPHW_CLP_LEN_REG_MAX 0x3ff -#define SPHW_CLP_START_OR_READY_REG_MAX 0x1 - struct sphw_recv_msg { void *msg;
@@ -78,11 +40,6 @@ enum sphw_mgmt_msg_cb_state { SPHW_MGMT_MSG_CB_RUNNING, };
-struct sphw_clp_pf_to_mgmt { - struct semaphore clp_msg_lock; - void *clp_msg_buf; -}; - struct sphw_msg_pf_to_mgmt { struct sphw_hwdev *hwdev;
@@ -146,11 +103,4 @@ int sphw_api_cmd_read_ack(void *hwdev, u8 dest, const void *cmd, u16 size,
int sphw_api_cmd_write_nack(void *hwdev, u8 dest, const void *cmd, u16 size);
-int sphw_pf_clp_to_mgmt(void *hwdev, u8 mod, u16 cmd, const void *buf_in, - u16 in_size, void *buf_out, u16 *out_size); - -int sphw_clp_pf_to_mgmt_init(struct sphw_hwdev *hwdev); - -void sphw_clp_pf_to_mgmt_free(struct sphw_hwdev *hwdev); - #endif diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mt.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mt.h index 1960614b384b..d7fb58054202 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mt.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mt.h @@ -461,7 +461,6 @@ enum mt_api_type { API_TYPE_MBOX = 1, API_TYPE_API_CHAIN_BYPASS, API_TYPE_API_CHAIN_TO_MPU, - API_TYPE_CLP, };
struct npu_cmd_st {
From: Yanling Song songyl@ramaxel.com
Ramaxel inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4P01N CVE: NA
Remove the code of polling mode since the driver only use interrupt mode and not use poll mode.
Signed-off-by: Yanling Song songyl@ramaxel.com Reviewed-by: Yang Gan yanggan@ramaxel.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- .../net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c | 20 ++++--------------- .../net/ethernet/ramaxel/spnic/hw/sphw_crm.h | 2 -- .../net/ethernet/ramaxel/spnic/hw/sphw_eqs.c | 7 +------ .../ethernet/ramaxel/spnic/hw/sphw_hwdev.c | 1 - .../ethernet/ramaxel/spnic/hw/sphw_hwdev.h | 1 - .../net/ethernet/ramaxel/spnic/hw/sphw_mbox.c | 2 +- 6 files changed, 6 insertions(+), 27 deletions(-)
diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c index 9cc44f15fa0e..b6aaadac19b9 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c @@ -533,22 +533,10 @@ static int cmdq_ceq_handler_status(struct sphw_cmdq *cmdq, { ulong timeo; int err; - ulong start = 0; - ulong end = timeout; - - if (cmdq->hwdev->poll) { - while (start < end) { - sphw_cmdq_ceq_handler(cmdq->hwdev, 0); - if (saved_cmd_info->done->done != 0) - return 0; - usleep_range(900, 1000); - start++; - } - } else { - timeo = msecs_to_jiffies(timeout); - if (wait_for_completion_timeout(saved_cmd_info->done, timeo)) - return 0; - } + + timeo = msecs_to_jiffies(timeout); + if (wait_for_completion_timeout(saved_cmd_info->done, timeo)) + return 0;
spin_lock_bh(&cmdq->cmdq_lock);
diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_crm.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_crm.h index bba3d2d501f2..8cce36698e3d 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_crm.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_crm.h @@ -335,8 +335,6 @@ struct sphw_init_para { * need to trasmit message ppf mbox to bmgw arm host. */ void *ppf_hwdev; - /* if use polling mode, set it true */ - bool poll; };
/* B200 config BAR45 4MB, DB & DWQE both 2MB */ diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_eqs.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_eqs.c index 8f71d9de76c1..24c55d656f9c 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_eqs.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_eqs.c @@ -392,12 +392,7 @@ static void set_eq_cons_idx(struct sphw_eq *eq, u32 arm_state) u32 addr = EQ_CI_SIMPLE_INDIR_REG_ADDR(eq);
eq_wrap_ci = EQ_CONS_IDX(eq); - - /* if use poll mode only eq0 use int_arm mode */ - if (eq->q_id != 0 && eq->hwdev->poll) - val = EQ_CI_SIMPLE_INDIR_SET(SPHW_EQ_NOT_ARMED, ARMED); - else - val = EQ_CI_SIMPLE_INDIR_SET(arm_state, ARMED); + val = EQ_CI_SIMPLE_INDIR_SET(arm_state, ARMED); if (eq->type == SPHW_AEQ) { val = val | EQ_CI_SIMPLE_INDIR_SET(eq_wrap_ci, CI) | diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.c index 8eda93a5c5bd..783fa46bcfe5 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.c @@ -938,7 +938,6 @@ int sphw_init_hwdev(struct sphw_init_para *para) hwdev->pcidev_hdl = para->pcidev_hdl; hwdev->dev_hdl = para->dev_hdl; hwdev->chip_node = para->chip_node; - hwdev->poll = para->poll;
hwdev->chip_fault_stats = vzalloc(SPHW_CHIP_FAULT_SIZE); if (!hwdev->chip_fault_stats) diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.h index 83f9a6630c8b..10da31bda3d2 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.h @@ -42,7 +42,6 @@ struct sphw_hwdev {
u32 wq_page_size; int chip_present_flag; - bool poll; /*use polling mode or int mode*/
struct sphw_hwif *hwif; /* include void __iomem *bar */ struct comm_global_attr glb_attr; diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.c index 672882190907..8abb47422bdd 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.c @@ -1062,7 +1062,7 @@ static int send_mbox_msg(struct sphw_mbox *func_to_func, u8 mod, u16 cmd, u8 *msg_seg = NULL; u64 header = 0;
- if (hwdev->poll || hwdev->hwif->attr.num_aeqs >= 2) + if (hwdev->hwif->attr.num_aeqs >= 2) rsp_aeq_id = SPHW_MBOX_RSP_MSG_AEQ; else rsp_aeq_id = 0;
From: Yanling Song songyl@ramaxel.com
Ramaxel inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4P01N CVE: NA
Remove the code of endian converting since hardware converts endian automatically.
Signed-off-by: Yanling Song songyl@ramaxel.com Reviewed-by: Yang Gan yanggan@ramaxel.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- .../net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c | 38 +++++------------- .../ethernet/ramaxel/spnic/hw/sphw_common.h | 12 ------ .../net/ethernet/ramaxel/spnic/spnic_nic_io.h | 6 +-- .../net/ethernet/ramaxel/spnic/spnic_nic_qp.h | 7 +--- drivers/net/ethernet/ramaxel/spnic/spnic_rx.c | 39 +++++++------------ drivers/net/ethernet/ramaxel/spnic/spnic_tx.c | 20 +++++----- 6 files changed, 34 insertions(+), 88 deletions(-)
diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c index b6aaadac19b9..5421b813d484 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c @@ -343,10 +343,6 @@ static void cmdq_set_db(struct sphw_cmdq *cmdq,
cmdq_fill_db(&db, cmdq_type, prod_idx);
- /* The data that is written to HW should be in Big Endian Format */ - db.db_info = sphw_hw_be32(db.db_info); - db.db_head = sphw_hw_be32(db.db_head); - wmb(); /* write all before the doorbell */ writeq(*((u64 *)&db), CMDQ_DB_ADDR(cmdq->db_base, prod_idx)); } @@ -482,24 +478,21 @@ static void cmdq_update_cmd_status(struct sphw_cmdq *cmdq, u16 prod_idx, cmd_info = &cmdq->cmd_infos[prod_idx];
if (cmd_info->errcode) { - status_info = sphw_hw_cpu32(wqe_lcmd->status.status_info); + status_info = wqe_lcmd->status.status_info; *cmd_info->errcode = WQE_ERRCODE_GET(status_info, VAL); }
if (cmd_info->direct_resp) - *cmd_info->direct_resp = - sphw_hw_cpu32(wqe_lcmd->completion.direct_resp); + *cmd_info->direct_resp = wqe_lcmd->completion.direct_resp; }
static int sphw_cmdq_sync_timeout_check(struct sphw_cmdq *cmdq, struct sphw_cmdq_wqe *wqe, u16 pi) { struct sphw_cmdq_wqe_lcmd *wqe_lcmd; - struct sphw_ctrl *ctrl; u32 ctrl_info;
wqe_lcmd = &wqe->wqe_lcmd; - ctrl = &wqe_lcmd->ctrl; - ctrl_info = sphw_hw_cpu32((ctrl)->ctrl_info); + ctrl_info = wqe_lcmd->ctrl.ctrl_info; if (!WQE_COMPLETED(ctrl_info)) { sdk_info(cmdq->hwdev->dev_hdl, "Cmdq sync command check busy bit not set\n"); return -EFAULT; @@ -640,7 +633,7 @@ static int cmdq_sync_cmd_direct_resp(struct sphw_cmdq *cmdq, u8 mod, struct sphw_cmdq_cmd_info *cmd_info = NULL, saved_cmd_info; struct completion done; u16 curr_prod_idx, next_prod_idx; - int wrapped, errcode = 0, wqe_size = WQE_LCMD_SIZE; + int wrapped, errcode = 0; int cmpt_code = CMDQ_SEND_CMPT_CODE; u64 curr_msg_id; int err; @@ -682,9 +675,6 @@ static int cmdq_sync_cmd_direct_resp(struct sphw_cmdq *cmdq, u8 mod, cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_DIRECT_RESP, buf_in, NULL, wrapped, mod, cmd, curr_prod_idx);
- /* The data that is written to HW should be in Big Endian Format */ - sphw_hw_be32_len(&wqe, wqe_size); - /* CMDQ WQE is not shadow, therefore wqe will be written to wq */ cmdq_wqe_fill(curr_wqe, &wqe);
@@ -726,7 +716,7 @@ static int cmdq_sync_cmd_detail_resp(struct sphw_cmdq *cmdq, u8 mod, u8 cmd, struct sphw_cmdq_cmd_info *cmd_info = NULL, saved_cmd_info; struct completion done; u16 curr_prod_idx, next_prod_idx; - int wrapped, errcode = 0, wqe_size = WQE_LCMD_SIZE; + int wrapped, errcode = 0; int cmpt_code = CMDQ_SEND_CMPT_CODE; u64 curr_msg_id; int err; @@ -768,8 +758,6 @@ static int cmdq_sync_cmd_detail_resp(struct sphw_cmdq *cmdq, u8 mod, u8 cmd, cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_SGE_RESP, buf_in, buf_out, wrapped, mod, cmd, curr_prod_idx);
- sphw_hw_be32_len(&wqe, wqe_size); - cmdq_wqe_fill(curr_wqe, &wqe);
(cmd_info->cmdq_msg_id)++; @@ -805,7 +793,6 @@ static int cmdq_async_cmd(struct sphw_cmdq *cmdq, u8 mod, u8 cmd, { struct sphw_cmdq_cmd_info *cmd_info = NULL; struct sphw_wq *wq = &cmdq->wq; - int wqe_size = WQE_LCMD_SIZE; u16 curr_prod_idx, next_prod_idx; struct sphw_cmdq_wqe *curr_wqe = NULL, wqe; int wrapped, err; @@ -832,8 +819,6 @@ static int cmdq_async_cmd(struct sphw_cmdq *cmdq, u8 mod, u8 cmd, cmdq_set_lcmd_wqe(&wqe, ASYNC_CMD, buf_in, NULL, wrapped, mod, cmd, curr_prod_idx);
- /* The data that is written to HW should be in Big Endian Format */ - sphw_hw_be32_len(&wqe, wqe_size); cmdq_wqe_fill(curr_wqe, &wqe);
cmd_info = &cmdq->cmd_infos[curr_prod_idx]; @@ -858,7 +843,7 @@ int cmdq_set_arm_bit(struct sphw_cmdq *cmdq, const void *buf_in, struct sphw_wq *wq = &cmdq->wq; struct sphw_cmdq_wqe *curr_wqe = NULL, wqe; u16 curr_prod_idx, next_prod_idx; - int wrapped, wqe_size = WQE_SCMD_SIZE; + int wrapped;
/* Keep wrapped and doorbell index correct. bh - for tasklet(ceq) */ spin_lock_bh(&cmdq->cmdq_lock); @@ -883,9 +868,6 @@ int cmdq_set_arm_bit(struct sphw_cmdq *cmdq, const void *buf_in, wrapped, SPHW_MOD_COMM, CMDQ_SET_ARM_CMD, curr_prod_idx);
- /* The data that is written to HW should be in Big Endian Format */ - sphw_cpu_to_be32(&wqe, wqe_size); - /* cmdq wqe is not shadow, therefore wqe will be written to wq */ cmdq_wqe_fill(curr_wqe, &wqe);
@@ -1102,7 +1084,7 @@ static void clear_wqe_complete_bit(struct sphw_cmdq *cmdq, struct sphw_cmdq_wqe *wqe, u16 ci) { struct sphw_ctrl *ctrl = NULL; - u32 header_info = sphw_hw_cpu32(WQE_HEADER(wqe)->header_info); + u32 header_info = WQE_HEADER(wqe)->header_info; enum data_format df = CMDQ_WQE_HEADER_GET(header_info, DATA_FMT);
if (df == DATA_SGE) @@ -1157,7 +1139,7 @@ static int cmdq_arm_ceq_handler(struct sphw_cmdq *cmdq, struct sphw_cmdq_wqe *wqe, u16 ci) { struct sphw_ctrl *ctrl = &wqe->inline_wqe.wqe_scmd.ctrl; - u32 ctrl_info = sphw_hw_cpu32((ctrl)->ctrl_info); + u32 ctrl_info = ctrl->ctrl_info;
if (!WQE_COMPLETED(ctrl_info)) return -EBUSY; @@ -1188,7 +1170,6 @@ void sphw_cmdq_ceq_handler(void *handle, u32 ceqe_data) struct sphw_hwdev *hwdev = cmdqs->hwdev; struct sphw_cmdq_wqe *wqe = NULL; struct sphw_cmdq_wqe_lcmd *wqe_lcmd = NULL; - struct sphw_ctrl *ctrl = NULL; struct sphw_cmdq_cmd_info *cmd_info = NULL; u32 ctrl_info; u16 ci; @@ -1216,8 +1197,7 @@ void sphw_cmdq_ceq_handler(void *handle, u32 ceqe_data) default: /* only arm bit is using scmd wqe, the wqe is lcmd */ wqe_lcmd = &wqe->wqe_lcmd; - ctrl = &wqe_lcmd->ctrl; - ctrl_info = sphw_hw_cpu32((ctrl)->ctrl_info); + ctrl_info = wqe_lcmd->ctrl.ctrl_info;
if (!WQE_COMPLETED(ctrl_info)) return; diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_common.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_common.h index d6e2f183cc36..05327bd4bcfe 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_common.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_common.h @@ -93,18 +93,6 @@ static inline void sphw_set_sge(struct sphw_sge *sge, dma_addr_t addr, int len) sge->len = len; }
-#define sphw_hw_be32(val) (val) -#define sphw_hw_cpu32(val) (val) -#define sphw_hw_cpu16(val) (val) - -static inline void sphw_hw_be32_len(void *data, int len) -{ -} - -static inline void sphw_hw_cpu32_len(void *data, int len) -{ -} - #define sdk_err(dev, format, ...) dev_err(dev, "[COMM]" format, ##__VA_ARGS__) #define sdk_warn(dev, format, ...) dev_warn(dev, "[COMM]" format, ##__VA_ARGS__) #define sdk_notice(dev, format, ...) dev_notice(dev, "[COMM]" format, ##__VA_ARGS__) diff --git a/drivers/net/ethernet/ramaxel/spnic/spnic_nic_io.h b/drivers/net/ethernet/ramaxel/spnic/spnic_nic_io.h index ab1399d3e36c..e237ba33d82d 100644 --- a/drivers/net/ethernet/ramaxel/spnic/spnic_nic_io.h +++ b/drivers/net/ethernet/ramaxel/spnic/spnic_nic_io.h @@ -101,8 +101,7 @@ static inline u16 spnic_get_sq_local_pi(struct spnic_io_queue *sq) */ static inline u16 spnic_get_sq_hw_ci(struct spnic_io_queue *sq) { - return WQ_MASK_IDX(&sq->wq, - sphw_hw_cpu16(*(u16 *)sq->tx.cons_idx_addr)); + return WQ_MASK_IDX(&sq->wq, *(u16 *)sq->tx.cons_idx_addr); }
/* * @@ -281,9 +280,6 @@ static inline void spnic_write_db(struct spnic_io_queue *queue, int cos, u8 cfla db.db_info = DB_INFO_SET(SRC_TYPE, TYPE) | DB_INFO_SET(cflag, CFLAG) | DB_INFO_SET(cos, COS) | DB_INFO_SET(queue->q_id, QID); db.pi_hi = DB_PI_HIGH(pi); - /* Data should be written to HW in Big Endian Format */ - db.db_info = sphw_hw_be32(db.db_info); - db.pi_hi = sphw_hw_be32(db.pi_hi);
wmb(); /* Write all before the doorbell */
diff --git a/drivers/net/ethernet/ramaxel/spnic/spnic_nic_qp.h b/drivers/net/ethernet/ramaxel/spnic/spnic_nic_qp.h index 4c3f37e45a36..a8abdc1734d3 100644 --- a/drivers/net/ethernet/ramaxel/spnic/spnic_nic_qp.h +++ b/drivers/net/ethernet/ramaxel/spnic/spnic_nic_qp.h @@ -352,7 +352,7 @@ enum sq_wqe_tasksect_len_type {
static inline u32 spnic_get_pkt_len_for_super_cqe(struct spnic_rq_cqe *cqe, bool last) { - u32 pkt_len = sphw_hw_cpu32(cqe->pkt_info); + u32 pkt_len = cqe->pkt_info;
if (!last) return RQ_CQE_PKT_LEN_GET(pkt_len, FIRST_LEN); @@ -376,7 +376,6 @@ static inline void spnic_prepare_sq_ctrl(struct spnic_sq_wqe_combo *wqe_combo, SQ_CTRL_SET(wqe_combo->wqe_type, EXTENDED) | SQ_CTRL_SET(owner, OWNER);
- wqe_desc->ctrl_len = sphw_hw_be32(wqe_desc->ctrl_len); /* compact wqe queue_info will transfer to ucode */ wqe_desc->queue_info = 0; return; @@ -388,8 +387,6 @@ static inline void spnic_prepare_sq_ctrl(struct spnic_sq_wqe_combo *wqe_combo, SQ_CTRL_SET(wqe_combo->wqe_type, EXTENDED) | SQ_CTRL_SET(owner, OWNER);
- wqe_desc->ctrl_len = sphw_hw_be32(wqe_desc->ctrl_len); - wqe_desc->queue_info = queue_info; wqe_desc->queue_info |= SQ_CTRL_QUEUE_INFO_SET(1U, UC);
@@ -400,8 +397,6 @@ static inline void spnic_prepare_sq_ctrl(struct spnic_sq_wqe_combo *wqe_combo, wqe_desc->queue_info = SQ_CTRL_QUEUE_INFO_CLEAR(wqe_desc->queue_info, MSS); wqe_desc->queue_info |= SQ_CTRL_QUEUE_INFO_SET(TX_MSS_MIN, MSS); } - - wqe_desc->queue_info = sphw_hw_be32(wqe_desc->queue_info); }
/* * diff --git a/drivers/net/ethernet/ramaxel/spnic/spnic_rx.c b/drivers/net/ethernet/ramaxel/spnic/spnic_rx.c index e58da6771ff4..3ae2f15c727b 100644 --- a/drivers/net/ethernet/ramaxel/spnic/spnic_rx.c +++ b/drivers/net/ethernet/ramaxel/spnic/spnic_rx.c @@ -92,7 +92,6 @@ static u32 spnic_rx_fill_wqe(struct spnic_rxq *rxq) { struct net_device *netdev = rxq->netdev; struct spnic_nic_dev *nic_dev = netdev_priv(netdev); - int rq_wqe_len = rxq->rq->wq.wqebb_size; struct spnic_rq_wqe *rq_wqe = NULL; struct spnic_rx_info *rx_info = NULL; u32 i; @@ -113,7 +112,6 @@ static u32 spnic_rx_fill_wqe(struct spnic_rxq *rxq) rq_wqe->normal_wqe.cqe_lo_addr = lower_32_bits(rx_info->cqe_dma); }
- sphw_hw_be32_len(rq_wqe, rq_wqe_len); rx_info->rq_wqe = rq_wqe; }
@@ -179,17 +177,12 @@ static u32 stub_spnic_rx_fill_buffers(struct spnic_rxq *rxq) dma_addr = rx_info->buf_dma_addr;
if (rxq->rq->wqe_type == SPNIC_EXTEND_RQ_WQE) { - rq_wqe->extend_wqe.buf_desc.sge.hi_addr = - sphw_hw_be32(upper_32_bits(dma_addr)); - rq_wqe->extend_wqe.buf_desc.sge.lo_addr = - sphw_hw_be32(lower_32_bits(dma_addr)); - rq_wqe->extend_wqe.buf_desc.sge.len = - sphw_hw_be32(rx_info->skb_len); + rq_wqe->extend_wqe.buf_desc.sge.hi_addr = upper_32_bits(dma_addr); + rq_wqe->extend_wqe.buf_desc.sge.lo_addr = lower_32_bits(dma_addr); + rq_wqe->extend_wqe.buf_desc.sge.len = rx_info->skb_len; } else { - rq_wqe->normal_wqe.buf_hi_addr = - sphw_hw_be32(upper_32_bits(dma_addr)); - rq_wqe->normal_wqe.buf_lo_addr = - sphw_hw_be32(lower_32_bits(dma_addr)); + rq_wqe->normal_wqe.buf_hi_addr = upper_32_bits(dma_addr); + rq_wqe->normal_wqe.buf_lo_addr = lower_32_bits(dma_addr); } rxq->next_to_update = (rxq->next_to_update + 1) & rxq->q_mask; } @@ -236,15 +229,11 @@ static u32 spnic_rx_fill_buffers(struct spnic_rxq *rxq) rq_wqe = rx_info->rq_wqe;
if (rxq->rq->wqe_type == SPNIC_EXTEND_RQ_WQE) { - rq_wqe->extend_wqe.buf_desc.sge.hi_addr = - sphw_hw_be32(upper_32_bits(dma_addr)); - rq_wqe->extend_wqe.buf_desc.sge.lo_addr = - sphw_hw_be32(lower_32_bits(dma_addr)); + rq_wqe->extend_wqe.buf_desc.sge.hi_addr = upper_32_bits(dma_addr); + rq_wqe->extend_wqe.buf_desc.sge.lo_addr = lower_32_bits(dma_addr); } else { - rq_wqe->normal_wqe.buf_hi_addr = - sphw_hw_be32(upper_32_bits(dma_addr)); - rq_wqe->normal_wqe.buf_lo_addr = - sphw_hw_be32(lower_32_bits(dma_addr)); + rq_wqe->normal_wqe.buf_hi_addr = upper_32_bits(dma_addr); + rq_wqe->normal_wqe.buf_lo_addr = lower_32_bits(dma_addr); } rxq->next_to_update = (rxq->next_to_update + 1) & rxq->q_mask; } @@ -784,7 +773,7 @@ int recv_one_pkt(struct spnic_rxq *rxq, struct spnic_rq_cqe *rx_cqe, if (skb_is_nonlinear(skb)) spnic_pull_tail(skb);
- offload_type = sphw_hw_cpu32(rx_cqe->offload_type); + offload_type = rx_cqe->offload_type; spnic_rx_csum(rxq, offload_type, status, skb);
spnic_rx_gro(rxq, offload_type, skb); @@ -867,7 +856,7 @@ static inline int recv_supper_cqe(struct spnic_rxq *rxq, struct spnic_rq_cqe *rx #define LRO_PKT_HDR_LEN_IPV4 66 #define LRO_PKT_HDR_LEN_IPV6 86 #define LRO_PKT_HDR_LEN(cqe) \ - (SPNIC_GET_RX_IP_TYPE(sphw_hw_cpu32((cqe)->offload_type)) == \ + (SPNIC_GET_RX_IP_TYPE((cqe)->offload_type) == \ SPNIC_RX_IPV6_PKT ? LRO_PKT_HDR_LEN_IPV6 : LRO_PKT_HDR_LEN_IPV4)
static void stub_rx_recv_jumbo_pkt(struct spnic_rxq *rxq, struct sk_buff *head_skb, @@ -997,7 +986,7 @@ int spnic_rx_poll(struct spnic_rxq *rxq, int budget) while (likely(pkts < budget)) { sw_ci = rxq->cons_idx & rxq->q_mask; rx_cqe = rxq->rx_info[sw_ci].cqe; - status = sphw_hw_cpu32(rx_cqe->status); + status = rx_cqe->status;
if (!SPNIC_GET_RX_DONE(status)) break; @@ -1005,8 +994,8 @@ int spnic_rx_poll(struct spnic_rxq *rxq, int budget) /* make sure we read rx_done before packet length */ rmb();
- vlan_len = sphw_hw_cpu32(rx_cqe->vlan_len); - pkt_info = sphw_hw_cpu32(rx_cqe->pkt_info); + vlan_len = rx_cqe->vlan_len; + pkt_info = rx_cqe->pkt_info; pkt_len = SPNIC_GET_RX_PKT_LEN(vlan_len);
if (unlikely(SPNIC_GET_SUPER_CQE_EN(pkt_info))) { diff --git a/drivers/net/ethernet/ramaxel/spnic/spnic_tx.c b/drivers/net/ethernet/ramaxel/spnic/spnic_tx.c index 57344f89a4dc..7478e76aa729 100644 --- a/drivers/net/ethernet/ramaxel/spnic/spnic_tx.c +++ b/drivers/net/ethernet/ramaxel/spnic/spnic_tx.c @@ -86,9 +86,9 @@ static void txq_stats_init(struct spnic_txq *txq)
static inline void spnic_set_buf_desc(struct spnic_sq_bufdesc *buf_descs, dma_addr_t addr, u32 len) { - buf_descs->hi_addr = sphw_hw_be32(upper_32_bits(addr)); - buf_descs->lo_addr = sphw_hw_be32(lower_32_bits(addr)); - buf_descs->len = sphw_hw_be32(len); + buf_descs->hi_addr = upper_32_bits(addr); + buf_descs->lo_addr = lower_32_bits(addr); + buf_descs->len = len; }
static int tx_map_skb(struct spnic_nic_dev *nic_dev, struct sk_buff *skb, @@ -112,8 +112,8 @@ static int tx_map_skb(struct spnic_nic_dev *nic_dev, struct sk_buff *skb,
dma_info[0].len = skb_headlen(skb);
- wqe_desc->hi_addr = sphw_hw_be32(upper_32_bits(dma_info[0].dma)); - wqe_desc->lo_addr = sphw_hw_be32(lower_32_bits(dma_info[0].dma)); + wqe_desc->hi_addr = upper_32_bits(dma_info[0].dma); + wqe_desc->lo_addr = lower_32_bits(dma_info[0].dma);
wqe_desc->ctrl_len = dma_info[0].len;
@@ -525,12 +525,10 @@ static netdev_tx_t spnic_send_one_skb(struct sk_buff *skb, struct net_device *ne
owner = spnic_set_wqe_combo(txq, &wqe_combo, offload, num_sge, &pi); if (offload) { - /* ip6_frag_id is big endiant, not need to transfer */ - wqe_combo.task->ip_identify = sphw_hw_be32(task.ip_identify); - wqe_combo.task->pkt_info0 = sphw_hw_be32(task.pkt_info0); - wqe_combo.task->pkt_info2 = sphw_hw_be32(task.pkt_info2); - wqe_combo.task->vlan_offload = - sphw_hw_be32(task.vlan_offload); + wqe_combo.task->ip_identify = task.ip_identify; + wqe_combo.task->pkt_info0 = task.pkt_info0; + wqe_combo.task->pkt_info2 = task.pkt_info2; + wqe_combo.task->vlan_offload = task.vlan_offload; }
tx_info = &txq->tx_info[pi];
From: Xiongfeng Wang wangxiongfeng2@huawei.com
mainline inclusion from mainline-v5.16-rc3 commit d5624bb29f49b849ac8d1e9783dbf9c65cf33457 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QKQ3 CVE: NA
----------------------
For memory accesses with write-combining attributes (e.g. those returned by ioremap_wc()), the CPU may wait for prior accesses to be merged with subsequent ones. But in some situation, such wait is bad for the performance.
We introduce io_stop_wc() to prevent the merging of write-combining memory accesses before this macro with those after it.
We add implementation for ARM64 using DGH instruction and provide NOP implementation for other architectures.
Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Suggested-by: Will Deacon will@kernel.org Suggested-by: Catalin Marinas catalin.marinas@arm.com Acked-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20211221035556.60346-1-wangxiongfeng2@huawei.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com
Conflicts: arch/arm64/include/asm/barrier.h Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- Documentation/memory-barriers.txt | 8 ++++++++ arch/arm64/include/asm/barrier.h | 10 ++++++++++ include/asm-generic/barrier.h | 11 +++++++++++ 3 files changed, 29 insertions(+)
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 17c8e0c2deb4..e0ebb5747d95 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -1950,6 +1950,14 @@ There are some more advanced barrier functions: For load from persistent memory, existing read memory barriers are sufficient to ensure read ordering.
+ (*) io_stop_wc(); + + For memory accesses with write-combining attributes (e.g. those returned + by ioremap_wc(), the CPU may wait for prior accesses to be merged with + subsequent ones. io_stop_wc() can be used to prevent the merging of + write-combining memory accesses before this macro with those after it when + such wait has performance implications. + =============================== IMPLICIT KERNEL MEMORY BARRIERS =============================== diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h index 37d891af8ea5..2a13b1c2c390 100644 --- a/arch/arm64/include/asm/barrier.h +++ b/arch/arm64/include/asm/barrier.h @@ -25,6 +25,14 @@ #define psb_csync() asm volatile("hint #17" : : : "memory") #define csdb() asm volatile("hint #20" : : : "memory")
+/* + * Data Gathering Hint: + * This instruction prevents merging memory accesses with Normal-NC or + * Device-GRE attributes before the hint instruction with any memory accesses + * appearing after the hint instruction. + */ +#define dgh() asm volatile("hint #6" : : : "memory") + #define spec_bar() asm volatile(ALTERNATIVE("dsb nsh\nisb\n", \ SB_BARRIER_INSN"nop\n", \ ARM64_HAS_SB)) @@ -49,6 +57,8 @@ #define dma_rmb() dmb(oshld) #define dma_wmb() dmb(oshst)
+#define io_stop_wc() dgh() + /* * Generate a mask for array_index__nospec() that is ~0UL when 0 <= idx < sz * and 0 otherwise. diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h index 640f09479bdf..4c2c1b830344 100644 --- a/include/asm-generic/barrier.h +++ b/include/asm-generic/barrier.h @@ -251,5 +251,16 @@ do { \ #define pmem_wmb() wmb() #endif
+/* + * ioremap_wc() maps I/O memory as memory with write-combining attributes. For + * this kind of memory accesses, the CPU may wait for prior accesses to be + * merged with subsequent ones. In some situation, such wait is bad for the + * performance. io_stop_wc() can be used to prevent the merging of + * write-combining memory accesses before this macro with those after it. + */ +#ifndef io_stop_wc +#define io_stop_wc do { } while (0) +#endif + #endif /* !__ASSEMBLY__ */ #endif /* __ASM_GENERIC_BARRIER_H */
From: Yufeng Mo moyufeng@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QHSV
----------------------------------------------------------------------
For the device that supports the TX push capability, the BD can be directly copied to the device memory. However, due to hardware restrictions, the push mode can be used only when there are no more than two BDs, otherwise, the doorbell mode based on device memory is used.
Signed-off-by: Yufeng Mo moyufeng@huawei.com Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_enet.c | 79 ++++++++++++++++++- .../net/ethernet/hisilicon/hns3/hns3_enet.h | 6 ++ .../ethernet/hisilicon/hns3/hns3_ethtool.c | 2 + .../hisilicon/hns3/hns3pf/hclge_main.c | 11 ++- .../hisilicon/hns3/hns3pf/hclge_main.h | 8 ++ .../hisilicon/hns3/hns3vf/hclgevf_main.c | 11 ++- .../hisilicon/hns3/hns3vf/hclgevf_main.h | 8 ++ 8 files changed, 118 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index a2ca47757ef9..7b5e84de53a4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -166,6 +166,7 @@ struct hnae3_handle;
struct hnae3_queue { void __iomem *io_base; + void __iomem *mem_base; struct hnae3_ae_algo *ae_algo; struct hnae3_handle *handle; int tqp_index; /* index in a handle */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index c1444dd93195..7d418823d6fc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -2027,9 +2027,73 @@ static int hns3_fill_skb_to_desc(struct hns3_enet_ring *ring, return bd_num; }
+static void hns3_tx_push_bd(struct hns3_enet_ring *ring, int num) +{ +#define HNS3_BYTES_PER_64BIT 8 + + struct hns3_desc desc[HNS3_MAX_PUSH_BD_NUM] = {}; + int offset = 0; + + /* make sure everything is visible to device before + * excuting tx push or updating doorbell + */ + dma_wmb(); + + do { + int idx = (ring->next_to_use - num + ring->desc_num) % + ring->desc_num; + + u64_stats_update_begin(&ring->syncp); + ring->stats.tx_push++; + u64_stats_update_end(&ring->syncp); + memcpy(&desc[offset], &ring->desc[idx], + sizeof(struct hns3_desc)); + offset++; + } while (--num); + + __iowrite64_copy(ring->tqp->mem_base, desc, + (sizeof(struct hns3_desc) * HNS3_MAX_PUSH_BD_NUM) / + HNS3_BYTES_PER_64BIT); + + io_stop_wc(); +} + +static void hns3_tx_mem_doorbell(struct hns3_enet_ring *ring) +{ +#define HNS3_MEM_DOORBELL_OFFSET 64 + + __le64 bd_num = cpu_to_le64((u64)ring->pending_buf); + + /* make sure everything is visible to device before + * excuting tx push or updating doorbell + */ + dma_wmb(); + + __iowrite64_copy(ring->tqp->mem_base + HNS3_MEM_DOORBELL_OFFSET, + &bd_num, 1); + u64_stats_update_begin(&ring->syncp); + ring->stats.tx_mem_doorbell += ring->pending_buf; + u64_stats_update_end(&ring->syncp); + + io_stop_wc(); +} + static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num, bool doorbell) { + struct net_device *netdev = ring_to_netdev(ring); + struct hns3_nic_priv *priv = netdev_priv(netdev); + + /* when tx push is enabled, the packet whose number of BD below + * HNS3_MAX_PUSH_BD_NUM can be pushed directly. + */ + if (test_bit(HNS3_NIC_STATE_TX_PUSH_ENABLE, &priv->state) && num && + !ring->pending_buf && num <= HNS3_MAX_PUSH_BD_NUM && doorbell) { + hns3_tx_push_bd(ring, num); + WRITE_ONCE(ring->last_to_use, ring->next_to_use); + return; + } + ring->pending_buf += num;
if (!doorbell) { @@ -2037,11 +2101,12 @@ static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num, return; }
- if (!ring->pending_buf) - return; + if (ring->tqp->mem_base) + hns3_tx_mem_doorbell(ring); + else + writel(ring->pending_buf, + ring->tqp->io_base + HNS3_RING_TX_RING_TAIL_REG);
- writel(ring->pending_buf, - ring->tqp->io_base + HNS3_RING_TX_RING_TAIL_REG); ring->pending_buf = 0; WRITE_ONCE(ring->last_to_use, ring->next_to_use); } @@ -2731,6 +2796,9 @@ static void hns3_dump_queue_stats(struct net_device *ndev, "seg_pkt_cnt: %llu, tx_more: %llu, restart_queue: %llu, tx_busy: %llu\n", tx_ring->stats.seg_pkt_cnt, tx_ring->stats.tx_more, tx_ring->stats.restart_queue, tx_ring->stats.tx_busy); + + netdev_info(ndev, "tx_push: %llu, tx_mem_doorbell: %llu\n", + tx_ring->stats.tx_push, tx_ring->stats.tx_mem_doorbell); }
static void hns3_dump_queue_reg(struct net_device *ndev, @@ -5093,6 +5161,9 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNS3_NIC_STATE_INITED, &priv->state);
+ if (test_bit(HNAE3_DEV_SUPPORT_TX_PUSH_B, ae_dev->caps)) + set_bit(HNS3_NIC_STATE_TX_PUSH_ENABLE, &priv->state); + if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) set_bit(HNAE3_PFLAG_LIMIT_PROMISC, &handle->supported_pflags);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index a05a0c7423ce..4a3253692dcc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -7,6 +7,7 @@ #include <linux/dim.h> #include <linux/if_vlan.h> #include <net/page_pool.h> +#include <asm/barrier.h>
#include "hnae3.h"
@@ -25,9 +26,12 @@ enum hns3_nic_state { HNS3_NIC_STATE2_RESET_REQUESTED, HNS3_NIC_STATE_HW_TX_CSUM_ENABLE, HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, + HNS3_NIC_STATE_TX_PUSH_ENABLE, HNS3_NIC_STATE_MAX };
+#define HNS3_MAX_PUSH_BD_NUM 2 + #define HNS3_RING_RX_RING_BASEADDR_L_REG 0x00000 #define HNS3_RING_RX_RING_BASEADDR_H_REG 0x00004 #define HNS3_RING_RX_RING_BD_NUM_REG 0x00008 @@ -410,6 +414,8 @@ struct ring_stats { u64 tx_pkts; u64 tx_bytes; u64 tx_more; + u64 tx_push; + u64 tx_mem_doorbell; u64 restart_queue; u64 tx_busy; u64 tx_copy; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index c06c39ece80d..6469238ae090 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -23,6 +23,8 @@ static const struct hns3_stats hns3_txq_stats[] = { HNS3_TQP_STAT("packets", tx_pkts), HNS3_TQP_STAT("bytes", tx_bytes), HNS3_TQP_STAT("more", tx_more), + HNS3_TQP_STAT("push", tx_push), + HNS3_TQP_STAT("mem_doorbell", tx_mem_doorbell), HNS3_TQP_STAT("wake", restart_queue), HNS3_TQP_STAT("busy", tx_busy), HNS3_TQP_STAT("copy", tx_copy), diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 6e0985e7ca2a..1e4c89d4b96b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -1643,6 +1643,7 @@ static int hclge_config_gro(struct hclge_dev *hdev)
static int hclge_alloc_tqps(struct hclge_dev *hdev) { + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); struct hclge_comm_tqp *tqp; int i;
@@ -1676,6 +1677,14 @@ static int hclge_alloc_tqps(struct hclge_dev *hdev) (i - HCLGE_TQP_MAX_SIZE_DEV_V2) * HCLGE_TQP_REG_SIZE;
+ /* when device supports tx push and has device memory, + * the queue can execute push mode or doorbell mode on + * device memory. + */ + if (test_bit(HNAE3_DEV_SUPPORT_TX_PUSH_B, ae_dev->caps)) + tqp->q.mem_base = hdev->hw.hw.mem_base + + HCLGE_TQP_MEM_OFFSET(hdev, i); + tqp++; }
@@ -11008,8 +11017,6 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
static int hclge_dev_mem_map(struct hclge_dev *hdev) { -#define HCLGE_MEM_BAR 4 - struct pci_dev *pdev = hdev->pdev; struct hclge_hw *hw = &hdev->hw;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index adfb26e79262..f7f5a4b09068 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -169,6 +169,14 @@ enum HLCGE_PORT_TYPE { #define HCLGE_VECTOR0_ALL_MSIX_ERR_B 6U #define HCLGE_TRIGGER_IMP_RESET_B 7U
+#define HCLGE_TQP_MEM_SIZE 0x10000 +#define HCLGE_MEM_BAR 4 +/* in the bar4, the first half is for roce, and the second half is for nic */ +#define HCLGE_NIC_MEM_OFFSET(hdev) \ + (pci_resource_len((hdev)->pdev, HCLGE_MEM_BAR) >> 1) +#define HCLGE_TQP_MEM_OFFSET(hdev, i) \ + (HCLGE_NIC_MEM_OFFSET(hdev) + HCLGE_TQP_MEM_SIZE * (i)) + #define HCLGE_MAC_DEFAULT_FRAME \ (ETH_HLEN + ETH_FCS_LEN + 2 * VLAN_HLEN + ETH_DATA_LEN) #define HCLGE_MAC_MIN_FRAME 64 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 383b213c8512..a2ec2d8c2151 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -321,6 +321,7 @@ static int hclgevf_get_pf_media_type(struct hclgevf_dev *hdev)
static int hclgevf_alloc_tqps(struct hclgevf_dev *hdev) { + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); struct hclge_comm_tqp *tqp; int i;
@@ -354,6 +355,14 @@ static int hclgevf_alloc_tqps(struct hclgevf_dev *hdev) (i - HCLGEVF_TQP_MAX_SIZE_DEV_V2) * HCLGEVF_TQP_REG_SIZE;
+ /* when device supports tx push and has device memory, + * the queue can execute push mode or doorbell mode on + * device memory. + */ + if (test_bit(HNAE3_DEV_SUPPORT_TX_PUSH_B, ae_dev->caps)) + tqp->q.mem_base = hdev->hw.hw.mem_base + + HCLGEVF_TQP_MEM_OFFSET(hdev, i); + tqp++; }
@@ -2547,8 +2556,6 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client,
static int hclgevf_dev_mem_map(struct hclgevf_dev *hdev) { -#define HCLGEVF_MEM_BAR 4 - struct pci_dev *pdev = hdev->pdev; struct hclgevf_hw *hw = &hdev->hw;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index 502ca1ce1a90..4b00fd44f118 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -96,6 +96,14 @@
#define HCLGEVF_RSS_IND_TBL_SIZE 512
+#define HCLGEVF_TQP_MEM_SIZE 0x10000 +#define HCLGEVF_MEM_BAR 4 +/* in the bar4, the first half is for roce, and the second half is for nic */ +#define HCLGEVF_NIC_MEM_OFFSET(hdev) \ + (pci_resource_len((hdev)->pdev, HCLGEVF_MEM_BAR) >> 1) +#define HCLGEVF_TQP_MEM_OFFSET(hdev, i) \ + (HCLGEVF_NIC_MEM_OFFSET(hdev) + HCLGEVF_TQP_MEM_SIZE * (i)) + #define HCLGEVF_MAC_MAX_FRAME 9728
#define HCLGEVF_STATS_TIMER_INTERVAL 36U
From: Yufeng Mo moyufeng@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QHSV
----------------------------------------------------------------------
Add a control private flag in ethtool for enable/disable TX push feature.
Signed-off-by: Yufeng Mo moyufeng@huawei.com Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_enet.c | 5 ++++- .../ethernet/hisilicon/hns3/hns3_ethtool.c | 19 ++++++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 7b5e84de53a4..cd0ef12b6e85 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -817,6 +817,7 @@ struct hnae3_roce_private_info {
enum hnae3_pflag { HNAE3_PFLAG_LIMIT_PROMISC, + HNAE3_PFLAG_PUSH_ENABLE, HNAE3_PFLAG_MAX };
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 7d418823d6fc..edaf84e7fc85 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -5161,8 +5161,11 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNS3_NIC_STATE_INITED, &priv->state);
- if (test_bit(HNAE3_DEV_SUPPORT_TX_PUSH_B, ae_dev->caps)) + if (test_bit(HNAE3_DEV_SUPPORT_TX_PUSH_B, ae_dev->caps)) { set_bit(HNS3_NIC_STATE_TX_PUSH_ENABLE, &priv->state); + handle->priv_flags |= BIT(HNAE3_PFLAG_PUSH_ENABLE); + set_bit(HNAE3_PFLAG_PUSH_ENABLE, &handle->supported_pflags); + }
if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) set_bit(HNAE3_PFLAG_LIMIT_PROMISC, &handle->supported_pflags); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index 6469238ae090..a7cf5fee9f48 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -440,8 +440,25 @@ static void hns3_update_limit_promisc_mode(struct net_device *netdev, hns3_request_update_promisc_mode(handle); }
+static void hns3_update_state(struct net_device *netdev, + enum hns3_nic_state state, bool enable) +{ + struct hns3_nic_priv *priv = netdev_priv(netdev); + + if (enable) + set_bit(state, &priv->state); + else + clear_bit(state, &priv->state); +} + +static void hns3_update_push_state(struct net_device *netdev, bool enable) +{ + hns3_update_state(netdev, HNS3_NIC_STATE_TX_PUSH_ENABLE, enable); +} + static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = { - { "limit_promisc", hns3_update_limit_promisc_mode } + { "limit_promisc", hns3_update_limit_promisc_mode }, + { "tx_push_enable", hns3_update_push_state } };
static int hns3_get_sset_count(struct net_device *netdev, int stringset)
From: Xiongfeng Wang wangxiongfeng2@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QKQ3
---------------------------
After using io_stop_wc(), drivers reports following compile error when compiled on X86.
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c: In function ‘hns3_tx_push_bd’: drivers/net/ethernet/hisilicon/hns3/hns3_enet.c:2058:12: error: expected ‘;’ before ‘(’ token io_stop_wc(); ^ It is because I missed to add the brackets after io_stop_wc macro. So let's add the missing brackets.
Fixes: d5624bb29f49 ("asm-generic: introduce io_stop_wc() and add implementation for ARM64") Reported-by: Guangbin Huang huangguangbin2@huawei.com Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- include/asm-generic/barrier.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h index 4c2c1b830344..3385ca5ca5c0 100644 --- a/include/asm-generic/barrier.h +++ b/include/asm-generic/barrier.h @@ -259,7 +259,7 @@ do { \ * write-combining memory accesses before this macro with those after it. */ #ifndef io_stop_wc -#define io_stop_wc do { } while (0) +#define io_stop_wc() do { } while (0) #endif
#endif /* !__ASSEMBLY__ */
From: Giovanni Gherdovich ggherdovich@suse.cz
mainline inclusion from mainline-v5.14-rc1 commit fbdc21e9b038 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QV7E CVE: NA
----------------------
Users may disable HWP in firmware, in which case intel_pstate wouldn't load unless the CPU model is explicitly supported.
Add ICELAKE_X to the list of CPUs that can register intel_pstate while not advertising the HWP capability. Without this change, an ICELAKE_X in no-HWP mode could only use the acpi_cpufreq frequency scaling driver.
See also commit d8de7a44e11f ("cpufreq: intel_pstate: Add Skylake servers support").
Signed-off-by: Giovanni Gherdovich ggherdovich@suse.cz Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/cpufreq/intel_pstate.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 1686705bee7b..14504c761588 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -2100,6 +2100,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { X86_MATCH(ATOM_GOLDMONT, core_funcs), X86_MATCH(ATOM_GOLDMONT_PLUS, core_funcs), X86_MATCH(SKYLAKE_X, core_funcs), + X86_MATCH(ICELAKE_X, core_funcs), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
From: Yanling Song songyl@ramaxel.com
Ramaxel inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QLBP CVE: NA
Changes: 1. Read lb mode from chip 2. Disable fake vf function 3. Remove unnecessary code
Signed-off-by: Yanling Song songyl@ramaxel.com Reviewed-by: Yun Xu xuyun@ramaxel.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- .../ethernet/ramaxel/spnic/hw/sphw_cfg_cmd.h | 3 +- .../ethernet/ramaxel/spnic/hw/sphw_hw_cfg.c | 3 + .../ethernet/ramaxel/spnic/hw/sphw_hw_cfg.h | 3 + drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c | 43 +-- drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c | 10 +- drivers/scsi/spfc/hw/spfc_cqm_main.c | 299 +----------------- drivers/scsi/spfc/hw/spfc_cqm_main.h | 3 - drivers/scsi/spfc/hw/spfc_cqm_object.c | 21 -- 8 files changed, 29 insertions(+), 356 deletions(-)
diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cfg_cmd.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cfg_cmd.h index 23644958e33a..63b89e71c552 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cfg_cmd.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_cfg_cmd.h @@ -40,7 +40,8 @@ struct cfg_cmd_dev_cap {
u8 sf_svc_attr; u8 func_sf_en; - u16 rsvd_sf; + u8 lb_mode; + u8 smf_pg;
u32 max_conn_num; u16 max_stick2cache_num; diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.c b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.c index 5d6a53307f0a..4b2674ec66f0 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.c +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.c @@ -112,6 +112,9 @@ static void parse_pub_res_cap(struct sphw_hwdev *hwdev, else cap->sf_en = false;
+ cap->lb_mode = dev_cap->lb_mode; + cap->smf_pg = dev_cap->smf_pg; + cap->timer_en = (u8)timer_enable; /* timer enable */ cap->host_oq_id_mask_val = dev_cap->host_oq_id_mask_val; cap->max_connect_num = dev_cap->max_conn_num; diff --git a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.h b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.h index 1147beeb76ad..1b48e0991563 100644 --- a/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.h +++ b/drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.h @@ -201,6 +201,9 @@ struct service_cap { u8 timer_en; /* 0:disable, 1:enable */ u8 bloomfilter_en; /* 0:disable, 1:enable*/
+ u8 lb_mode; + u8 smf_pg; + /* For test */ u32 test_mode; u32 test_qpc_num; diff --git a/drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c b/drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c index 30fb56a9bfed..0c1d97d9e3e6 100644 --- a/drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c +++ b/drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c @@ -53,17 +53,6 @@ cqm_bat_fill_cla_common_gpa(struct cqm_handle *cqm_handle, gpa.acs_spu_en = 0; }
- /* In fake mode, fake_vf_en in the GPA address of the BAT - * must be set to 1. - */ - if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_CHILD) { - gpa.fake_vf_en = 1; - func_attr = &cqm_handle->parent_cqm_handle->func_attribute; - gpa.pf_id = func_attr->func_global_idx; - } else { - gpa.fake_vf_en = 0; - } - memcpy(&cla_gpa_h, &gpa, sizeof(u32)); bat_entry_standerd->cla_gpa_h = cla_gpa_h;
@@ -379,13 +368,8 @@ s32 cqm_bat_update(struct cqm_handle *cqm_handle) CQM_PTR_CHECK_RET(buf_in, CQM_FAIL, CQM_ALLOC_FAIL(buf_in)); buf_in->size = sizeof(struct cqm_cmdq_bat_update);
- /* In non-fake mode, func_id is set to 0xffff, indicating the current func. - * In fake mode, the value of func_id is specified. This is a fake func_id. - */ - if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_CHILD) - func_id = cqm_handle->func_attribute.func_global_idx; - else - func_id = 0xffff; + /* In non-fake mode, func_id is set to 0xffff */ + func_id = 0xffff;
/* The LB scenario is supported. * The normal mode is the traditional mode and is configured on SMF0. @@ -545,19 +529,6 @@ s32 cqm_cla_fill_buf(struct cqm_handle *cqm_handle, struct cqm_buf *cla_base_buf spu_en = 0; }
- /* fake enable */ - if (cqm_handle->func_capability.fake_func_type == - CQM_FAKE_FUNC_CHILD) { - fake_en = 1ULL << 62; - func_attr = - &cqm_handle->parent_cqm_handle->func_attribute; - pf_id = func_attr->func_global_idx; - pf_id = (pf_id & 0x1f) << 57; - } else { - fake_en = 0; - pf_id = 0; - } - *base = (((((cla_sub_buf->buf_list[i].pa & CQM_CHIP_GPA_MASK) | spu_en) | fake_en) | @@ -1248,14 +1219,8 @@ s32 cqm_cla_update(struct cqm_handle *cqm_handle, struct cqm_buf_list *buf_node_ } }
- /* In non-fake mode, set func_id to 0xffff. - * Indicates the current func fake mode, set func_id to the - * specified value, This is a fake func_id. - */ - if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_CHILD) - cmd.func_id = cqm_handle->func_attribute.func_global_idx; - else - cmd.func_id = 0xffff; + /* In non-fake mode, set func_id to 0xffff. */ + cmd.func_id = 0xffff;
/* Mode 0 is hashed to 4 SMF engines (excluding PPF) by func ID. */ if (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_NORMAL || diff --git a/drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c b/drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c index 4e482776a14f..21100e8db8f4 100644 --- a/drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c +++ b/drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c @@ -405,14 +405,8 @@ s32 cqm_cla_cache_invalid(struct cqm_handle *cqm_handle, dma_addr_t gpa, u32 cac cmd.gpa_h = CQM_ADDR_HI(gpa); cmd.gpa_l = CQM_ADDR_LW(gpa);
- /* In non-fake mode, set func_id to 0xffff. - * Indicate the current func fake mode. - * The value of func_id is a fake func ID. - */ - if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_CHILD) - cmd.func_id = cqm_handle->func_attribute.func_global_idx; - else - cmd.func_id = 0xffff; + /* In non-fake mode, set func_id to 0xffff. */ + cmd.func_id = 0xffff;
/* Mode 0 is hashed to 4 SMF engines (excluding PPF) by func ID. */ if (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_NORMAL || diff --git a/drivers/scsi/spfc/hw/spfc_cqm_main.c b/drivers/scsi/spfc/hw/spfc_cqm_main.c index a4c8e60971b1..52cc2c7838e9 100644 --- a/drivers/scsi/spfc/hw/spfc_cqm_main.c +++ b/drivers/scsi/spfc/hw/spfc_cqm_main.c @@ -11,21 +11,8 @@ #include "sphw_crm.h" #include "sphw_hw.h" #include "sphw_hw_cfg.h" - #include "spfc_cqm_main.h"
-static unsigned char cqm_lb_mode = CQM_LB_MODE_NORMAL; -module_param(cqm_lb_mode, byte, 0644); -MODULE_PARM_DESC(cqm_lb_mode, "for cqm lb mode (default=0xff)"); - -static unsigned char cqm_fake_mode = CQM_FAKE_MODE_DISABLE; -module_param(cqm_fake_mode, byte, 0644); -MODULE_PARM_DESC(cqm_fake_mode, "for cqm fake mode (default=0 disable)"); - -static unsigned char cqm_platform_mode = CQM_FPGA_MODE; -module_param(cqm_platform_mode, byte, 0644); -MODULE_PARM_DESC(cqm_platform_mode, "for cqm platform mode (default=0 FPGA)"); - s32 cqm3_init(void *ex_handle) { struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle; @@ -63,19 +50,6 @@ s32 cqm3_init(void *ex_handle) goto err1; }
- /* In FAKE mode, only the bitmap of the timer of the function is - * enabled, and resources are not initialized. Otherwise, the - * configuration of the fake function is overwritten. - */ - if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_CHILD_CONFLICT) { - if (sphw_func_tmr_bitmap_set(ex_handle, true) != CQM_SUCCESS) - cqm_err(handle->dev_hdl, "Timer start: enable timer bitmap failed\n"); - - handle->cqm_hdl = NULL; - kfree(cqm_handle); - return CQM_SUCCESS; - } - /* Initialize memory entries such as BAT, CLA, and bitmap. */ if (cqm_mem_init(ex_handle) != CQM_SUCCESS) { cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_mem_init)); @@ -287,64 +261,6 @@ void cqm_service_capability_init(struct cqm_handle *cqm_handle, cqm_service_capability_init_fc(cqm_handle, (void *)service_capability); }
-s32 cqm_get_fake_func_type(struct cqm_handle *cqm_handle) -{ - struct cqm_func_capability *func_cap = &cqm_handle->func_capability; - u32 parent_func, child_func_start, child_func_number, i; - u32 idx = cqm_handle->func_attribute.func_global_idx; - - /* Currently, only one set of fake configurations is implemented. - * fake_cfg_number = 1 - */ - for (i = 0; i < func_cap->fake_cfg_number; i++) { - parent_func = func_cap->fake_cfg[i].parent_func; - child_func_start = func_cap->fake_cfg[i].child_func_start; - child_func_number = func_cap->fake_cfg[i].child_func_number; - - if (idx == parent_func) { - return CQM_FAKE_FUNC_PARENT; - } else if ((idx >= child_func_start) && - (idx < (child_func_start + child_func_number))) { - return CQM_FAKE_FUNC_CHILD_CONFLICT; - } - } - - return CQM_FAKE_FUNC_NORMAL; -} - -s32 cqm_get_child_func_start(struct cqm_handle *cqm_handle) -{ - struct cqm_func_capability *func_cap = &cqm_handle->func_capability; - struct sphw_func_attr *func_attr = &cqm_handle->func_attribute; - u32 i; - - /* Currently, only one set of fake configurations is implemented. - * fake_cfg_number = 1 - */ - for (i = 0; i < func_cap->fake_cfg_number; i++) { - if (func_attr->func_global_idx == - func_cap->fake_cfg[i].parent_func) - return (s32)(func_cap->fake_cfg[i].child_func_start); - } - - return CQM_FAIL; -} - -s32 cqm_get_child_func_number(struct cqm_handle *cqm_handle) -{ - struct cqm_func_capability *func_cap = &cqm_handle->func_capability; - struct sphw_func_attr *func_attr = &cqm_handle->func_attribute; - u32 i; - - for (i = 0; i < func_cap->fake_cfg_number; i++) { - if (func_attr->func_global_idx == - func_cap->fake_cfg[i].parent_func) - return (s32)(func_cap->fake_cfg[i].child_func_number); - } - - return CQM_FAIL; -} - /* Set func_type in fake_cqm_handle to ppf, pf, or vf. */ void cqm_set_func_type(struct cqm_handle *cqm_handle) { @@ -358,41 +274,20 @@ void cqm_set_func_type(struct cqm_handle *cqm_handle) cqm_handle->func_attribute.func_type = CQM_VF; }
-void cqm_lb_fake_mode_init(struct cqm_handle *cqm_handle) +void cqm_lb_fake_mode_init(struct cqm_handle *cqm_handle, struct service_cap *svc_cap) { struct cqm_func_capability *func_cap = &cqm_handle->func_capability; - struct cqm_fake_cfg *cfg = func_cap->fake_cfg;
- func_cap->lb_mode = cqm_lb_mode; - func_cap->fake_mode = cqm_fake_mode; + func_cap->lb_mode = svc_cap->lb_mode;
/* Initializing the LB Mode */ - if (func_cap->lb_mode == CQM_LB_MODE_NORMAL) { + if (func_cap->lb_mode == CQM_LB_MODE_NORMAL) func_cap->smf_pg = 0; - } else { - /* The LB mode is tailored on the FPGA. - * Only SMF0 and SMF2 are instantiated. - */ - if (cqm_platform_mode == CQM_FPGA_MODE) - func_cap->smf_pg = 0x5; - else - func_cap->smf_pg = 0xF; - } + else + func_cap->smf_pg = svc_cap->smf_pg;
- /* Initializing the FAKE Mode */ - if (func_cap->fake_mode == CQM_FAKE_MODE_DISABLE) { - func_cap->fake_cfg_number = 0; - func_cap->fake_func_type = CQM_FAKE_FUNC_NORMAL; - } else { - func_cap->fake_cfg_number = 1; - - /* When configuring fake mode, ensure that the parent function - * cannot be contained in the child function; otherwise, the - * system will be initialized repeatedly. - */ - cfg[0].child_func_start = CQM_FAKE_CFUNC_START; - func_cap->fake_func_type = cqm_get_fake_func_type(cqm_handle); - } + func_cap->fake_cfg_number = 0; + func_cap->fake_func_type = CQM_FAKE_FUNC_NORMAL; }
s32 cqm_capability_init(void *ex_handle) @@ -465,10 +360,9 @@ s32 cqm_capability_init(void *ex_handle)
func_cap->gpa_check_enable = true;
- cqm_lb_fake_mode_init(cqm_handle); + cqm_lb_fake_mode_init(cqm_handle, service_capability); cqm_info(handle->dev_hdl, "Cap init: lb_mode=%u\n", func_cap->lb_mode); cqm_info(handle->dev_hdl, "Cap init: smf_pg=%u\n", func_cap->smf_pg); - cqm_info(handle->dev_hdl, "Cap init: fake_mode=%u\n", func_cap->fake_mode); cqm_info(handle->dev_hdl, "Cap init: fake_func_type=%u\n", func_cap->fake_func_type); cqm_info(handle->dev_hdl, "Cap init: fake_cfg_number=%u\n", func_cap->fake_cfg_number);
@@ -517,153 +411,6 @@ s32 cqm_capability_init(void *ex_handle) return err; }
-void cqm_fake_uninit(struct cqm_handle *cqm_handle) -{ - u32 i; - - if (cqm_handle->func_capability.fake_func_type != - CQM_FAKE_FUNC_PARENT) - return; - - for (i = 0; i < CQM_FAKE_FUNC_MAX; i++) { - kfree(cqm_handle->fake_cqm_handle[i]); - cqm_handle->fake_cqm_handle[i] = NULL; - } -} - -s32 cqm_fake_init(struct cqm_handle *cqm_handle) -{ - struct sphw_hwdev *handle = cqm_handle->ex_handle; - struct cqm_func_capability *func_cap = NULL; - struct cqm_handle *fake_cqm_handle = NULL; - struct sphw_func_attr *func_attr = NULL; - s32 child_func_start, child_func_number; - u32 i; - - func_cap = &cqm_handle->func_capability; - if (func_cap->fake_func_type != CQM_FAKE_FUNC_PARENT) - return CQM_SUCCESS; - - child_func_start = cqm_get_child_func_start(cqm_handle); - if (child_func_start == CQM_FAIL) { - cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(child_func_start)); - return CQM_FAIL; - } - - child_func_number = cqm_get_child_func_number(cqm_handle); - if (child_func_number == CQM_FAIL) { - cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(child_func_number)); - return CQM_FAIL; - } - - for (i = 0; i < (u32)child_func_number; i++) { - fake_cqm_handle = kmalloc(sizeof(*fake_cqm_handle), GFP_KERNEL | __GFP_ZERO); - if (!fake_cqm_handle) { - cqm_err(handle->dev_hdl, - CQM_ALLOC_FAIL(fake_cqm_handle)); - goto err; - } - - /* Copy the attributes of the parent CQM handle to the child CQM - * handle and modify the values of function. - */ - memcpy(fake_cqm_handle, cqm_handle, sizeof(struct cqm_handle)); - func_attr = &fake_cqm_handle->func_attribute; - func_cap = &fake_cqm_handle->func_capability; - func_attr->func_global_idx = (u16)(child_func_start + i); - cqm_set_func_type(fake_cqm_handle); - func_cap->fake_func_type = CQM_FAKE_FUNC_CHILD; - cqm_info(handle->dev_hdl, "Fake func init: function[%u] type %d(0:PF,1:VF,2:PPF)\n", - func_attr->func_global_idx, func_attr->func_type); - - fake_cqm_handle->parent_cqm_handle = cqm_handle; - cqm_handle->fake_cqm_handle[i] = fake_cqm_handle; - } - - return CQM_SUCCESS; - -err: - cqm_fake_uninit(cqm_handle); - return CQM_FAIL; -} - -void cqm_fake_mem_uninit(struct cqm_handle *cqm_handle) -{ - struct sphw_hwdev *handle = cqm_handle->ex_handle; - struct cqm_handle *fake_cqm_handle = NULL; - s32 child_func_number; - u32 i; - - if (cqm_handle->func_capability.fake_func_type != CQM_FAKE_FUNC_PARENT) - return; - - child_func_number = cqm_get_child_func_number(cqm_handle); - if (child_func_number == CQM_FAIL) { - cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(child_func_number)); - return; - } - - for (i = 0; i < (u32)child_func_number; i++) { - fake_cqm_handle = cqm_handle->fake_cqm_handle[i]; - cqm_object_table_uninit(fake_cqm_handle); - cqm_bitmap_uninit(fake_cqm_handle); - cqm_cla_uninit(fake_cqm_handle, CQM_BAT_ENTRY_MAX); - cqm_bat_uninit(fake_cqm_handle); - } -} - -s32 cqm_fake_mem_init(struct cqm_handle *cqm_handle) -{ - struct sphw_hwdev *handle = cqm_handle->ex_handle; - struct cqm_handle *fake_cqm_handle = NULL; - s32 child_func_number; - u32 i; - - if (cqm_handle->func_capability.fake_func_type != - CQM_FAKE_FUNC_PARENT) - return CQM_SUCCESS; - - child_func_number = cqm_get_child_func_number(cqm_handle); - if (child_func_number == CQM_FAIL) { - cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(child_func_number)); - return CQM_FAIL; - } - - for (i = 0; i < (u32)child_func_number; i++) { - fake_cqm_handle = cqm_handle->fake_cqm_handle[i]; - - if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) { - cqm_err(handle->dev_hdl, - CQM_FUNCTION_FAIL(cqm_bat_init)); - goto err; - } - - if (cqm_cla_init(fake_cqm_handle) != CQM_SUCCESS) { - cqm_err(handle->dev_hdl, - CQM_FUNCTION_FAIL(cqm_cla_init)); - goto err; - } - - if (cqm_bitmap_init(fake_cqm_handle) != CQM_SUCCESS) { - cqm_err(handle->dev_hdl, - CQM_FUNCTION_FAIL(cqm_bitmap_init)); - goto err; - } - - if (cqm_object_table_init(fake_cqm_handle) != CQM_SUCCESS) { - cqm_err(handle->dev_hdl, - CQM_FUNCTION_FAIL(cqm_object_table_init)); - goto err; - } - } - - return CQM_SUCCESS; - -err: - cqm_fake_mem_uninit(cqm_handle); - return CQM_FAIL; -} - s32 cqm_mem_init(void *ex_handle) { struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle; @@ -671,49 +418,35 @@ s32 cqm_mem_init(void *ex_handle)
cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) { - cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fake_init)); - return CQM_FAIL; - } - - if (cqm_fake_mem_init(cqm_handle) != CQM_SUCCESS) { - cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fake_mem_init)); - goto err1; - } - if (cqm_bat_init(cqm_handle) != CQM_SUCCESS) { cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bat_init)); - goto err2; + return CQM_FAIL; }
if (cqm_cla_init(cqm_handle) != CQM_SUCCESS) { cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_init)); - goto err3; + goto err1; }
if (cqm_bitmap_init(cqm_handle) != CQM_SUCCESS) { cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bitmap_init)); - goto err4; + goto err2; }
if (cqm_object_table_init(cqm_handle) != CQM_SUCCESS) { cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_object_table_init)); - goto err5; + goto err3; }
return CQM_SUCCESS;
-err5: - cqm_bitmap_uninit(cqm_handle); -err4: - cqm_cla_uninit(cqm_handle, CQM_BAT_ENTRY_MAX); err3: - cqm_bat_uninit(cqm_handle); + cqm_bitmap_uninit(cqm_handle); err2: - cqm_fake_mem_uninit(cqm_handle); + cqm_cla_uninit(cqm_handle, CQM_BAT_ENTRY_MAX); err1: - cqm_fake_uninit(cqm_handle); + cqm_bat_uninit(cqm_handle); return CQM_FAIL; }
@@ -728,8 +461,6 @@ void cqm_mem_uninit(void *ex_handle) cqm_bitmap_uninit(cqm_handle); cqm_cla_uninit(cqm_handle, CQM_BAT_ENTRY_MAX); cqm_bat_uninit(cqm_handle); - cqm_fake_mem_uninit(cqm_handle); - cqm_fake_uninit(cqm_handle); }
s32 cqm_event_init(void *ex_handle) diff --git a/drivers/scsi/spfc/hw/spfc_cqm_main.h b/drivers/scsi/spfc/hw/spfc_cqm_main.h index 1b8cf8bdb3b7..cf10d7f5c339 100644 --- a/drivers/scsi/spfc/hw/spfc_cqm_main.h +++ b/drivers/scsi/spfc/hw/spfc_cqm_main.h @@ -328,9 +328,6 @@ void cqm_mem_uninit(void *ex_handle); s32 cqm_event_init(void *ex_handle); void cqm_event_uninit(void *ex_handle); u8 cqm_aeq_callback(void *ex_handle, u8 event, u8 *data); -s32 cqm_get_fake_func_type(struct cqm_handle *cqm_handle); -s32 cqm_get_child_func_start(struct cqm_handle *cqm_handle); -s32 cqm_get_child_func_number(struct cqm_handle *cqm_handle);
s32 cqm3_init(void *ex_handle); void cqm3_uninit(void *ex_handle); diff --git a/drivers/scsi/spfc/hw/spfc_cqm_object.c b/drivers/scsi/spfc/hw/spfc_cqm_object.c index b895d37aebae..165794e9c7e5 100644 --- a/drivers/scsi/spfc/hw/spfc_cqm_object.c +++ b/drivers/scsi/spfc/hw/spfc_cqm_object.c @@ -155,8 +155,6 @@ struct cqm_qpc_mpt *cqm3_object_qpc_mpt_create(void *ex_handle, u32 service_type struct cqm_qpc_mpt_info *qpc_mpt_info = NULL; struct cqm_handle *cqm_handle = NULL; s32 ret = CQM_FAIL; - u32 relative_index; - u32 fake_func_id;
CQM_PTR_CHECK_RET(ex_handle, NULL, CQM_PTR_NULL(ex_handle));
@@ -180,25 +178,6 @@ struct cqm_qpc_mpt *cqm3_object_qpc_mpt_create(void *ex_handle, u32 service_type return NULL; }
- /* fake vf adaption, switch to corresponding VF. */ - if (cqm_handle->func_capability.fake_func_type == - CQM_FAKE_FUNC_PARENT) { - fake_func_id = index / cqm_handle->func_capability.qpc_number; - relative_index = index % cqm_handle->func_capability.qpc_number; - - cqm_info(handle->dev_hdl, "qpc create: fake_func_id=%u, relative_index=%u\n", - fake_func_id, relative_index); - - if ((s32)fake_func_id >= - cqm_get_child_func_number(cqm_handle)) { - cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(fake_func_id)); - return NULL; - } - - index = relative_index; - cqm_handle = cqm_handle->fake_cqm_handle[fake_func_id]; - } - qpc_mpt_info = kmalloc(sizeof(*qpc_mpt_info), GFP_ATOMIC | __GFP_ZERO); CQM_PTR_CHECK_RET(qpc_mpt_info, NULL, CQM_ALLOC_FAIL(qpc_mpt_info));