Re: [kvm-unit-tests PATCH v2 2/9] arch-run: Clean up temporary files properly
On 02/02/2024 07.57, Nicholas Piggin wrote: Migration files weren't being removed when tests were interrupted. This improves the situation. Signed-off-by: Nicholas Piggin --- scripts/arch-run.bash | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/arch-run.bash b/scripts/arch-run.bash index d0864360..f22ead6f 100644 --- a/scripts/arch-run.bash +++ b/scripts/arch-run.bash @@ -134,12 +134,14 @@ run_migration () qmp1=$(mktemp -u -t mig-helper-qmp1.XX) qmp2=$(mktemp -u -t mig-helper-qmp2.XX) fifo=$(mktemp -u -t mig-helper-fifo.XX) + + # race here between file creation and trap + trap "trap - TERM ; kill 0 ; exit 2" INT TERM + trap "rm -f ${migout1} ${migsock} ${qmp1} ${qmp2} ${fifo}" RETURN EXIT + qmpout1=/dev/null qmpout2=/dev/null - trap 'kill 0; exit 2' INT TERM - trap 'rm -f ${migout1} ${migsock} ${qmp1} ${qmp2} ${fifo}' RETURN EXIT - eval "$@" -chardev socket,id=mon1,path=${qmp1},server=on,wait=off \ -mon chardev=mon1,mode=control | tee ${migout1} & live_pid=`jobs -l %+ | grep "eval" | awk '{print$2}'` @@ -211,8 +213,8 @@ run_panic () qmp=$(mktemp -u -t panic-qmp.XX) - trap 'kill 0; exit 2' INT TERM - trap 'rm -f ${qmp}' RETURN EXIT + trap "trap - TERM ; kill 0 ; exit 2" INT TERM + trap "rm -f ${qmp}" RETURN EXIT # start VM stopped so we don't miss any events eval "$@" -chardev socket,id=mon1,path=${qmp},server=on,wait=off \ So the point is that the "EXIT" trap wasn't executed without the "trap - TERM" in the other trap? ... ok, then your patch certainly makes sense. Reviewed-by: Thomas Huth
Re: [revert commit 9f079dda1433] [mainline] [6.8.0-rc3] [NVME] OOPS kernel crash while booting
Thanks Keith for the patch. I have tested the patch without reverting old commits. The patch fixes the issue. Tested-by: Tasmiya Nalatwad On 2/6/24 23:22, Keith Busch wrote: On Tue, Feb 06, 2024 at 10:05:20PM +0530, Tasmiya Nalatwad wrote: Greetings, [revert commit 9f079dda1433] [mainline] [6.8.0-rc3] [NVME] OOPS kernel crash while booting to kernel Reverting below commit fixes the problem commit 9f079dda14339ee87d864306a9dc8c6b4e4da40b nvme: allow passthru cmd error logging Thanks for the report. Let's take a shot at fixing it before considering a revert. I copied you on the patch proposal. -- Regards, Tasmiya Nalatwad IBM Linux Technology Center
Re: [PATCH] drivers/ps3: select VIDEO to provide cmdline functions
Hi, On 2/7/24 12:37, Randy Dunlap wrote: > When VIDEO is not set, there is a build error. Fix that by selecting > VIDEO for PS3_PS3AV. > > ERROR: modpost: ".video_get_options" [drivers/ps3/ps3av_mod.ko] undefined! > > Fixes: dae7fbf43fd0 ("driver/ps3: Include for mode parsing") > Signed-off-by: Randy Dunlap > Cc: Michael Ellerman > Cc: Nicholas Piggin > Cc: Christophe Leroy > Cc: Aneesh Kumar K.V > Cc: Naveen N. Rao > Cc: linuxppc-dev@lists.ozlabs.org > Cc: Thomas Zimmermann > Cc: Geoff Levand > --- > arch/powerpc/platforms/ps3/Kconfig |1 + > 1 file changed, 1 insertion(+) > > diff -- a/arch/powerpc/platforms/ps3/Kconfig > b/arch/powerpc/platforms/ps3/Kconfig > --- a/arch/powerpc/platforms/ps3/Kconfig > +++ b/arch/powerpc/platforms/ps3/Kconfig > @@ -67,6 +67,7 @@ config PS3_VUART > config PS3_PS3AV > depends on PPC_PS3 > tristate "PS3 AV settings driver" if PS3_ADVANCED > + select VIDEO > select PS3_VUART > default y > help Seems good. Acked-by: Geoff Levand
[PATCH v4 5/5] sched: rename SD_SHARE_PKG_RESOURCES to SD_SHARE_LLC
From: Alex Shi SD_CLUSTER shares the CPU resources like llc tags or l2 cache, that's easy confuse with SD_SHARE_PKG_RESOURCES. So let's specifical point what the latter shares: LLC. That would reduce some confusing. Suggested-by: Valentin Schneider Signed-off-by: Alex Shi To: linux-ker...@vger.kernel.org To: linuxppc-dev@lists.ozlabs.org To: Miaohe Lin To: Barry Song To: Mark Rutland To: Frederic Weisbecker To: Daniel Bristot de Oliveira To: Ben Segall To: Steven Rostedt To: Dietmar Eggemann To: Juri Lelli To: Ingo Molnar To: "Naveen N. Rao" To: "Aneesh Kumar K.V" To: Christophe Leroy Cc: "Gautham R. Shenoy" Cc: Yicong Yang Cc: Ricardo Neri Cc: Josh Poimboeuf Cc: Srikar Dronamraju Cc: Valentin Schneider Cc: Nicholas Piggin Cc: Michael Ellerman --- arch/powerpc/kernel/smp.c | 6 +++--- include/linux/sched/sd_flags.h | 4 ++-- include/linux/sched/topology.h | 6 +++--- kernel/sched/fair.c| 2 +- kernel/sched/topology.c| 16 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 693334c20d07..a60e4139214b 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -984,7 +984,7 @@ static bool shared_caches __ro_after_init; /* cpumask of CPUs with asymmetric SMT dependency */ static int powerpc_smt_flags(void) { - int flags = SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES; + int flags = SD_SHARE_CPUCAPACITY | SD_SHARE_LLC; if (cpu_has_feature(CPU_FTR_ASYM_SMT)) { printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n"); @@ -1010,9 +1010,9 @@ static __ro_after_init DEFINE_STATIC_KEY_FALSE(splpar_asym_pack); static int powerpc_shared_cache_flags(void) { if (static_branch_unlikely(&splpar_asym_pack)) - return SD_SHARE_PKG_RESOURCES | SD_ASYM_PACKING; + return SD_SHARE_LLC | SD_ASYM_PACKING; - return SD_SHARE_PKG_RESOURCES; + return SD_SHARE_LLC; } static int powerpc_shared_proc_flags(void) diff --git a/include/linux/sched/sd_flags.h b/include/linux/sched/sd_flags.h index a8b28647aafc..b04a5d04dee9 100644 --- a/include/linux/sched/sd_flags.h +++ b/include/linux/sched/sd_flags.h @@ -117,13 +117,13 @@ SD_FLAG(SD_SHARE_CPUCAPACITY, SDF_SHARED_CHILD | SDF_NEEDS_GROUPS) SD_FLAG(SD_CLUSTER, SDF_NEEDS_GROUPS) /* - * Domain members share CPU package resources (i.e. caches) + * Domain members share CPU Last Level Caches * * SHARED_CHILD: Set from the base domain up until spanned CPUs no longer share * the same cache(s). * NEEDS_GROUPS: Caches are shared between groups. */ -SD_FLAG(SD_SHARE_PKG_RESOURCES, SDF_SHARED_CHILD | SDF_NEEDS_GROUPS) +SD_FLAG(SD_SHARE_LLC, SDF_SHARED_CHILD | SDF_NEEDS_GROUPS) /* * Only a single load balancing instance diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h index a6e04b4a21d7..191b122158fb 100644 --- a/include/linux/sched/topology.h +++ b/include/linux/sched/topology.h @@ -38,21 +38,21 @@ extern const struct sd_flag_debug sd_flag_debug[]; #ifdef CONFIG_SCHED_SMT static inline int cpu_smt_flags(void) { - return SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES; + return SD_SHARE_CPUCAPACITY | SD_SHARE_LLC; } #endif #ifdef CONFIG_SCHED_CLUSTER static inline int cpu_cluster_flags(void) { - return SD_CLUSTER | SD_SHARE_PKG_RESOURCES; + return SD_CLUSTER | SD_SHARE_LLC; } #endif #ifdef CONFIG_SCHED_MC static inline int cpu_core_flags(void) { - return SD_SHARE_PKG_RESOURCES; + return SD_SHARE_LLC; } #endif diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 10ae28e1c088..188597640b1f 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -10695,7 +10695,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s */ if (local->group_type == group_has_spare) { if ((busiest->group_type > group_fully_busy) && - !(env->sd->flags & SD_SHARE_PKG_RESOURCES)) { + !(env->sd->flags & SD_SHARE_LLC)) { /* * If busiest is overloaded, try to fill spare * capacity. This might end up creating spare capacity diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index 0b33f7b05d21..e877730219d3 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -684,7 +684,7 @@ static void update_top_cache_domain(int cpu) int id = cpu; int size = 1; - sd = highest_flag_domain(cpu, SD_SHARE_PKG_RESOURCES); + sd = highest_flag_domain(cpu, SD_SHARE_LLC); if (sd) { id = cpumask_first(sched_domain_span(sd)); size = cpumask_weight(sched_domain_span(sd)); @@ -1554,7 +1554,7 @@ static struct cpumask ***sched_domains_numa_masks; * function. For details, see include/linux/sched/sd_
[PATCH v4] KVM: PPC: Book3S HV: Fix L2 guest reboot failure due to empty 'arch_compat'
Currently, rebooting a pseries nested qemu-kvm guest (L2) results in below error as L1 qemu sends PVR value 'arch_compat' == 0 via ppc_set_compat ioctl. This triggers a condition failure in kvmppc_set_arch_compat() resulting in an EINVAL. qemu-system-ppc64: Unable to set CPU compatibility mode in KVM: Invalid argument Also, a value of 0 for arch_compat generally refers the default compatibility of the host. But, arch_compat, being a Guest Wide Element in nested API v2, cannot be set to 0 in GSB as PowerVM (L0) expects a non-zero value. A value of 0 triggers a kernel trap during a reboot and consequently causes it to fail: [ 22.106360] reboot: Restarting system KVM: unknown exit, hardware reason ffea NIP 0100 LR fe44 CTR XER 20040092 CPU#0 MSR 1000 HID0 HF 6c00 iidx 3 didx 3 TB DECR 0 GPR00 c2a8c300 7fe0 GPR04 1002 82803033 GPR08 0a00 0004 2fff GPR12 c2e1 000105639200 0004 GPR16 00010563a090 GPR20 000105639e20 0001056399c8 7fffe54abab0 000105639288 GPR24 0001 0001 GPR28 c2b30840 CR [ - - - - - - - - ] RES 000@ SRR0 SRR1 PVR 00800200 VRSAVE SPRG0 SPRG1 SPRG2 SPRG3 SPRG4 SPRG5 SPRG6 SPRG7 HSRR0 HSRR1 CFAR LPCR 00020400 PTCR DAR DSISR kernel:trap=0xffea | pc=0x100 | msr=0x1000 This patch updates kvmppc_set_arch_compat() to use the host PVR value if 'compat_pvr' == 0 indicating that qemu doesn't want to enforce any specific PVR compat mode. The relevant part of the code might need a rework if PowerVM implements a support for `arch_compat == 0` in nestedv2 API. Fixes: 19d31c5f1157 ("KVM: PPC: Add support for nestedv2 guests") Reviewed-by: Aneesh Kumar K.V (IBM) Reviewed-by: Vaibhav Jain Signed-off-by: Amit Machhiwal --- Changes v3 -> v4: - Moved part of a code comment around implementation of `arch_compat == 0` in PowerVM to the patch description based on an off mailing list discussion Changes v2 -> v3: - Vaibhav: Use a 'break' instead of switch-case fallthrough - v2: https://lore.kernel.org/all/20240205132607.2776637-1-amach...@linux.ibm.com/ Changes v1 -> v2: - Added descriptive error log in the patch description when `arch_compat == 0` passed in GSB - Added a helper function for PCR to capabilities mapping - Added relevant comments around the changes being made - v1: https://lore.kernel.org/lkml/20240118095653.2588129-1-amach...@linux.ibm.com/ arch/powerpc/kvm/book3s_hv.c | 26 -- arch/powerpc/kvm/book3s_hv_nestedv2.c | 20 ++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 52427fc2a33f..0b921704da45 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -391,6 +391,24 @@ static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr) /* Dummy value used in computing PCR value below */ #define PCR_ARCH_31(PCR_ARCH_300 << 1) +static inline unsigned long map_pcr_to_cap(unsigned long pcr) +{ + unsigned long cap = 0; + + switch (pcr) { + case PCR_ARCH_300: + cap = H_GUEST_CAP_POWER9; + break; + case PCR_ARCH_31: + cap = H_GUEST_CAP_POWER10; + break; + default: + break; + } + + return cap; +} + static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat) { unsigned long host_pcr_bit = 0, guest_pcr_bit = 0, cap = 0; @@ -424,11 +442,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat) break; case PVR_ARCH_300: guest_pcr_bit = PCR_ARCH_300; - cap = H_GUEST_CAP_POWER9; break; case PVR_ARCH_31: guest_pcr_bit = PCR_ARCH_31; - cap = H_GUEST_CAP_POWER10; break; default: return -EINVAL; @@ -440,6 +456,12 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat) return -EINVAL; if (kvmhv_on_pseries() &&
Re: Re: [PATCH v3] KVM: PPC: Book3S HV: Fix L2 guest reboot failure due to empty 'arch_compat'
Hi Michael, Thanks for looking into the patch and your comments. On 2024/02/06 09:09 PM, Michael Ellerman wrote: > Hi Amit, > > One comment below ... > > Amit Machhiwal writes: > > Currently, rebooting a pseries nested qemu-kvm guest (L2) results in > > below error as L1 qemu sends PVR value 'arch_compat' == 0 via > > ppc_set_compat ioctl. This triggers a condition failure in > > kvmppc_set_arch_compat() resulting in an EINVAL. > ... > > > > diff --git a/arch/powerpc/kvm/book3s_hv_nestedv2.c > > b/arch/powerpc/kvm/book3s_hv_nestedv2.c > > index 5378eb40b162..6042bdc70230 100644 > > --- a/arch/powerpc/kvm/book3s_hv_nestedv2.c > > +++ b/arch/powerpc/kvm/book3s_hv_nestedv2.c > > @@ -347,8 +348,26 @@ static int gs_msg_ops_vcpu_fill_info(struct > > kvmppc_gs_buff *gsb, > > break; > > } > > case KVMPPC_GSID_LOGICAL_PVR: > > - rc = kvmppc_gse_put_u32(gsb, iden, > > - vcpu->arch.vcore->arch_compat); > > + /* > > +* Though 'arch_compat == 0' would mean the default > > +* compatibility, arch_compat, being a Guest Wide > > +* Element, cannot be filled with a value of 0 in GSB > > +* as this would result into a kernel trap. > > +* Hence, when `arch_compat == 0`, arch_compat should > > +* default to L1's PVR. > > +* > > +* Rework this when PowerVM supports a value of 0 > > +* for arch_compat for KVM API v2. > > +*/ > > Is there an actual plan that PowerVM will support this in future? > > If so, how will a future kernel know that it's running on a version of > PowerVM that does support arch_compat == 0? > > Similarly how will we know when it's OK to drop support for this > workaround? I'm sending a v4 based on an off mailing list discussion. > > cheers ~Amit
[PATCH 1/2] powerpc/pseries: Add a clear modifier to ibm,pa/pi-features parser
When a new ibm,pa/pi-features bit is introduced that is intended to apply to existing systems and features, it may have an "inverted" meaning (i.e., bit clear => feature available; bit set => unavailable). Depending on the nature of the feature, this may give the best backward compatibility result where old firmware will continue to have that bit clear and therefore the feature available. The 'invert' modifier presumably was introduced for this type of feature bit. However it invert will set the feature if the bit is clear, which prevents it being used in the situation where an old CPU lacks a feature that a new CPU has, then a new firmware comes out to disable that feature on the new CPU if the bit is set. Adding an 'invert' entry for that feature would incorrectly enable it for the old CPU. So add a 'clear' modifier that clears the feature if the bit is set, but it does not set the feature if the bit is clear. The feature is expected to be set in the cpu table. This replaces the 'invert' modifier, which is unused since commit 7d4703455168 ("powerpc/feature: Remove CPU_FTR_NODSISRALIGN"). Signed-off-by: Nicholas Piggin --- arch/powerpc/kernel/prom.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 0b5878c3125b..62f4a0229fae 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -151,6 +151,9 @@ static void __init move_device_tree(void) * pa-features property is missing, or a 1/0 to indicate if the feature * is supported/not supported. Note that the bit numbers are * big-endian to match the definition in PAPR. + * Note: the 'clear' flag clears the feature if the bit is set in the + * the ibm,pa/pi-features property, it does not set the feature if the + * bit is clear. */ struct ibm_feature { unsigned long cpu_features; /* CPU_FTR_xxx bit */ @@ -159,7 +162,7 @@ struct ibm_feature { unsigned intcpu_user_ftrs2; /* PPC_FEATURE2_xxx bit */ unsigned char pabyte; /* byte number in ibm,pa/pi-features */ unsigned char pabit; /* bit number (big-endian) */ - unsigned char invert; /* if 1, pa bit set => clear feature */ + unsigned char clear; /* if 1, pa bit set => clear feature */ }; static struct ibm_feature ibm_pa_features[] __initdata = { @@ -220,12 +223,12 @@ static void __init scan_features(unsigned long node, const unsigned char *ftrs, if (fp->pabyte >= ftrs[0]) continue; bit = (ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1; - if (bit ^ fp->invert) { + if (bit && !fp->clear) { cur_cpu_spec->cpu_features |= fp->cpu_features; cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs; cur_cpu_spec->cpu_user_features2 |= fp->cpu_user_ftrs2; cur_cpu_spec->mmu_features |= fp->mmu_features; - } else { + } else if (bit == fp->clear) { cur_cpu_spec->cpu_features &= ~fp->cpu_features; cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs; cur_cpu_spec->cpu_user_features2 &= ~fp->cpu_user_ftrs2; -- 2.42.0
[PATCH 2/2] powerpc/pseries: Set CPU_FTR_DBELL according to ibm,pi-features
PAPR will define a new ibm,pi-features bit which says that doorbells should not be used even on architectures where they exist. This could be because they are emulated and slower than using the interrupt controller directly for IPIs. Wire this bit into the pi-features parser to clear CPU_FTR_DBELL, and ensure CPU_FTR_DBELL is not in CPU_FTRS_ALWAYS. Signed-off-by: Nicholas Piggin --- arch/powerpc/include/asm/cputable.h | 11 ++- arch/powerpc/kernel/prom.c | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 8765d5158324..48471ca388dd 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -542,19 +542,20 @@ enum { #define CPU_FTRS_DT_CPU_BASE (~0ul) #endif +/* pseries may disable DBELL with ibm,pi-features */ #ifdef CONFIG_CPU_LITTLE_ENDIAN #define CPU_FTRS_ALWAYS \ - (CPU_FTRS_POSSIBLE & ~CPU_FTR_HVMODE & CPU_FTRS_POWER7 & \ -CPU_FTRS_POWER8E & CPU_FTRS_POWER8 & CPU_FTRS_POWER9 & \ -CPU_FTRS_POWER9_DD2_1 & CPU_FTRS_POWER9_DD2_2 & \ + (CPU_FTRS_POSSIBLE & ~CPU_FTR_HVMODE & ~CPU_FTR_DBELL & \ +CPU_FTRS_POWER7 & CPU_FTRS_POWER8E & CPU_FTRS_POWER8 & \ +CPU_FTRS_POWER9 & CPU_FTRS_POWER9_DD2_1 & CPU_FTRS_POWER9_DD2_2 & \ CPU_FTRS_POWER10 & CPU_FTRS_DT_CPU_BASE) #else #define CPU_FTRS_ALWAYS\ (CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \ CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \ CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \ -~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE & CPU_FTRS_POWER9 & \ -CPU_FTRS_POWER9_DD2_1 & CPU_FTRS_POWER9_DD2_2 & \ +~CPU_FTR_HVMODE & ~CPU_FTR_DBELL & CPU_FTRS_POSSIBLE & \ +CPU_FTRS_POWER9 & CPU_FTRS_POWER9_DD2_1 & CPU_FTRS_POWER9_DD2_2 & \ CPU_FTRS_POWER10 & CPU_FTRS_DT_CPU_BASE) #endif /* CONFIG_CPU_LITTLE_ENDIAN */ #endif diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 62f4a0229fae..e3e8fe70475f 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -196,6 +196,7 @@ static struct ibm_feature ibm_pa_features[] __initdata = { */ static struct ibm_feature ibm_pi_features[] __initdata = { { .pabyte = 0, .pabit = 3, .mmu_features = MMU_FTR_NX_DSI }, + { .pabyte = 0, .pabit = 4, .cpu_features = CPU_FTR_DBELL, .clear = 1 }, }; static void __init scan_features(unsigned long node, const unsigned char *ftrs, -- 2.42.0
[PATCH] drivers/ps3: select VIDEO to provide cmdline functions
When VIDEO is not set, there is a build error. Fix that by selecting VIDEO for PS3_PS3AV. ERROR: modpost: ".video_get_options" [drivers/ps3/ps3av_mod.ko] undefined! Fixes: dae7fbf43fd0 ("driver/ps3: Include for mode parsing") Signed-off-by: Randy Dunlap Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Christophe Leroy Cc: Aneesh Kumar K.V Cc: Naveen N. Rao Cc: linuxppc-dev@lists.ozlabs.org Cc: Thomas Zimmermann Cc: Geoff Levand --- arch/powerpc/platforms/ps3/Kconfig |1 + 1 file changed, 1 insertion(+) diff -- a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig @@ -67,6 +67,7 @@ config PS3_VUART config PS3_PS3AV depends on PPC_PS3 tristate "PS3 AV settings driver" if PS3_ADVANCED + select VIDEO select PS3_VUART default y help
Re: [PATCH v2 1/2] powerpc: Add Power11 architected and raw mode
Madhavan Srinivasan writes: > On 2/5/24 2:13 PM, Aneesh Kumar K.V wrote: >> Madhavan Srinivasan writes: >> >>> reg.h is updated with Power11 pvr. pvr_mask value of 0x0F07 >>> means we are arch v3.1 compliant. ... >>> diff --git a/arch/powerpc/kernel/cpu_setup_power.c >>> b/arch/powerpc/kernel/cpu_setup_power.c >>> index 98bd4e6c1770..8c24fc67d90f 100644 >>> --- a/arch/powerpc/kernel/cpu_setup_power.c >>> +++ b/arch/powerpc/kernel/cpu_setup_power.c >>> @@ -286,3 +286,13 @@ void __restore_cpu_power10(void) >>> init_HFSCR(); >>> init_PMU_HV(); >>> } >>> + >>> +void __setup_cpu_power11(unsigned long offset, struct cpu_spec *t) >>> +{ >>> + return __setup_cpu_power10(offset, t); >>> +} >>> + >>> +void __restore_cpu_power11(void) >>> +{ >>> + return __restore_cpu_power10(); >>> +} >>> >> Do we need to duplicate these functions if they don't add anything >> extra? > > What will be the preference in case of macros? Should we re-use > power10 macros in the table instead of defining new macros. I guess I would say yes to defining new macros, eg. +#define CPU_FTRS_POWER11 CPU_FTRS_POWER10 That is good to have because someone will eventually grep for CPU_FTRS_POWER11 and expect to find it. On the other hand global functions that do nothing but call the power10 version are not the best, because they will (slightly) bloat the binary for no real gain. cheers
Re: [PATCH 5/5] sched/vtime: do not include header
Le Sun, Jan 28, 2024 at 08:58:54PM +0100, Alexander Gordeev a écrit : > There is no architecture-specific code or data left > that generic needs to know about. > Thus, avoid the inclusion of header. > > Signed-off-by: Alexander Gordeev Reviewed-by: Frederic Weisbecker
Re: [PATCH 3/5] s390/vtime: remove unused __ARCH_HAS_VTIME_TASK_SWITCH leftover
Le Sun, Jan 28, 2024 at 08:58:52PM +0100, Alexander Gordeev a écrit : > __ARCH_HAS_VTIME_TASK_SWITCH macro is not used anymore. > > Signed-off-by: Alexander Gordeev Reviewed-by: Frederic Weisbecker > --- > arch/s390/include/asm/vtime.h | 2 -- > 1 file changed, 2 deletions(-) > > diff --git a/arch/s390/include/asm/vtime.h b/arch/s390/include/asm/vtime.h > index fe17e448c0c5..561c91c1a87c 100644 > --- a/arch/s390/include/asm/vtime.h > +++ b/arch/s390/include/asm/vtime.h > @@ -2,8 +2,6 @@ > #ifndef _S390_VTIME_H > #define _S390_VTIME_H > > -#define __ARCH_HAS_VTIME_TASK_SWITCH > - > static inline void update_timer_sys(void) > { > S390_lowcore.system_timer += S390_lowcore.last_update_timer - > S390_lowcore.exit_timer; > -- > 2.40.1 >
Re: [PATCH 2/5] sched/vtime: get rid of generic vtime_task_switch() implementation
Le Sun, Jan 28, 2024 at 08:58:51PM +0100, Alexander Gordeev a écrit : > The generic vtime_task_switch() implementation gets built only > if __ARCH_HAS_VTIME_TASK_SWITCH is not defined, but requires an > architecture to implement arch_vtime_task_switch() callback at > the same time, which is confusing. > > Further, arch_vtime_task_switch() is implemented for 32-bit PowerPC > architecture only and vtime_task_switch() generic variant is rather > superfluous. > > Simplify the whole vtime_task_switch() wiring by moving the existing > generic implementation to PowerPC. > > Signed-off-by: Alexander Gordeev Reviewed-by: Frederic Weisbecker
Re: [PATCH v2 2/4] eventfd: simplify eventfd_signal()
vhost and VIRTIO-related parts: Reviewed-by: Stefan Hajnoczi On Wed, 22 Nov 2023 at 07:50, Christian Brauner wrote: > > Ever since the evenfd type was introduced back in 2007 in commit > e1ad7468c77d ("signal/timer/event: eventfd core") the eventfd_signal() > function only ever passed 1 as a value for @n. There's no point in > keeping that additional argument. > > Signed-off-by: Christian Brauner > --- > arch/x86/kvm/hyperv.c | 2 +- > arch/x86/kvm/xen.c| 2 +- > drivers/accel/habanalabs/common/device.c | 2 +- > drivers/fpga/dfl.c| 2 +- > drivers/gpu/drm/drm_syncobj.c | 6 +++--- > drivers/gpu/drm/i915/gvt/interrupt.c | 2 +- > drivers/infiniband/hw/mlx5/devx.c | 2 +- > drivers/misc/ocxl/file.c | 2 +- > drivers/s390/cio/vfio_ccw_chp.c | 2 +- > drivers/s390/cio/vfio_ccw_drv.c | 4 ++-- > drivers/s390/cio/vfio_ccw_ops.c | 6 +++--- > drivers/s390/crypto/vfio_ap_ops.c | 2 +- > drivers/usb/gadget/function/f_fs.c| 4 ++-- > drivers/vdpa/vdpa_user/vduse_dev.c| 6 +++--- > drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c| 2 +- > drivers/vfio/pci/vfio_pci_core.c | 6 +++--- > drivers/vfio/pci/vfio_pci_intrs.c | 12 ++-- > drivers/vfio/platform/vfio_platform_irq.c | 4 ++-- > drivers/vhost/vdpa.c | 4 ++-- > drivers/vhost/vhost.c | 10 +- > drivers/vhost/vhost.h | 2 +- > drivers/virt/acrn/ioeventfd.c | 2 +- > drivers/xen/privcmd.c | 2 +- > fs/aio.c | 2 +- > fs/eventfd.c | 9 +++-- > include/linux/eventfd.h | 4 ++-- > mm/memcontrol.c | 10 +- > mm/vmpressure.c | 2 +- > samples/vfio-mdev/mtty.c | 4 ++-- > virt/kvm/eventfd.c| 4 ++-- > 30 files changed, 60 insertions(+), 63 deletions(-) > > diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c > index 238afd7335e4..4943f6b2bbee 100644 > --- a/arch/x86/kvm/hyperv.c > +++ b/arch/x86/kvm/hyperv.c > @@ -2388,7 +2388,7 @@ static u16 kvm_hvcall_signal_event(struct kvm_vcpu > *vcpu, struct kvm_hv_hcall *h > if (!eventfd) > return HV_STATUS_INVALID_PORT_ID; > > - eventfd_signal(eventfd, 1); > + eventfd_signal(eventfd); > return HV_STATUS_SUCCESS; > } > > diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c > index e53fad915a62..523bb6df5ac9 100644 > --- a/arch/x86/kvm/xen.c > +++ b/arch/x86/kvm/xen.c > @@ -2088,7 +2088,7 @@ static bool kvm_xen_hcall_evtchn_send(struct kvm_vcpu > *vcpu, u64 param, u64 *r) > if (ret < 0 && ret != -ENOTCONN) > return false; > } else { > - eventfd_signal(evtchnfd->deliver.eventfd.ctx, 1); > + eventfd_signal(evtchnfd->deliver.eventfd.ctx); > } > > *r = 0; > diff --git a/drivers/accel/habanalabs/common/device.c > b/drivers/accel/habanalabs/common/device.c > index 9711e8fc979d..3a89644f087c 100644 > --- a/drivers/accel/habanalabs/common/device.c > +++ b/drivers/accel/habanalabs/common/device.c > @@ -2044,7 +2044,7 @@ static void hl_notifier_event_send(struct > hl_notifier_event *notifier_event, u64 > notifier_event->events_mask |= event_mask; > > if (notifier_event->eventfd) > - eventfd_signal(notifier_event->eventfd, 1); > + eventfd_signal(notifier_event->eventfd); > > mutex_unlock(¬ifier_event->lock); > } > diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c > index dd7a783d53b5..e73f88050f08 100644 > --- a/drivers/fpga/dfl.c > +++ b/drivers/fpga/dfl.c > @@ -1872,7 +1872,7 @@ static irqreturn_t dfl_irq_handler(int irq, void *arg) > { > struct eventfd_ctx *trigger = arg; > > - eventfd_signal(trigger, 1); > + eventfd_signal(trigger); > return IRQ_HANDLED; > } > > diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c > index 01da6789d044..b9cc62982196 100644 > --- a/drivers/gpu/drm/drm_syncobj.c > +++ b/drivers/gpu/drm/drm_syncobj.c > @@ -1365,7 +1365,7 @@ static void syncobj_eventfd_entry_fence_func(struct > dma_fence *fence, > struct syncobj_eventfd_entry *entry = > container_of(cb, struct syncobj_eventfd_entry, fence_cb); > > - eventfd_signal(entry->ev_fd_ctx, 1); > + eventfd_signal(entry->ev_fd_ctx); > syncobj_eventfd_entry_free(entry); > } > > @@ -1388,13 +1388,13 @@ syncobj_eventfd_entry_func(struct drm_syncobj > *syncobj, > entry->fence = fence; > > if (entry->flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE) { > - eventfd_signal(entry->ev_fd_ctx, 1); > + eventfd_signal(entry->ev_fd_ctx); >
Re: [PATCH 1/5] sched/vtime: remove confusing arch_vtime_task_switch() declaration
Le Sun, Jan 28, 2024 at 08:58:50PM +0100, Alexander Gordeev a écrit : > Callback arch_vtime_task_switch() is only defined when > CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is selected. Yet, the > function prototype forward declaration is present for > CONFIG_VIRT_CPU_ACCOUNTING_GEN variant. Remove it. > > Signed-off-by: Alexander Gordeev Reviewed-by: Frederic Weisbecker
Re: [PATCH] perf/pmu-events/powerpc: Update json mapfile with Power11 PVR
On Mon, 29 Jan 2024 17:38:55 +0530, Madhavan Srinivasan wrote: > Update the Power11 PVR to json mapfile to enable > json events. Power11 is PowerISA v3.1 compliant > and support Power10 events. > > Applied to perf-tools-next, thanks! Best regards, -- Namhyung Kim
Re: [revert commit 9f079dda1433] [mainline] [6.8.0-rc3] [NVME] OOPS kernel crash while booting
On Tue, Feb 06, 2024 at 10:05:20PM +0530, Tasmiya Nalatwad wrote: > Greetings, > > [revert commit 9f079dda1433] [mainline] [6.8.0-rc3] [NVME] OOPS kernel crash > while booting to kernel > > Reverting below commit fixes the problem > > commit 9f079dda14339ee87d864306a9dc8c6b4e4da40b > nvme: allow passthru cmd error logging Thanks for the report. Let's take a shot at fixing it before considering a revert. I copied you on the patch proposal.
Re: [PATCH v2 1/4] PCI/AER: Store more information in aer_err_info
On Wed, Feb 07, 2024 at 12:41:41AM +0800, Wang, Qingshun wrote: > On Mon, Feb 05, 2024 at 05:12:31PM -0600, Bjorn Helgaas wrote: > > On Thu, Jan 25, 2024 at 02:27:59PM +0800, Wang, Qingshun wrote: > > > When Advisory Non-Fatal errors are raised, both correctable and > > > uncorrectable error statuses will be set. The current kernel code cannot > > > store both statuses at the same time, thus failing to handle ANFE > > > properly. > > > In addition, to avoid clearing UEs that are not ANFE by accident, UE > > > severity and Device Status also need to be recorded: any fatal UE cannot > > > be ANFE, and if Fatal/Non-Fatal Error Detected is set in Device Status, do > > > not take any assumption and let UE handler to clear UE status. > > > > > > Store status and mask of both correctable and uncorrectable errors in > > > aer_err_info. The severity of UEs and the values of the Device Status > > > register are also recorded, which will be used to determine UEs that > > > should > > > be handled by the ANFE handler. Refactor the rest of the code to use > > > cor/uncor_status and cor/uncor_mask fields instead of status and mask > > > fields. > > > > There's a lot going on in this patch. Could it possibly be split up a > > bit, e.g., first tease apart aer_err_info.status/.mask into > > .cor_status/mask and .uncor_status/mask, then add .uncor_severity, > > then add the device_status bit separately? If it could be split up, I > > think the ANFE case would be easier to see. > > Thanks for the feedback! Will split it up into two pacthes in the next > version. Or even three: 1) tease apart aer_err_info.status/.mask into .cor_status/mask and .uncor_status/mask 2) add .uncor_severity 3) add device_status Looking at this again, I'm a little confused about 2) and 3). I see the new read of PCI_ERR_UNCOR_SEVER into .uncor_severity, but there's no actual *use* of it. Same for 3), I see the new read of PCI_EXP_DEVSTA, but AFAICS there's no use of that value. We should have the addition of these new values in the same patch that *uses* them. Bjorn
Re: [PATCH v2 2/4] PCI/AER: Handle Advisory Non-Fatal properly
On Mon, Feb 05, 2024 at 05:26:16PM -0600, Bjorn Helgaas wrote: > In the subject, "properly" really doesn't convey information. I think > this patch does two things: > > - Prints error bits that might be ANFE > - Clears UNCOR_STATUS bits that were previously not cleared > > Maybe the subject line could say something about those (clearing > UNCOR_STATUS might be more important, or maybe this could even be > split into two patches so we could see both). > Good idea, thanks. I think splitting it into two patches would be the better approach.
Re: [PATCH v2 1/4] PCI/AER: Store more information in aer_err_info
On Mon, Feb 05, 2024 at 05:12:31PM -0600, Bjorn Helgaas wrote: > On Thu, Jan 25, 2024 at 02:27:59PM +0800, Wang, Qingshun wrote: > > When Advisory Non-Fatal errors are raised, both correctable and > > uncorrectable error statuses will be set. The current kernel code cannot > > store both statuses at the same time, thus failing to handle ANFE properly. > > In addition, to avoid clearing UEs that are not ANFE by accident, UE > > severity and Device Status also need to be recorded: any fatal UE cannot > > be ANFE, and if Fatal/Non-Fatal Error Detected is set in Device Status, do > > not take any assumption and let UE handler to clear UE status. > > > > Store status and mask of both correctable and uncorrectable errors in > > aer_err_info. The severity of UEs and the values of the Device Status > > register are also recorded, which will be used to determine UEs that should > > be handled by the ANFE handler. Refactor the rest of the code to use > > cor/uncor_status and cor/uncor_mask fields instead of status and mask > > fields. > > There's a lot going on in this patch. Could it possibly be split up a > bit, e.g., first tease apart aer_err_info.status/.mask into > .cor_status/mask and .uncor_status/mask, then add .uncor_severity, > then add the device_status bit separately? If it could be split up, I > think the ANFE case would be easier to see. > > Thanks a lot for working on this area! > > Bjorn Thanks for the feedback! Will split it up into two pacthes in the next version. -- Best regards, Wang, Qingshun
[revert commit 9f079dda1433] [mainline] [6.8.0-rc3] [NVME] OOPS kernel crash while booting
Greetings, [revert commit 9f079dda1433] [mainline] [6.8.0-rc3] [NVME] OOPS kernel crash while booting to kernel Reverting below commit fixes the problem commit 9f079dda14339ee87d864306a9dc8c6b4e4da40b nvme: allow passthru cmd error logging --- Traces --- [ 15.639835] BUG: Kernel NULL pointer dereference on read at 0x03d8 [ 15.639840] Faulting instruction address: 0xc008215b01dc [ 15.639845] Oops: Kernel access of bad area, sig: 11 [#1] [ 15.639849] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=8192 NUMA pSeries [ 15.639855] Modules linked in: xsk_diag bonding tls nft_compat nf_tables nfnetlink rfkill binfmt_misc dm_multipath dm_mod pseries_rng dax_pmem drm drm_panel_orientation_quirks ext4 mbcache jbd2 ibmvfc nd_pmem nd_btt scsi_transport_fc ibmveth nvme papr_scm bnx2x nvme_core t10_pi vmx_crypto libnvdimm crc64_rocksoft_generic crc64_rocksoft mdio crc64 libcrc32c fuse [ 15.639901] CPU: 1 PID: 3289 Comm: udevadm Not tainted 6.8.0-rc3-auto-g99bd3cb0d12e #1 [ 15.639907] Hardware name: IBM,9009-42A POWER9 (raw) 0x4e0202 0xf05 of:IBM,FW950.A0 (VL950_141) hv:phyp pSeries [ 15.639913] NIP: c008215b01dc LR: c0a197bc CTR: c008215b01b8 [ 15.639918] REGS: c0006f3177f0 TRAP: 0300 Not tainted (6.8.0-rc3-auto-g99bd3cb0d12e) [ 15.639923] MSR: 80009033 CR: 84888480 XER: 2004 [ 15.639936] CFAR: c000dbbc DAR: 03d8 DSISR: 4000 IRQMASK: 0 [ 15.639936] GPR00: c0a197bc c0006f317a90 c008215d8200 c0009281 [ 15.639936] GPR04: c008215d2570 c0009281 c0009282 [ 15.639936] GPR08: c0009281 0001 22888482 [ 15.639936] GPR12: c008215b01b8 cf8cf300 [ 15.639936] GPR16: 0001 [ 15.639936] GPR20: 00400cc0 c00086d14c28 7fff [ 15.639936] GPR24: f000 c00086d14c18 0001 [ 15.639936] GPR28: c0007509c180 c5bc1448 c008215d2570 c00086d14bf0 [ 15.63] NIP [c008215b01dc] nvme_io_passthru_err_log_enabled_show+0x24/0x80 [nvme_core] [ 15.640013] LR [c0a197bc] dev_attr_show+0x40/0xac [ 15.640020] Call Trace: [ 15.640023] [c0006f317a90] [c0006f317b10] 0xc0006f317b10 (unreliable) [ 15.640030] [c0006f317af0] [c0a197bc] dev_attr_show+0x40/0xac [ 15.640037] [c0006f317b60] [c06c11a0] sysfs_kf_seq_show+0xcc/0x1f0 [ 15.640045] [c0006f317bf0] [c06be224] kernfs_seq_show+0x44/0x58 [ 15.640052] [c0006f317c10] [c060882c] seq_read_iter+0x254/0x69c [ 15.640060] [c0006f317cf0] [c06bed60] kernfs_fop_read_iter+0x4c/0x60 [ 15.640067] [c0006f317d10] [c05bf61c] vfs_read+0x2bc/0x390 [ 15.640074] [c0006f317dc0] [c05c040c] ksys_read+0x84/0x144 [ 15.640081] [c0006f317e10] [c0033358] system_call_exception+0x138/0x330 [ 15.640088] [c0006f317e50] [c000d05c] system_call_vectored_common+0x15c/0x2ec [ 15.640096] --- interrupt: 3000 at 0x7fff87d342e4 [ 15.640101] NIP: 7fff87d342e4 LR: CTR: [ 15.640106] REGS: c0006f317e80 TRAP: 3000 Not tainted (6.8.0-rc3-auto-g99bd3cb0d12e) [ 15.640110] MSR: 8280f033 CR: 42884482 XER: [ 15.640126] IRQMASK: 0 [ 15.640126] GPR00: 0003 7fffea617e80 7fff87e47200 0003 [ 15.640126] GPR04: 010009494f20 00010008 7fff87e40e18 0100094a4f20 [ 15.640126] GPR08: 00010008 [ 15.640126] GPR12: 7fff88434ba0 [ 15.640126] GPR16: 00013e082f48 7fffea618290 7fffea617ee8 [ 15.640126] GPR20: 003e 7fffea618108 7fffea618110 8000 [ 15.640126] GPR24: 0002 003e [ 15.640126] GPR28: 00010007 00010008 010009494f20 0003 [ 15.640185] NIP [7fff87d342e4] 0x7fff87d342e4 [ 15.640189] LR [] 0x0 [ 15.640193] --- interrupt: 3000 [ 15.640196] Code: e8410018 00028048 3c4c0003 38428048 7c0802a6 6000 7c0802a6 f8010010 f821ffa1 e9230078 7ca32b78 <892903d8> 2c09 4082002c 3d22 [ 15.640217] ---[ end trace ]--- -- Regards, Tasmiya Nalatwad IBM Linux Technology Center
[PATCH v3 6/6] net: wan: fsl_qmc_hdlc: Add framer support
Add framer support in the fsl_qmc_hdlc driver in order to be able to signal carrier changes to the network stack based on the framer status Also use this framer to provide information related to the E1/T1 line interface on IF_GET_IFACE and configure the line interface according to IF_IFACE_{E1,T1} information. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/net/wan/fsl_qmc_hdlc.c | 239 - 1 file changed, 235 insertions(+), 4 deletions(-) diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c index b25d918d5e4e..432b5111b106 100644 --- a/drivers/net/wan/fsl_qmc_hdlc.c +++ b/drivers/net/wan/fsl_qmc_hdlc.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -28,6 +29,9 @@ struct qmc_hdlc { struct device *dev; struct qmc_chan *qmc_chan; struct net_device *netdev; + struct framer *framer; + spinlock_t carrier_lock; /* Protect carrier detection */ + struct notifier_block nb; bool is_crc32; spinlock_t tx_lock; /* Protect tx descriptors */ struct qmc_hdlc_desc tx_descs[8]; @@ -41,6 +45,195 @@ static struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev) return dev_to_hdlc(netdev)->priv; } +static int qmc_hdlc_framer_set_carrier(struct qmc_hdlc *qmc_hdlc) +{ + struct framer_status framer_status; + unsigned long flags; + int ret; + + if (!qmc_hdlc->framer) + return 0; + + spin_lock_irqsave(&qmc_hdlc->carrier_lock, flags); + + ret = framer_get_status(qmc_hdlc->framer, &framer_status); + if (ret) { + dev_err(qmc_hdlc->dev, "get framer status failed (%d)\n", ret); + goto end; + } + if (framer_status.link_is_on) + netif_carrier_on(qmc_hdlc->netdev); + else + netif_carrier_off(qmc_hdlc->netdev); + +end: + spin_unlock_irqrestore(&qmc_hdlc->carrier_lock, flags); + return ret; +} + +static int qmc_hdlc_framer_notifier(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct qmc_hdlc *qmc_hdlc = container_of(nb, struct qmc_hdlc, nb); + int ret; + + if (action != FRAMER_EVENT_STATUS) + return NOTIFY_DONE; + + ret = qmc_hdlc_framer_set_carrier(qmc_hdlc); + return ret ? NOTIFY_DONE : NOTIFY_OK; +} + +static int qmc_hdlc_framer_start(struct qmc_hdlc *qmc_hdlc) +{ + struct framer_status framer_status; + int ret; + + if (!qmc_hdlc->framer) + return 0; + + ret = framer_power_on(qmc_hdlc->framer); + if (ret) { + dev_err(qmc_hdlc->dev, "framer power-on failed (%d)\n", ret); + return ret; + } + + /* Be sure that get_status is supported */ + ret = framer_get_status(qmc_hdlc->framer, &framer_status); + if (ret) { + dev_err(qmc_hdlc->dev, "get framer status failed (%d)\n", ret); + goto framer_power_off; + } + + qmc_hdlc->nb.notifier_call = qmc_hdlc_framer_notifier; + ret = framer_notifier_register(qmc_hdlc->framer, &qmc_hdlc->nb); + if (ret) { + dev_err(qmc_hdlc->dev, "framer notifier register failed (%d)\n", ret); + goto framer_power_off; + } + + return 0; + +framer_power_off: + framer_power_off(qmc_hdlc->framer); + return ret; +} + +static void qmc_hdlc_framer_stop(struct qmc_hdlc *qmc_hdlc) +{ + if (!qmc_hdlc->framer) + return; + + framer_notifier_unregister(qmc_hdlc->framer, &qmc_hdlc->nb); + framer_power_off(qmc_hdlc->framer); +} + +static int qmc_hdlc_framer_set_iface(struct qmc_hdlc *qmc_hdlc, int if_iface, +const te1_settings *te1) +{ + struct framer_config config; + int ret; + + if (!qmc_hdlc->framer) + return 0; + + ret = framer_get_config(qmc_hdlc->framer, &config); + if (ret) + return ret; + + switch (if_iface) { + case IF_IFACE_E1: + config.iface = FRAMER_IFACE_E1; + break; + case IF_IFACE_T1: + config.iface = FRAMER_IFACE_T1; + break; + default: + return -EINVAL; + } + + switch (te1->clock_type) { + case CLOCK_DEFAULT: + /* Keep current value */ + break; + case CLOCK_EXT: + config.clock_type = FRAMER_CLOCK_EXT; + break; + case CLOCK_INT: + config.clock_type = FRAMER_CLOCK_INT; + break; + default: + return -EINVAL; + } + config.line_clock_rate = te1->clock_rate; + + return framer_set_config(qmc_hdlc->framer, &config); +} + +static int qmc_hdlc_framer_get_iface(struct qmc_hdlc *qmc_hdlc, int *if_iface, te1_settings *te1) +{ +
[PATCH v3 1/6] net: wan: Add support for QMC HDLC
The QMC HDLC driver provides support for HDLC using the QMC (QUICC Multichannel Controller) to transfer the HDLC data. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy Acked-by: Jakub Kicinski --- drivers/net/wan/Kconfig| 12 + drivers/net/wan/Makefile | 1 + drivers/net/wan/fsl_qmc_hdlc.c | 426 + 3 files changed, 439 insertions(+) create mode 100644 drivers/net/wan/fsl_qmc_hdlc.c diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 7dda87756d3f..31ab2136cdf1 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig @@ -197,6 +197,18 @@ config FARSYNC To compile this driver as a module, choose M here: the module will be called farsync. +config FSL_QMC_HDLC + tristate "Freescale QMC HDLC support" + depends on HDLC + depends on CPM_QMC + help + HDLC support using the Freescale QUICC Multichannel Controller (QMC). + + To compile this driver as a module, choose M here: the + module will be called fsl_qmc_hdlc. + + If unsure, say N. + config FSL_UCC_HDLC tristate "Freescale QUICC Engine HDLC support" depends on HDLC diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile index 8119b49d1da9..00e9b7ee1e01 100644 --- a/drivers/net/wan/Makefile +++ b/drivers/net/wan/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_WANXL) += wanxl.o obj-$(CONFIG_PCI200SYN)+= pci200syn.o obj-$(CONFIG_PC300TOO) += pc300too.o obj-$(CONFIG_IXP4XX_HSS) += ixp4xx_hss.o +obj-$(CONFIG_FSL_QMC_HDLC) += fsl_qmc_hdlc.o obj-$(CONFIG_FSL_UCC_HDLC) += fsl_ucc_hdlc.o obj-$(CONFIG_SLIC_DS26522) += slic_ds26522.o diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c new file mode 100644 index ..835500910d1b --- /dev/null +++ b/drivers/net/wan/fsl_qmc_hdlc.c @@ -0,0 +1,426 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Freescale QMC HDLC Device Driver + * + * Copyright 2023 CS GROUP France + * + * Author: Herve Codina + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct qmc_hdlc_desc { + struct net_device *netdev; + struct sk_buff *skb; /* NULL if the descriptor is not in use */ + dma_addr_t dma_addr; + size_t dma_size; +}; + +struct qmc_hdlc { + struct device *dev; + struct qmc_chan *qmc_chan; + struct net_device *netdev; + bool is_crc32; + spinlock_t tx_lock; /* Protect tx descriptors */ + struct qmc_hdlc_desc tx_descs[8]; + unsigned int tx_out; + struct qmc_hdlc_desc rx_descs[4]; +}; + +static struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev) +{ + return dev_to_hdlc(netdev)->priv; +} + +static int qmc_hdlc_recv_queue(struct qmc_hdlc *qmc_hdlc, struct qmc_hdlc_desc *desc, size_t size); + +#define QMC_HDLC_RX_ERROR_FLAGS (QMC_RX_FLAG_HDLC_OVF | \ +QMC_RX_FLAG_HDLC_UNA | \ +QMC_RX_FLAG_HDLC_ABORT | \ +QMC_RX_FLAG_HDLC_CRC) + +static void qmc_hcld_recv_complete(void *context, size_t length, unsigned int flags) +{ + struct qmc_hdlc_desc *desc = context; + struct net_device *netdev = desc->netdev; + struct qmc_hdlc *qmc_hdlc = netdev_to_qmc_hdlc(netdev); + int ret; + + dma_unmap_single(qmc_hdlc->dev, desc->dma_addr, desc->dma_size, DMA_FROM_DEVICE); + + if (flags & QMC_HDLC_RX_ERROR_FLAGS) { + netdev->stats.rx_errors++; + if (flags & QMC_RX_FLAG_HDLC_OVF) /* Data overflow */ + netdev->stats.rx_over_errors++; + if (flags & QMC_RX_FLAG_HDLC_UNA) /* bits received not multiple of 8 */ + netdev->stats.rx_frame_errors++; + if (flags & QMC_RX_FLAG_HDLC_ABORT) /* Received an abort sequence */ + netdev->stats.rx_frame_errors++; + if (flags & QMC_RX_FLAG_HDLC_CRC) /* CRC error */ + netdev->stats.rx_crc_errors++; + kfree_skb(desc->skb); + } else { + netdev->stats.rx_packets++; + netdev->stats.rx_bytes += length; + + skb_put(desc->skb, length); + desc->skb->protocol = hdlc_type_trans(desc->skb, netdev); + netif_rx(desc->skb); + } + + /* Re-queue a transfer using the same descriptor */ + ret = qmc_hdlc_recv_queue(qmc_hdlc, desc, desc->dma_size); + if (ret) { + dev_err(qmc_hdlc->dev, "queue recv desc failed (%d)\n", ret); + netdev->stats.rx_errors++; + } +} + +static int qmc_hdlc_recv_queue(struct qmc_hdlc *qmc_hdlc, struct qmc_hdlc_desc *desc, size_t size) +{ + int ret; + + desc->skb = dev_alloc_skb(size); + if (!desc->skb) + return -ENOMEM; + + desc->dma_size = size;
[PATCH v3 2/6] MAINTAINERS: Add the Freescale QMC HDLC driver entry
After contributing the driver, add myself as the maintainer for the Freescale QMC HDLC driver. Signed-off-by: Herve Codina --- MAINTAINERS | 7 +++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8d1052fa6a69..15cd3a8e5866 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8584,6 +8584,13 @@ F: Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml F: drivers/soc/fsl/qe/qmc.c F: include/soc/fsl/qe/qmc.h +FREESCALE QUICC ENGINE QMC HDLC DRIVER +M: Herve Codina +L: net...@vger.kernel.org +L: linuxppc-dev@lists.ozlabs.org +S: Maintained +F: drivers/net/wan/fsl_qmc_hdlc.c + FREESCALE QUICC ENGINE TSA DRIVER M: Herve Codina L: linuxppc-dev@lists.ozlabs.org -- 2.43.0
[PATCH v3 5/6] net: wan: fsl_qmc_hdlc: Add runtime timeslots changes support
QMC channels support runtime timeslots changes but nothing is done at the QMC HDLC driver to handle these changes. Use existing IFACE ioctl in order to configure the timeslots to use. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy Acked-by: Jakub Kicinski --- drivers/net/wan/fsl_qmc_hdlc.c | 152 - 1 file changed, 151 insertions(+), 1 deletion(-) diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c index 835500910d1b..b25d918d5e4e 100644 --- a/drivers/net/wan/fsl_qmc_hdlc.c +++ b/drivers/net/wan/fsl_qmc_hdlc.c @@ -7,6 +7,7 @@ * Author: Herve Codina */ +#include #include #include #include @@ -32,6 +33,7 @@ struct qmc_hdlc { struct qmc_hdlc_desc tx_descs[8]; unsigned int tx_out; struct qmc_hdlc_desc rx_descs[4]; + u32 slot_map; }; static struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev) @@ -206,6 +208,144 @@ static netdev_tx_t qmc_hdlc_xmit(struct sk_buff *skb, struct net_device *netdev) return ret; } +static int qmc_hdlc_xlate_slot_map(struct qmc_hdlc *qmc_hdlc, + u32 slot_map, struct qmc_chan_ts_info *ts_info) +{ + DECLARE_BITMAP(ts_mask_avail, 64); + DECLARE_BITMAP(ts_mask, 64); + DECLARE_BITMAP(map, 64); + + /* Tx and Rx available masks must be identical */ + if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) { + dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch (0x%llx, 0x%llx)\n", + ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail); + return -EINVAL; + } + + bitmap_from_u64(ts_mask_avail, ts_info->rx_ts_mask_avail); + bitmap_from_u64(map, slot_map); + bitmap_onto(ts_mask, map, ts_mask_avail, 64); + + if (bitmap_weight(ts_mask, 64) != bitmap_weight(map, 64)) { + dev_err(qmc_hdlc->dev, "Cannot translate timeslots %*pb -> (%*pb, %*pb)\n", + 64, map, 64, ts_mask_avail, 64, ts_mask); + return -EINVAL; + } + + bitmap_to_arr64(&ts_info->tx_ts_mask, ts_mask, 64); + ts_info->rx_ts_mask = ts_info->tx_ts_mask; + return 0; +} + +static int qmc_hdlc_xlate_ts_info(struct qmc_hdlc *qmc_hdlc, + const struct qmc_chan_ts_info *ts_info, u32 *slot_map) +{ + DECLARE_BITMAP(ts_mask_avail, 64); + DECLARE_BITMAP(ts_mask, 64); + DECLARE_BITMAP(map, 64); + u32 array32[2]; + + /* Tx and Rx masks and available masks must be identical */ + if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) { + dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch (0x%llx, 0x%llx)\n", + ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail); + return -EINVAL; + } + if (ts_info->rx_ts_mask != ts_info->tx_ts_mask) { + dev_err(qmc_hdlc->dev, "tx and rx timeslots mismatch (0x%llx, 0x%llx)\n", + ts_info->rx_ts_mask, ts_info->tx_ts_mask); + return -EINVAL; + } + + bitmap_from_u64(ts_mask_avail, ts_info->rx_ts_mask_avail); + bitmap_from_u64(ts_mask, ts_info->rx_ts_mask); + bitmap_off(map, ts_mask, ts_mask_avail, 64); + + if (bitmap_weight(ts_mask, 64) != bitmap_weight(map, 64)) { + dev_err(qmc_hdlc->dev, "Cannot translate timeslots (%*pb, %*pb) -> %*pb\n", + 64, ts_mask_avail, 64, ts_mask, 64, map); + return -EINVAL; + } + + bitmap_to_arr32(array32, map, 64); + if (array32[1]) { + dev_err(qmc_hdlc->dev, "Slot map out of 32bit (%*pb, %*pb) -> %*pb\n", + 64, ts_mask_avail, 64, ts_mask, 64, map); + return -EINVAL; + } + + *slot_map = array32[0]; + return 0; +} + +static int qmc_hdlc_set_iface(struct qmc_hdlc *qmc_hdlc, int if_iface, const te1_settings *te1) +{ + struct qmc_chan_ts_info ts_info; + int ret; + + ret = qmc_chan_get_ts_info(qmc_hdlc->qmc_chan, &ts_info); + if (ret) { + dev_err(qmc_hdlc->dev, "get QMC channel ts info failed %d\n", ret); + return ret; + } + ret = qmc_hdlc_xlate_slot_map(qmc_hdlc, te1->slot_map, &ts_info); + if (ret) + return ret; + + ret = qmc_chan_set_ts_info(qmc_hdlc->qmc_chan, &ts_info); + if (ret) { + dev_err(qmc_hdlc->dev, "set QMC channel ts info failed %d\n", ret); + return ret; + } + + qmc_hdlc->slot_map = te1->slot_map; + + return 0; +} + +static int qmc_hdlc_ioctl(struct net_device *netdev, struct if_settings *ifs) +{ + struct qmc_hdlc *qmc_hdlc = netdev_to_qmc_hdlc(netdev); + te1_settings te1; + + switch (ifs->type) { + case IF_GET_IFACE: + ifs->type = IF_IFACE_E1; + if (ifs->size
[PATCH v3 0/6] Add support for QMC HDLC
Hi, This series introduces the QMC HDLC support. Patches were previously sent as part of a full feature series and were previously reviewed in that context: "Add support for QMC HDLC, framer infrastructure and PEF2256 framer" [1] In order to ease the merge, the full feature series has been split and needed parts were merged in v6.8-rc1: - "Prepare the PowerQUICC QMC and TSA for the HDLC QMC driver" [2] - "Add support for framer infrastructure and PEF2256 framer" [3] This series contains patches related to the QMC HDLC part (QMC HDLC driver): - Introduce the QMC HDLC driver (patches 1 and 2) - Add timeslots change support in QMC HDLC (patch 3) - Add framer support as a framer consumer in QMC HDLC (patch 4) Compare to the original full feature series, a modification was done on patch 3 in order to use a coherent prefix in the commit title. I kept the patches unsquashed as they were previously sent and reviewed. Of course, I can squash them if needed. Compared to the previous iteration: https://lore.kernel.org/linux-kernel/20240130084035.115086-1-herve.cod...@bootlin.com/ this v3 series: - Remove 'inline' function specifier from .c file. - Fixed a bug introduced in the previous iteration. - Remove one lock/unlock sequence in the QMC HDCL xmit path. - Use bitmap_from_u64(). Best regards, Hervé [1]: https://lore.kernel.org/linux-kernel/20231115144007.478111-1-herve.cod...@bootlin.com/ [2]: https://lore.kernel.org/linux-kernel/20231205152116.122512-1-herve.cod...@bootlin.com/ [3]: https://lore.kernel.org/linux-kernel/20231128132534.258459-1-herve.cod...@bootlin.com/ Changes v2 -> v3 - Patch 1 Remove 'inline' function specifier from .c file. Fix a bug introduced when added WARN_ONCE(). The warn condition must be desc->skb (descriptor used) instead of !desc->skb. Remove a lock/unlock section locking the entire qmc_hdlc_xmit() function. - Patch 5 Use bitmap_from_u64() everywhere instead of bitmap_from_arr32() and bitmap_from_arr64(). Changes v1 -> v2 - Patch 1 Use the same qmc_hdlc initialisation in qmc_hcld_recv_complete() than the one present in qmc_hcld_xmit_complete(). Use WARN_ONCE() - Patch 3 (new patch in v2) Make bitmap_onto() available to users - Patch 4 (new patch in v2) Introduce bitmap_off() - Patch 5 (patch 3 in v1) Use bitmap_*() functions - Patch 6 (patch 4 in v1) No changes Changes compare to the full feature series: - Patch 3 Use 'net: wan: fsl_qmc_hdlc:' as commit title prefix Patches extracted: - Patch 1 : full feature series patch 7 - Patch 2 : full feature series patch 8 - Patch 3 : full feature series patch 20 - Patch 4 : full feature series patch 27 Herve Codina (6): net: wan: Add support for QMC HDLC MAINTAINERS: Add the Freescale QMC HDLC driver entry bitmap: Make bitmap_onto() available to users bitmap: Introduce bitmap_off() net: wan: fsl_qmc_hdlc: Add runtime timeslots changes support net: wan: fsl_qmc_hdlc: Add framer support MAINTAINERS| 7 + drivers/net/wan/Kconfig| 12 + drivers/net/wan/Makefile | 1 + drivers/net/wan/fsl_qmc_hdlc.c | 807 + include/linux/bitmap.h | 3 + lib/bitmap.c | 45 +- 6 files changed, 874 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wan/fsl_qmc_hdlc.c -- 2.43.0
[PATCH v3 3/6] bitmap: Make bitmap_onto() available to users
Currently the bitmap_onto() is available only for CONFIG_NUMA=y case, while some users may benefit out of it and being independent to NUMA code. Make it available to users by moving out of ifdeffery and exporting for modules. Signed-off-by: Herve Codina --- lib/bitmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/bitmap.c b/lib/bitmap.c index 09522af227f1..2feccb5047dc 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -547,7 +547,6 @@ int bitmap_bitremap(int oldbit, const unsigned long *old, } EXPORT_SYMBOL(bitmap_bitremap); -#ifdef CONFIG_NUMA /** * bitmap_onto - translate one bitmap relative to another * @dst: resulting translated bitmap @@ -681,7 +680,9 @@ void bitmap_onto(unsigned long *dst, const unsigned long *orig, m++; } } +EXPORT_SYMBOL(bitmap_onto); +#ifdef CONFIG_NUMA /** * bitmap_fold - fold larger bitmap into smaller, modulo specified size * @dst: resulting smaller bitmap -- 2.43.0
[PATCH v3 4/6] bitmap: Introduce bitmap_off()
The bitmap_onto() function translates one bitmap relative to another but no function are present to perform the reverse translation. Introduce bitmap_off() to fill this hole. Signed-off-by: Herve Codina --- include/linux/bitmap.h | 3 +++ lib/bitmap.c | 42 ++ 2 files changed, 45 insertions(+) diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 99451431e4d6..5ecfcbbc91f4 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -65,6 +65,7 @@ struct device; * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src) * bitmap_bitremap(oldbit, old, new, nbits)newbit = map(old, new)(oldbit) * bitmap_onto(dst, orig, relmap, nbits) *dst = orig relative to relmap + * bitmap_off(dst, orig, relmap, nbits)*dst = bitmap_onto() reverse operation * bitmap_fold(dst, orig, sz, nbits) dst bits = orig bits mod sz * bitmap_parse(buf, buflen, dst, nbits) Parse bitmap dst from kernel buf * bitmap_parse_user(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf @@ -208,6 +209,8 @@ int bitmap_bitremap(int oldbit, const unsigned long *old, const unsigned long *new, int bits); void bitmap_onto(unsigned long *dst, const unsigned long *orig, const unsigned long *relmap, unsigned int bits); +void bitmap_off(unsigned long *dst, const unsigned long *orig, + const unsigned long *relmap, unsigned int bits); void bitmap_fold(unsigned long *dst, const unsigned long *orig, unsigned int sz, unsigned int nbits); diff --git a/lib/bitmap.c b/lib/bitmap.c index 2feccb5047dc..71343967335e 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -682,6 +682,48 @@ void bitmap_onto(unsigned long *dst, const unsigned long *orig, } EXPORT_SYMBOL(bitmap_onto); +/** + * bitmap_off - revert operation done by bitmap_onto() + * @dst: resulting translated bitmap + * @orig: original untranslated bitmap + * @relmap: bitmap relative to which translated + * @bits: number of bits in each of these bitmaps + * + * Suppose onto computed using bitmap_onto(onto, src, relmap, n) + * The operation bitmap_off(result, onto, relmap, n) leads to a + * result equal or equivalent to src. + * + * The result can be 'equivalent' because bitmap_onto() and + * bitmap_off() are not bijective. + * The result and src values are equivalent in that sense that a + * call to bitmap_onto(onto, src, relmap, n) and a call to + * bitmap_onto(onto, result, relmap, n) will lead to the same onto + * value. + * + * If either of @orig or @relmap is empty (no set bits), then @dst + * will be returned empty. + * + * All bits in @dst not set by the above rule are cleared. + */ +void bitmap_off(unsigned long *dst, const unsigned long *orig, + const unsigned long *relmap, unsigned int bits) +{ + unsigned int n, m; /* same meaning as in above comment */ + + if (dst == orig)/* following doesn't handle inplace mappings */ + return; + bitmap_zero(dst, bits); + + m = 0; + for_each_set_bit(n, relmap, bits) { + /* m == bitmap_pos_to_ord(relmap, n, bits) */ + if (test_bit(n, orig)) + set_bit(m, dst); + m++; + } +} +EXPORT_SYMBOL(bitmap_off); + #ifdef CONFIG_NUMA /** * bitmap_fold - fold larger bitmap into smaller, modulo specified size -- 2.43.0
[PATCH 4/4] PCI: Create helper to print TLP Header and Prefix Log
Add pcie_print_tlp_log() helper to print TLP Header and Prefix Log. Print End-End Prefixes only if they are non-zero. Consolidate the few places which currently print TLP using custom formatting. Signed-off-by: Ilpo Järvinen --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +-- drivers/pci/pci.c | 28 +++ drivers/pci/pcie/aer.c| 10 ++- drivers/pci/pcie/dpc.c| 5 +--- include/linux/aer.h | 2 ++ 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 6ce720726a1a..73eabf3215e5 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -11355,8 +11355,8 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, vf = FIELD_GET(0x7F, req_id); e_dev_err("VF %d has caused a PCIe error\n", vf); - e_dev_err("TLP: dw0: %8.8x\tdw1: %8.8x\tdw2: %8.8x\tdw3: %8.8x\n", - tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]); + pcie_print_tlp_log(pdev, &tlp_log, ""); + switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: device_id = IXGBE_82599_VF_DEVICE_ID; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 268a5b9f1dff..d7974d25ae44 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -1118,6 +1119,33 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2, } EXPORT_SYMBOL_GPL(pcie_read_tlp_log); +/** + * pcie_print_tlp_log - Print TLP Header / Prefix Log contents + * @dev: PCIe device + * @tlp_log: TLP Log structure + * @pfx: Internal string prefix (for indentation) + * + * Prints TLP Header and Prefix Log information held by @tlp_log. + */ +void pcie_print_tlp_log(const struct pci_dev *dev, + const struct pcie_tlp_log *tlp_log, const char *pfx) +{ + unsigned int i; + + pci_err(dev, "%sTLP Header: %#010x %#010x %#010x %#010x", + pfx, tlp_log->dw[0], tlp_log->dw[1], tlp_log->dw[2], tlp_log->dw[3]); + + if (tlp_log->prefix[0]) + pr_cont(" E-E Prefixes:"); + for (i = 0; i < ARRAY_SIZE(tlp_log->prefix); i++) { + if (!tlp_log->prefix[i]) + break; + pr_cont(" %#010x", tlp_log->prefix[i]); + } + pr_cont("\n"); +} +EXPORT_SYMBOL_GPL(pcie_print_tlp_log); + /** * pci_restore_bars - restore a device's BAR values (e.g. after wake-up) * @dev: PCI device to have its BARs restored diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index ecc1dea5a208..efb9e728fe94 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -664,12 +664,6 @@ static void pci_rootport_aer_stats_incr(struct pci_dev *pdev, } } -static void __print_tlp_header(struct pci_dev *dev, struct pcie_tlp_log *t) -{ - pci_err(dev, " TLP Header: %08x %08x %08x %08x\n", - t->dw[0], t->dw[1], t->dw[2], t->dw[3]); -} - static void __aer_print_error(struct pci_dev *dev, struct aer_err_info *info) { @@ -724,7 +718,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) __aer_print_error(dev, info); if (info->tlp_header_valid) - __print_tlp_header(dev, &info->tlp); + pcie_print_tlp_log(dev, &info->tlp, " "); out: if (info->id && info->error_dev_num > 1 && info->id == id) @@ -796,7 +790,7 @@ void pci_print_aer(struct pci_dev *dev, int aer_severity, aer->uncor_severity); if (tlp_header_valid) - __print_tlp_header(dev, &aer->header_log); + pcie_print_tlp_log(dev, &aer->header_log, " "); trace_aer_event(dev_name(&dev->dev), (status & ~mask), aer_severity, tlp_header_valid, &aer->header_log); diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index f384d0b02aa0..9c93871fbe37 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c @@ -229,10 +229,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev) pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG, cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG, dpc_tlp_log_len(pdev), &tlp_log); - pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n", - tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]); - for (i = 0; i < pdev->dpc_rp_log_size - 5; i++) - pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, tlp_log.prefix[i]); + pcie_print_tlp_log(pdev, &tlp_log, ""); if (pdev->dpc_rp_log_size < 5) got
[PATCH 3/4] PCI: Add TLP Prefix reading into pcie_read_tlp_log()
pcie_read_tlp_log() handles only 4 TLP Header Log DWORDs but TLP Prefix Log (PCIe r6.1 secs 7.8.4.12 & 7.9.14.13) may also be present. Generalize pcie_read_tlp_log() and struct pcie_tlp_log to handle also TLP Prefix Log. The layout of relevant registers in AER and DPC Capability is not identical but the offsets of TLP Header Log and TLP Prefix Log vary so the callers must pass the offsets to pcie_read_tlp_log(). Convert eetlp_prefix_path into integer called eetlp_prefix_max and make is available also when CONFIG_PCI_PASID is not configured to be able to determine the number of E-E Prefixes. Signed-off-by: Ilpo Järvinen --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +- drivers/pci/ats.c | 2 +- drivers/pci/pci.c | 37 --- drivers/pci/pcie/aer.c| 4 +- drivers/pci/pcie/dpc.c| 22 +++ drivers/pci/probe.c | 14 --- include/linux/aer.h | 5 ++- include/linux/pci.h | 2 +- include/uapi/linux/pci_regs.h | 2 + 9 files changed, 69 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 5fdf37968b2d..6ce720726a1a 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -11336,7 +11336,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, if (!pos) goto skip_bad_vf_detection; - ret = pcie_read_tlp_log(pdev, pos + PCI_ERR_HEADER_LOG, &tlp_log); + ret = pcie_read_tlp_log(pdev, pos + PCI_ERR_HEADER_LOG, + pos + PCI_ERR_PREFIX_LOG, + aer_tlp_log_len(pdev), &tlp_log); if (ret < 0) { ixgbe_check_cfg_remove(hw, pdev); goto skip_bad_vf_detection; diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index c570892b2090..e13433dcfc82 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -377,7 +377,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features) if (WARN_ON(pdev->pasid_enabled)) return -EBUSY; - if (!pdev->eetlp_prefix_path && !pdev->pasid_no_tlp) + if (!pdev->eetlp_prefix_max && !pdev->pasid_no_tlp) return -EINVAL; if (!pasid) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0152f0144eec..268a5b9f1dff 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1068,23 +1068,48 @@ static void pci_enable_acs(struct pci_dev *dev) } /** - * pcie_read_tlp_log - Reads TLP Header Log + * aer_tlp_log_len - Calculates TLP Header/Prefix Log length + * @dev: PCIe device + * + * Return: TLP Header/Prefix Log length + */ +unsigned int aer_tlp_log_len(struct pci_dev *dev) +{ + return 4 + dev->eetlp_prefix_max; +} +EXPORT_SYMBOL_GPL(aer_tlp_log_len); + +/** + * pcie_read_tlp_log - Reads TLP Header and Prefix Log * @dev: PCIe device * @where: PCI Config offset of TLP Header Log + * @where2:PCI Config offset of TLP Prefix Log + * @tlp_len: TLP Log length (in DWORDs) * @tlp_log: TLP Log structure to fill * - * Fills @tlp_log from TLP Header Log registers. + * Fills @tlp_log from TLP Header and Prefix Log registers. * * Return: 0 on success and filled TLP Log structure, <0 on error. */ -int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log *tlp_log) +int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2, + unsigned int tlp_len, struct pcie_tlp_log *tlp_log) { - int i, ret; + unsigned int i; + int off, ret; + u32 *to; memset(tlp_log, 0, sizeof(*tlp_log)); - for (i = 0; i < 4; i++) { - ret = pci_read_config_dword(dev, where + i * 4, &tlp_log->dw[i]); + for (i = 0; i < tlp_len; i++) { + if (i < 4) { + to = &tlp_log->dw[i]; + off = where + i * 4; + } else { + to = &tlp_log->prefix[i - 4]; + off = where2 + (i - 4) * 4; + } + + ret = pci_read_config_dword(dev, off, to); if (ret) return pcibios_err_to_errno(ret); } diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index ac6293c24976..ecc1dea5a208 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -1245,7 +1245,9 @@ int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) if (info->status & AER_LOG_TLP_MASKS) { info->tlp_header_valid = 1; - pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, &info->tlp); + pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, +
[PATCH 2/4] PCI: Generalize TLP Header Log reading
Both AER and DPC RP PIO provide TLP Header Log registers (PCIe r6.1 secs 7.8.4 & 7.9.14) to convey error diagnostics but the struct is named after AER as the struct aer_header_log_regs. Also, not all places that handle TLP Header Log use the struct and the struct members are named individually. Generalize the struct name and members, and use it consistently where TLP Header Log is being handled so that a pcie_read_tlp_log() helper can be easily added. Signed-off-by: Ilpo Järvinen --- drivers/firmware/efi/cper.c | 4 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 37 +-- drivers/pci/pci.c | 26 + drivers/pci/pci.h | 2 +- drivers/pci/pcie/aer.c| 14 ++- drivers/pci/pcie/dpc.c| 14 ++- include/linux/aer.h | 11 +++--- include/ras/ras_event.h | 10 ++--- 8 files changed, 56 insertions(+), 62 deletions(-) diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index 35c37f667781..d3f98161171e 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -445,8 +445,8 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, printk("%saer_uncor_severity: 0x%08x\n", pfx, aer->uncor_severity); printk("%sTLP Header: %08x %08x %08x %08x\n", pfx, - aer->header_log.dw0, aer->header_log.dw1, - aer->header_log.dw2, aer->header_log.dw3); + aer->header_log.dw[0], aer->header_log.dw[1], + aer->header_log.dw[2], aer->header_log.dw[3]); } } diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index bd541527c8c7..5fdf37968b2d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright(c) 1999 - 2018 Intel Corporation. */ +#include #include #include #include @@ -391,22 +392,6 @@ u16 ixgbe_read_pci_cfg_word(struct ixgbe_hw *hw, u32 reg) return value; } -#ifdef CONFIG_PCI_IOV -static u32 ixgbe_read_pci_cfg_dword(struct ixgbe_hw *hw, u32 reg) -{ - struct ixgbe_adapter *adapter = hw->back; - u32 value; - - if (ixgbe_removed(hw->hw_addr)) - return IXGBE_FAILED_READ_CFG_DWORD; - pci_read_config_dword(adapter->pdev, reg, &value); - if (value == IXGBE_FAILED_READ_CFG_DWORD && - ixgbe_check_cfg_remove(hw, adapter->pdev)) - return IXGBE_FAILED_READ_CFG_DWORD; - return value; -} -#endif /* CONFIG_PCI_IOV */ - void ixgbe_write_pci_cfg_word(struct ixgbe_hw *hw, u32 reg, u16 value) { struct ixgbe_adapter *adapter = hw->back; @@ -11332,8 +11317,8 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, #ifdef CONFIG_PCI_IOV struct ixgbe_hw *hw = &adapter->hw; struct pci_dev *bdev, *vfdev; - u32 dw0, dw1, dw2, dw3; - int vf, pos; + struct pcie_tlp_log tlp_log; + int vf, pos, ret; u16 req_id, pf_func; if (adapter->hw.mac.type == ixgbe_mac_82598EB || @@ -11351,14 +11336,13 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, if (!pos) goto skip_bad_vf_detection; - dw0 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG); - dw1 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 4); - dw2 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 8); - dw3 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 12); - if (ixgbe_removed(hw->hw_addr)) + ret = pcie_read_tlp_log(pdev, pos + PCI_ERR_HEADER_LOG, &tlp_log); + if (ret < 0) { + ixgbe_check_cfg_remove(hw, pdev); goto skip_bad_vf_detection; + } - req_id = dw1 >> 16; + req_id = tlp_log.dw[1] >> 16; /* On the 82599 if bit 7 of the requestor ID is set then it's a VF */ if (!(req_id & 0x0080)) goto skip_bad_vf_detection; @@ -11369,9 +11353,8 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, vf = FIELD_GET(0x7F, req_id); e_dev_err("VF %d has caused a PCIe error\n", vf); - e_dev_err("TLP: dw0: %8.8x\tdw1: %8.8x\tdw2: " - "%8.8x\tdw3: %8.8x\n", - dw0, dw1, dw2, dw3); + e_dev_err("TLP: dw0: %8.8x\tdw1: %8.8x\tdw2: %8.8x\tdw3: %8.8x\n", + tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]); switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: device_id = IXGBE_82599_VF_DEVICE_ID; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d8f
[PATCH 1/4] PCI/AER: Cleanup register variable
Use u32 for PCIe Capability register variable and name it aercc (Advanced Error Capabilities and Control register, PCIe r6.1 sec 7.8.4.7) instead of temp. Signed-off-by: Ilpo Järvinen --- drivers/pci/pcie/aer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index 05fc30bb5134..e31e6a9a7773 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -1210,7 +1210,7 @@ int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) { int type = pci_pcie_type(dev); int aer = dev->aer_cap; - int temp; + u32 aercc; /* Must reset in this function */ info->status = 0; @@ -1241,8 +1241,8 @@ int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) return 0; /* Get First Error Pointer */ - pci_read_config_dword(dev, aer + PCI_ERR_CAP, &temp); - info->first_error = PCI_ERR_CAP_FEP(temp); + pci_read_config_dword(dev, aer + PCI_ERR_CAP, &aercc); + info->first_error = PCI_ERR_CAP_FEP(aercc); if (info->status & AER_LOG_TLP_MASKS) { info->tlp_header_valid = 1; -- 2.39.2
[PATCH 0/4] PCI: Consolidate TLP Log reading and printing
This series consolidates AER & DPC TLP Log handling code. Helpers are added for reading and printing the TLP Log and the format is made to include E-E Prefixes in both cases (previously only one DPC RP PIO displayed the E-E Prefixes). I'd appreciate if people familiar with ixgbe could check the error handling conversion within the driver is correct. Ilpo Järvinen (4): PCI/AER: Cleanup register variable PCI: Generalize TLP Header Log reading PCI: Add TLP Prefix reading into pcie_read_tlp_log() PCI: Create helper to print TLP Header and Prefix Log drivers/firmware/efi/cper.c | 4 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 39 +++-- drivers/pci/ats.c | 2 +- drivers/pci/pci.c | 79 +++ drivers/pci/pci.h | 2 +- drivers/pci/pcie/aer.c| 28 ++- drivers/pci/pcie/dpc.c| 31 drivers/pci/probe.c | 14 ++-- include/linux/aer.h | 16 ++-- include/linux/pci.h | 2 +- include/ras/ras_event.h | 10 +-- include/uapi/linux/pci_regs.h | 2 + 12 files changed, 145 insertions(+), 84 deletions(-) -- 2.39.2
[powerpc:fixes-test] BUILD SUCCESS 4a7aee96200ad281a5cc4cf5c7a2e2a49d2b97b0
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git fixes-test branch HEAD: 4a7aee96200ad281a5cc4cf5c7a2e2a49d2b97b0 powerpc/kasan: Fix addr error caused by page alignment elapsed time: 1451m configs tested: 224 configs skipped: 3 The following configs have been built successfully. More configs may be tested in the coming days. tested configs: alpha allnoconfig gcc alphaallyesconfig gcc alpha defconfig gcc arc allmodconfig gcc arc allnoconfig gcc arc allyesconfig gcc arc defconfig gcc arc haps_hs_smp_defconfig gcc arcnsimosci_defconfig gcc arc randconfig-001-20240206 gcc arc randconfig-002-20240206 gcc arc tb10x_defconfig gcc arm allmodconfig gcc arm allnoconfig clang arm allyesconfig gcc arm bcm2835_defconfig clang arm collie_defconfig gcc arm defconfig clang armmmp2_defconfig gcc armmvebu_v5_defconfig gcc arm mxs_defconfig clang arm netwinder_defconfig gcc arm randconfig-002-20240206 gcc arm randconfig-003-20240206 gcc arm tegra_defconfig gcc arm64allmodconfig clang arm64 allnoconfig gcc arm64 defconfig gcc arm64 randconfig-001-20240206 gcc arm64 randconfig-003-20240206 gcc arm64 randconfig-004-20240206 gcc csky allmodconfig gcc csky allnoconfig gcc csky allyesconfig gcc cskydefconfig gcc csky randconfig-001-20240206 gcc csky randconfig-002-20240206 gcc hexagon allmodconfig clang hexagon allnoconfig clang hexagon allyesconfig clang hexagon defconfig clang i386 allmodconfig gcc i386 allnoconfig gcc i386 allyesconfig gcc i386 buildonly-randconfig-001-20240205 clang i386 buildonly-randconfig-002-20240205 clang i386 buildonly-randconfig-003-20240205 clang i386 buildonly-randconfig-003-20240206 gcc i386 buildonly-randconfig-004-20240205 clang i386 buildonly-randconfig-005-20240205 clang i386 buildonly-randconfig-005-20240206 gcc i386 buildonly-randconfig-006-20240205 clang i386 buildonly-randconfig-006-20240206 gcc i386defconfig clang i386 randconfig-001-20240205 clang i386 randconfig-002-20240205 clang i386 randconfig-003-20240205 clang i386 randconfig-004-20240205 gcc i386 randconfig-005-20240205 clang i386 randconfig-006-20240205 gcc i386 randconfig-011-20240205 gcc i386 randconfig-012-20240205 clang i386 randconfig-012-20240206 gcc i386 randconfig-013-20240205 gcc i386 randconfig-014-20240205 gcc i386 randconfig-014-20240206 gcc i386 randconfig-015-20240205 clang i386 randconfig-015-20240206 gcc i386 randconfig-016-20240205 gcc i386 randconfig-016-20240206 gcc loongarchallmodconfig gcc loongarch allnoconfig gcc loongarchallyesconfig gcc loongarch defconfig gcc loongarch randconfig-001-20240206 gcc loongarch randconfig-002-20240206 gcc m68k allmodconfig gcc m68k allnoconfig gcc m68k allyesconfig gcc m68k atari_defconfig gcc m68kdefconfig gcc m68km5407c3_defconfig gcc m68kmac_defconfig gcc m68kmvme16x_defconfig gcc microblaze allmodconfig gcc microblaze
Re: [PATCH v3] KVM: PPC: Book3S HV: Fix L2 guest reboot failure due to empty 'arch_compat'
Hi Amit, One comment below ... Amit Machhiwal writes: > Currently, rebooting a pseries nested qemu-kvm guest (L2) results in > below error as L1 qemu sends PVR value 'arch_compat' == 0 via > ppc_set_compat ioctl. This triggers a condition failure in > kvmppc_set_arch_compat() resulting in an EINVAL. ... > > diff --git a/arch/powerpc/kvm/book3s_hv_nestedv2.c > b/arch/powerpc/kvm/book3s_hv_nestedv2.c > index 5378eb40b162..6042bdc70230 100644 > --- a/arch/powerpc/kvm/book3s_hv_nestedv2.c > +++ b/arch/powerpc/kvm/book3s_hv_nestedv2.c > @@ -347,8 +348,26 @@ static int gs_msg_ops_vcpu_fill_info(struct > kvmppc_gs_buff *gsb, > break; > } > case KVMPPC_GSID_LOGICAL_PVR: > - rc = kvmppc_gse_put_u32(gsb, iden, > - vcpu->arch.vcore->arch_compat); > + /* > + * Though 'arch_compat == 0' would mean the default > + * compatibility, arch_compat, being a Guest Wide > + * Element, cannot be filled with a value of 0 in GSB > + * as this would result into a kernel trap. > + * Hence, when `arch_compat == 0`, arch_compat should > + * default to L1's PVR. > + * > + * Rework this when PowerVM supports a value of 0 > + * for arch_compat for KVM API v2. > + */ Is there an actual plan that PowerVM will support this in future? If so, how will a future kernel know that it's running on a version of PowerVM that does support arch_compat == 0? Similarly how will we know when it's OK to drop support for this workaround? cheers