From a4d68c56e188a6a8a701951bf62a418eed2d5c5f Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Aug 28 2020 15:47:53 +0000 Subject: Merge branch 'SLE12-SP5' (ebf69d7bc6a7) into 'SLE12-SP5-RT' - Modified -rt patches patches.rt/0262-net-move-xmit_recursion-to-per-task-variable-on-RT.patch --- diff --git a/blacklist.conf b/blacklist.conf index 8eb25d4..0af94ae 100644 --- a/blacklist.conf +++ b/blacklist.conf @@ -1606,3 +1606,9 @@ f29aa08852e1953e461f2d47ab13c34e14bc08b3 # Duplicate of 35f760b44b1b9cb16a306bdc a2bdd0c904da12b223c8d7218e98138d4e6d9f4f # Documentation 37b4100180641968056cb4e034cebc38338e8652 # Duplicate of d41f36a6464a85c06ad920703d878e4491d2c023 c4b4c2a78a9fc0c532c58504e8cb5441224ff1d9 # Breaks KABI for wb_reason and the dangling reason is harmless +7ef282e05132d56b6f6b71e3873f317664bea78b # cleanup only, not critical +96b4833b6827a62c295b149213c68b559514c929 # CONFIG_HWLAT_TRACER is not set anywhere +5f987caec521cbb00d4ba2dc641ac8074626b762 # Inapplicable on 4.12 - #ifdef not in the fadump code +41040cf7c5f0f26c368bc5d3016fed3a9ca6dba4 # No big-endian platform supported +d071fd294f2474118629f4021a6a3dedef28e09f # Cosmetic +2f0af8600e82e9f950fc32908386b9c639f88d48 # Applied in perf package diff --git a/patches.kabi/genetlink-remove-genl_bind.patch b/patches.kabi/genetlink-remove-genl_bind.patch new file mode 100644 index 0000000..1767d70 --- /dev/null +++ b/patches.kabi/genetlink-remove-genl_bind.patch @@ -0,0 +1,28 @@ +From: Jiri Slaby +Subject: kABI: genetlink: remove genl_bind +Patch-mainline: never, kabi +References: kabi + +In networking-stable-20_07_17, commit 1e82a62fec61 (genetlink: remove +genl_bind) removed 2 members from struct genl_family. This made the kABI +checker complaining. + +Reintroduce the members as placeholders. + +Signed-off-by: Jiri Slaby +--- + include/net/genetlink.h | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/include/net/genetlink.h ++++ b/include/net/genetlink.h +@@ -55,6 +55,9 @@ struct genl_family { + void (*post_doit)(const struct genl_ops *ops, + struct sk_buff *skb, + struct genl_info *info); ++ /* these 2 are kABI placeholders */ ++ int (*mcast_bind)(struct net *net, int group); ++ void (*mcast_unbind)(struct net *net, int group); + struct nlattr ** attrbuf; /* private */ + const struct genl_ops * ops; + const struct genl_multicast_group *mcgrps; diff --git a/patches.rt/0262-net-move-xmit_recursion-to-per-task-variable-on-RT.patch b/patches.rt/0262-net-move-xmit_recursion-to-per-task-variable-on-RT.patch index 95a1284..30aeab6 100644 --- a/patches.rt/0262-net-move-xmit_recursion-to-per-task-variable-on-RT.patch +++ b/patches.rt/0262-net-move-xmit_recursion-to-per-task-variable-on-RT.patch @@ -28,12 +28,12 @@ Signed-off-by: Mike Galbraith --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -2612,14 +2612,53 @@ void netdev_freemem(struct net_device *d +@@ -2617,14 +2617,53 @@ void netdev_freemem(struct net_device *d void synchronize_net(void); int init_dummy_netdev(struct net_device *dev); -DECLARE_PER_CPU(int, xmit_recursion); - #define XMIT_RECURSION_LIMIT 10 + #define XMIT_RECURSION_LIMIT 8 +#ifdef CONFIG_PREEMPT_RT_FULL +static inline int dev_recursion_level(void) +{ @@ -85,7 +85,7 @@ Signed-off-by: Mike Galbraith struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1085,6 +1085,9 @@ struct task_struct { +@@ -1093,6 +1093,9 @@ struct task_struct { #ifdef CONFIG_DEBUG_ATOMIC_SLEEP unsigned long task_state_change; #endif @@ -97,7 +97,7 @@ Signed-off-by: Mike Galbraith struct task_struct *oom_reaper_list; --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -3492,8 +3492,10 @@ static void skb_update_prio(struct sk_bu +@@ -3494,8 +3494,10 @@ static void skb_update_prio(struct sk_bu #define skb_update_prio(skb) #endif @@ -108,7 +108,7 @@ Signed-off-by: Mike Galbraith /** * dev_loopback_xmit - loop back @skb -@@ -3785,8 +3787,7 @@ static int __dev_queue_xmit(struct sk_bu +@@ -3787,8 +3789,7 @@ static int __dev_queue_xmit(struct sk_bu int cpu = smp_processor_id(); /* ok because BHs are off */ if (txq->xmit_lock_owner != cpu) { @@ -118,7 +118,7 @@ Signed-off-by: Mike Galbraith goto recursion_alert; skb = validate_xmit_skb(skb, dev, &again); -@@ -3796,9 +3797,9 @@ static int __dev_queue_xmit(struct sk_bu +@@ -3798,9 +3799,9 @@ static int __dev_queue_xmit(struct sk_bu HARD_TX_LOCK(dev, txq, cpu); if (!netif_xmit_stopped(txq)) { @@ -130,6 +130,21 @@ Signed-off-by: Mike Galbraith if (dev_xmit_complete(rc)) { HARD_TX_UNLOCK(dev, txq); goto out; +@@ -3883,12 +3883,12 @@ int dev_direct_xmit(struct sk_buff *skb, u16 queue_id) + + local_bh_disable(); + +- __this_cpu_inc(xmit_recursion); ++ xmit_rec_inc(); + HARD_TX_LOCK(dev, txq, smp_processor_id()); + if (!netif_xmit_frozen_or_drv_stopped(txq)) + ret = netdev_start_xmit(skb, dev, txq, false); + HARD_TX_UNLOCK(dev, txq); +- __this_cpu_dec(xmit_recursion); ++ xmit_rec_dec(); + + local_bh_enable(); + --- a/net/core/filter.c +++ b/net/core/filter.c @@ -1978,7 +1978,7 @@ static inline int __bpf_tx_skb(struct ne diff --git a/patches.suse/0016-arm64-vgic-v2-Fix-proxying-of-cpuif-access.patch b/patches.suse/0016-arm64-vgic-v2-Fix-proxying-of-cpuif-access.patch index e4e815f..a41be42 100644 --- a/patches.suse/0016-arm64-vgic-v2-Fix-proxying-of-cpuif-access.patch +++ b/patches.suse/0016-arm64-vgic-v2-Fix-proxying-of-cpuif-access.patch @@ -67,10 +67,10 @@ Signed-off-by: Mian Yousaf Kaukab + return !!(read_sysreg(SCTLR_EL1) & SCTLR_ELx_EE); +} + - static void __hyp_text save_elrsr(struct kvm_vcpu *vcpu, void __iomem *base) + static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base) { struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; -@@ -143,14 +152,19 @@ int __hyp_text __vgic_v2_perform_cpuif_a +@@ -129,14 +138,19 @@ int __hyp_text __vgic_v2_perform_cpuif_a addr += fault_ipa - vgic->vgic_cpu_base; if (kvm_vcpu_dabt_iswrite(vcpu)) { diff --git a/patches.suse/KVM-PPC-Book3S-PR-Remove-uninitialized_var-usage.patch b/patches.suse/KVM-PPC-Book3S-PR-Remove-uninitialized_var-usage.patch new file mode 100644 index 0000000..ec5dd93 --- /dev/null +++ b/patches.suse/KVM-PPC-Book3S-PR-Remove-uninitialized_var-usage.patch @@ -0,0 +1,46 @@ +From 1ef79040a57faa808416d6c7554babafbc34e69f Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Wed, 3 Jun 2020 13:28:45 -0700 +Subject: [PATCH] KVM: PPC: Book3S PR: Remove uninitialized_var() usage + +References: bsc#1065729 +Patch-mainline: v5.9-rc1 +Git-commit: 1ef79040a57faa808416d6c7554babafbc34e69f + +Using uninitialized_var() is dangerous as it papers over real bugs[1] +(or can in the future), and suppresses unrelated compiler warnings (e.g. +"unused variable"). If the compiler thinks it is uninitialized, either +simply initialize the variable or make compiler changes. As a precursor +to removing[2] this[3] macro[4], just remove this variable since it was +actually unused: + +arch/powerpc/kvm/book3s_pr.c:1832:16: warning: unused variable 'vrsave' [-Wunused-variable] + unsigned long vrsave; + ^ + +[1] https://lore.kernel.org/lkml/20200603174714.192027-1-glider@google.com/ +[2] https://lore.kernel.org/lkml/CA+55aFw+Vbj0i=1TGqCR5vQkCzWJ0QxK6CernOU6eedsudAixw@mail.gmail.com/ +[3] https://lore.kernel.org/lkml/CA+55aFwgbgqhbp1fkxvRKEpzyR5J8n1vKT1VZdz9knmPuXhOeg@mail.gmail.com/ +[4] https://lore.kernel.org/lkml/CA+55aFz2500WfbKXAx8s67wrm9=yVJu65TpLgN_ybYNv0VEOKA@mail.gmail.com/ + +Suggested-by: Nathan Chancellor +Fixes: f05ed4d56e9c ("KVM: PPC: Split out code from book3s.c into book3s_pr.c") +Reviewed-by: Nick Desaulniers +Signed-off-by: Kees Cook +Acked-by: Michal Suchanek +--- + arch/powerpc/kvm/book3s_pr.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/arch/powerpc/kvm/book3s_pr.c ++++ b/arch/powerpc/kvm/book3s_pr.c +@@ -1527,9 +1527,6 @@ static void kvmppc_core_vcpu_free_pr(str + static int kvmppc_vcpu_run_pr(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) + { + int ret; +-#ifdef CONFIG_ALTIVEC +- unsigned long uninitialized_var(vrsave); +-#endif + + /* Check if we can run the vcpu at all */ + if (!vcpu->arch.sane) { diff --git a/patches.suse/KVM-arm-arm64-Get-rid-of-vgic_elrsr.patch b/patches.suse/KVM-arm-arm64-Get-rid-of-vgic_elrsr.patch new file mode 100644 index 0000000..47a1fd7 --- /dev/null +++ b/patches.suse/KVM-arm-arm64-Get-rid-of-vgic_elrsr.patch @@ -0,0 +1,147 @@ +From: Christoffer Dall +Date: Thu, 5 Oct 2017 00:02:41 +0200 +Subject: KVM: arm/arm64: Get rid of vgic_elrsr +Patch-mainline: v4.17-rc1 +Git-commit: bb5ed7035918d265189e2623d71c8f458713d3e9 +References: bsc#1085308 CVE-2018-3639 + +There is really no need to store the vgic_elrsr on the VGIC data +structures as the only need we have for the elrsr is to figure out if an +LR is inactive when we save the VGIC state upon returning from the +guest. We can might as well store this in a temporary local variable. + +Reviewed-by: Marc Zyngier +Signed-off-by: Christoffer Dall +Signed-off-by: Marc Zyngier +Acked-by: Liang Yan +--- + include/kvm/arm_vgic.h | 4 ++-- + virt/kvm/arm/hyp/vgic-v2-sr.c | 28 +++++++--------------------- + virt/kvm/arm/hyp/vgic-v3-sr.c | 6 +++--- + virt/kvm/arm/vgic/vgic-v2.c | 1 - + virt/kvm/arm/vgic/vgic-v3.c | 1 - + 5 files changed, 12 insertions(+), 28 deletions(-) + +--- a/include/kvm/arm_vgic.h ++++ b/include/kvm/arm_vgic.h +@@ -252,7 +252,7 @@ struct vgic_dist { + struct vgic_v2_cpu_if { + u32 vgic_hcr; + u32 vgic_vmcr; +- u64 vgic_elrsr; /* Saved only */ ++ u64 vgic_elrsr; /* Keep it to avoid kabi break */ + u32 vgic_apr; + u32 vgic_lr[VGIC_V2_MAX_LRS]; + }; +@@ -260,8 +260,8 @@ struct vgic_v2_cpu_if { + struct vgic_v3_cpu_if { + u32 vgic_hcr; + u32 vgic_vmcr; ++ u64 vgic_elrsr; /* Keep it to avoid kabi break */ + u32 vgic_sre; /* Restored only, change ignored */ +- u32 vgic_elrsr; /* Saved only */ + u32 vgic_ap0r[4]; + u32 vgic_ap1r[4]; + u64 vgic_lr[VGIC_V3_MAX_LRS]; +--- a/virt/kvm/arm/hyp/vgic-v2-sr.c ++++ b/virt/kvm/arm/hyp/vgic-v2-sr.c +@@ -23,29 +23,19 @@ + #include + #include + +-static void __hyp_text save_elrsr(struct kvm_vcpu *vcpu, void __iomem *base) +-{ +- struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; +- int nr_lr = (kern_hyp_va(&kvm_vgic_global_state))->nr_lr; +- u32 elrsr0, elrsr1; +- +- elrsr0 = readl_relaxed(base + GICH_ELRSR0); +- if (unlikely(nr_lr > 32)) +- elrsr1 = readl_relaxed(base + GICH_ELRSR1); +- else +- elrsr1 = 0; +- +- cpu_if->vgic_elrsr = ((u64)elrsr1 << 32) | elrsr0; +-} +- + static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base) + { + struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; +- int i; + u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs; ++ u64 elrsr; ++ int i; ++ ++ elrsr = readl_relaxed(base + GICH_ELRSR0); ++ if (unlikely(used_lrs > 32)) ++ elrsr |= ((u64)readl_relaxed(base + GICH_ELRSR1)) << 32; + + for (i = 0; i < used_lrs; i++) { +- if (cpu_if->vgic_elrsr & (1UL << i)) ++ if (elrsr & (1UL << i)) + cpu_if->vgic_lr[i] &= ~GICH_LR_STATE; + else + cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4)); +@@ -68,13 +58,9 @@ void __hyp_text __vgic_v2_save_state(str + + if (used_lrs) { + cpu_if->vgic_apr = readl_relaxed(base + GICH_APR); +- +- save_elrsr(vcpu, base); + save_lrs(vcpu, base); +- + writel_relaxed(0, base + GICH_HCR); + } else { +- cpu_if->vgic_elrsr = ~0UL; + cpu_if->vgic_apr = 0; + } + } +--- a/virt/kvm/arm/hyp/vgic-v3-sr.c ++++ b/virt/kvm/arm/hyp/vgic-v3-sr.c +@@ -223,15 +223,16 @@ void __hyp_text __vgic_v3_save_state(str + if (used_lrs) { + int i; + u32 nr_pre_bits; ++ u32 elrsr; + +- cpu_if->vgic_elrsr = read_gicreg(ICH_ELSR_EL2); ++ elrsr = read_gicreg(ICH_ELSR_EL2); + + write_gicreg(0, ICH_HCR_EL2); + val = read_gicreg(ICH_VTR_EL2); + nr_pre_bits = vtr_to_nr_pre_bits(val); + + for (i = 0; i < used_lrs; i++) { +- if (cpu_if->vgic_elrsr & (1 << i)) ++ if (elrsr & (1 << i)) + cpu_if->vgic_lr[i] &= ~ICH_LR_STATE; + else + cpu_if->vgic_lr[i] = __gic_v3_get_lr(i); +@@ -263,7 +264,6 @@ void __hyp_text __vgic_v3_save_state(str + cpu_if->its_vpe.its_vm) + write_gicreg(0, ICH_HCR_EL2); + +- cpu_if->vgic_elrsr = 0xffff; + cpu_if->vgic_ap0r[0] = 0; + cpu_if->vgic_ap0r[1] = 0; + cpu_if->vgic_ap0r[2] = 0; +--- a/virt/kvm/arm/vgic/vgic-v2.c ++++ b/virt/kvm/arm/vgic/vgic-v2.c +@@ -236,7 +236,6 @@ void vgic_v2_enable(struct kvm_vcpu *vcp + * anyway. + */ + vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0; +- vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr = ~0; + + /* Get the show on the road... */ + vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN; +--- a/virt/kvm/arm/vgic/vgic-v3.c ++++ b/virt/kvm/arm/vgic/vgic-v3.c +@@ -238,7 +238,6 @@ void vgic_v3_enable(struct kvm_vcpu *vcp + * anyway. + */ + vgic_v3->vgic_vmcr = 0; +- vgic_v3->vgic_elrsr = ~0; + + /* + * If we are emulating a GICv3, we do it in an non-GICv2-compatible diff --git a/patches.suse/KVM-arm-arm64-Handle-VGICv2-save-restore-from-the-ma.patch b/patches.suse/KVM-arm-arm64-Handle-VGICv2-save-restore-from-the-ma.patch new file mode 100644 index 0000000..51cc325 --- /dev/null +++ b/patches.suse/KVM-arm-arm64-Handle-VGICv2-save-restore-from-the-ma.patch @@ -0,0 +1,211 @@ +From: Christoffer Dall +Date: Thu, 22 Dec 2016 20:39:10 +0100 +Subject: KVM: arm/arm64: Handle VGICv2 save/restore from the main VGIC code +Patch-mainline: v4.17-rc1 +Git-commit: 75174ba6ca9dcfddda88aa420da4d7aa2b279fdf +References: bsc#1085308 CVE-2018-3639 + +We can program the GICv2 hypervisor control interface logic directly +from the core vgic code and can instead do the save/restore directly +from the flush/sync functions, which can lead to a number of future +optimizations. + +Signed-off-by: Christoffer Dall +Signed-off-by: Marc Zyngier +Acked-by: Liang Yan +--- + arch/arm/kvm/hyp/switch.c | 4 -- + arch/arm64/include/asm/kvm_hyp.h | 2 - + arch/arm64/kvm/hyp/switch.c | 4 -- + virt/kvm/arm/vgic/vgic-v2.c | 63 +++++++++++++++++++++++++++++++++++++++ + virt/kvm/arm/vgic/vgic.c | 19 +++++++++++ + virt/kvm/arm/vgic/vgic.h | 3 + + 6 files changed, 84 insertions(+), 11 deletions(-) + +--- a/arch/arm/kvm/hyp/switch.c ++++ b/arch/arm/kvm/hyp/switch.c +@@ -92,16 +92,12 @@ static void __hyp_text __vgic_save_state + { + if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) + __vgic_v3_save_state(vcpu); +- else +- __vgic_v2_save_state(vcpu); + } + + static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu) + { + if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) + __vgic_v3_restore_state(vcpu); +- else +- __vgic_v2_restore_state(vcpu); + } + + static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu) +--- a/arch/arm64/include/asm/kvm_hyp.h ++++ b/arch/arm64/include/asm/kvm_hyp.h +@@ -120,8 +120,6 @@ typeof(orig) * __hyp_text fname(void) + return val; \ + } + +-void __vgic_v2_save_state(struct kvm_vcpu *vcpu); +-void __vgic_v2_restore_state(struct kvm_vcpu *vcpu); + int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu); + + void __vgic_v3_save_state(struct kvm_vcpu *vcpu); +--- a/arch/arm64/kvm/hyp/switch.c ++++ b/arch/arm64/kvm/hyp/switch.c +@@ -171,8 +171,6 @@ static void __hyp_text __vgic_save_state + { + if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) + __vgic_v3_save_state(vcpu); +- else +- __vgic_v2_save_state(vcpu); + + write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2); + } +@@ -188,8 +186,6 @@ static void __hyp_text __vgic_restore_st + + if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) + __vgic_v3_restore_state(vcpu); +- else +- __vgic_v2_restore_state(vcpu); + } + + static bool __hyp_text __true_value(void) +--- a/virt/kvm/arm/vgic/vgic-v2.c ++++ b/virt/kvm/arm/vgic/vgic-v2.c +@@ -392,6 +392,69 @@ out: + return ret; + } + ++static void save_lrs(struct kvm_vcpu *vcpu, void __iomem *base) ++{ ++ struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; ++ u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs; ++ u64 elrsr; ++ int i; ++ ++ elrsr = readl_relaxed(base + GICH_ELRSR0); ++ if (unlikely(used_lrs > 32)) ++ elrsr |= ((u64)readl_relaxed(base + GICH_ELRSR1)) << 32; ++ ++ for (i = 0; i < used_lrs; i++) { ++ if (elrsr & (1UL << i)) ++ cpu_if->vgic_lr[i] &= ~GICH_LR_STATE; ++ else ++ cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4)); ++ ++ writel_relaxed(0, base + GICH_LR0 + (i * 4)); ++ } ++} ++ ++void vgic_v2_save_state(struct kvm_vcpu *vcpu) ++{ ++ struct kvm *kvm = vcpu->kvm; ++ struct vgic_dist *vgic = &kvm->arch.vgic; ++ struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; ++ void __iomem *base = vgic->vctrl_base; ++ u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs; ++ ++ if (!base) ++ return; ++ ++ if (used_lrs) { ++ cpu_if->vgic_apr = readl_relaxed(base + GICH_APR); ++ save_lrs(vcpu, base); ++ writel_relaxed(0, base + GICH_HCR); ++ } else { ++ cpu_if->vgic_apr = 0; ++ } ++} ++ ++void vgic_v2_restore_state(struct kvm_vcpu *vcpu) ++{ ++ struct kvm *kvm = vcpu->kvm; ++ struct vgic_dist *vgic = &kvm->arch.vgic; ++ struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; ++ void __iomem *base = vgic->vctrl_base; ++ u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs; ++ int i; ++ ++ if (!base) ++ return; ++ ++ if (used_lrs) { ++ writel_relaxed(cpu_if->vgic_hcr, base + GICH_HCR); ++ writel_relaxed(cpu_if->vgic_apr, base + GICH_APR); ++ for (i = 0; i < used_lrs; i++) { ++ writel_relaxed(cpu_if->vgic_lr[i], ++ base + GICH_LR0 + (i * 4)); ++ } ++ } ++} ++ + void vgic_v2_load(struct kvm_vcpu *vcpu) + { + struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; +--- a/virt/kvm/arm/vgic/vgic.c ++++ b/virt/kvm/arm/vgic/vgic.c +@@ -714,11 +714,19 @@ next: + vgic_clear_lr(vcpu, count); + } + ++static inline void vgic_save_state(struct kvm_vcpu *vcpu) ++{ ++ if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) ++ vgic_v2_save_state(vcpu); ++} ++ + /* Sync back the hardware VGIC state into our emulation after a guest's run. */ + void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) + { + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + ++ vgic_save_state(vcpu); ++ + WARN_ON(vgic_v4_sync_hwstate(vcpu)); + + /* An empty ap_list_head implies used_lrs == 0 */ +@@ -730,6 +738,12 @@ void kvm_vgic_sync_hwstate(struct kvm_vc + vgic_prune_ap_list(vcpu); + } + ++static inline void vgic_restore_state(struct kvm_vcpu *vcpu) ++{ ++ if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) ++ vgic_v2_restore_state(vcpu); ++} ++ + /* Flush our emulation state into the GIC hardware before entering the guest. */ + void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) + { +@@ -745,13 +759,16 @@ void kvm_vgic_flush_hwstate(struct kvm_v + * this. + */ + if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head)) +- return; ++ goto out; + + DEBUG_SPINLOCK_BUG_ON(!irqs_disabled()); + + spin_lock(&vcpu->arch.vgic_cpu.ap_list_lock); + vgic_flush_lr_state(vcpu); + spin_unlock(&vcpu->arch.vgic_cpu.ap_list_lock); ++ ++out: ++ vgic_restore_state(vcpu); + } + + void kvm_vgic_load(struct kvm_vcpu *vcpu) +--- a/virt/kvm/arm/vgic/vgic.h ++++ b/virt/kvm/arm/vgic/vgic.h +@@ -169,6 +169,9 @@ void vgic_v2_init_lrs(void); + void vgic_v2_load(struct kvm_vcpu *vcpu); + void vgic_v2_put(struct kvm_vcpu *vcpu); + ++void vgic_v2_save_state(struct kvm_vcpu *vcpu); ++void vgic_v2_restore_state(struct kvm_vcpu *vcpu); ++ + static inline void vgic_get_irq_kref(struct vgic_irq *irq) + { + if (irq->intid < VGIC_MIN_LPI) diff --git a/patches.suse/KVM-arm-arm64-Move-arm64-only-vgic-v2-sr.c-file-to-a.patch b/patches.suse/KVM-arm-arm64-Move-arm64-only-vgic-v2-sr.c-file-to-a.patch index 64fd9e8..46dfc22 100644 --- a/patches.suse/KVM-arm-arm64-Move-arm64-only-vgic-v2-sr.c-file-to-a.patch +++ b/patches.suse/KVM-arm-arm64-Move-arm64-only-vgic-v2-sr.c-file-to-a.patch @@ -22,9 +22,9 @@ Acked-by: Liang Yan --- arch/arm/kvm/hyp/Makefile | 1 arch/arm64/kvm/hyp/Makefile | 2 - arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c | 157 ++++++++++++++++++++++++++++++ - virt/kvm/arm/hyp/vgic-v2-sr.c | 159 ------------------------------- - 4 files changed, 158 insertions(+), 161 deletions(-) + arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c | 143 ++++++++++++++++++++++++++++++ + virt/kvm/arm/hyp/vgic-v2-sr.c | 145 ------------------------------- + 4 files changed, 144 insertions(+), 147 deletions(-) rename virt/kvm/arm/hyp/vgic-v2-sr.c => arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c (98%) --- a/arch/arm/kvm/hyp/Makefile @@ -53,7 +53,7 @@ Acked-by: Liang Yan obj-$(CONFIG_KVM_ARM_HOST) += entry.o --- /dev/null +++ b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c -@@ -0,0 +1,157 @@ +@@ -0,0 +1,143 @@ +/* + * Copyright (C) 2012-2015 - ARM Ltd + * Author: Marc Zyngier @@ -79,29 +79,19 @@ Acked-by: Liang Yan +#include +#include + -+static void __hyp_text save_elrsr(struct kvm_vcpu *vcpu, void __iomem *base) -+{ -+ struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; -+ int nr_lr = (kern_hyp_va(&kvm_vgic_global_state))->nr_lr; -+ u32 elrsr0, elrsr1; -+ -+ elrsr0 = readl_relaxed(base + GICH_ELRSR0); -+ if (unlikely(nr_lr > 32)) -+ elrsr1 = readl_relaxed(base + GICH_ELRSR1); -+ else -+ elrsr1 = 0; -+ -+ cpu_if->vgic_elrsr = ((u64)elrsr1 << 32) | elrsr0; -+} -+ +static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base) +{ + struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; -+ int i; + u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs; ++ u64 elrsr; ++ int i; ++ ++ elrsr = readl_relaxed(base + GICH_ELRSR0); ++ if (unlikely(used_lrs > 32)) ++ elrsr |= ((u64)readl_relaxed(base + GICH_ELRSR1)) << 32; + + for (i = 0; i < used_lrs; i++) { -+ if (cpu_if->vgic_elrsr & (1UL << i)) ++ if (elrsr & (1UL << i)) + cpu_if->vgic_lr[i] &= ~GICH_LR_STATE; + else + cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4)); @@ -124,13 +114,9 @@ Acked-by: Liang Yan + + if (used_lrs) { + cpu_if->vgic_apr = readl_relaxed(base + GICH_APR); -+ -+ save_elrsr(vcpu, base); + save_lrs(vcpu, base); -+ + writel_relaxed(0, base + GICH_HCR); + } else { -+ cpu_if->vgic_elrsr = ~0UL; + cpu_if->vgic_apr = 0; + } +} @@ -213,7 +199,7 @@ Acked-by: Liang Yan +} --- a/virt/kvm/arm/hyp/vgic-v2-sr.c +++ /dev/null -@@ -1,159 +0,0 @@ +@@ -1,145 +0,0 @@ -/* - * Copyright (C) 2012-2015 - ARM Ltd - * Author: Marc Zyngier @@ -239,29 +225,19 @@ Acked-by: Liang Yan -#include -#include - --static void __hyp_text save_elrsr(struct kvm_vcpu *vcpu, void __iomem *base) --{ -- struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; -- int nr_lr = (kern_hyp_va(&kvm_vgic_global_state))->nr_lr; -- u32 elrsr0, elrsr1; -- -- elrsr0 = readl_relaxed(base + GICH_ELRSR0); -- if (unlikely(nr_lr > 32)) -- elrsr1 = readl_relaxed(base + GICH_ELRSR1); -- else -- elrsr1 = 0; -- -- cpu_if->vgic_elrsr = ((u64)elrsr1 << 32) | elrsr0; --} -- -static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base) -{ - struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; -- int i; - u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs; +- u64 elrsr; +- int i; +- +- elrsr = readl_relaxed(base + GICH_ELRSR0); +- if (unlikely(used_lrs > 32)) +- elrsr |= ((u64)readl_relaxed(base + GICH_ELRSR1)) << 32; - - for (i = 0; i < used_lrs; i++) { -- if (cpu_if->vgic_elrsr & (1UL << i)) +- if (elrsr & (1UL << i)) - cpu_if->vgic_lr[i] &= ~GICH_LR_STATE; - else - cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4)); @@ -284,13 +260,9 @@ Acked-by: Liang Yan - - if (used_lrs) { - cpu_if->vgic_apr = readl_relaxed(base + GICH_APR); -- -- save_elrsr(vcpu, base); - save_lrs(vcpu, base); -- - writel_relaxed(0, base + GICH_HCR); - } else { -- cpu_if->vgic_elrsr = ~0UL; - cpu_if->vgic_apr = 0; - } -} diff --git a/patches.suse/PCI-dwc-Fix-find_next_bit-usage.patch b/patches.suse/PCI-dwc-Fix-find_next_bit-usage.patch index fd28095..d734b16 100644 --- a/patches.suse/PCI-dwc-Fix-find_next_bit-usage.patch +++ b/patches.suse/PCI-dwc-Fix-find_next_bit-usage.patch @@ -27,7 +27,7 @@ Acked-by: Takashi Iwai --- a/drivers/pci/dwc/pcie-designware-host.c +++ b/drivers/pci/dwc/pcie-designware-host.c -@@ -56,20 +56,21 @@ static struct irq_chip dw_msi_irq_chip = +@@ -67,20 +67,21 @@ static struct irq_chip dw_msi_irq_chip = /* MSI int handler */ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) { @@ -53,4 +53,4 @@ Acked-by: Takashi Iwai + while ((pos = find_next_bit(&val, 32, pos)) != 32) { irq = irq_find_mapping(pp->irq_domain, i * 32 + pos); generic_handle_irq(irq); - dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, + pos++; diff --git a/patches.suse/PCI-dwc-Move-interrupt-acking-into-the-proper-callba.patch b/patches.suse/PCI-dwc-Move-interrupt-acking-into-the-proper-callba.patch new file mode 100644 index 0000000..a4621f4 --- /dev/null +++ b/patches.suse/PCI-dwc-Move-interrupt-acking-into-the-proper-callba.patch @@ -0,0 +1,79 @@ +From: Marc Zyngier +Date: Tue, 13 Nov 2018 22:57:34 +0000 +Subject: PCI: dwc: Move interrupt acking into the proper callback +References: bsc#1175666 + +Git-commit: 3f7bb2ec20ce07c02b2002349d256c91a463fcc5 +Patch-mainline: v4.14.96 + +commit 3f7bb2ec20ce07c02b2002349d256c91a463fcc5 upstream. + +The write to the status register is really an ACK for the HW, +and should be treated as such by the driver. Let's move it to the +irq_ack() callback, which will prevent people from moving it around +in order to paper over other bugs. + +Fixes: 8c934095fa2f ("PCI: dwc: Clear MSI interrupt status after it is handled, +not before") +Fixes: 7c5925afbc58 ("PCI: dwc: Move MSI IRQs allocation to IRQ domains +hierarchical API") +Link: https://lore.kernel.org/linux-pci/20181113225734.8026-1-marc.zyngier@arm.com/ +Reported-by: Trent Piepho +Tested-by: Niklas Cassel +Tested-by: Gustavo Pimentel +Tested-by: Stanimir Varbanov +Signed-off-by: Marc Zyngier +[lorenzo.pieralisi@arm.com: updated commit log] +Signed-off-by: Lorenzo Pieralisi +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/pci/dwc/pcie-designware-host.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c +index bc3e2d8d0cce..58b38c54a7cf 100644 +--- a/drivers/pci/dwc/pcie-designware-host.c ++++ b/drivers/pci/dwc/pcie-designware-host.c +@@ -45,8 +45,19 @@ static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size, + return dw_pcie_write(pci->dbi_base + where, size, val); + } + ++static void dwc_irq_ack(struct irq_data *d) ++{ ++ struct msi_desc *msi = irq_data_get_msi_desc(d); ++ struct pcie_port *pp = msi_desc_to_pci_sysdata(msi); ++ int pos = d->hwirq % 32; ++ int i = d->hwirq / 32; ++ ++ dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4, BIT(pos)); ++} ++ + static struct irq_chip dw_msi_irq_chip = { + .name = "PCI-MSI", ++ .irq_ack = dwc_irq_ack, + .irq_enable = pci_msi_unmask_irq, + .irq_disable = pci_msi_mask_irq, + .irq_mask = pci_msi_mask_irq, +@@ -72,8 +83,6 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) + pos)) != 32) { + irq = irq_find_mapping(pp->irq_domain, i * 32 + pos); + generic_handle_irq(irq); +- dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, +- 4, 1 << pos); + pos++; + } + } +@@ -263,7 +272,7 @@ static struct msi_controller dw_pcie_msi_chip = { + static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq, + irq_hw_number_t hwirq) + { +- irq_set_chip_and_handler(irq, &dw_msi_irq_chip, handle_simple_irq); ++ irq_set_chip_and_handler(irq, &dw_msi_irq_chip, handle_edge_irq); + irq_set_chip_data(irq, domain->host_data); + + return 0; +-- +2.26.2 + diff --git a/patches.suse/PM-devfreq-rk3399_dmc-Add-missing-of_node_put.patch b/patches.suse/PM-devfreq-rk3399_dmc-Add-missing-of_node_put.patch new file mode 100644 index 0000000..b2d5854 --- /dev/null +++ b/patches.suse/PM-devfreq-rk3399_dmc-Add-missing-of_node_put.patch @@ -0,0 +1,33 @@ +From: Yangtao Li +Date: Sat, 14 Dec 2019 18:11:30 +0000 +Subject: PM / devfreq: rk3399_dmc: Add missing of_node_put() + +Git-commit: 29d867e97f7d781972ed542acfca3c2c0b512603 +Patch-mainline: v5.6-rc1 +References: bsc#1175668 + +of_node_put() needs to be called when the device node which is got +from of_parse_phandle has finished using. + +Signed-off-by: Yangtao Li +Signed-off-by: Chanwoo Choi +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/devfreq/rk3399_dmc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c +index 2e65d7279d79..2f1027c5b647 100644 +--- a/drivers/devfreq/rk3399_dmc.c ++++ b/drivers/devfreq/rk3399_dmc.c +@@ -372,6 +372,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) + node = of_parse_phandle(np, "rockchip,pmu", 0); + if (node) { + data->regmap_pmu = syscon_node_to_regmap(node); ++ of_node_put(node); + if (IS_ERR(data->regmap_pmu)) + return PTR_ERR(data->regmap_pmu); + } +-- +2.26.2 + diff --git a/patches.suse/PM-devfreq-rk3399_dmc-Disable-devfreq-event-device-w.patch b/patches.suse/PM-devfreq-rk3399_dmc-Disable-devfreq-event-device-w.patch new file mode 100644 index 0000000..bf71901 --- /dev/null +++ b/patches.suse/PM-devfreq-rk3399_dmc-Disable-devfreq-event-device-w.patch @@ -0,0 +1,79 @@ +From: Yangtao Li +Date: Sun, 22 Dec 2019 17:41:31 +0000 +Subject: PM / devfreq: rk3399_dmc: Disable devfreq-event device when fails + + +Git-commit: 39a6e4739c19d5334e552d71ceca544ed84f4b87 +Patch-mainline: v5.6-rc1 +References: bsc#1175668 + +The probe process may fail, but the devfreq event device remains +enabled. Call devfreq_event_disable_edev on the error return path. + +Signed-off-by: Yangtao Li +Signed-off-by: Chanwoo Choi +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/devfreq/rk3399_dmc.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c +index 2f1027c5b647..24f04f78285b 100644 +--- a/drivers/devfreq/rk3399_dmc.c ++++ b/drivers/devfreq/rk3399_dmc.c +@@ -364,7 +364,8 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) + if (res.a0) { + dev_err(dev, "Failed to set dram param: %ld\n", + res.a0); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_edev; + } + } + } +@@ -373,8 +374,10 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) + if (node) { + data->regmap_pmu = syscon_node_to_regmap(node); + of_node_put(node); +- if (IS_ERR(data->regmap_pmu)) +- return PTR_ERR(data->regmap_pmu); ++ if (IS_ERR(data->regmap_pmu)) { ++ ret = PTR_ERR(data->regmap_pmu); ++ goto err_edev; ++ } + } + + regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val); +@@ -392,7 +395,8 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) + data->odt_dis_freq = data->timing.lpddr4_odt_dis_freq; + break; + default: +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_edev; + }; + + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0, +@@ -426,7 +430,8 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) + */ + if (dev_pm_opp_of_add_table(dev)) { + dev_err(dev, "Invalid operating-points in device tree.\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_edev; + } + + of_property_read_u32(np, "upthreshold", +@@ -466,6 +471,9 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) + + err_free_opp: + dev_pm_opp_of_remove_table(&pdev->dev); ++err_edev: ++ devfreq_event_disable_edev(data->edev); ++ + return ret; + } + +-- +2.26.2 + diff --git a/patches.suse/PM-devfreq-rk3399_dmc-Fix-kernel-oops-when-rockchip-.patch b/patches.suse/PM-devfreq-rk3399_dmc-Fix-kernel-oops-when-rockchip-.patch new file mode 100644 index 0000000..b5bc7e5 --- /dev/null +++ b/patches.suse/PM-devfreq-rk3399_dmc-Fix-kernel-oops-when-rockchip-.patch @@ -0,0 +1,100 @@ +From: Marc Zyngier +Date: Tue, 30 Jun 2020 11:05:46 +0100 +Subject: PM / devfreq: rk3399_dmc: Fix kernel oops when rockchip,pmu is absent +References: bsc#1175668 + +Git-commit: 63ef91f24f9bfc70b6446319f6cabfd094481372 +Patch-mainline: v5.9-rc1 + +Booting a recent kernel on a rk3399-based system (nanopc-t4), +equipped with a recent u-boot and ATF results in an Oops due +to a NULL pointer dereference. + +This turns out to be due to the rk3399-dmc driver looking for +an *undocumented* property (rockchip,pmu), and happily using +a NULL pointer when the property isn't there. + +Instead, make most of what was brought in with 9173c5ceb035 +("PM / devfreq: rk3399_dmc: Pass ODT and auto power down parameters +to TF-A.") conditioned on finding this property in the device-tree, +preventing the driver from exploding. + +Cc: stable@vger.kernel.org +Fixes: 9173c5ceb035 ("PM / devfreq: rk3399_dmc: Pass ODT and auto power down parameters to TF-A.") +Signed-off-by: Marc Zyngier +Signed-off-by: Chanwoo Choi +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/devfreq/rk3399_dmc.c | 42 ++++++++++++++++++++---------------- + 1 file changed, 23 insertions(+), 19 deletions(-) + +diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c +index 24f04f78285b..027769e39f9b 100644 +--- a/drivers/devfreq/rk3399_dmc.c ++++ b/drivers/devfreq/rk3399_dmc.c +@@ -95,18 +95,20 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq, + + mutex_lock(&dmcfreq->lock); + +- if (target_rate >= dmcfreq->odt_dis_freq) +- odt_enable = true; +- +- /* +- * This makes a SMC call to the TF-A to set the DDR PD (power-down) +- * timings and to enable or disable the ODT (on-die termination) +- * resistors. +- */ +- arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0, +- dmcfreq->odt_pd_arg1, +- ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD, +- odt_enable, 0, 0, 0, &res); ++ if (dmcfreq->regmap_pmu) { ++ if (target_rate >= dmcfreq->odt_dis_freq) ++ odt_enable = true; ++ ++ /* ++ * This makes a SMC call to the TF-A to set the DDR PD ++ * (power-down) timings and to enable or disable the ++ * ODT (on-die termination) resistors. ++ */ ++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0, ++ dmcfreq->odt_pd_arg1, ++ ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD, ++ odt_enable, 0, 0, 0, &res); ++ } + + /* + * If frequency scaling from low to high, adjust voltage first. +@@ -371,13 +373,14 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) + } + + node = of_parse_phandle(np, "rockchip,pmu", 0); +- if (node) { +- data->regmap_pmu = syscon_node_to_regmap(node); +- of_node_put(node); +- if (IS_ERR(data->regmap_pmu)) { +- ret = PTR_ERR(data->regmap_pmu); +- goto err_edev; +- } ++ if (!node) ++ goto no_pmu; ++ ++ data->regmap_pmu = syscon_node_to_regmap(node); ++ of_node_put(node); ++ if (IS_ERR(data->regmap_pmu)) { ++ ret = PTR_ERR(data->regmap_pmu); ++ goto err_edev; + } + + regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val); +@@ -399,6 +402,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) + goto err_edev; + }; + ++no_pmu: + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0, + ROCKCHIP_SIP_CONFIG_DRAM_INIT, + 0, 0, 0, 0, &res); +-- +2.26.2 + diff --git a/patches.suse/arm64-KVM-Add-ARCH_WORKAROUND_2-support-for-guests.patch b/patches.suse/arm64-KVM-Add-ARCH_WORKAROUND_2-support-for-guests.patch index 95c7bec..8746d55 100644 --- a/patches.suse/arm64-KVM-Add-ARCH_WORKAROUND_2-support-for-guests.patch +++ b/patches.suse/arm64-KVM-Add-ARCH_WORKAROUND_2-support-for-guests.patch @@ -23,9 +23,9 @@ Acked-by: Liang Yan arch/arm64/include/asm/kvm_asm.h | 3 +++ arch/arm64/include/asm/kvm_host.h | 3 +++ arch/arm64/include/asm/kvm_mmu.h | 24 ++++++++++++++++++++++++ - arch/arm64/kvm/hyp/switch.c | 34 ++++++++++++++++++++++++++++++++++ + arch/arm64/kvm/hyp/switch.c | 38 ++++++++++++++++++++++++++++++++++++++ virt/kvm/arm/arm.c | 4 ++++ - 6 files changed, 73 insertions(+) + 6 files changed, 77 insertions(+) --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h @@ -108,8 +108,8 @@ Acked-by: Liang Yan #include #include #include -@@ -425,6 +426,39 @@ again: - return exit_code; +@@ -300,6 +301,39 @@ static bool __hyp_text __skip_instr(stru + } } +static inline bool __hyp_text __needs_ssbd_off(struct kvm_vcpu *vcpu) @@ -145,9 +145,27 @@ Acked-by: Liang Yan +#endif +} + - static const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n"; + int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) + { + struct kvm_cpu_context *host_ctxt; +@@ -330,6 +364,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm + __sysreg_restore_guest_state(guest_ctxt); + __debug_restore_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt); + ++ __set_guest_arch_workaround_state(vcpu); ++ + /* Jump in the fire! */ + again: + exit_code = __guest_enter(vcpu, host_ctxt); +@@ -398,6 +434,8 @@ again: + /* 0 falls through to be handled out of EL2 */ + } + ++ __set_host_arch_workaround_state(vcpu); ++ + fp_enabled = __fpsimd_enabled(); - static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par, + __sysreg_save_guest_state(guest_ctxt); --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -1439,6 +1439,10 @@ static int init_hyp_mode(void) diff --git a/patches.suse/arm64-ssbs-Fix-context-switch-when-SSBS-is-present-o.patch b/patches.suse/arm64-ssbs-Fix-context-switch-when-SSBS-is-present-o.patch new file mode 100644 index 0000000..563a764 --- /dev/null +++ b/patches.suse/arm64-ssbs-Fix-context-switch-when-SSBS-is-present-o.patch @@ -0,0 +1,49 @@ +From: Will Deacon +Date: Thu, 6 Feb 2020 10:42:58 +0000 +Subject: arm64: ssbs: Fix context-switch when SSBS is present on all CPUs +References: bsc#1175669 + +Git-commit: fca3d33d8ad61eb53eca3ee4cac476d1e31b9008 +Patch-mainline: v5.6-rc2 + +When all CPUs in the system implement the SSBS extension, the SSBS field +in PSTATE is the definitive indication of the mitigation state. Further, +when the CPUs implement the SSBS manipulation instructions (advertised +to userspace via an HWCAP), EL0 can toggle the SSBS field directly and +so we cannot rely on any shadow state such as TIF_SSBD at all. + +Avoid forcing the SSBS field in context-switch on such a system, and +simply rely on the PSTATE register instead. + +Cc: +Cc: Catalin Marinas +Cc: Srinivas Ramana +Fixes: cbdf8a189a66 ("arm64: Force SSBS on context switch") +Reviewed-by: Marc Zyngier +Signed-off-by: Will Deacon +Signed-off-by: Mian Yousaf Kaukab +--- + arch/arm64/kernel/process.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c +index a480b6760808..00626057a384 100644 +--- a/arch/arm64/kernel/process.c ++++ b/arch/arm64/kernel/process.c +@@ -466,6 +466,13 @@ static void ssbs_thread_switch(struct task_struct *next) + if (unlikely(next->flags & PF_KTHREAD)) + return; + ++ /* ++ * If all CPUs implement the SSBS extension, then we just need to ++ * context-switch the PSTATE field. ++ */ ++ if (cpu_have_feature(cpu_feature(SSBS))) ++ return; ++ + /* If the mitigation is enabled, then we leave SSBS clear. */ + if ((arm64_get_ssbd_state() == ARM64_SSBD_FORCE_ENABLE) || + test_tsk_thread_flag(next, TIF_SSBD)) +-- +2.26.2 + diff --git a/patches.suse/dlm-Fix-kobject-memleak.patch b/patches.suse/dlm-Fix-kobject-memleak.patch new file mode 100644 index 0000000..e0a3f7b --- /dev/null +++ b/patches.suse/dlm-Fix-kobject-memleak.patch @@ -0,0 +1,52 @@ +From 0ffddafc3a3970ef7013696e7f36b3d378bc4c16 Mon Sep 17 00:00:00 2001 +From: Wang Hai +Date: Mon, 15 Jun 2020 11:25:33 +0800 +Subject: [PATCH] dlm: Fix kobject memleak +Git-commit: 0ffddafc3a3970ef7013696e7f36b3d378bc4c16 +Patch-mainline: v5.9-rc1 +References: bsc#1175768 + +Currently the error return path from kobject_init_and_add() is not +followed by a call to kobject_put() - which means we are leaking +the kobject. + +Set do_unreg = 1 before kobject_init_and_add() to ensure that +kobject_put() can be called in its error patch. + +Fixes: 901195ed7f4b ("Kobject: change GFS2 to use kobject_init_and_add") +Reported-by: Hulk Robot +Signed-off-by: Wang Hai +Signed-off-by: David Teigland +Acked-by: Jan Kara + +--- + fs/dlm/lockspace.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c +index e93670ecfae5..624617c12250 100644 +--- a/fs/dlm/lockspace.c ++++ b/fs/dlm/lockspace.c +@@ -622,6 +622,9 @@ static int new_lockspace(const char *name, const char *cluster, + wait_event(ls->ls_recover_lock_wait, + test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags)); + ++ /* let kobject handle freeing of ls if there's an error */ ++ do_unreg = 1; ++ + ls->ls_kobj.kset = dlm_kset; + error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL, + "%s", ls->ls_name); +@@ -629,9 +632,6 @@ static int new_lockspace(const char *name, const char *cluster, + goto out_recoverd; + kobject_uevent(&ls->ls_kobj, KOBJ_ADD); + +- /* let kobject handle freeing of ls if there's an error */ +- do_unreg = 1; +- + /* This uevent triggers dlm_controld in userspace to add us to the + group of nodes that are members of this lockspace (managed by the + cluster infrastructure.) Once it's done that, it tells us who the +-- +2.16.4 + diff --git a/patches.suse/dpaa_eth-FMan-erratum-A050385-workaround.patch b/patches.suse/dpaa_eth-FMan-erratum-A050385-workaround.patch new file mode 100644 index 0000000..bd9f341 --- /dev/null +++ b/patches.suse/dpaa_eth-FMan-erratum-A050385-workaround.patch @@ -0,0 +1,252 @@ +From: Madalin Bucur +Date: Wed, 4 Mar 2020 18:04:28 +0200 +Subject: dpaa_eth: FMan erratum A050385 workaround + +Git-commit: 3c68b8fffb48c0018c24e73c48f2bac768c6203e +Patch-mainline: v5.6-rc6 +References: bsc#1174550 + +Align buffers, data start, SG fragment length to avoid DMA splits. +These changes prevent the A050385 erratum to manifest itself: + +FMAN DMA read or writes under heavy traffic load may cause FMAN +internal resource leak; thus stopping further packet processing. + +The FMAN internal queue can overflow when FMAN splits single +read or write transactions into multiple smaller transactions +such that more than 17 AXI transactions are in flight from FMAN +to interconnect. When the FMAN internal queue overflows, it can +stall further packet processing. The issue can occur with any one +of the following three conditions: + + 1. FMAN AXI transaction crosses 4K address boundary (Errata + A010022) + 2. FMAN DMA address for an AXI transaction is not 16 byte + aligned, i.e. the last 4 bits of an address are non-zero + 3. Scatter Gather (SG) frames have more than one SG buffer in + the SG list and any one of the buffers, except the last + buffer in the SG list has data size that is not a multiple + of 16 bytes, i.e., other than 16, 32, 48, 64, etc. + +With any one of the above three conditions present, there is +likelihood of stalled FMAN packet processing, especially under +stress with multiple ports injecting line-rate traffic. + +To avoid situations that stall FMAN packet processing, all of the +above three conditions must be avoided; therefore, configure the +system with the following rules: + + 1. Frame buffers must not span a 4KB address boundary, unless + the frame start address is 256 byte aligned + 2. All FMAN DMA start addresses (for example, BMAN buffer + address, FD[address] + FD[offset]) are 16B aligned + 3. SG table and buffer addresses are 16B aligned and the size + of SG buffers are multiple of 16 bytes, except for the last + SG buffer that can be of any size. + +Additional workaround notes: +- Address alignment of 64 bytes is recommended for maximally +efficient system bus transactions (although 16 byte alignment is +sufficient to avoid the stall condition) +- To support frame sizes that are larger than 4K bytes, there are +two options: + 1. Large single buffer frames that span a 4KB page boundary can + be converted into SG frames to avoid transaction splits at + the 4KB boundary, + 2. Align the large single buffer to 256B address boundaries, + ensure that the frame address plus offset is 256B aligned. +- If software generated SG frames have buffers that are unaligned +and with random non-multiple of 16 byte lengths, before +transmitting such frames via FMAN, frames will need to be copied +into a new single buffer or multiple buffer SG frame that is +compliant with the three rules listed above. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + .../net/ethernet/freescale/dpaa/dpaa_eth.c | 110 +++++++++++++++++- + 1 file changed, 107 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index fd93d542f497..e3ac9ec54c7c 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -1,4 +1,5 @@ + /* Copyright 2008 - 2016 Freescale Semiconductor Inc. ++ * Copyright 2020 NXP + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: +@@ -123,7 +124,22 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms"); + #define FSL_QMAN_MAX_OAL 127 + + /* Default alignment for start of data in an Rx FD */ ++#ifdef CONFIG_DPAA_ERRATUM_A050385 ++/* aligning data start to 64 avoids DMA transaction splits, unless the buffer ++ * is crossing a 4k page boundary ++ */ ++#define DPAA_FD_DATA_ALIGNMENT (fman_has_errata_a050385() ? 64 : 16) ++/* aligning to 256 avoids DMA transaction splits caused by 4k page boundary ++ * crossings; also, all SG fragments except the last must have a size multiple ++ * of 256 to avoid DMA transaction splits ++ */ ++#define DPAA_A050385_ALIGN 256 ++#define DPAA_FD_RX_DATA_ALIGNMENT (fman_has_errata_a050385() ? \ ++ DPAA_A050385_ALIGN : 16) ++#else + #define DPAA_FD_DATA_ALIGNMENT 16 ++#define DPAA_FD_RX_DATA_ALIGNMENT DPAA_FD_DATA_ALIGNMENT ++#endif + + /* The DPAA requires 256 bytes reserved and mapped for the SGT */ + #define DPAA_SGT_SIZE 256 +@@ -158,8 +174,13 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms"); + #define DPAA_PARSE_RESULTS_SIZE sizeof(struct fman_prs_result) + #define DPAA_TIME_STAMP_SIZE 8 + #define DPAA_HASH_RESULTS_SIZE 8 ++#ifdef CONFIG_DPAA_ERRATUM_A050385 ++#define DPAA_RX_PRIV_DATA_SIZE (DPAA_A050385_ALIGN - (DPAA_PARSE_RESULTS_SIZE\ ++ + DPAA_TIME_STAMP_SIZE + DPAA_HASH_RESULTS_SIZE)) ++#else + #define DPAA_RX_PRIV_DATA_SIZE (u16)(DPAA_TX_PRIV_DATA_SIZE + \ + dpaa_rx_extra_headroom) ++#endif + + #define DPAA_ETH_PCD_RXQ_NUM 128 + +@@ -180,7 +201,12 @@ static struct dpaa_bp *dpaa_bp_array[BM_MAX_NUM_OF_POOLS]; + + #define DPAA_BP_RAW_SIZE 4096 + ++#ifdef CONFIG_DPAA_ERRATUM_A050385 ++#define dpaa_bp_size(raw_size) (SKB_WITH_OVERHEAD(raw_size) & \ ++ ~(DPAA_A050385_ALIGN - 1)) ++#else + #define dpaa_bp_size(raw_size) SKB_WITH_OVERHEAD(raw_size) ++#endif + + static int dpaa_max_frm; + +@@ -1192,7 +1218,7 @@ static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp *bp, + buf_prefix_content.pass_prs_result = true; + buf_prefix_content.pass_hash_result = true; + buf_prefix_content.pass_time_stamp = true; +- buf_prefix_content.data_align = DPAA_FD_DATA_ALIGNMENT; ++ buf_prefix_content.data_align = DPAA_FD_RX_DATA_ALIGNMENT; + + rx_p = ¶ms.specific_params.rx_params; + rx_p->err_fqid = errq->fqid; +@@ -1662,6 +1688,8 @@ static u8 rx_csum_offload(const struct dpaa_priv *priv, const struct qm_fd *fd) + return CHECKSUM_NONE; + } + ++#define PTR_IS_ALIGNED(x, a) (IS_ALIGNED((unsigned long)(x), (a))) ++ + /* Build a linear skb around the received buffer. + * We are guaranteed there is enough room at the end of the data buffer to + * accommodate the shared info area of the skb. +@@ -1733,8 +1761,7 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, + + sg_addr = qm_sg_addr(&sgt[i]); + sg_vaddr = phys_to_virt(sg_addr); +- WARN_ON(!IS_ALIGNED((unsigned long)sg_vaddr, +- SMP_CACHE_BYTES)); ++ WARN_ON(!PTR_IS_ALIGNED(sg_vaddr, SMP_CACHE_BYTES)); + + dma_unmap_page(priv->rx_dma_dev, sg_addr, + DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); +@@ -2022,6 +2049,75 @@ static inline int dpaa_xmit(struct dpaa_priv *priv, + return 0; + } + ++#ifdef CONFIG_DPAA_ERRATUM_A050385 ++int dpaa_a050385_wa(struct net_device *net_dev, struct sk_buff **s) ++{ ++ struct dpaa_priv *priv = netdev_priv(net_dev); ++ struct sk_buff *new_skb, *skb = *s; ++ unsigned char *start, i; ++ ++ /* check linear buffer alignment */ ++ if (!PTR_IS_ALIGNED(skb->data, DPAA_A050385_ALIGN)) ++ goto workaround; ++ ++ /* linear buffers just need to have an aligned start */ ++ if (!skb_is_nonlinear(skb)) ++ return 0; ++ ++ /* linear data size for nonlinear skbs needs to be aligned */ ++ if (!IS_ALIGNED(skb_headlen(skb), DPAA_A050385_ALIGN)) ++ goto workaround; ++ ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; ++ ++ /* all fragments need to have aligned start addresses */ ++ if (!IS_ALIGNED(frag->page_offset, DPAA_A050385_ALIGN)) ++ goto workaround; ++ ++ /* all but last fragment need to have aligned sizes */ ++ if (!IS_ALIGNED(skb_frag_size(frag), DPAA_A050385_ALIGN) && ++ (i < skb_shinfo(skb)->nr_frags - 1)) ++ goto workaround; ++ } ++ ++ return 0; ++ ++workaround: ++ /* copy all the skb content into a new linear buffer */ ++ new_skb = netdev_alloc_skb(net_dev, skb->len + DPAA_A050385_ALIGN - 1 + ++ priv->tx_headroom); ++ if (!new_skb) ++ return -ENOMEM; ++ ++ /* NET_SKB_PAD bytes already reserved, adding up to tx_headroom */ ++ skb_reserve(new_skb, priv->tx_headroom - NET_SKB_PAD); ++ ++ /* Workaround for DPAA_A050385 requires data start to be aligned */ ++ start = PTR_ALIGN(new_skb->data, DPAA_A050385_ALIGN); ++ if (start - new_skb->data != 0) ++ skb_reserve(new_skb, start - new_skb->data); ++ ++ skb_put(new_skb, skb->len); ++ skb_copy_bits(skb, 0, new_skb->data, skb->len); ++ skb_copy_header(new_skb, skb); ++ new_skb->dev = skb->dev; ++ ++ /* We move the headroom when we align it so we have to reset the ++ * network and transport header offsets relative to the new data ++ * pointer. The checksum offload relies on these offsets. ++ */ ++ skb_set_network_header(new_skb, skb_network_offset(skb)); ++ skb_set_transport_header(new_skb, skb_transport_offset(skb)); ++ ++ /* TODO: does timestamping need the result in the old skb? */ ++ dev_kfree_skb(skb); ++ *s = new_skb; ++ ++ return 0; ++} ++#endif ++ + static netdev_tx_t + dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev) + { +@@ -2068,6 +2164,14 @@ dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev) + nonlinear = skb_is_nonlinear(skb); + } + ++#ifdef CONFIG_DPAA_ERRATUM_A050385 ++ if (unlikely(fman_has_errata_a050385())) { ++ if (dpaa_a050385_wa(net_dev, &skb)) ++ goto enomem; ++ nonlinear = skb_is_nonlinear(skb); ++ } ++#endif ++ + if (nonlinear) { + /* Just create a S/G fd based on the skb */ + err = skb_to_sg_fd(priv, skb, &fd); +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-Fix-one-possible-memleak-in-dpaa_eth_probe.patch b/patches.suse/dpaa_eth-Fix-one-possible-memleak-in-dpaa_eth_probe.patch new file mode 100644 index 0000000..e576b68 --- /dev/null +++ b/patches.suse/dpaa_eth-Fix-one-possible-memleak-in-dpaa_eth_probe.patch @@ -0,0 +1,35 @@ +From: Liu Jian +Date: Mon, 20 Jul 2020 22:28:29 +0800 +Subject: dpaa_eth: Fix one possible memleak in dpaa_eth_probe + +Git-commit: 6790711f8ac5faabc43237c0d05d93db431a1ecc +Patch-mainline: v5.8-rc7 +References: bsc#1174550 + +When dma_coerce_mask_and_coherent() fails, the alloced netdev need to be freed. + +Fixes: 060ad66f9795 ("dpaa_eth: change DMA device") +Signed-off-by: Liu Jian +Acked-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index 2972244e6eb0..43570f4911ea 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -2938,7 +2938,7 @@ static int dpaa_eth_probe(struct platform_device *pdev) + DMA_BIT_MASK(40)); + if (err) { + netdev_err(net_dev, "dma_coerce_mask_and_coherent() failed\n"); +- return err; ++ goto free_netdev; + } + + /* If fsl_fm_max_frm is set to a higher value than the all-common 1500, +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-add-dropped-frames-to-percpu-ethtool-stats.patch b/patches.suse/dpaa_eth-add-dropped-frames-to-percpu-ethtool-stats.patch new file mode 100644 index 0000000..fcbcfd0 --- /dev/null +++ b/patches.suse/dpaa_eth-add-dropped-frames-to-percpu-ethtool-stats.patch @@ -0,0 +1,48 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:55 +0200 +Subject: dpaa_eth: add dropped frames to percpu ethtool stats + +Git-commit: 46e93e5443a7adb66d7503f3e32a0cc3bf5b4d3e +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Prior to this change, the frames dropped on receive or transmit +were not displayed in the ethtool statistics, leaving the dropped +frames unaccounted for. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +index bc6ed1df53ca..1c689e11c61f 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +@@ -47,6 +47,8 @@ static const char dpaa_stats_percpu[][ETH_GSTRING_LEN] = { + "tx S/G", + "tx error", + "rx error", ++ "rx dropped", ++ "tx dropped", + }; + + static char dpaa_stats_global[][ETH_GSTRING_LEN] = { +@@ -262,6 +264,12 @@ static void copy_stats(struct dpaa_percpu_priv *percpu_priv, int num_cpus, + data[crr * num_values + crr_cpu] = percpu_priv->stats.rx_errors; + data[crr++ * num_values + num_cpus] += percpu_priv->stats.rx_errors; + ++ data[crr * num_values + crr_cpu] = percpu_priv->stats.rx_dropped; ++ data[crr++ * num_values + num_cpus] += percpu_priv->stats.rx_dropped; ++ ++ data[crr * num_values + crr_cpu] = percpu_priv->stats.tx_dropped; ++ data[crr++ * num_values + num_cpus] += percpu_priv->stats.tx_dropped; ++ + data[crr * num_values + crr_cpu] = bp_count; + data[crr++ * num_values + num_cpus] += bp_count; + } +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-add-newline-in-dev_err-msg.patch b/patches.suse/dpaa_eth-add-newline-in-dev_err-msg.patch new file mode 100644 index 0000000..e8e639e --- /dev/null +++ b/patches.suse/dpaa_eth-add-newline-in-dev_err-msg.patch @@ -0,0 +1,33 @@ +From: Madalin Bucur +Date: Wed, 23 Oct 2019 12:08:46 +0300 +Subject: dpaa_eth: add newline in dev_err() msg + +Git-commit: 6e6583c91f947973b77995ffc487f7166c257911 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Newline was missing at the end of the error message. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index e376c32fa003..d3214541c7c5 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -901,7 +901,7 @@ static void dpaa_fq_setup(struct dpaa_priv *priv, + + if (num_portals == 0) + dev_err(priv->net_dev->dev.parent, +- "No Qman software (affine) channels found"); ++ "No Qman software (affine) channels found\n"); + + /* Initialize each FQ in the list */ + list_for_each_entry(fq, &priv->dpaa_fq_list, list) { +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-change-DMA-device.patch b/patches.suse/dpaa_eth-change-DMA-device.patch new file mode 100644 index 0000000..5bc6e41 --- /dev/null +++ b/patches.suse/dpaa_eth-change-DMA-device.patch @@ -0,0 +1,343 @@ +From: Madalin Bucur +Date: Wed, 23 Oct 2019 12:08:44 +0300 +Subject: dpaa_eth: change DMA device + +Git-commit: 060ad66f97954fa93ad495542c8a4f1b6c45aa34 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +The DPAA Ethernet driver is using the FMan MAC as the device for DMA +mapping. This is not actually correct, as the real DMA device is the +FMan port (the FMan Rx port for reception and the FMan Tx port for +transmission). Changing the device used for DMA mapping to the Fman +Rx and Tx port devices. + +Signed-off-by: Madalin Bucur +Signed-off-by: Laurentiu Tudor +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 105 +++++++++++++------------ + drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 8 + + 2 files changed, 62 insertions(+), 51 deletions(-) + +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -1335,15 +1335,15 @@ static void dpaa_fd_release(const struct + vaddr = phys_to_virt(qm_fd_addr(fd)); + sgt = vaddr + qm_fd_get_offset(fd); + +- dma_unmap_single(dpaa_bp->dev, qm_fd_addr(fd), dpaa_bp->size, +- DMA_FROM_DEVICE); ++ dma_unmap_single(dpaa_bp->priv->rx_dma_dev, qm_fd_addr(fd), ++ dpaa_bp->size, DMA_FROM_DEVICE); + + dpaa_release_sgt_members(sgt); + +- addr = dma_map_single(dpaa_bp->dev, vaddr, dpaa_bp->size, +- DMA_FROM_DEVICE); +- if (dma_mapping_error(dpaa_bp->dev, addr)) { +- dev_err(dpaa_bp->dev, "DMA mapping failed"); ++ addr = dma_map_single(dpaa_bp->priv->rx_dma_dev, vaddr, ++ dpaa_bp->size, DMA_FROM_DEVICE); ++ if (dma_mapping_error(dpaa_bp->priv->rx_dma_dev, addr)) { ++ netdev_err(net_dev, "DMA mapping failed\n"); + return; + } + bm_buffer_set64(&bmb, addr); +@@ -1488,7 +1488,7 @@ return_error: + + static int dpaa_bp_add_8_bufs(const struct dpaa_bp *dpaa_bp) + { +- struct device *dev = dpaa_bp->dev; ++ struct net_device *net_dev = dpaa_bp->priv->net_dev; + struct bm_buffer bmb[8]; + dma_addr_t addr; + void *new_buf; +@@ -1497,16 +1497,18 @@ static int dpaa_bp_add_8_bufs(const stru + for (i = 0; i < 8; i++) { + new_buf = netdev_alloc_frag(dpaa_bp->raw_size); + if (unlikely(!new_buf)) { +- dev_err(dev, "netdev_alloc_frag() failed, size %zu\n", +- dpaa_bp->raw_size); ++ netdev_err(net_dev, ++ "netdev_alloc_frag() failed, size %zu\n", ++ dpaa_bp->raw_size); + goto release_previous_buffs; + } + new_buf = PTR_ALIGN(new_buf, SMP_CACHE_BYTES); + +- addr = dma_map_single(dev, new_buf, ++ addr = dma_map_single(dpaa_bp->priv->rx_dma_dev, new_buf, + dpaa_bp->size, DMA_FROM_DEVICE); +- if (unlikely(dma_mapping_error(dev, addr))) { +- dev_err(dpaa_bp->dev, "DMA map failed"); ++ if (unlikely(dma_mapping_error(dpaa_bp->priv->rx_dma_dev, ++ addr))) { ++ netdev_err(net_dev, "DMA map failed\n"); + goto release_previous_buffs; + } + +@@ -1634,7 +1636,7 @@ static struct sk_buff *dpaa_cleanup_tx_f + + if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) { + nr_frags = skb_shinfo(skb)->nr_frags; +- dma_unmap_single(dev, addr, ++ dma_unmap_single(priv->tx_dma_dev, addr, + qm_fd_get_offset(fd) + DPAA_SGT_SIZE, + dma_dir); + +@@ -1644,21 +1646,21 @@ static struct sk_buff *dpaa_cleanup_tx_f + sgt = phys_to_virt(addr + qm_fd_get_offset(fd)); + + /* sgt[0] is from lowmem, was dma_map_single()-ed */ +- dma_unmap_single(dev, qm_sg_addr(&sgt[0]), ++ dma_unmap_single(priv->tx_dma_dev, qm_sg_addr(&sgt[0]), + qm_sg_entry_get_len(&sgt[0]), dma_dir); + + /* remaining pages were mapped with skb_frag_dma_map() */ + for (i = 1; i <= nr_frags; i++) { + WARN_ON(qm_sg_entry_is_ext(&sgt[i])); + +- dma_unmap_page(dev, qm_sg_addr(&sgt[i]), ++ dma_unmap_page(priv->tx_dma_dev, qm_sg_addr(&sgt[i]), + qm_sg_entry_get_len(&sgt[i]), dma_dir); + } + + /* Free the page frag that we allocated on Tx */ + skb_free_frag(phys_to_virt(addr)); + } else { +- dma_unmap_single(dev, addr, ++ dma_unmap_single(priv->tx_dma_dev, addr, + skb_tail_pointer(skb) - (u8 *)skbh, dma_dir); + } + +@@ -1762,8 +1764,8 @@ static struct sk_buff *sg_fd_to_skb(cons + goto free_buffers; + + count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); +- dma_unmap_single(dpaa_bp->dev, sg_addr, dpaa_bp->size, +- DMA_FROM_DEVICE); ++ dma_unmap_single(dpaa_bp->priv->rx_dma_dev, sg_addr, ++ dpaa_bp->size, DMA_FROM_DEVICE); + if (!skb) { + sz = dpaa_bp->size + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +@@ -1853,7 +1855,6 @@ static int skb_to_contig_fd(struct dpaa_ + int *offset) + { + struct net_device *net_dev = priv->net_dev; +- struct device *dev = net_dev->dev.parent; + enum dma_data_direction dma_dir; + unsigned char *buffer_start; + struct sk_buff **skbh; +@@ -1889,9 +1890,9 @@ static int skb_to_contig_fd(struct dpaa_ + fd->cmd |= cpu_to_be32(FM_FD_CMD_FCO); + + /* Map the entire buffer size that may be seen by FMan, but no more */ +- addr = dma_map_single(dev, skbh, ++ addr = dma_map_single(priv->tx_dma_dev, skbh, + skb_tail_pointer(skb) - buffer_start, dma_dir); +- if (unlikely(dma_mapping_error(dev, addr))) { ++ if (unlikely(dma_mapping_error(priv->tx_dma_dev, addr))) { + if (net_ratelimit()) + netif_err(priv, tx_err, net_dev, "dma_map_single() failed\n"); + return -EINVAL; +@@ -1907,7 +1908,6 @@ static int skb_to_sg_fd(struct dpaa_priv + const enum dma_data_direction dma_dir = DMA_TO_DEVICE; + const int nr_frags = skb_shinfo(skb)->nr_frags; + struct net_device *net_dev = priv->net_dev; +- struct device *dev = net_dev->dev.parent; + struct qm_sg_entry *sgt; + struct sk_buff **skbh; + int i, j, err, sz; +@@ -1946,10 +1946,10 @@ static int skb_to_sg_fd(struct dpaa_priv + qm_sg_entry_set_len(&sgt[0], frag_len); + sgt[0].bpid = FSL_DPAA_BPID_INV; + sgt[0].offset = 0; +- addr = dma_map_single(dev, skb->data, ++ addr = dma_map_single(priv->tx_dma_dev, skb->data, + skb_headlen(skb), dma_dir); +- if (unlikely(dma_mapping_error(dev, addr))) { +- dev_err(dev, "DMA mapping failed"); ++ if (unlikely(dma_mapping_error(priv->tx_dma_dev, addr))) { ++ netdev_err(priv->net_dev, "DMA mapping failed\n"); + err = -EINVAL; + goto sg0_map_failed; + } +@@ -1960,10 +1960,10 @@ static int skb_to_sg_fd(struct dpaa_priv + frag = &skb_shinfo(skb)->frags[i]; + frag_len = frag->size; + WARN_ON(!skb_frag_page(frag)); +- addr = skb_frag_dma_map(dev, frag, 0, ++ addr = skb_frag_dma_map(priv->tx_dma_dev, frag, 0, + frag_len, dma_dir); +- if (unlikely(dma_mapping_error(dev, addr))) { +- dev_err(dev, "DMA mapping failed"); ++ if (unlikely(dma_mapping_error(priv->tx_dma_dev, addr))) { ++ netdev_err(priv->net_dev, "DMA mapping failed\n"); + err = -EINVAL; + goto sg_map_failed; + } +@@ -1986,10 +1986,10 @@ static int skb_to_sg_fd(struct dpaa_priv + skbh = (struct sk_buff **)buffer_start; + *skbh = skb; + +- addr = dma_map_single(dev, buffer_start, ++ addr = dma_map_single(priv->tx_dma_dev, buffer_start, + priv->tx_headroom + DPAA_SGT_SIZE, dma_dir); +- if (unlikely(dma_mapping_error(dev, addr))) { +- dev_err(dev, "DMA mapping failed"); ++ if (unlikely(dma_mapping_error(priv->tx_dma_dev, addr))) { ++ netdev_err(priv->net_dev, "DMA mapping failed\n"); + err = -EINVAL; + goto sgt_map_failed; + } +@@ -2003,7 +2003,7 @@ static int skb_to_sg_fd(struct dpaa_priv + sgt_map_failed: + sg_map_failed: + for (j = 0; j < i; j++) +- dma_unmap_page(dev, qm_sg_addr(&sgt[j]), ++ dma_unmap_page(priv->tx_dma_dev, qm_sg_addr(&sgt[j]), + qm_sg_entry_get_len(&sgt[j]), dma_dir); + sg0_map_failed: + csum_failed: +@@ -2299,7 +2299,8 @@ static enum qman_cb_dqrr_result rx_defau + return qman_cb_dqrr_consume; + } + +- dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE); ++ dma_unmap_single(dpaa_bp->priv->rx_dma_dev, addr, dpaa_bp->size, ++ DMA_FROM_DEVICE); + + /* prefetch the first 64 bytes of the frame or the SGT start */ + vaddr = phys_to_virt(addr); +@@ -2651,7 +2652,7 @@ static inline void dpaa_bp_free_pf(const + { + dma_addr_t addr = bm_buf_addr(bmb); + +- dma_unmap_single(bp->dev, addr, bp->size, DMA_FROM_DEVICE); ++ dma_unmap_single(bp->priv->rx_dma_dev, addr, bp->size, DMA_FROM_DEVICE); + + skb_free_frag(phys_to_virt(addr)); + } +@@ -2761,25 +2762,27 @@ static int dpaa_eth_probe(struct platfor + int err = 0, i, channel; + struct device *dev; + ++ dev = &pdev->dev; ++ + err = bman_is_probed(); + if (!err) + return -EPROBE_DEFER; + if (err < 0) { +- dev_err(&pdev->dev, "failing probe due to bman probe error\n"); ++ dev_err(dev, "failing probe due to bman probe error\n"); + return -ENODEV; + } + err = qman_is_probed(); + if (!err) + return -EPROBE_DEFER; + if (err < 0) { +- dev_err(&pdev->dev, "failing probe due to qman probe error\n"); ++ dev_err(dev, "failing probe due to qman probe error\n"); + return -ENODEV; + } + err = bman_portals_probed(); + if (!err) + return -EPROBE_DEFER; + if (err < 0) { +- dev_err(&pdev->dev, ++ dev_err(dev, + "failing probe due to bman portals probe error\n"); + return -ENODEV; + } +@@ -2787,19 +2790,11 @@ static int dpaa_eth_probe(struct platfor + if (!err) + return -EPROBE_DEFER; + if (err < 0) { +- dev_err(&pdev->dev, ++ dev_err(dev, + "failing probe due to qman portals probe error\n"); + return -ENODEV; + } + +- /* device used for DMA mapping */ +- dev = pdev->dev.parent; +- err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40)); +- if (err) { +- dev_err(dev, "dma_coerce_mask_and_coherent() failed\n"); +- return err; +- } +- + /* Allocate this early, so we can store relevant information in + * the private area + */ +@@ -2820,11 +2815,23 @@ static int dpaa_eth_probe(struct platfor + + mac_dev = dpaa_mac_dev_get(pdev); + if (IS_ERR(mac_dev)) { +- dev_err(dev, "dpaa_mac_dev_get() failed\n"); ++ netdev_err(net_dev, "dpaa_mac_dev_get() failed\n"); + err = PTR_ERR(mac_dev); + goto free_netdev; + } + ++ /* Devices used for DMA mapping */ ++ priv->rx_dma_dev = fman_port_get_device(mac_dev->port[RX]); ++ priv->tx_dma_dev = fman_port_get_device(mac_dev->port[TX]); ++ err = dma_coerce_mask_and_coherent(priv->rx_dma_dev, DMA_BIT_MASK(40)); ++ if (!err) ++ err = dma_coerce_mask_and_coherent(priv->tx_dma_dev, ++ DMA_BIT_MASK(40)); ++ if (err) { ++ netdev_err(net_dev, "dma_coerce_mask_and_coherent() failed\n"); ++ return err; ++ } ++ + /* If fsl_fm_max_frm is set to a higher value than the all-common 1500, + * we choose conservatively and let the user explicitly set a higher + * MTU via ifconfig. Otherwise, the user may end up with different MTUs +@@ -2851,7 +2858,7 @@ static int dpaa_eth_probe(struct platfor + dpaa_bps[i]->raw_size = bpool_buffer_raw_size(i, DPAA_BPS_NUM); + /* avoid runtime computations by keeping the usable size here */ + dpaa_bps[i]->size = dpaa_bp_size(dpaa_bps[i]->raw_size); +- dpaa_bps[i]->dev = dev; ++ dpaa_bps[i]->priv = priv; + + err = dpaa_bp_alloc_pool(dpaa_bps[i]); + if (err < 0) +@@ -2974,7 +2981,7 @@ static int dpaa_remove(struct platform_d + struct device *dev; + int err; + +- dev = pdev->dev.parent; ++ dev = &pdev->dev; + net_dev = dev_get_drvdata(dev); + + priv = netdev_priv(net_dev); +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +@@ -79,9 +79,11 @@ struct dpaa_fq_cbs { + struct qman_fq egress_ern; + }; + ++struct dpaa_priv; ++ + struct dpaa_bp { +- /* device used in the DMA mapping operations */ +- struct device *dev; ++ /* used in the DMA mapping operations */ ++ struct dpaa_priv *priv; + /* current number of buffers in the buffer pool alloted to each CPU */ + int __percpu *percpu_count; + /* all buffers allocated for this pool have this raw size */ +@@ -152,6 +154,8 @@ struct dpaa_priv { + u16 tx_headroom; + struct net_device *net_dev; + struct mac_device *mac_dev; ++ struct device *rx_dma_dev; ++ struct device *tx_dma_dev; + struct qman_fq *egress_fqs[DPAA_ETH_TXQ_NUM]; + struct qman_fq *conf_fqs[DPAA_ETH_TXQ_NUM]; + diff --git a/patches.suse/dpaa_eth-cleanup-skb_to_contig_fd.patch b/patches.suse/dpaa_eth-cleanup-skb_to_contig_fd.patch new file mode 100644 index 0000000..e2dd967 --- /dev/null +++ b/patches.suse/dpaa_eth-cleanup-skb_to_contig_fd.patch @@ -0,0 +1,75 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:53 +0200 +Subject: dpaa_eth: cleanup skb_to_contig_fd() + +Git-commit: 2388ba36e94594406a755aceafc5983c289e68bf +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Remove cast, align variable name, simplify DMA map size computation. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index a278651c81f6..f3aa154172c3 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -1369,7 +1369,7 @@ static void count_ern(struct dpaa_percpu_priv *percpu_priv, + static int dpaa_enable_tx_csum(struct dpaa_priv *priv, + struct sk_buff *skb, + struct qm_fd *fd, +- char *parse_results) ++ void *parse_results) + { + struct fman_prs_result *parse_result; + u16 ethertype = ntohs(skb->protocol); +@@ -1831,7 +1831,7 @@ static int skb_to_contig_fd(struct dpaa_priv *priv, + { + struct net_device *net_dev = priv->net_dev; + enum dma_data_direction dma_dir; +- unsigned char *buffer_start; ++ unsigned char *buff_start; + struct sk_buff **skbh; + dma_addr_t addr; + int err; +@@ -1840,10 +1840,10 @@ static int skb_to_contig_fd(struct dpaa_priv *priv, + * available, so just use that for offset. + */ + fd->bpid = FSL_DPAA_BPID_INV; +- buffer_start = skb->data - priv->tx_headroom; ++ buff_start = skb->data - priv->tx_headroom; + dma_dir = DMA_TO_DEVICE; + +- skbh = (struct sk_buff **)buffer_start; ++ skbh = (struct sk_buff **)buff_start; + *skbh = skb; + + /* Enable L3/L4 hardware checksum computation. +@@ -1852,7 +1852,7 @@ static int skb_to_contig_fd(struct dpaa_priv *priv, + * need to write into the skb. + */ + err = dpaa_enable_tx_csum(priv, skb, fd, +- ((char *)skbh) + DPAA_TX_PRIV_DATA_SIZE); ++ buff_start + DPAA_TX_PRIV_DATA_SIZE); + if (unlikely(err < 0)) { + if (net_ratelimit()) + netif_err(priv, tx_err, net_dev, "HW csum error: %d\n", +@@ -1865,8 +1865,8 @@ static int skb_to_contig_fd(struct dpaa_priv *priv, + fd->cmd |= cpu_to_be32(FM_FD_CMD_FCO); + + /* Map the entire buffer size that may be seen by FMan, but no more */ +- addr = dma_map_single(priv->tx_dma_dev, skbh, +- skb_tail_pointer(skb) - buffer_start, dma_dir); ++ addr = dma_map_single(priv->tx_dma_dev, buff_start, ++ priv->tx_headroom + skb->len, dma_dir); + if (unlikely(dma_mapping_error(priv->tx_dma_dev, addr))) { + if (net_ratelimit()) + netif_err(priv, tx_err, net_dev, "dma_map_single() failed\n"); +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-defer-probing-after-qbman.patch b/patches.suse/dpaa_eth-defer-probing-after-qbman.patch new file mode 100644 index 0000000..2e12fc5 --- /dev/null +++ b/patches.suse/dpaa_eth-defer-probing-after-qbman.patch @@ -0,0 +1,66 @@ +From: Laurentiu Tudor +Date: Wed, 23 Oct 2019 12:08:41 +0300 +Subject: dpaa_eth: defer probing after qbman + +Git-commit: 5537b32985767632f0cba17706c2beb6ee76c089 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +If the DPAA 1 Ethernet driver gets probed before the QBMan driver it will +cause a boot crash. Add predictability in the probing order by deferring +the Ethernet driver probe after QBMan and portals by using the recently +introduced QBMan APIs. + +Signed-off-by: Laurentiu Tudor +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + .../net/ethernet/freescale/dpaa/dpaa_eth.c | 31 +++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index b4b82b9c5cd6..75eeb2ef409f 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -2773,6 +2773,37 @@ static int dpaa_eth_probe(struct platform_device *pdev) + int err = 0, i, channel; + struct device *dev; + ++ err = bman_is_probed(); ++ if (!err) ++ return -EPROBE_DEFER; ++ if (err < 0) { ++ dev_err(&pdev->dev, "failing probe due to bman probe error\n"); ++ return -ENODEV; ++ } ++ err = qman_is_probed(); ++ if (!err) ++ return -EPROBE_DEFER; ++ if (err < 0) { ++ dev_err(&pdev->dev, "failing probe due to qman probe error\n"); ++ return -ENODEV; ++ } ++ err = bman_portals_probed(); ++ if (!err) ++ return -EPROBE_DEFER; ++ if (err < 0) { ++ dev_err(&pdev->dev, ++ "failing probe due to bman portals probe error\n"); ++ return -ENODEV; ++ } ++ err = qman_portals_probed(); ++ if (!err) ++ return -EPROBE_DEFER; ++ if (err < 0) { ++ dev_err(&pdev->dev, ++ "failing probe due to qman portals probe error\n"); ++ return -ENODEV; ++ } ++ + /* device used for DMA mapping */ + dev = pdev->dev.parent; + err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40)); +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-extend-delays-in-ndo_stop.patch b/patches.suse/dpaa_eth-extend-delays-in-ndo_stop.patch new file mode 100644 index 0000000..35d2c47 --- /dev/null +++ b/patches.suse/dpaa_eth-extend-delays-in-ndo_stop.patch @@ -0,0 +1,44 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:57 +0200 +Subject: dpaa_eth: extend delays in ndo_stop + +Git-commit: e414696d49521b9ceb7734e037d5aa18ef92d8a3 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Make sure all the frames that are in flight have time to be processed +before the interface is completely brought down. Add a missing delay +for the Rx path. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index ef81ec32ef57..d8b41a0a7e3c 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -266,7 +266,7 @@ static int dpaa_stop(struct net_device *net_dev) + /* Allow the Fman (Tx) port to process in-flight frames before we + * try switching it off. + */ +- usleep_range(5000, 10000); ++ msleep(200); + + err = mac_dev->stop(mac_dev); + if (err < 0) +@@ -283,6 +283,8 @@ static int dpaa_stop(struct net_device *net_dev) + phy_disconnect(net_dev->phydev); + net_dev->phydev = NULL; + ++ msleep(200); ++ + return err; + } + +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-fix-DMA-mapping-leak.patch b/patches.suse/dpaa_eth-fix-DMA-mapping-leak.patch new file mode 100644 index 0000000..f9c5272 --- /dev/null +++ b/patches.suse/dpaa_eth-fix-DMA-mapping-leak.patch @@ -0,0 +1,104 @@ +From: Madalin Bucur +Date: Mon, 23 Dec 2019 09:39:22 +0200 +Subject: dpaa_eth: fix DMA mapping leak + +Git-commit: c27569fcd6e1b11bd24361346504f2995a256e4e +Patch-mainline: v5.5-rc5 +References: bsc#1174550 + +On the error path some fragments remain DMA mapped. Adding a fix +that unmaps all the fragments. Rework cleanup path to be simpler. + +Fixes: 8151ee88bad5 ("dpaa_eth: use page backed rx buffers") +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + .../net/ethernet/freescale/dpaa/dpaa_eth.c | 39 ++++++++++--------- + 1 file changed, 20 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index 6a9d12dad5d9..a301f0095223 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -1719,7 +1719,7 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, + int page_offset; + unsigned int sz; + int *count_ptr; +- int i; ++ int i, j; + + vaddr = phys_to_virt(addr); + WARN_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES)); +@@ -1736,14 +1736,14 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, + WARN_ON(!IS_ALIGNED((unsigned long)sg_vaddr, + SMP_CACHE_BYTES)); + ++ dma_unmap_page(priv->rx_dma_dev, sg_addr, ++ DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); ++ + /* We may use multiple Rx pools */ + dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); + if (!dpaa_bp) + goto free_buffers; + +- count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); +- dma_unmap_page(priv->rx_dma_dev, sg_addr, +- DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); + if (!skb) { + sz = dpaa_bp->size + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +@@ -1786,7 +1786,9 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, + skb_add_rx_frag(skb, i - 1, head_page, frag_off, + frag_len, dpaa_bp->size); + } ++ + /* Update the pool count for the current {cpu x bpool} */ ++ count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); + (*count_ptr)--; + + if (qm_sg_entry_is_final(&sgt[i])) +@@ -1800,26 +1802,25 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, + return skb; + + free_buffers: +- /* compensate sw bpool counter changes */ +- for (i--; i >= 0; i--) { +- dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); +- if (dpaa_bp) { +- count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); +- (*count_ptr)++; +- } +- } + /* free all the SG entries */ +- for (i = 0; i < DPAA_SGT_MAX_ENTRIES ; i++) { +- sg_addr = qm_sg_addr(&sgt[i]); ++ for (j = 0; j < DPAA_SGT_MAX_ENTRIES ; j++) { ++ sg_addr = qm_sg_addr(&sgt[j]); + sg_vaddr = phys_to_virt(sg_addr); ++ /* all pages 0..i were unmaped */ ++ if (j > i) ++ dma_unmap_page(priv->rx_dma_dev, qm_sg_addr(&sgt[j]), ++ DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); + free_pages((unsigned long)sg_vaddr, 0); +- dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); +- if (dpaa_bp) { +- count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); +- (*count_ptr)--; ++ /* counters 0..i-1 were decremented */ ++ if (j >= i) { ++ dpaa_bp = dpaa_bpid2pool(sgt[j].bpid); ++ if (dpaa_bp) { ++ count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); ++ (*count_ptr)--; ++ } + } + +- if (qm_sg_entry_is_final(&sgt[i])) ++ if (qm_sg_entry_is_final(&sgt[j])) + break; + } + /* free the SGT fragment */ +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-perform-DMA-unmapping-before-read.patch b/patches.suse/dpaa_eth-perform-DMA-unmapping-before-read.patch index 3b09e81..92646c7 100644 --- a/patches.suse/dpaa_eth-perform-DMA-unmapping-before-read.patch +++ b/patches.suse/dpaa_eth-perform-DMA-unmapping-before-read.patch @@ -19,7 +19,7 @@ Signed-off-by: Mian Yousaf Kaukab --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -1620,18 +1620,6 @@ static struct sk_buff *dpaa_cleanup_tx_f +@@ -1591,18 +1591,6 @@ static struct sk_buff *dpaa_cleanup_tx_f skbh = (struct sk_buff **)phys_to_virt(addr); skb = *skbh; @@ -37,15 +37,15 @@ Signed-off-by: Mian Yousaf Kaukab - if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) { nr_frags = skb_shinfo(skb)->nr_frags; - dma_unmap_single(dev, addr, -@@ -1655,13 +1643,28 @@ static struct sk_buff *dpaa_cleanup_tx_f + dma_unmap_single(priv->tx_dma_dev, addr, +@@ -1626,13 +1614,28 @@ static struct sk_buff *dpaa_cleanup_tx_f qm_sg_entry_get_len(&sgt[i]), dma_dir); } - /* Free the page frag that we allocated on Tx */ - skb_free_frag(phys_to_virt(addr)); } else { - dma_unmap_single(dev, addr, + dma_unmap_single(priv->tx_dma_dev, addr, skb_tail_pointer(skb) - (u8 *)skbh, dma_dir); } @@ -69,4 +69,3 @@ Signed-off-by: Mian Yousaf Kaukab return skb; } - diff --git a/patches.suse/dpaa_eth-register-a-device-link-for-the-qman-portal-.patch b/patches.suse/dpaa_eth-register-a-device-link-for-the-qman-portal-.patch new file mode 100644 index 0000000..6d460fa --- /dev/null +++ b/patches.suse/dpaa_eth-register-a-device-link-for-the-qman-portal-.patch @@ -0,0 +1,82 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:59 +0200 +Subject: dpaa_eth: register a device link for the qman portal used + +Git-commit: e06eea555b878f2c95b498aa1c485250ad30c960 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Before this change, unbinding the QMan portals did not trigger a +corresponding unbinding of the dpaa_eth making use of it; the first +QMan portal related operation issued afterwards crashed the kernel. +The device link ensures the dpaa_eth dependency upon the qman portal +used is honoured at the QMan portal removal. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 5 +++-- + drivers/soc/fsl/qbman/qman.c | 6 ------ + include/soc/fsl/qman.h | 7 ------- + 3 files changed, 3 insertions(+), 15 deletions(-) + +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -750,7 +750,7 @@ static void dpaa_release_channel(void) + qman_release_pool(rx_pool_channel); + } + +-static void dpaa_eth_add_channel(u16 channel) ++static void dpaa_eth_add_channel(u16 channel, struct device *dev) + { + u32 pool = QM_SDQCR_CHANNELS_POOL_CONV(channel); + const cpumask_t *cpus = qman_affine_cpus(); +@@ -760,6 +760,7 @@ static void dpaa_eth_add_channel(u16 cha + for_each_cpu(cpu, cpus) { + portal = qman_get_affine_portal(cpu); + qman_p_static_dequeue_add(portal, pool); ++ qman_start_using_portal(portal, dev); + } + } + +@@ -2866,7 +2867,7 @@ static int dpaa_eth_probe(struct platfor + /* Walk the CPUs with affine portals + * and add this pool channel to each's dequeue mask. + */ +- dpaa_eth_add_channel(priv->channel); ++ dpaa_eth_add_channel(priv->channel, &pdev->dev); + + dpaa_fq_setup(priv, &dpaa_fq_cbs, priv->mac_dev->port[TX]); + +--- a/drivers/soc/fsl/qbman/qman.c ++++ b/drivers/soc/fsl/qbman/qman.c +@@ -1723,12 +1723,6 @@ int qman_start_using_portal(struct qman_ + } + EXPORT_SYMBOL(qman_start_using_portal); + +-void qman_stop_using_portal(struct qman_portal *p, struct device *dev) +-{ +- device_link_remove(dev, p->config->dev); +-} +-EXPORT_SYMBOL(qman_stop_using_portal); +- + int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit) + { + return __poll_portal_fast(p, limit); +--- a/include/soc/fsl/qman.h ++++ b/include/soc/fsl/qman.h +@@ -926,13 +926,6 @@ struct qman_portal *qman_get_affine_port + int qman_start_using_portal(struct qman_portal *p, struct device *dev); + + /** +- * qman_stop_using_portal - deregister a device link for the portal user +- * @p: the portal that will no longer be in use +- * @dev: the device that uses the portal +- */ +-void qman_stop_using_portal(struct qman_portal *p, struct device *dev); +- +-/** + * qman_p_poll_dqrr - process DQRR (fast-path) entries + * @limit: the maximum number of DQRR entries to process + * diff --git a/patches.suse/dpaa_eth-remove-netdev_err-for-user-errors.patch b/patches.suse/dpaa_eth-remove-netdev_err-for-user-errors.patch new file mode 100644 index 0000000..9436c21 --- /dev/null +++ b/patches.suse/dpaa_eth-remove-netdev_err-for-user-errors.patch @@ -0,0 +1,75 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:56 +0200 +Subject: dpaa_eth: remove netdev_err() for user errors + +Git-commit: 1f722e19a2648c4310d6f3443558549edaca4081 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +User reports that an application making an (incorrect) call to +restart AN on a fixed link DPAA interface triggers an error in +the kernel log while the returned EINVAL should be enough. + +Reported-by: Joakim Tjernlund +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + .../net/ethernet/freescale/dpaa/dpaa_ethtool.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +index 1c689e11c61f..66d150872d48 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +@@ -80,10 +80,8 @@ static char dpaa_stats_global[][ETH_GSTRING_LEN] = { + static int dpaa_get_link_ksettings(struct net_device *net_dev, + struct ethtool_link_ksettings *cmd) + { +- if (!net_dev->phydev) { +- netdev_dbg(net_dev, "phy device not initialized\n"); ++ if (!net_dev->phydev) + return 0; +- } + + phy_ethtool_ksettings_get(net_dev->phydev, cmd); + +@@ -95,10 +93,8 @@ static int dpaa_set_link_ksettings(struct net_device *net_dev, + { + int err; + +- if (!net_dev->phydev) { +- netdev_err(net_dev, "phy device not initialized\n"); ++ if (!net_dev->phydev) + return -ENODEV; +- } + + err = phy_ethtool_ksettings_set(net_dev->phydev, cmd); + if (err < 0) +@@ -142,10 +138,8 @@ static int dpaa_nway_reset(struct net_device *net_dev) + { + int err; + +- if (!net_dev->phydev) { +- netdev_err(net_dev, "phy device not initialized\n"); ++ if (!net_dev->phydev) + return -ENODEV; +- } + + err = 0; + if (net_dev->phydev->autoneg) { +@@ -167,10 +161,8 @@ static void dpaa_get_pauseparam(struct net_device *net_dev, + priv = netdev_priv(net_dev); + mac_dev = priv->mac_dev; + +- if (!net_dev->phydev) { +- netdev_err(net_dev, "phy device not initialized\n"); ++ if (!net_dev->phydev) + return; +- } + + epause->autoneg = mac_dev->autoneg_pause; + epause->rx_pause = mac_dev->rx_pause_active; +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-remove-redundant-code.patch b/patches.suse/dpaa_eth-remove-redundant-code.patch new file mode 100644 index 0000000..71984c1 --- /dev/null +++ b/patches.suse/dpaa_eth-remove-redundant-code.patch @@ -0,0 +1,35 @@ +From: Madalin Bucur +Date: Wed, 23 Oct 2019 12:08:42 +0300 +Subject: dpaa_eth: remove redundant code + +Git-commit: 1076aaeeeacfa998c71bfad42e5ac65b490fc456 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Condition was previously checked, removing duplicate code. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index 75eeb2ef409f..8d5686d88d30 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -2304,10 +2304,6 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal, + return qman_cb_dqrr_consume; + } + +- dpaa_bp = dpaa_bpid2pool(fd->bpid); +- if (!dpaa_bp) +- return qman_cb_dqrr_consume; +- + dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE); + + /* prefetch the first 64 bytes of the frame or the SGT start */ +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-simplify-variables-used-in-dpaa_cleanup_tx_.patch b/patches.suse/dpaa_eth-simplify-variables-used-in-dpaa_cleanup_tx_.patch new file mode 100644 index 0000000..f72f150 --- /dev/null +++ b/patches.suse/dpaa_eth-simplify-variables-used-in-dpaa_cleanup_tx_.patch @@ -0,0 +1,72 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:51 +0200 +Subject: dpaa_eth: simplify variables used in dpaa_cleanup_tx_fd() + +Git-commit: ae1512fb745f60d35de4e2140df7b4b2e3497abb +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Avoid casts and repeated conversions. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -1585,13 +1585,13 @@ static struct sk_buff *dpaa_cleanup_tx_f + struct device *dev = priv->net_dev->dev.parent; + struct skb_shared_hwtstamps shhwtstamps; + dma_addr_t addr = qm_fd_addr(fd); ++ void *vaddr = phys_to_virt(addr); + const struct qm_sg_entry *sgt; +- struct sk_buff **skbh, *skb; ++ struct sk_buff *skb; + int nr_frags, i; + u64 ns; + +- skbh = (struct sk_buff **)phys_to_virt(addr); +- skb = *skbh; ++ skb = *(struct sk_buff **)vaddr; + + if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) { + nr_frags = skb_shinfo(skb)->nr_frags; +@@ -1602,7 +1602,7 @@ static struct sk_buff *dpaa_cleanup_tx_f + /* The sgt buffer has been allocated with netdev_alloc_frag(), + * it's from lowmem. + */ +- sgt = phys_to_virt(addr + qm_fd_get_offset(fd)); ++ sgt = vaddr + qm_fd_get_offset(fd); + + /* sgt[0] is from lowmem, was dma_map_single()-ed */ + dma_unmap_single(priv->tx_dma_dev, qm_sg_addr(&sgt[0]), +@@ -1618,7 +1618,7 @@ static struct sk_buff *dpaa_cleanup_tx_f + + } else { + dma_unmap_single(priv->tx_dma_dev, addr, +- skb_tail_pointer(skb) - (u8 *)skbh, dma_dir); ++ skb_tail_pointer(skb) - (u8 *)vaddr, dma_dir); + } + + /* DMA unmapping is required before accessing the HW provided info */ +@@ -1626,7 +1626,7 @@ static struct sk_buff *dpaa_cleanup_tx_f + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); + +- if (!fman_port_get_tstamp(priv->mac_dev->port[TX], (void *)skbh, ++ if (!fman_port_get_tstamp(priv->mac_dev->port[TX], vaddr, + &ns)) { + shhwtstamps.hwtstamp = ns_to_ktime(ns); + skb_tstamp_tx(skb, &shhwtstamps); +@@ -1637,7 +1637,7 @@ static struct sk_buff *dpaa_cleanup_tx_f + + if (qm_fd_get_format(fd) == qm_fd_sg) + /* Free the page frag that we allocated on Tx */ +- skb_free_frag(phys_to_virt(addr)); ++ skb_free_frag(vaddr); + + return skb; + } diff --git a/patches.suse/dpaa_eth-use-a-page-to-store-the-SGT.patch b/patches.suse/dpaa_eth-use-a-page-to-store-the-SGT.patch new file mode 100644 index 0000000..e33d4c4 --- /dev/null +++ b/patches.suse/dpaa_eth-use-a-page-to-store-the-SGT.patch @@ -0,0 +1,126 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:54 +0200 +Subject: dpaa_eth: use a page to store the SGT + +Git-commit: 84d06c606ca4726d0c1e8f2eecacfafed8aec3c5 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Use a page to store the scatter gather table on the transmit path. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + .../net/ethernet/freescale/dpaa/dpaa_eth.c | 43 +++++++++---------- + 1 file changed, 21 insertions(+), 22 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index f3aa154172c3..ef81ec32ef57 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -1592,9 +1592,9 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv, + int i; + + if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) { +- dma_unmap_single(priv->tx_dma_dev, addr, +- qm_fd_get_offset(fd) + DPAA_SGT_SIZE, +- dma_dir); ++ dma_unmap_page(priv->tx_dma_dev, addr, ++ qm_fd_get_offset(fd) + DPAA_SGT_SIZE, ++ dma_dir); + + /* The sgt buffer has been allocated with netdev_alloc_frag(), + * it's from lowmem. +@@ -1636,8 +1636,8 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv, + } + + if (qm_fd_get_format(fd) == qm_fd_sg) +- /* Free the page frag that we allocated on Tx */ +- skb_free_frag(vaddr); ++ /* Free the page that we allocated on Tx for the SGT */ ++ free_pages((unsigned long)vaddr, 0); + + return skb; + } +@@ -1885,21 +1885,20 @@ static int skb_to_sg_fd(struct dpaa_priv *priv, + struct net_device *net_dev = priv->net_dev; + struct qm_sg_entry *sgt; + struct sk_buff **skbh; +- int i, j, err, sz; +- void *buffer_start; ++ void *buff_start; + skb_frag_t *frag; + dma_addr_t addr; + size_t frag_len; +- void *sgt_buf; +- +- /* get a page frag to store the SGTable */ +- sz = SKB_DATA_ALIGN(priv->tx_headroom + DPAA_SGT_SIZE); +- sgt_buf = netdev_alloc_frag(sz); +- if (unlikely(!sgt_buf)) { +- netdev_err(net_dev, "netdev_alloc_frag() failed for size %d\n", +- sz); ++ struct page *p; ++ int i, j, err; ++ ++ /* get a page to store the SGTable */ ++ p = dev_alloc_pages(0); ++ if (unlikely(!p)) { ++ netdev_err(net_dev, "dev_alloc_pages() failed\n"); + return -ENOMEM; + } ++ buff_start = page_address(p); + + /* Enable L3/L4 hardware checksum computation. + * +@@ -1907,7 +1906,7 @@ static int skb_to_sg_fd(struct dpaa_priv *priv, + * need to write into the skb. + */ + err = dpaa_enable_tx_csum(priv, skb, fd, +- sgt_buf + DPAA_TX_PRIV_DATA_SIZE); ++ buff_start + DPAA_TX_PRIV_DATA_SIZE); + if (unlikely(err < 0)) { + if (net_ratelimit()) + netif_err(priv, tx_err, net_dev, "HW csum error: %d\n", +@@ -1916,7 +1915,7 @@ static int skb_to_sg_fd(struct dpaa_priv *priv, + } + + /* SGT[0] is used by the linear part */ +- sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom); ++ sgt = (struct qm_sg_entry *)(buff_start + priv->tx_headroom); + frag_len = skb_headlen(skb); + qm_sg_entry_set_len(&sgt[0], frag_len); + sgt[0].bpid = FSL_DPAA_BPID_INV; +@@ -1954,15 +1953,15 @@ static int skb_to_sg_fd(struct dpaa_priv *priv, + /* Set the final bit in the last used entry of the SGT */ + qm_sg_entry_set_f(&sgt[nr_frags], frag_len); + ++ /* set fd offset to priv->tx_headroom */ + qm_fd_set_sg(fd, priv->tx_headroom, skb->len); + + /* DMA map the SGT page */ +- buffer_start = (void *)sgt - priv->tx_headroom; +- skbh = (struct sk_buff **)buffer_start; ++ skbh = (struct sk_buff **)buff_start; + *skbh = skb; + +- addr = dma_map_single(priv->tx_dma_dev, buffer_start, +- priv->tx_headroom + DPAA_SGT_SIZE, dma_dir); ++ addr = dma_map_page(priv->tx_dma_dev, p, 0, ++ priv->tx_headroom + DPAA_SGT_SIZE, dma_dir); + if (unlikely(dma_mapping_error(priv->tx_dma_dev, addr))) { + netdev_err(priv->net_dev, "DMA mapping failed\n"); + err = -EINVAL; +@@ -1982,7 +1981,7 @@ static int skb_to_sg_fd(struct dpaa_priv *priv, + qm_sg_entry_get_len(&sgt[j]), dma_dir); + sg0_map_failed: + csum_failed: +- skb_free_frag(sgt_buf); ++ free_pages((unsigned long)buff_start, 0); + + return err; + } +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-use-fd-information-in-dpaa_cleanup_tx_fd.patch b/patches.suse/dpaa_eth-use-fd-information-in-dpaa_cleanup_tx_fd.patch new file mode 100644 index 0000000..7999c9c --- /dev/null +++ b/patches.suse/dpaa_eth-use-fd-information-in-dpaa_cleanup_tx_fd.patch @@ -0,0 +1,59 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:52 +0200 +Subject: dpaa_eth: use fd information in dpaa_cleanup_tx_fd() + +Git-commit: 7689d82c4585cf2047801b36f9a78410c8237a25 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Instead of reading skb fields, use information from the DPAA frame +descriptor. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -1588,13 +1588,10 @@ static struct sk_buff *dpaa_cleanup_tx_f + void *vaddr = phys_to_virt(addr); + const struct qm_sg_entry *sgt; + struct sk_buff *skb; +- int nr_frags, i; + u64 ns; +- +- skb = *(struct sk_buff **)vaddr; ++ int i; + + if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) { +- nr_frags = skb_shinfo(skb)->nr_frags; + dma_unmap_single(priv->tx_dma_dev, addr, + qm_fd_get_offset(fd) + DPAA_SGT_SIZE, + dma_dir); +@@ -1609,7 +1606,8 @@ static struct sk_buff *dpaa_cleanup_tx_f + qm_sg_entry_get_len(&sgt[0]), dma_dir); + + /* remaining pages were mapped with skb_frag_dma_map() */ +- for (i = 1; i <= nr_frags; i++) { ++ for (i = 1; (i < DPAA_SGT_MAX_ENTRIES) && ++ !qm_sg_entry_is_final(&sgt[i - 1]); i++) { + WARN_ON(qm_sg_entry_is_ext(&sgt[i])); + + dma_unmap_page(priv->tx_dma_dev, qm_sg_addr(&sgt[i]), +@@ -1618,9 +1616,12 @@ static struct sk_buff *dpaa_cleanup_tx_f + + } else { + dma_unmap_single(priv->tx_dma_dev, addr, +- skb_tail_pointer(skb) - (u8 *)vaddr, dma_dir); ++ priv->tx_headroom + qm_fd_get_length(fd), ++ dma_dir); + } + ++ skb = *(struct sk_buff **)vaddr; ++ + /* DMA unmapping is required before accessing the HW provided info */ + if (ts && priv->tx_tstamp && + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { diff --git a/patches.suse/dpaa_eth-use-only-one-buffer-pool-per-interface.patch b/patches.suse/dpaa_eth-use-only-one-buffer-pool-per-interface.patch new file mode 100644 index 0000000..14315d8 --- /dev/null +++ b/patches.suse/dpaa_eth-use-only-one-buffer-pool-per-interface.patch @@ -0,0 +1,357 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:47 +0200 +Subject: dpaa_eth: use only one buffer pool per interface + +Git-commit: f07f30042f8e0f7e67c5bf573e764a846ca9e8b5 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Currently the DPAA Ethernet driver is using three buffer pools +for each interface, with three different sizes for the buffers +provided for the FMan reception path. This patch reduces the +number of buffer pools to one per interface. This change is in +preparation of another, that will be switching from netdev_frags +to page backed buffers for the receive path. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + .../net/ethernet/freescale/dpaa/dpaa_eth.c | 95 +++++++------------ + .../net/ethernet/freescale/dpaa/dpaa_eth.h | 4 +- + .../ethernet/freescale/dpaa/dpaa_eth_sysfs.c | 6 +- + .../ethernet/freescale/dpaa/dpaa_ethtool.c | 44 ++++----- + 4 files changed, 57 insertions(+), 92 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index d3214541c7c5..9af6fdbeb9af 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -178,23 +178,7 @@ struct fm_port_fqs { + /* All the dpa bps in use at any moment */ + static struct dpaa_bp *dpaa_bp_array[BM_MAX_NUM_OF_POOLS]; + +-/* The raw buffer size must be cacheline aligned */ + #define DPAA_BP_RAW_SIZE 4096 +-/* When using more than one buffer pool, the raw sizes are as follows: +- * 1 bp: 4KB +- * 2 bp: 2KB, 4KB +- * 3 bp: 1KB, 2KB, 4KB +- * 4 bp: 1KB, 2KB, 4KB, 8KB +- */ +-static inline size_t bpool_buffer_raw_size(u8 index, u8 cnt) +-{ +- size_t res = DPAA_BP_RAW_SIZE / 4; +- u8 i; +- +- for (i = (cnt < 3) ? cnt : 3; i < 3 + index; i++) +- res *= 2; +- return res; +-} + + /* FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is + * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that, +@@ -596,10 +580,7 @@ static void dpaa_bp_free(struct dpaa_bp *dpaa_bp) + + static void dpaa_bps_free(struct dpaa_priv *priv) + { +- int i; +- +- for (i = 0; i < DPAA_BPS_NUM; i++) +- dpaa_bp_free(priv->dpaa_bps[i]); ++ dpaa_bp_free(priv->dpaa_bp); + } + + /* Use multiple WQs for FQ assignment: +@@ -1197,15 +1178,15 @@ static int dpaa_eth_init_tx_port(struct fman_port *port, struct dpaa_fq *errq, + return err; + } + +-static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps, +- size_t count, struct dpaa_fq *errq, ++static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp *bp, ++ struct dpaa_fq *errq, + struct dpaa_fq *defq, struct dpaa_fq *pcdq, + struct dpaa_buffer_layout *buf_layout) + { + struct fman_buffer_prefix_content buf_prefix_content; + struct fman_port_rx_params *rx_p; + struct fman_port_params params; +- int i, err; ++ int err; + + memset(¶ms, 0, sizeof(params)); + memset(&buf_prefix_content, 0, sizeof(buf_prefix_content)); +@@ -1224,12 +1205,9 @@ static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps, + rx_p->pcd_fqs_count = DPAA_ETH_PCD_RXQ_NUM; + } + +- count = min(ARRAY_SIZE(rx_p->ext_buf_pools.ext_buf_pool), count); +- rx_p->ext_buf_pools.num_of_pools_used = (u8)count; +- for (i = 0; i < count; i++) { +- rx_p->ext_buf_pools.ext_buf_pool[i].id = bps[i]->bpid; +- rx_p->ext_buf_pools.ext_buf_pool[i].size = (u16)bps[i]->size; +- } ++ rx_p->ext_buf_pools.num_of_pools_used = 1; ++ rx_p->ext_buf_pools.ext_buf_pool[0].id = bp->bpid; ++ rx_p->ext_buf_pools.ext_buf_pool[0].size = (u16)bp->size; + + err = fman_port_config(port, ¶ms); + if (err) { +@@ -1252,7 +1230,7 @@ static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps, + } + + static int dpaa_eth_init_ports(struct mac_device *mac_dev, +- struct dpaa_bp **bps, size_t count, ++ struct dpaa_bp *bp, + struct fm_port_fqs *port_fqs, + struct dpaa_buffer_layout *buf_layout, + struct device *dev) +@@ -1266,7 +1244,7 @@ static int dpaa_eth_init_ports(struct mac_device *mac_dev, + if (err) + return err; + +- err = dpaa_eth_init_rx_port(rxport, bps, count, port_fqs->rx_errq, ++ err = dpaa_eth_init_rx_port(rxport, bp, port_fqs->rx_errq, + port_fqs->rx_defq, port_fqs->rx_pcdq, + &buf_layout[RX]); + +@@ -1583,17 +1561,16 @@ static int dpaa_eth_refill_bpools(struct dpaa_priv *priv) + { + struct dpaa_bp *dpaa_bp; + int *countptr; +- int res, i; ++ int res; ++ ++ dpaa_bp = priv->dpaa_bp; ++ if (!dpaa_bp) ++ return -EINVAL; ++ countptr = this_cpu_ptr(dpaa_bp->percpu_count); ++ res = dpaa_eth_refill_bpool(dpaa_bp, countptr); ++ if (res) ++ return res; + +- for (i = 0; i < DPAA_BPS_NUM; i++) { +- dpaa_bp = priv->dpaa_bps[i]; +- if (!dpaa_bp) +- return -EINVAL; +- countptr = this_cpu_ptr(dpaa_bp->percpu_count); +- res = dpaa_eth_refill_bpool(dpaa_bp, countptr); +- if (res) +- return res; +- } + return 0; + } + +@@ -2761,13 +2738,13 @@ static inline u16 dpaa_get_headroom(struct dpaa_buffer_layout *bl) + + static int dpaa_eth_probe(struct platform_device *pdev) + { +- struct dpaa_bp *dpaa_bps[DPAA_BPS_NUM] = {NULL}; + struct net_device *net_dev = NULL; ++ struct dpaa_bp *dpaa_bp = NULL; + struct dpaa_fq *dpaa_fq, *tmp; + struct dpaa_priv *priv = NULL; + struct fm_port_fqs port_fqs; + struct mac_device *mac_dev; +- int err = 0, i, channel; ++ int err = 0, channel; + struct device *dev; + + dev = &pdev->dev; +@@ -2856,23 +2833,21 @@ static int dpaa_eth_probe(struct platform_device *pdev) + priv->buf_layout[TX].priv_data_size = DPAA_TX_PRIV_DATA_SIZE; /* Tx */ + + /* bp init */ +- for (i = 0; i < DPAA_BPS_NUM; i++) { +- dpaa_bps[i] = dpaa_bp_alloc(dev); +- if (IS_ERR(dpaa_bps[i])) { +- err = PTR_ERR(dpaa_bps[i]); +- goto free_dpaa_bps; +- } +- /* the raw size of the buffers used for reception */ +- dpaa_bps[i]->raw_size = bpool_buffer_raw_size(i, DPAA_BPS_NUM); +- /* avoid runtime computations by keeping the usable size here */ +- dpaa_bps[i]->size = dpaa_bp_size(dpaa_bps[i]->raw_size); +- dpaa_bps[i]->priv = priv; +- +- err = dpaa_bp_alloc_pool(dpaa_bps[i]); +- if (err < 0) +- goto free_dpaa_bps; +- priv->dpaa_bps[i] = dpaa_bps[i]; ++ dpaa_bp = dpaa_bp_alloc(dev); ++ if (IS_ERR(dpaa_bp)) { ++ err = PTR_ERR(dpaa_bp); ++ goto free_dpaa_bps; + } ++ /* the raw size of the buffers used for reception */ ++ dpaa_bp->raw_size = DPAA_BP_RAW_SIZE; ++ /* avoid runtime computations by keeping the usable size here */ ++ dpaa_bp->size = dpaa_bp_size(dpaa_bp->raw_size); ++ dpaa_bp->priv = priv; ++ ++ err = dpaa_bp_alloc_pool(dpaa_bp); ++ if (err < 0) ++ goto free_dpaa_bps; ++ priv->dpaa_bp = dpaa_bp; + + INIT_LIST_HEAD(&priv->dpaa_fq_list); + +@@ -2930,7 +2905,7 @@ static int dpaa_eth_probe(struct platform_device *pdev) + priv->rx_headroom = dpaa_get_headroom(&priv->buf_layout[RX]); + + /* All real interfaces need their ports initialized */ +- err = dpaa_eth_init_ports(mac_dev, dpaa_bps, DPAA_BPS_NUM, &port_fqs, ++ err = dpaa_eth_init_ports(mac_dev, dpaa_bp, &port_fqs, + &priv->buf_layout[0], dev); + if (err) + goto free_dpaa_fqs; +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +index 1bdfead1d334..fc2cc4c48e06 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +@@ -47,8 +47,6 @@ + /* Total number of Tx queues */ + #define DPAA_ETH_TXQ_NUM (DPAA_TC_NUM * DPAA_TC_TXQ_NUM) + +-#define DPAA_BPS_NUM 3 /* number of bpools per interface */ +- + /* More detailed FQ types - used for fine-grained WQ assignments */ + enum dpaa_fq_type { + FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */ +@@ -148,7 +146,7 @@ struct dpaa_buffer_layout { + + struct dpaa_priv { + struct dpaa_percpu_priv __percpu *percpu_priv; +- struct dpaa_bp *dpaa_bps[DPAA_BPS_NUM]; ++ struct dpaa_bp *dpaa_bp; + /* Store here the needed Tx headroom for convenience and speed + * (even though it can be computed based on the fields of buf_layout) + */ +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c +index 0d9b185e317f..ee62d25cac81 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c +@@ -131,11 +131,9 @@ static ssize_t dpaa_eth_show_bpids(struct device *dev, + { + struct dpaa_priv *priv = netdev_priv(to_net_dev(dev)); + ssize_t bytes = 0; +- int i = 0; + +- for (i = 0; i < DPAA_BPS_NUM; i++) +- bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, "%u\n", +- priv->dpaa_bps[i]->bpid); ++ bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, "%u\n", ++ priv->dpaa_bp->bpid); + + return bytes; + } +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +index 7ce2e99b594d..bc6ed1df53ca 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +@@ -223,7 +223,7 @@ static int dpaa_get_sset_count(struct net_device *net_dev, int type) + unsigned int total_stats, num_stats; + + num_stats = num_online_cpus() + 1; +- total_stats = num_stats * (DPAA_STATS_PERCPU_LEN + DPAA_BPS_NUM) + ++ total_stats = num_stats * (DPAA_STATS_PERCPU_LEN + 1) + + DPAA_STATS_GLOBAL_LEN; + + switch (type) { +@@ -235,10 +235,10 @@ static int dpaa_get_sset_count(struct net_device *net_dev, int type) + } + + static void copy_stats(struct dpaa_percpu_priv *percpu_priv, int num_cpus, +- int crr_cpu, u64 *bp_count, u64 *data) ++ int crr_cpu, u64 bp_count, u64 *data) + { + int num_values = num_cpus + 1; +- int crr = 0, j; ++ int crr = 0; + + /* update current CPU's stats and also add them to the total values */ + data[crr * num_values + crr_cpu] = percpu_priv->in_interrupt; +@@ -262,23 +262,21 @@ static void copy_stats(struct dpaa_percpu_priv *percpu_priv, int num_cpus, + data[crr * num_values + crr_cpu] = percpu_priv->stats.rx_errors; + data[crr++ * num_values + num_cpus] += percpu_priv->stats.rx_errors; + +- for (j = 0; j < DPAA_BPS_NUM; j++) { +- data[crr * num_values + crr_cpu] = bp_count[j]; +- data[crr++ * num_values + num_cpus] += bp_count[j]; +- } ++ data[crr * num_values + crr_cpu] = bp_count; ++ data[crr++ * num_values + num_cpus] += bp_count; + } + + static void dpaa_get_ethtool_stats(struct net_device *net_dev, + struct ethtool_stats *stats, u64 *data) + { +- u64 bp_count[DPAA_BPS_NUM], cg_time, cg_num; + struct dpaa_percpu_priv *percpu_priv; + struct dpaa_rx_errors rx_errors; + unsigned int num_cpus, offset; ++ u64 bp_count, cg_time, cg_num; + struct dpaa_ern_cnt ern_cnt; + struct dpaa_bp *dpaa_bp; + struct dpaa_priv *priv; +- int total_stats, i, j; ++ int total_stats, i; + bool cg_status; + + total_stats = dpaa_get_sset_count(net_dev, ETH_SS_STATS); +@@ -292,12 +290,10 @@ static void dpaa_get_ethtool_stats(struct net_device *net_dev, + + for_each_online_cpu(i) { + percpu_priv = per_cpu_ptr(priv->percpu_priv, i); +- for (j = 0; j < DPAA_BPS_NUM; j++) { +- dpaa_bp = priv->dpaa_bps[j]; +- if (!dpaa_bp->percpu_count) +- continue; +- bp_count[j] = *(per_cpu_ptr(dpaa_bp->percpu_count, i)); +- } ++ dpaa_bp = priv->dpaa_bp; ++ if (!dpaa_bp->percpu_count) ++ continue; ++ bp_count = *(per_cpu_ptr(dpaa_bp->percpu_count, i)); + rx_errors.dme += percpu_priv->rx_errors.dme; + rx_errors.fpe += percpu_priv->rx_errors.fpe; + rx_errors.fse += percpu_priv->rx_errors.fse; +@@ -315,7 +311,7 @@ static void dpaa_get_ethtool_stats(struct net_device *net_dev, + copy_stats(percpu_priv, num_cpus, i, bp_count, data); + } + +- offset = (num_cpus + 1) * (DPAA_STATS_PERCPU_LEN + DPAA_BPS_NUM); ++ offset = (num_cpus + 1) * (DPAA_STATS_PERCPU_LEN + 1); + memcpy(data + offset, &rx_errors, sizeof(struct dpaa_rx_errors)); + + offset += sizeof(struct dpaa_rx_errors) / sizeof(u64); +@@ -363,18 +359,16 @@ static void dpaa_get_strings(struct net_device *net_dev, u32 stringset, + memcpy(strings, string_cpu, ETH_GSTRING_LEN); + strings += ETH_GSTRING_LEN; + } +- for (i = 0; i < DPAA_BPS_NUM; i++) { +- for (j = 0; j < num_cpus; j++) { +- snprintf(string_cpu, ETH_GSTRING_LEN, +- "bpool %c [CPU %d]", 'a' + i, j); +- memcpy(strings, string_cpu, ETH_GSTRING_LEN); +- strings += ETH_GSTRING_LEN; +- } +- snprintf(string_cpu, ETH_GSTRING_LEN, "bpool %c [TOTAL]", +- 'a' + i); ++ for (j = 0; j < num_cpus; j++) { ++ snprintf(string_cpu, ETH_GSTRING_LEN, ++ "bpool [CPU %d]", j); + memcpy(strings, string_cpu, ETH_GSTRING_LEN); + strings += ETH_GSTRING_LEN; + } ++ snprintf(string_cpu, ETH_GSTRING_LEN, "bpool [TOTAL]"); ++ memcpy(strings, string_cpu, ETH_GSTRING_LEN); ++ strings += ETH_GSTRING_LEN; ++ + memcpy(strings, dpaa_stats_global, size); + } + +-- +2.26.2 + diff --git a/patches.suse/dpaa_eth-use-page-backed-rx-buffers.patch b/patches.suse/dpaa_eth-use-page-backed-rx-buffers.patch new file mode 100644 index 0000000..33f9eef --- /dev/null +++ b/patches.suse/dpaa_eth-use-page-backed-rx-buffers.patch @@ -0,0 +1,154 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:48 +0200 +Subject: dpaa_eth: use page backed rx buffers + +Git-commit: 8151ee88bad568f0c8284d913310473f3b95945d +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Change the buffers used for reception from netdev_frags to pages. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + .../net/ethernet/freescale/dpaa/dpaa_eth.c | 51 ++++++++----------- + 1 file changed, 22 insertions(+), 29 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index 9af6fdbeb9af..9979cd09214c 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -180,13 +180,7 @@ static struct dpaa_bp *dpaa_bp_array[BM_MAX_NUM_OF_POOLS]; + + #define DPAA_BP_RAW_SIZE 4096 + +-/* FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is +- * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that, +- * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us +- * half-page-aligned buffers, so we reserve some more space for start-of-buffer +- * alignment. +- */ +-#define dpaa_bp_size(raw_size) SKB_WITH_OVERHEAD((raw_size) - SMP_CACHE_BYTES) ++#define dpaa_bp_size(raw_size) SKB_WITH_OVERHEAD(raw_size) + + static int dpaa_max_frm; + +@@ -1313,13 +1307,14 @@ static void dpaa_fd_release(const struct net_device *net_dev, + vaddr = phys_to_virt(qm_fd_addr(fd)); + sgt = vaddr + qm_fd_get_offset(fd); + +- dma_unmap_single(dpaa_bp->priv->rx_dma_dev, qm_fd_addr(fd), +- dpaa_bp->size, DMA_FROM_DEVICE); ++ dma_unmap_page(dpaa_bp->priv->rx_dma_dev, qm_fd_addr(fd), ++ DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); + + dpaa_release_sgt_members(sgt); + +- addr = dma_map_single(dpaa_bp->priv->rx_dma_dev, vaddr, +- dpaa_bp->size, DMA_FROM_DEVICE); ++ addr = dma_map_page(dpaa_bp->priv->rx_dma_dev, ++ virt_to_page(vaddr), 0, DPAA_BP_RAW_SIZE, ++ DMA_FROM_DEVICE); + if (dma_mapping_error(dpaa_bp->priv->rx_dma_dev, addr)) { + netdev_err(net_dev, "DMA mapping failed\n"); + return; +@@ -1469,21 +1464,18 @@ static int dpaa_bp_add_8_bufs(const struct dpaa_bp *dpaa_bp) + struct net_device *net_dev = dpaa_bp->priv->net_dev; + struct bm_buffer bmb[8]; + dma_addr_t addr; +- void *new_buf; ++ struct page *p; + u8 i; + + for (i = 0; i < 8; i++) { +- new_buf = netdev_alloc_frag(dpaa_bp->raw_size); +- if (unlikely(!new_buf)) { +- netdev_err(net_dev, +- "netdev_alloc_frag() failed, size %zu\n", +- dpaa_bp->raw_size); ++ p = dev_alloc_pages(0); ++ if (unlikely(!p)) { ++ netdev_err(net_dev, "dev_alloc_pages() failed\n"); + goto release_previous_buffs; + } +- new_buf = PTR_ALIGN(new_buf, SMP_CACHE_BYTES); + +- addr = dma_map_single(dpaa_bp->priv->rx_dma_dev, new_buf, +- dpaa_bp->size, DMA_FROM_DEVICE); ++ addr = dma_map_page(dpaa_bp->priv->rx_dma_dev, p, 0, ++ DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(dpaa_bp->priv->rx_dma_dev, + addr))) { + netdev_err(net_dev, "DMA map failed\n"); +@@ -1694,7 +1686,7 @@ static struct sk_buff *contig_fd_to_skb(const struct dpaa_priv *priv, + return skb; + + free_buffer: +- skb_free_frag(vaddr); ++ free_pages((unsigned long)vaddr, 0); + return NULL; + } + +@@ -1741,8 +1733,8 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, + goto free_buffers; + + count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); +- dma_unmap_single(dpaa_bp->priv->rx_dma_dev, sg_addr, +- dpaa_bp->size, DMA_FROM_DEVICE); ++ dma_unmap_page(priv->rx_dma_dev, sg_addr, ++ DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); + if (!skb) { + sz = dpaa_bp->size + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +@@ -1794,7 +1786,7 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, + WARN_ONCE(i == DPAA_SGT_MAX_ENTRIES, "No final bit on SGT\n"); + + /* free the SG table buffer */ +- skb_free_frag(vaddr); ++ free_pages((unsigned long)vaddr, 0); + + return skb; + +@@ -1811,7 +1803,7 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, + for (i = 0; i < DPAA_SGT_MAX_ENTRIES ; i++) { + sg_addr = qm_sg_addr(&sgt[i]); + sg_vaddr = phys_to_virt(sg_addr); +- skb_free_frag(sg_vaddr); ++ free_pages((unsigned long)sg_vaddr, 0); + dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); + if (dpaa_bp) { + count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); +@@ -1822,7 +1814,7 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, + break; + } + /* free the SGT fragment */ +- skb_free_frag(vaddr); ++ free_pages((unsigned long)vaddr, 0); + + return NULL; + } +@@ -2281,8 +2273,8 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal, + return qman_cb_dqrr_consume; + } + +- dma_unmap_single(dpaa_bp->priv->rx_dma_dev, addr, dpaa_bp->size, +- DMA_FROM_DEVICE); ++ dma_unmap_page(dpaa_bp->priv->rx_dma_dev, addr, DPAA_BP_RAW_SIZE, ++ DMA_FROM_DEVICE); + + /* prefetch the first 64 bytes of the frame or the SGT start */ + vaddr = phys_to_virt(addr); +@@ -2637,7 +2629,8 @@ static inline void dpaa_bp_free_pf(const struct dpaa_bp *bp, + { + dma_addr_t addr = bm_buf_addr(bmb); + +- dma_unmap_single(bp->priv->rx_dma_dev, addr, bp->size, DMA_FROM_DEVICE); ++ dma_unmap_page(bp->priv->rx_dma_dev, addr, DPAA_BP_RAW_SIZE, ++ DMA_FROM_DEVICE); + + skb_free_frag(phys_to_virt(addr)); + } +-- +2.26.2 + diff --git a/patches.suse/ext4-check-journal-inode-extents-more-carefully.patch b/patches.suse/ext4-check-journal-inode-extents-more-carefully.patch new file mode 100644 index 0000000..306a9a5 --- /dev/null +++ b/patches.suse/ext4-check-journal-inode-extents-more-carefully.patch @@ -0,0 +1,275 @@ +From ce9f24cccdc019229b70a5c15e2b09ad9c0ab5d1 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Tue, 28 Jul 2020 15:04:34 +0200 +Subject: [PATCH] ext4: check journal inode extents more carefully +Git-commit: ce9f24cccdc019229b70a5c15e2b09ad9c0ab5d1 +Patch-mainline: v5.9-rc2 +References: bsc#1173485 + +Currently, system zones just track ranges of block, that are "important" +fs metadata (bitmaps, group descriptors, journal blocks, etc.). This +however complicates how extent tree (or indirect blocks) can be checked +for inodes that actually track such metadata - currently the journal +inode but arguably we should be treating quota files or resize inode +similarly. We cannot run __ext4_ext_check() on such metadata inodes when +loading their extents as that would immediately trigger the validity +checks and so we just hack around that and special-case the journal +inode. This however leads to a situation that a journal inode which has +extent tree of depth at least one can have invalid extent tree that gets +unnoticed until ext4_cache_extents() crashes. + +To overcome this limitation, track inode number each system zone belongs +to (0 is used for zones not belonging to any inode). We can then verify +inode number matches the expected one when verifying extent tree and +thus avoid the false errors. With this there's no need to to +special-case journal inode during extent tree checking anymore so remove +it. + +Fixes: 0a944e8a6c66 ("ext4: don't perform block validity checks on the journal inode") +Reported-by: Wolfgang Frisch +Reviewed-by: Lukas Czerner +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20200728130437.7804-4-jack@suse.cz +Signed-off-by: Theodore Ts'o +Acked-by: Jan Kara + +--- + fs/ext4/block_validity.c | 37 +++++++++++++++++++++---------------- + fs/ext4/ext4.h | 6 +++--- + fs/ext4/extents.c | 16 ++++++---------- + fs/ext4/indirect.c | 6 ++---- + fs/ext4/inode.c | 5 ++--- + fs/ext4/mballoc.c | 4 ++-- + 6 files changed, 36 insertions(+), 38 deletions(-) + +--- a/fs/ext4/block_validity.c ++++ b/fs/ext4/block_validity.c +@@ -23,6 +23,7 @@ struct ext4_system_zone { + struct rb_node node; + ext4_fsblk_t start_blk; + unsigned int count; ++ u32 ino; + }; + + static struct kmem_cache *ext4_system_zone_cachep; +@@ -43,7 +44,8 @@ void ext4_exit_system_zone(void) + static inline int can_merge(struct ext4_system_zone *entry1, + struct ext4_system_zone *entry2) + { +- if ((entry1->start_blk + entry1->count) == entry2->start_blk) ++ if ((entry1->start_blk + entry1->count) == entry2->start_blk && ++ entry1->ino == entry2->ino) + return 1; + return 0; + } +@@ -55,7 +57,7 @@ static inline int can_merge(struct ext4_ + */ + static int add_system_zone(struct ext4_sb_info *sbi, + ext4_fsblk_t start_blk, +- unsigned int count) ++ unsigned int count, u32 ino) + { + struct ext4_system_zone *new_entry, *entry; + struct rb_node **n = &sbi->system_blks.rb_node, *node; +@@ -78,6 +80,7 @@ static int add_system_zone(struct ext4_s + return -ENOMEM; + new_entry->start_blk = start_blk; + new_entry->count = count; ++ new_entry->ino = ino; + new_node = &new_entry->node; + + rb_link_node(new_node, parent, n); +@@ -153,16 +156,16 @@ static int ext4_protect_reserved_inode(s + if (n == 0) { + i++; + } else { +- if (!ext4_data_block_valid(sbi, map.m_pblk, n)) { +- ext4_error(sb, "blocks %llu-%llu from inode %u " ++ err = add_system_zone(sbi, map.m_pblk, n, ino); ++ if (err < 0) { ++ if (err == -EFSCORRUPTED) { ++ ext4_error(sb, ++ "blocks %llu-%llu from inode %u " + "overlap system zone", map.m_pblk, + map.m_pblk + map.m_len - 1, ino); +- err = -EFSCORRUPTED; ++ } + break; + } +- err = add_system_zone(sbi, map.m_pblk, n); +- if (err < 0) +- break; + i += n; + } + } +@@ -191,16 +194,16 @@ int ext4_setup_system_zone(struct super_ + if (ext4_bg_has_super(sb, i) && + ((i < 5) || ((i % flex_size) == 0))) + add_system_zone(sbi, ext4_group_first_block_no(sb, i), +- ext4_bg_num_gdb(sb, i) + 1); ++ ext4_bg_num_gdb(sb, i) + 1, 0); + gdp = ext4_get_group_desc(sb, i, NULL); +- ret = add_system_zone(sbi, ext4_block_bitmap(sb, gdp), 1); ++ ret = add_system_zone(sbi, ext4_block_bitmap(sb, gdp), 1, 0); + if (ret) + return ret; +- ret = add_system_zone(sbi, ext4_inode_bitmap(sb, gdp), 1); ++ ret = add_system_zone(sbi, ext4_inode_bitmap(sb, gdp), 1, 0); + if (ret) + return ret; + ret = add_system_zone(sbi, ext4_inode_table(sb, gdp), +- sbi->s_itb_per_group); ++ sbi->s_itb_per_group, 0); + if (ret) + return ret; + } +@@ -233,10 +236,11 @@ void ext4_release_system_zone(struct sup + * start_blk+count) is valid; 0 if some part of the block region + * overlaps with filesystem metadata blocks. + */ +-int ext4_data_block_valid(struct ext4_sb_info *sbi, ext4_fsblk_t start_blk, +- unsigned int count) ++int ext4_inode_block_valid(struct inode *inode, ext4_fsblk_t start_blk, ++ unsigned int count) + { + struct ext4_system_zone *entry; ++ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + struct rb_node *n = sbi->system_blks.rb_node; + + if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || +@@ -252,6 +256,8 @@ int ext4_data_block_valid(struct ext4_sb + else if (start_blk >= (entry->start_blk + entry->count)) + n = n->rb_right; + else { ++ if (entry->ino == inode->i_ino) ++ return 1; + sbi->s_es->s_last_error_block = cpu_to_le64(start_blk); + return 0; + } +@@ -274,8 +280,7 @@ int ext4_check_blockref(const char *func + while (bref < p+max) { + blk = le32_to_cpu(*bref++); + if (blk && +- unlikely(!ext4_data_block_valid(EXT4_SB(inode->i_sb), +- blk, 1))) { ++ unlikely(!ext4_inode_block_valid(inode, blk, 1))) { + es->s_last_error_block = cpu_to_le64(blk); + ext4_error_inode(inode, function, line, blk, + "invalid block"); +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -3122,9 +3122,9 @@ extern void ext4_release_system_zone(str + extern int ext4_setup_system_zone(struct super_block *sb); + extern int __init ext4_init_system_zone(void); + extern void ext4_exit_system_zone(void); +-extern int ext4_data_block_valid(struct ext4_sb_info *sbi, +- ext4_fsblk_t start_blk, +- unsigned int count); ++extern int ext4_inode_block_valid(struct inode *inode, ++ ext4_fsblk_t start_blk, ++ unsigned int count); + extern int ext4_check_blockref(const char *, unsigned int, + struct inode *, __le32 *, unsigned int); + +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -389,7 +389,7 @@ static int ext4_valid_extent(struct inod + */ + if (lblock + len <= lblock) + return 0; +- return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len); ++ return ext4_inode_block_valid(inode, block, len); + } + + static int ext4_valid_extent_idx(struct inode *inode, +@@ -397,7 +397,7 @@ static int ext4_valid_extent_idx(struct + { + ext4_fsblk_t block = ext4_idx_pblock(ext_idx); + +- return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, 1); ++ return ext4_inode_block_valid(inode, block, 1); + } + + static int ext4_valid_extent_entries(struct inode *inode, +@@ -554,14 +554,10 @@ __read_extent_tree_block(const char *fun + } + if (buffer_verified(bh) && !(flags & EXT4_EX_FORCE_CACHE)) + return bh; +- if (!ext4_has_feature_journal(inode->i_sb) || +- (inode->i_ino != +- le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) { +- err = __ext4_ext_check(function, line, inode, +- ext_block_hdr(bh), depth, pblk); +- if (err) +- goto errout; +- } ++ err = __ext4_ext_check(function, line, inode, ++ ext_block_hdr(bh), depth, pblk); ++ if (err) ++ goto errout; + set_buffer_verified(bh); + /* + * If this is a leaf block, cache all of its entries +--- a/fs/ext4/indirect.c ++++ b/fs/ext4/indirect.c +@@ -840,8 +840,7 @@ static int ext4_clear_blocks(handle_t *h + else if (ext4_should_journal_data(inode)) + flags |= EXT4_FREE_BLOCKS_FORGET; + +- if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), block_to_free, +- count)) { ++ if (!ext4_inode_block_valid(inode, block_to_free, count)) { + EXT4_ERROR_INODE(inode, "attempt to clear invalid " + "blocks %llu len %lu", + (unsigned long long) block_to_free, count); +@@ -1003,8 +1002,7 @@ static void ext4_free_branches(handle_t + if (!nr) + continue; /* A hole */ + +- if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), +- nr, 1)) { ++ if (!ext4_inode_block_valid(inode, nr, 1)) { + EXT4_ERROR_INODE(inode, + "invalid indirect mapped " + "block %lu (level %d)", +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -388,8 +388,7 @@ static int __check_block_validity(struct + (inode->i_ino == + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) + return 0; +- if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), map->m_pblk, +- map->m_len)) { ++ if (!ext4_inode_block_valid(inode, map->m_pblk, map->m_len)) { + ext4_error_inode(inode, func, line, map->m_pblk, + "lblock %lu mapped to illegal pblock %llu " + "(length %d)", (unsigned long) map->m_lblk, +@@ -4953,7 +4952,7 @@ struct inode *__ext4_iget(struct super_b + + ret = 0; + if (ei->i_file_acl && +- !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) { ++ !ext4_inode_block_valid(inode, ei->i_file_acl, 1)) { + ext4_error_inode(inode, function, line, 0, + "iget: bad extended attribute block %llu", + ei->i_file_acl); +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -2971,7 +2971,7 @@ ext4_mb_mark_diskspace_used(struct ext4_ + block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); + + len = EXT4_C2B(sbi, ac->ac_b_ex.fe_len); +- if (!ext4_data_block_valid(sbi, block, len)) { ++ if (!ext4_inode_block_valid(ac->ac_inode, block, len)) { + ext4_error(sb, "Allocating blocks %llu-%llu which overlap " + "fs metadata", block, block+len); + /* File system mounted not to panic on error +@@ -4732,7 +4732,7 @@ void ext4_free_blocks(handle_t *handle, + + sbi = EXT4_SB(sb); + if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && +- !ext4_data_block_valid(sbi, block, count)) { ++ !ext4_inode_block_valid(inode, block, count)) { + ext4_error(sb, "Freeing blocks not in datazone - " + "block = %llu, count = %lu", block, count); + goto error_return; diff --git a/patches.suse/ext4-don-t-allow-overlapping-system-zones.patch b/patches.suse/ext4-don-t-allow-overlapping-system-zones.patch new file mode 100644 index 0000000..5bfa577 --- /dev/null +++ b/patches.suse/ext4-don-t-allow-overlapping-system-zones.patch @@ -0,0 +1,79 @@ +From bf9a379d0980e7413d94cb18dac73db2bfc5f470 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Tue, 28 Jul 2020 15:04:33 +0200 +Subject: [PATCH] ext4: don't allow overlapping system zones +Git-commit: bf9a379d0980e7413d94cb18dac73db2bfc5f470 +Patch-mainline: v5.9-rc2 +References: bsc#1173485 + +Currently, add_system_zone() just silently merges two added system zones +that overlap. However the overlap should not happen and it generally +suggests that some unrelated metadata overlap which indicates the fs is +corrupted. We should have caught such problems earlier (e.g. in +ext4_check_descriptors()) but add this check as another line of defense. +In later patch we also use this for stricter checking of journal inode +extent tree. + +Reviewed-by: Lukas Czerner +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20200728130437.7804-3-jack@suse.cz +Signed-off-by: Theodore Ts'o +Acked-by: Jan Kara + +--- + fs/ext4/block_validity.c | 34 ++++++++++++---------------------- + 1 file changed, 12 insertions(+), 22 deletions(-) + +--- a/fs/ext4/block_validity.c ++++ b/fs/ext4/block_validity.c +@@ -57,7 +57,7 @@ static int add_system_zone(struct ext4_s + ext4_fsblk_t start_blk, + unsigned int count) + { +- struct ext4_system_zone *new_entry = NULL, *entry; ++ struct ext4_system_zone *new_entry, *entry; + struct rb_node **n = &sbi->system_blks.rb_node, *node; + struct rb_node *parent = NULL, *new_node = NULL; + +@@ -68,30 +68,20 @@ static int add_system_zone(struct ext4_s + n = &(*n)->rb_left; + else if (start_blk >= (entry->start_blk + entry->count)) + n = &(*n)->rb_right; +- else { +- if (start_blk + count > (entry->start_blk + +- entry->count)) +- entry->count = (start_blk + count - +- entry->start_blk); +- new_node = *n; +- new_entry = rb_entry(new_node, struct ext4_system_zone, +- node); +- break; +- } ++ else /* Unexpected overlap of system zones. */ ++ return -EFSCORRUPTED; + } + +- if (!new_entry) { +- new_entry = kmem_cache_alloc(ext4_system_zone_cachep, +- GFP_KERNEL); +- if (!new_entry) +- return -ENOMEM; +- new_entry->start_blk = start_blk; +- new_entry->count = count; +- new_node = &new_entry->node; ++ new_entry = kmem_cache_alloc(ext4_system_zone_cachep, ++ GFP_KERNEL); ++ if (!new_entry) ++ return -ENOMEM; ++ new_entry->start_blk = start_blk; ++ new_entry->count = count; ++ new_node = &new_entry->node; + +- rb_link_node(new_node, parent, n); +- rb_insert_color(new_node, &sbi->system_blks); +- } ++ rb_link_node(new_node, parent, n); ++ rb_insert_color(new_node, &sbi->system_blks); + + /* Can we merge to the left? */ + node = rb_prev(new_node); diff --git a/patches.suse/ext4-fix-checking-of-directory-entry-validity-for-in.patch b/patches.suse/ext4-fix-checking-of-directory-entry-validity-for-in.patch new file mode 100644 index 0000000..c0ef70e --- /dev/null +++ b/patches.suse/ext4-fix-checking-of-directory-entry-validity-for-in.patch @@ -0,0 +1,56 @@ +From 7303cb5bfe845f7d43cd9b2dbd37dbb266efda9b Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Fri, 31 Jul 2020 18:21:35 +0200 +Subject: [PATCH] ext4: fix checking of directory entry validity for inline + directories +Git-commit: 7303cb5bfe845f7d43cd9b2dbd37dbb266efda9b +Patch-mainline: v5.9-rc2 +References: bsc#1175771 + +ext4_search_dir() and ext4_generic_delete_entry() can be called both for +standard director blocks and for inline directories stored inside inode +or inline xattr space. For the second case we didn't call +ext4_check_dir_entry() with proper constraints that could result in +accepting corrupted directory entry as well as false positive filesystem +errors like: + +EXT4-fs error (device dm-0): ext4_search_dir:1395: inode #28320400: +block 113246792: comm dockerd: bad entry in directory: directory entry too +close to block end - offset=0, inode=28320403, rec_len=32, name_len=8, +size=4096 + +Fix the arguments passed to ext4_check_dir_entry(). + +Fixes: 109ba779d6cc ("ext4: check for directory entries too close to block end") +Cc: stable@vger.kernel.org +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20200731162135.8080-1-jack@suse.cz +Signed-off-by: Theodore Ts'o +Acked-by: Jan Kara + +--- + fs/ext4/namei.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -1278,8 +1278,8 @@ int ext4_search_dir(struct buffer_head * + ext4_match(fname, de)) { + /* found a match - just to be sure, do + * a full check */ +- if (ext4_check_dir_entry(dir, NULL, de, bh, bh->b_data, +- bh->b_size, offset)) ++ if (ext4_check_dir_entry(dir, NULL, de, bh, search_buf, ++ buf_size, offset)) + return -1; + *res_dir = de; + return 1; +@@ -2309,7 +2309,7 @@ int ext4_generic_delete_entry(handle_t * + de = (struct ext4_dir_entry_2 *)entry_buf; + while (i < buf_size - csum_size) { + if (ext4_check_dir_entry(dir, NULL, de, bh, +- bh->b_data, bh->b_size, i)) ++ entry_buf, buf_size, i)) + return -EFSCORRUPTED; + if (de == de_del) { + if (pde) diff --git a/patches.suse/ext4-fix-potential-negative-array-index-in-do_split.patch b/patches.suse/ext4-fix-potential-negative-array-index-in-do_split.patch new file mode 100644 index 0000000..5cc61d3 --- /dev/null +++ b/patches.suse/ext4-fix-potential-negative-array-index-in-do_split.patch @@ -0,0 +1,68 @@ +From 5872331b3d91820e14716632ebb56b1399b34fe1 Mon Sep 17 00:00:00 2001 +From: Eric Sandeen +Date: Wed, 17 Jun 2020 14:19:04 -0500 +Subject: [PATCH] ext4: fix potential negative array index in do_split() +Git-commit: 5872331b3d91820e14716632ebb56b1399b34fe1 +Patch-mainline: v5.9-rc2 +References: bsc#1173798 CVE-2020-14314 + +If for any reason a directory passed to do_split() does not have enough +active entries to exceed half the size of the block, we can end up +iterating over all "count" entries without finding a split point. + +In this case, count == move, and split will be zero, and we will +attempt a negative index into map[]. + +Guard against this by detecting this case, and falling back to +split-to-half-of-count instead; in this case we will still have +plenty of space (> half blocksize) in each split block. + +Fixes: ef2b02d3e617 ("ext34: ensure do_split leaves enough free space in both blocks") +Signed-off-by: Eric Sandeen +Reviewed-by: Andreas Dilger +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/f53e246b-647c-64bb-16ec-135383c70ad7@redhat.com +Signed-off-by: Theodore Ts'o +Acked-by: Jan Kara + +--- + fs/ext4/namei.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 56738b538ddf..ef606301a106 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -1858,7 +1858,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, + blocksize, hinfo, map); + map -= count; + dx_sort_map(map, count); +- /* Split the existing block in the middle, size-wise */ ++ /* Ensure that neither split block is over half full */ + size = 0; + move = 0; + for (i = count-1; i >= 0; i--) { +@@ -1868,8 +1868,18 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, + size += map[i].size; + move++; + } +- /* map index at which we will split */ +- split = count - move; ++ /* ++ * map index at which we will split ++ * ++ * If the sum of active entries didn't exceed half the block size, just ++ * split it in half by count; each resulting block will have at least ++ * half the space free. ++ */ ++ if (i > 0) ++ split = count - move; ++ else ++ split = count/2; ++ + hash2 = map[split].hash; + continued = hash2 == map[split - 1].hash; + dxtrace(printk(KERN_INFO "Split block %lu at %x, %i/%i\n", +-- +2.16.4 + diff --git a/patches.suse/ext4-handle-error-of-ext4_setup_system_zone-on-remou.patch b/patches.suse/ext4-handle-error-of-ext4_setup_system_zone-on-remou.patch new file mode 100644 index 0000000..af3e863 --- /dev/null +++ b/patches.suse/ext4-handle-error-of-ext4_setup_system_zone-on-remou.patch @@ -0,0 +1,34 @@ +From d176b1f62f242ab259ff665a26fbac69db1aecba Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Tue, 28 Jul 2020 15:04:32 +0200 +Subject: [PATCH] ext4: handle error of ext4_setup_system_zone() on remount +Git-commit: d176b1f62f242ab259ff665a26fbac69db1aecba +Patch-mainline: v5.9-rc2 +References: bsc#1173485 + +ext4_setup_system_zone() can fail. Handle the failure in ext4_remount(). + +Reviewed-by: Lukas Czerner +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20200728130437.7804-2-jack@suse.cz +Signed-off-by: Theodore Ts'o +Acked-by: Jan Kara + +--- + fs/ext4/super.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -5254,7 +5254,10 @@ static int ext4_remount(struct super_blo + ext4_register_li_request(sb, first_not_zeroed); + } + +- ext4_setup_system_zone(sb); ++ err = ext4_setup_system_zone(sb); ++ if (err) ++ goto restore_opts; ++ + if (sbi->s_journal == NULL && !(old_sb_flags & MS_RDONLY)) + ext4_commit_super(sb, 1); + diff --git a/patches.suse/fsl-fman-add-API-to-get-the-device-behind-a-fman-por.patch b/patches.suse/fsl-fman-add-API-to-get-the-device-behind-a-fman-por.patch new file mode 100644 index 0000000..ebacae6 --- /dev/null +++ b/patches.suse/fsl-fman-add-API-to-get-the-device-behind-a-fman-por.patch @@ -0,0 +1,60 @@ +From: Laurentiu Tudor +Date: Wed, 23 Oct 2019 12:08:43 +0300 +Subject: fsl/fman: add API to get the device behind a fman port + +Git-commit: 681e38380c79e6ed00232385a613b2216dc23d22 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Add an API that retrieves the 'struct device' that the specified FMan +port probed against. The new API will be used in a subsequent patch +that corrects the DMA devices used by the dpaa_eth driver. + +Signed-off-by: Laurentiu Tudor +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/fman/fman_port.c | 14 ++++++++++++++ + drivers/net/ethernet/freescale/fman/fman_port.h | 2 ++ + 2 files changed, 16 insertions(+) + +diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c +index ee82ee1384eb..bd76c9730692 100644 +--- a/drivers/net/ethernet/freescale/fman/fman_port.c ++++ b/drivers/net/ethernet/freescale/fman/fman_port.c +@@ -1728,6 +1728,20 @@ u32 fman_port_get_qman_channel_id(struct fman_port *port) + } + EXPORT_SYMBOL(fman_port_get_qman_channel_id); + ++/** ++ * fman_port_get_device ++ * port: Pointer to the FMan port device ++ * ++ * Get the 'struct device' associated to the specified FMan port device ++ * ++ * Return: pointer to associated 'struct device' ++ */ ++struct device *fman_port_get_device(struct fman_port *port) ++{ ++ return port->dev; ++} ++EXPORT_SYMBOL(fman_port_get_device); ++ + int fman_port_get_hash_result_offset(struct fman_port *port, u32 *offset) + { + if (port->buffer_offsets.hash_result_offset == ILLEGAL_BASE) +diff --git a/drivers/net/ethernet/freescale/fman/fman_port.h b/drivers/net/ethernet/freescale/fman/fman_port.h +index 9dbb69f40121..82f12661a46d 100644 +--- a/drivers/net/ethernet/freescale/fman/fman_port.h ++++ b/drivers/net/ethernet/freescale/fman/fman_port.h +@@ -157,4 +157,6 @@ int fman_port_get_tstamp(struct fman_port *port, const void *data, u64 *tstamp); + + struct fman_port *fman_port_bind(struct device *dev); + ++struct device *fman_port_get_device(struct fman_port *port); ++ + #endif /* __FMAN_PORT_H */ +-- +2.26.2 + diff --git a/patches.suse/fsl-fman-detect-FMan-erratum-A050385.patch b/patches.suse/fsl-fman-detect-FMan-erratum-A050385.patch new file mode 100644 index 0000000..25bc778 --- /dev/null +++ b/patches.suse/fsl-fman-detect-FMan-erratum-A050385.patch @@ -0,0 +1,129 @@ +From: Madalin Bucur +Date: Wed, 4 Mar 2020 18:04:27 +0200 +Subject: fsl/fman: detect FMan erratum A050385 + +Git-commit: b281f7b93b258ce1419043bbd898a29254d5c9c7 +Patch-mainline: v5.6-rc6 +References: bsc#1174550 + +Detect the presence of the A050385 erratum. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/fman/Kconfig | 28 +++++++++++++++++++++ + drivers/net/ethernet/freescale/fman/fman.c | 18 +++++++++++++ + drivers/net/ethernet/freescale/fman/fman.h | 5 ++++ + 3 files changed, 51 insertions(+) + +diff --git a/drivers/net/ethernet/freescale/fman/Kconfig b/drivers/net/ethernet/freescale/fman/Kconfig +index 0139cb9042ec..34150182cc35 100644 +--- a/drivers/net/ethernet/freescale/fman/Kconfig ++++ b/drivers/net/ethernet/freescale/fman/Kconfig +@@ -8,3 +8,31 @@ config FSL_FMAN + help + Freescale Data-Path Acceleration Architecture Frame Manager + (FMan) support ++ ++config DPAA_ERRATUM_A050385 ++ bool ++ depends on ARM64 && FSL_DPAA ++ default y ++ help ++ DPAA FMan erratum A050385 software workaround implementation: ++ align buffers, data start, SG fragment length to avoid FMan DMA ++ splits. ++ FMAN DMA read or writes under heavy traffic load may cause FMAN ++ internal resource leak thus stopping further packet processing. ++ The FMAN internal queue can overflow when FMAN splits single ++ read or write transactions into multiple smaller transactions ++ such that more than 17 AXI transactions are in flight from FMAN ++ to interconnect. When the FMAN internal queue overflows, it can ++ stall further packet processing. The issue can occur with any ++ one of the following three conditions: ++ 1. FMAN AXI transaction crosses 4K address boundary (Errata ++ A010022) ++ 2. FMAN DMA address for an AXI transaction is not 16 byte ++ aligned, i.e. the last 4 bits of an address are non-zero ++ 3. Scatter Gather (SG) frames have more than one SG buffer in ++ the SG list and any one of the buffers, except the last ++ buffer in the SG list has data size that is not a multiple ++ of 16 bytes, i.e., other than 16, 32, 48, 64, etc. ++ With any one of the above three conditions present, there is ++ likelihood of stalled FMAN packet processing, especially under ++ stress with multiple ports injecting line-rate traffic. +diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c +index 934111def0be..f151d6e111dd 100644 +--- a/drivers/net/ethernet/freescale/fman/fman.c ++++ b/drivers/net/ethernet/freescale/fman/fman.c +@@ -1,5 +1,6 @@ + /* + * Copyright 2008-2015 Freescale Semiconductor Inc. ++ * Copyright 2020 NXP + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: +@@ -566,6 +567,10 @@ struct fman_cfg { + u32 qmi_def_tnums_thresh; + }; + ++#ifdef CONFIG_DPAA_ERRATUM_A050385 ++static bool fman_has_err_a050385; ++#endif ++ + static irqreturn_t fman_exceptions(struct fman *fman, + enum fman_exceptions exception) + { +@@ -2518,6 +2523,14 @@ struct fman *fman_bind(struct device *fm_dev) + } + EXPORT_SYMBOL(fman_bind); + ++#ifdef CONFIG_DPAA_ERRATUM_A050385 ++bool fman_has_errata_a050385(void) ++{ ++ return fman_has_err_a050385; ++} ++EXPORT_SYMBOL(fman_has_errata_a050385); ++#endif ++ + static irqreturn_t fman_err_irq(int irq, void *handle) + { + struct fman *fman = (struct fman *)handle; +@@ -2845,6 +2858,11 @@ static struct fman *read_dts_node(struct platform_device *of_dev) + goto fman_free; + } + ++#ifdef CONFIG_DPAA_ERRATUM_A050385 ++ fman_has_err_a050385 = ++ of_property_read_bool(fm_node, "fsl,erratum-a050385"); ++#endif ++ + return fman; + + fman_node_put: +diff --git a/drivers/net/ethernet/freescale/fman/fman.h b/drivers/net/ethernet/freescale/fman/fman.h +index 935c317fa696..f2ede1360f03 100644 +--- a/drivers/net/ethernet/freescale/fman/fman.h ++++ b/drivers/net/ethernet/freescale/fman/fman.h +@@ -1,5 +1,6 @@ + /* + * Copyright 2008-2015 Freescale Semiconductor Inc. ++ * Copyright 2020 NXP + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: +@@ -398,6 +399,10 @@ u16 fman_get_max_frm(void); + + int fman_get_rx_extra_headroom(void); + ++#ifdef CONFIG_DPAA_ERRATUM_A050385 ++bool fman_has_errata_a050385(void); ++#endif ++ + struct fman *fman_bind(struct device *dev); + + #endif /* __FM_H */ +-- +2.26.2 + diff --git a/patches.suse/fsl-fman-don-t-touch-liodn-base-regs-reserved-on-non.patch b/patches.suse/fsl-fman-don-t-touch-liodn-base-regs-reserved-on-non.patch new file mode 100644 index 0000000..8a25c27 --- /dev/null +++ b/patches.suse/fsl-fman-don-t-touch-liodn-base-regs-reserved-on-non.patch @@ -0,0 +1,53 @@ +From: Laurentiu Tudor +Date: Wed, 23 Oct 2019 12:08:40 +0300 +Subject: fsl/fman: don't touch liodn base regs reserved on non-PAMU SoCs + +Git-commit: 9b56beed1e8adc6b7b142bed5cf89531b9cf4a91 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +The liodn base registers are specific to PAMU based NXP systems and are +reserved on SMMU based ones. Don't access them unless PAMU is compiled in. + +Signed-off-by: Laurentiu Tudor +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/fman/fman.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c +index 210749bf1eac..934111def0be 100644 +--- a/drivers/net/ethernet/freescale/fman/fman.c ++++ b/drivers/net/ethernet/freescale/fman/fman.c +@@ -634,6 +634,9 @@ static void set_port_liodn(struct fman *fman, u8 port_id, + { + u32 tmp; + ++ iowrite32be(liodn_ofst, &fman->bmi_regs->fmbm_spliodn[port_id - 1]); ++ if (!IS_ENABLED(CONFIG_FSL_PAMU)) ++ return; + /* set LIODN base for this port */ + tmp = ioread32be(&fman->dma_regs->fmdmplr[port_id / 2]); + if (port_id % 2) { +@@ -644,7 +647,6 @@ static void set_port_liodn(struct fman *fman, u8 port_id, + tmp |= liodn_base << DMA_LIODN_SHIFT; + } + iowrite32be(tmp, &fman->dma_regs->fmdmplr[port_id / 2]); +- iowrite32be(liodn_ofst, &fman->bmi_regs->fmbm_spliodn[port_id - 1]); + } + + static void enable_rams_ecc(struct fman_fpm_regs __iomem *fpm_rg) +@@ -1942,6 +1944,8 @@ static int fman_init(struct fman *fman) + + fman->liodn_offset[i] = + ioread32be(&fman->bmi_regs->fmbm_spliodn[i - 1]); ++ if (!IS_ENABLED(CONFIG_FSL_PAMU)) ++ continue; + liodn_base = ioread32be(&fman->dma_regs->fmdmplr[i / 2]); + if (i % 2) { + /* FMDM_PLR LSB holds LIODN base for odd ports */ +-- +2.26.2 + diff --git a/patches.suse/fsl-fman-remove-unused-struct-member.patch b/patches.suse/fsl-fman-remove-unused-struct-member.patch new file mode 100644 index 0000000..f059585 --- /dev/null +++ b/patches.suse/fsl-fman-remove-unused-struct-member.patch @@ -0,0 +1,43 @@ +From: Madalin Bucur +Date: Wed, 23 Oct 2019 12:08:45 +0300 +Subject: fsl/fman: remove unused struct member + +Git-commit: 2579bce4cf62980f8d4f6bf7d485da85dc677a91 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Remove unused struct member second_largest_buf_size. Also, an out of +bounds access would have occurred in the removed code if there was only +one buffer pool in use. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/net/ethernet/freescale/fman/fman_port.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c +index bd76c9730692..87b26f063cc8 100644 +--- a/drivers/net/ethernet/freescale/fman/fman_port.c ++++ b/drivers/net/ethernet/freescale/fman/fman_port.c +@@ -435,7 +435,6 @@ struct fman_port_cfg { + + struct fman_port_rx_pools_params { + u8 num_of_pools; +- u16 second_largest_buf_size; + u16 largest_buf_size; + }; + +@@ -946,8 +945,6 @@ static int set_ext_buffer_pools(struct fman_port *port) + port->rx_pools_params.num_of_pools = ext_buf_pools->num_of_pools_used; + port->rx_pools_params.largest_buf_size = + sizes_array[ordered_array[ext_buf_pools->num_of_pools_used - 1]]; +- port->rx_pools_params.second_largest_buf_size = +- sizes_array[ordered_array[ext_buf_pools->num_of_pools_used - 2]]; + + /* FMBM_RMPD reg. - pool depletion */ + if (buf_pool_depletion->pools_grp_mode_enable) { +-- +2.26.2 + diff --git a/patches.suse/genetlink-remove-genl_bind.patch b/patches.suse/genetlink-remove-genl_bind.patch new file mode 100644 index 0000000..83f3eff --- /dev/null +++ b/patches.suse/genetlink-remove-genl_bind.patch @@ -0,0 +1,132 @@ +From: Sean Tranchetti +Date: Tue, 30 Jun 2020 11:50:17 -0600 +Subject: genetlink: remove genl_bind +Git-commit: 1e82a62fec613844da9e558f3493540a5b7a7b67 +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +A potential deadlock can occur during registering or unregistering a +new generic netlink family between the main nl_table_lock and the +cb_lock where each thread wants the lock held by the other, as +demonstrated below. + +1) Thread 1 is performing a netlink_bind() operation on a socket. As part + of this call, it will call netlink_lock_table(), incrementing the + nl_table_users count to 1. +2) Thread 2 is registering (or unregistering) a genl_family via the + genl_(un)register_family() API. The cb_lock semaphore will be taken for + writing. +3) Thread 1 will call genl_bind() as part of the bind operation to handle + subscribing to GENL multicast groups at the request of the user. It will + attempt to take the cb_lock semaphore for reading, but it will fail and + be scheduled away, waiting for Thread 2 to finish the write. +4) Thread 2 will call netlink_table_grab() during the (un)registration + call. However, as Thread 1 has incremented nl_table_users, it will not + be able to proceed, and both threads will be stuck waiting for the + other. + +genl_bind() is a noop, unless a genl_family implements the mcast_bind() +function to handle setting up family-specific multicast operations. Since +no one in-tree uses this functionality as Cong pointed out, simply removing +the genl_bind() function will remove the possibility for deadlock, as there +is no attempt by Thread 1 above to take the cb_lock semaphore. + +Fixes: c380d9a7afff ("genetlink: pass multicast bind/unbind to families") +Suggested-by: Cong Wang +Acked-by: Johannes Berg +Reported-by: kernel test robot +Signed-off-by: Sean Tranchetti +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + include/net/genetlink.h | 8 ------- + net/netlink/genetlink.c | 49 ------------------------------------------------ + 2 files changed, 57 deletions(-) + +--- a/include/net/genetlink.h ++++ b/include/net/genetlink.h +@@ -33,12 +33,6 @@ struct genl_info; + * do additional, common, filtering and return an error + * @post_doit: called after an operation's doit callback, it may + * undo operations done by pre_doit, for example release locks +- * @mcast_bind: a socket bound to the given multicast group (which +- * is given as the offset into the groups array) +- * @mcast_unbind: a socket was unbound from the given multicast group. +- * Note that unbind() will not be called symmetrically if the +- * generic netlink family is removed while there are still open +- * sockets. + * @attrbuf: buffer to store parsed attributes (private) + * @mcgrps: multicast groups used by this family + * @n_mcgrps: number of multicast groups +@@ -61,8 +55,6 @@ struct genl_family { + void (*post_doit)(const struct genl_ops *ops, + struct sk_buff *skb, + struct genl_info *info); +- int (*mcast_bind)(struct net *net, int group); +- void (*mcast_unbind)(struct net *net, int group); + struct nlattr ** attrbuf; /* private */ + const struct genl_ops * ops; + const struct genl_multicast_group *mcgrps; +--- a/net/netlink/genetlink.c ++++ b/net/netlink/genetlink.c +@@ -958,60 +958,11 @@ static struct genl_family genl_ctrl __ro + .netnsok = true, + }; + +-static int genl_bind(struct net *net, int group) +-{ +- struct genl_family *f; +- int err = -ENOENT; +- unsigned int id; +- +- down_read(&cb_lock); +- +- idr_for_each_entry(&genl_fam_idr, f, id) { +- if (group >= f->mcgrp_offset && +- group < f->mcgrp_offset + f->n_mcgrps) { +- int fam_grp = group - f->mcgrp_offset; +- +- if (!f->netnsok && net != &init_net) +- err = -ENOENT; +- else if (f->mcast_bind) +- err = f->mcast_bind(net, fam_grp); +- else +- err = 0; +- break; +- } +- } +- up_read(&cb_lock); +- +- return err; +-} +- +-static void genl_unbind(struct net *net, int group) +-{ +- struct genl_family *f; +- unsigned int id; +- +- down_read(&cb_lock); +- +- idr_for_each_entry(&genl_fam_idr, f, id) { +- if (group >= f->mcgrp_offset && +- group < f->mcgrp_offset + f->n_mcgrps) { +- int fam_grp = group - f->mcgrp_offset; +- +- if (f->mcast_unbind) +- f->mcast_unbind(net, fam_grp); +- break; +- } +- } +- up_read(&cb_lock); +-} +- + static int __net_init genl_pernet_init(struct net *net) + { + struct netlink_kernel_cfg cfg = { + .input = genl_rcv, + .flags = NL_CFG_F_NONROOT_RECV, +- .bind = genl_bind, +- .unbind = genl_unbind, + }; + + /* we'll bump the group number right afterwards */ diff --git a/patches.suse/ip6_gre-fix-null-ptr-deref-in-ip6gre_init_net.patch b/patches.suse/ip6_gre-fix-null-ptr-deref-in-ip6gre_init_net.patch new file mode 100644 index 0000000..81cc6fc --- /dev/null +++ b/patches.suse/ip6_gre-fix-null-ptr-deref-in-ip6gre_init_net.patch @@ -0,0 +1,79 @@ +From: Wei Yongjun +Date: Mon, 13 Jul 2020 23:59:50 +0800 +Subject: ip6_gre: fix null-ptr-deref in ip6gre_init_net() +Git-commit: 46ef5b89ec0ecf290d74c4aee844f063933c4da4 +Patch-mainline: 5.8-rc7 +References: git-fixes + +KASAN report null-ptr-deref error when register_netdev() failed: + +KASAN: null-ptr-deref in range [0x00000000000003c0-0x00000000000003c7] +CPU: 2 PID: 422 Comm: ip Not tainted 5.8.0-rc4+ #12 +Call Trace: + ip6gre_init_net+0x4ab/0x580 + ? ip6gre_tunnel_uninit+0x3f0/0x3f0 + ops_init+0xa8/0x3c0 + setup_net+0x2de/0x7e0 + ? rcu_read_lock_bh_held+0xb0/0xb0 + ? ops_init+0x3c0/0x3c0 + ? kasan_unpoison_shadow+0x33/0x40 + ? __kasan_kmalloc.constprop.0+0xc2/0xd0 + copy_net_ns+0x27d/0x530 + create_new_namespaces+0x382/0xa30 + unshare_nsproxy_namespaces+0xa1/0x1d0 + ksys_unshare+0x39c/0x780 + ? walk_process_tree+0x2a0/0x2a0 + ? trace_hardirqs_on+0x4a/0x1b0 + ? _raw_spin_unlock_irq+0x1f/0x30 + ? syscall_trace_enter+0x1a7/0x330 + ? do_syscall_64+0x1c/0xa0 + __x64_sys_unshare+0x2d/0x40 + do_syscall_64+0x56/0xa0 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +ip6gre_tunnel_uninit() has set 'ign->fb_tunnel_dev' to NULL, later +access to ign->fb_tunnel_dev cause null-ptr-deref. Fix it by saving +'ign->fb_tunnel_dev' to local variable ndev. + +Fixes: dafabb6590cb ("ip6_gre: fix use-after-free in ip6gre_tunnel_lookup()") +Reported-by: Hulk Robot +Signed-off-by: Wei Yongjun +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv6/ip6_gre.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -1175,15 +1175,16 @@ static void ip6gre_destroy_tunnels(struc + static int __net_init ip6gre_init_net(struct net *net) + { + struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); ++ struct net_device *ndev; + int err; + +- ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0", +- NET_NAME_UNKNOWN, +- ip6gre_tunnel_setup); +- if (!ign->fb_tunnel_dev) { ++ ndev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0", ++ NET_NAME_UNKNOWN, ip6gre_tunnel_setup); ++ if (!ndev) { + err = -ENOMEM; + goto err_alloc_dev; + } ++ ign->fb_tunnel_dev = ndev; + dev_net_set(ign->fb_tunnel_dev, net); + /* FB netdevice is special: we have one, and only one per netns. + * Allowing to move it to another netns is clearly unsafe. +@@ -1203,7 +1204,7 @@ static int __net_init ip6gre_init_net(st + return 0; + + err_reg_dev: +- free_netdev(ign->fb_tunnel_dev); ++ free_netdev(ndev); + err_alloc_dev: + return err; + } diff --git a/patches.suse/ip6_gre-fix-use-after-free-in-ip6gre_tunnel_lookup.patch b/patches.suse/ip6_gre-fix-use-after-free-in-ip6gre_tunnel_lookup.patch new file mode 100644 index 0000000..5f64075 --- /dev/null +++ b/patches.suse/ip6_gre-fix-use-after-free-in-ip6gre_tunnel_lookup.patch @@ -0,0 +1,112 @@ +From: Taehee Yoo +Date: Tue, 16 Jun 2020 16:04:00 +0000 +Subject: ip6_gre: fix use-after-free in ip6gre_tunnel_lookup() +Git-commit: dafabb6590cb15f300b77c095d50312e2c7c8e0f +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +In the datapath, the ip6gre_tunnel_lookup() is used and it internally uses +fallback tunnel device pointer, which is fb_tunnel_dev. +This pointer variable should be set to NULL when a fb interface is deleted. +But there is no routine to set fb_tunnel_dev pointer to NULL. +So, this pointer will be still used after interface is deleted and +it eventually results in the use-after-free problem. + +Test commands: + ip netns add A + ip netns add B + ip link add eth0 type veth peer name eth1 + ip link set eth0 netns A + ip link set eth1 netns B + + ip netns exec A ip link set lo up + ip netns exec A ip link set eth0 up + ip netns exec A ip link add ip6gre1 type ip6gre local fc:0::1 \ + remote fc:0::2 + ip netns exec A ip -6 a a fc:100::1/64 dev ip6gre1 + ip netns exec A ip link set ip6gre1 up + ip netns exec A ip -6 a a fc:0::1/64 dev eth0 + ip netns exec A ip link set ip6gre0 up + + ip netns exec B ip link set lo up + ip netns exec B ip link set eth1 up + ip netns exec B ip link add ip6gre1 type ip6gre local fc:0::2 \ + remote fc:0::1 + ip netns exec B ip -6 a a fc:100::2/64 dev ip6gre1 + ip netns exec B ip link set ip6gre1 up + ip netns exec B ip -6 a a fc:0::2/64 dev eth1 + ip netns exec B ip link set ip6gre0 up + ip netns exec A ping fc:100::2 -s 60000 & + ip netns del B + +Splat looks like: +[ 73.087285][ C1] BUG: KASAN: use-after-free in ip6gre_tunnel_lookup+0x1064/0x13f0 [ip6_gre] +[ 73.088361][ C1] Read of size 4 at addr ffff888040559218 by task ping/1429 +[ 73.089317][ C1] +[ 73.089638][ C1] CPU: 1 PID: 1429 Comm: ping Not tainted 5.7.0+ #602 +[ 73.090531][ C1] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 +[ 73.091725][ C1] Call Trace: +[ 73.092160][ C1] +[ 73.092556][ C1] dump_stack+0x96/0xdb +[ 73.093122][ C1] print_address_description.constprop.6+0x2cc/0x450 +[ 73.094016][ C1] ? ip6gre_tunnel_lookup+0x1064/0x13f0 [ip6_gre] +[ 73.094894][ C1] ? ip6gre_tunnel_lookup+0x1064/0x13f0 [ip6_gre] +[ 73.095767][ C1] ? ip6gre_tunnel_lookup+0x1064/0x13f0 [ip6_gre] +[ 73.096619][ C1] kasan_report+0x154/0x190 +[ 73.097209][ C1] ? ip6gre_tunnel_lookup+0x1064/0x13f0 [ip6_gre] +[ 73.097989][ C1] ip6gre_tunnel_lookup+0x1064/0x13f0 [ip6_gre] +[ 73.098750][ C1] ? gre_del_protocol+0x60/0x60 [gre] +[ 73.099500][ C1] gre_rcv+0x1c5/0x1450 [ip6_gre] +[ 73.100199][ C1] ? ip6gre_header+0xf00/0xf00 [ip6_gre] +[ 73.100985][ C1] ? rcu_read_lock_sched_held+0xc0/0xc0 +[ 73.101830][ C1] ? ip6_input_finish+0x5/0xf0 +[ 73.102483][ C1] ip6_protocol_deliver_rcu+0xcbb/0x1510 +[ 73.103296][ C1] ip6_input_finish+0x5b/0xf0 +[ 73.103920][ C1] ip6_input+0xcd/0x2c0 +[ 73.104473][ C1] ? ip6_input_finish+0xf0/0xf0 +[ 73.105115][ C1] ? rcu_read_lock_held+0x90/0xa0 +[ 73.105783][ C1] ? rcu_read_lock_sched_held+0xc0/0xc0 +[ 73.106548][ C1] ipv6_rcv+0x1f1/0x300 +[ ... ] + +Suggested-by: Eric Dumazet +Fixes: c12b395a4664 ("gre: Support GRE over IPv6") +Signed-off-by: Taehee Yoo +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv6/ip6_gre.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -124,6 +124,7 @@ static struct ip6_tnl *ip6gre_tunnel_loo + int dev_type = (gre_proto == htons(ETH_P_TEB)) ? + ARPHRD_ETHER : ARPHRD_IP6GRE; + int score, cand_score = 4; ++ struct net_device *ndev; + + for_each_ip_tunnel_rcu(t, ign->tunnels_r_l[h0 ^ h1]) { + if (!ipv6_addr_equal(local, &t->parms.laddr) || +@@ -226,9 +227,9 @@ static struct ip6_tnl *ip6gre_tunnel_loo + if (cand) + return cand; + +- dev = ign->fb_tunnel_dev; +- if (dev->flags & IFF_UP) +- return netdev_priv(dev); ++ ndev = READ_ONCE(ign->fb_tunnel_dev); ++ if (ndev && ndev->flags & IFF_UP) ++ return netdev_priv(ndev); + + return NULL; + } +@@ -364,6 +365,8 @@ static void ip6gre_tunnel_uninit(struct + struct ip6gre_net *ign = net_generic(t->net, ip6gre_net_id); + + ip6gre_tunnel_unlink(ign, t); ++ if (ign->fb_tunnel_dev == dev) ++ WRITE_ONCE(ign->fb_tunnel_dev, NULL); + dst_cache_reset(&t->dst_cache); + dev_put(dev); + } diff --git a/patches.suse/ip_tunnel-fix-use-after-free-in-ip_tunnel_lookup.patch b/patches.suse/ip_tunnel-fix-use-after-free-in-ip_tunnel_lookup.patch new file mode 100644 index 0000000..7ccf1bc --- /dev/null +++ b/patches.suse/ip_tunnel-fix-use-after-free-in-ip_tunnel_lookup.patch @@ -0,0 +1,120 @@ +From: Taehee Yoo +Date: Tue, 16 Jun 2020 16:51:51 +0000 +Subject: ip_tunnel: fix use-after-free in ip_tunnel_lookup() +Git-commit: ba61539c6ae57f4146284a5cb4f7b7ed8d42bf45 +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +In the datapath, the ip_tunnel_lookup() is used and it internally uses +fallback tunnel device pointer, which is fb_tunnel_dev. +This pointer variable should be set to NULL when a fb interface is deleted. +But there is no routine to set fb_tunnel_dev pointer to NULL. +So, this pointer will be still used after interface is deleted and +it eventually results in the use-after-free problem. + +Test commands: + ip netns add A + ip netns add B + ip link add eth0 type veth peer name eth1 + ip link set eth0 netns A + ip link set eth1 netns B + + ip netns exec A ip link set lo up + ip netns exec A ip link set eth0 up + ip netns exec A ip link add gre1 type gre local 10.0.0.1 \ + remote 10.0.0.2 + ip netns exec A ip link set gre1 up + ip netns exec A ip a a 10.0.100.1/24 dev gre1 + ip netns exec A ip a a 10.0.0.1/24 dev eth0 + + ip netns exec B ip link set lo up + ip netns exec B ip link set eth1 up + ip netns exec B ip link add gre1 type gre local 10.0.0.2 \ + remote 10.0.0.1 + ip netns exec B ip link set gre1 up + ip netns exec B ip a a 10.0.100.2/24 dev gre1 + ip netns exec B ip a a 10.0.0.2/24 dev eth1 + ip netns exec A hping3 10.0.100.2 -2 --flood -d 60000 & + ip netns del B + +Splat looks like: +[ 77.793450][ C3] ================================================================== +[ 77.794702][ C3] BUG: KASAN: use-after-free in ip_tunnel_lookup+0xcc4/0xf30 +[ 77.795573][ C3] Read of size 4 at addr ffff888060bd9c84 by task hping3/2905 +[ 77.796398][ C3] +[ 77.796664][ C3] CPU: 3 PID: 2905 Comm: hping3 Not tainted 5.8.0-rc1+ #616 +[ 77.797474][ C3] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 +[ 77.798453][ C3] Call Trace: +[ 77.798815][ C3] +[ 77.799142][ C3] dump_stack+0x9d/0xdb +[ 77.799605][ C3] print_address_description.constprop.7+0x2cc/0x450 +[ 77.800365][ C3] ? ip_tunnel_lookup+0xcc4/0xf30 +[ 77.800908][ C3] ? ip_tunnel_lookup+0xcc4/0xf30 +[ 77.801517][ C3] ? ip_tunnel_lookup+0xcc4/0xf30 +[ 77.802145][ C3] kasan_report+0x154/0x190 +[ 77.802821][ C3] ? ip_tunnel_lookup+0xcc4/0xf30 +[ 77.803503][ C3] ip_tunnel_lookup+0xcc4/0xf30 +[ 77.804165][ C3] __ipgre_rcv+0x1ab/0xaa0 [ip_gre] +[ 77.804862][ C3] ? rcu_read_lock_sched_held+0xc0/0xc0 +[ 77.805621][ C3] gre_rcv+0x304/0x1910 [ip_gre] +[ 77.806293][ C3] ? lock_acquire+0x1a9/0x870 +[ 77.806925][ C3] ? gre_rcv+0xfe/0x354 [gre] +[ 77.807559][ C3] ? erspan_xmit+0x2e60/0x2e60 [ip_gre] +[ 77.808305][ C3] ? rcu_read_lock_sched_held+0xc0/0xc0 +[ 77.809032][ C3] ? rcu_read_lock_held+0x90/0xa0 +[ 77.809713][ C3] gre_rcv+0x1b8/0x354 [gre] +[ ... ] + +Suggested-by: Eric Dumazet +Fixes: c54419321455 ("GRE: Refactor GRE tunneling code.") +Signed-off-by: Taehee Yoo +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv4/ip_tunnel.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c +index f4f1d11eab50..0c1f36404471 100644 +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -85,9 +85,10 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, + __be32 remote, __be32 local, + __be32 key) + { +- unsigned int hash; + struct ip_tunnel *t, *cand = NULL; + struct hlist_head *head; ++ struct net_device *ndev; ++ unsigned int hash; + + hash = ip_tunnel_hash(key, remote); + head = &itn->tunnels[hash]; +@@ -162,8 +163,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, + if (t && t->dev->flags & IFF_UP) + return t; + +- if (itn->fb_tunnel_dev && itn->fb_tunnel_dev->flags & IFF_UP) +- return netdev_priv(itn->fb_tunnel_dev); ++ ndev = READ_ONCE(itn->fb_tunnel_dev); ++ if (ndev && ndev->flags & IFF_UP) ++ return netdev_priv(ndev); + + return NULL; + } +@@ -1259,9 +1261,9 @@ void ip_tunnel_uninit(struct net_device *dev) + struct ip_tunnel_net *itn; + + itn = net_generic(net, tunnel->ip_tnl_net_id); +- /* fb_tunnel_dev will be unregisted in net-exit call. */ +- if (itn->fb_tunnel_dev != dev) +- ip_tunnel_del(itn, netdev_priv(dev)); ++ ip_tunnel_del(itn, netdev_priv(dev)); ++ if (itn->fb_tunnel_dev == dev) ++ WRITE_ONCE(itn->fb_tunnel_dev, NULL); + + dst_cache_reset(&tunnel->dst_cache); + } +-- +2.28.0 + diff --git a/patches.suse/ipv4-fill-fl4_icmp_-type-code-in-ping_v4_sendmsg.patch b/patches.suse/ipv4-fill-fl4_icmp_-type-code-in-ping_v4_sendmsg.patch new file mode 100644 index 0000000..8bf0da6 --- /dev/null +++ b/patches.suse/ipv4-fill-fl4_icmp_-type-code-in-ping_v4_sendmsg.patch @@ -0,0 +1,48 @@ +From: Sabrina Dubroca +Date: Fri, 3 Jul 2020 17:00:32 +0200 +Subject: ipv4: fill fl4_icmp_{type,code} in ping_v4_sendmsg +Git-commit: 5eff06902394425c722f0a44d9545909a8800f79 +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +IPv4 ping sockets don't set fl4.fl4_icmp_{type,code}, which leads to +incomplete IPsec ACQUIRE messages being sent to userspace. Currently, +both raw sockets and IPv6 ping sockets set those fields. + +Expected output of "ip xfrm monitor": + acquire proto esp + sel src 10.0.2.15/32 dst 8.8.8.8/32 proto icmp type 8 code 0 dev ens4 + policy src 10.0.2.15/32 dst 8.8.8.8/32 + + +Currently with ping sockets: + acquire proto esp + sel src 10.0.2.15/32 dst 8.8.8.8/32 proto icmp type 0 code 0 dev ens4 + policy src 10.0.2.15/32 dst 8.8.8.8/32 + + +The Libreswan test suite found this problem after Fedora changed the +value for the sysctl net.ipv4.ping_group_range. + +Fixes: c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind") +Reported-by: Paul Wouters +Tested-by: Paul Wouters +Signed-off-by: Sabrina Dubroca +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv4/ping.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -801,6 +801,9 @@ static int ping_v4_sendmsg(struct sock * + inet_sk_flowi_flags(sk), faddr, saddr, 0, 0, + sk->sk_uid); + ++ fl4.fl4_icmp_type = user_icmph.type; ++ fl4.fl4_icmp_code = user_icmph.code; ++ + security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); + rt = ip_route_output_flow(net, &fl4, sk); + if (IS_ERR(rt)) { diff --git a/patches.suse/jbd2-add-the-missing-unlock_buffer-in-the-error-path.patch b/patches.suse/jbd2-add-the-missing-unlock_buffer-in-the-error-path.patch new file mode 100644 index 0000000..9081bbe --- /dev/null +++ b/patches.suse/jbd2-add-the-missing-unlock_buffer-in-the-error-path.patch @@ -0,0 +1,44 @@ +From ef3f5830b859604eda8723c26d90ab23edc027a4 Mon Sep 17 00:00:00 2001 +From: "zhangyi (F)" +Date: Sat, 20 Jun 2020 14:19:48 +0800 +Subject: [PATCH] jbd2: add the missing unlock_buffer() in the error path of + jbd2_write_superblock() +Git-commit: ef3f5830b859604eda8723c26d90ab23edc027a4 +Patch-mainline: v5.9-rc2 +References: bsc#1175772 + +jbd2_write_superblock() is under the buffer lock of journal superblock +before ending that superblock write, so add a missing unlock_buffer() in +in the error path before submitting buffer. + +Fixes: 742b06b5628f ("jbd2: check superblock mapped prior to committing") +Signed-off-by: zhangyi (F) +Reviewed-by: Ritesh Harjani +Cc: stable@kernel.org +Link: https://lore.kernel.org/r/20200620061948.2049579-1-yi.zhang@huawei.com +Signed-off-by: Theodore Ts'o +Acked-by: Jan Kara + +--- + fs/jbd2/journal.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index e4944436e733..5493a0da23dd 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -1367,8 +1367,10 @@ static int jbd2_write_superblock(journal_t *journal, int write_flags) + int ret; + + /* Buffer got discarded which means block device got invalidated */ +- if (!buffer_mapped(bh)) ++ if (!buffer_mapped(bh)) { ++ unlock_buffer(bh); + return -EIO; ++ } + + trace_jbd2_write_superblock(journal, write_flags); + if (!(journal->j_flags & JBD2_BARRIER)) +-- +2.16.4 + diff --git a/patches.suse/kernfs-do-not-call-fsnotify-with-name-without-a-pare.patch b/patches.suse/kernfs-do-not-call-fsnotify-with-name-without-a-pare.patch new file mode 100644 index 0000000..f99b741 --- /dev/null +++ b/patches.suse/kernfs-do-not-call-fsnotify-with-name-without-a-pare.patch @@ -0,0 +1,43 @@ +From 9991bb84b27a2594187898f261866cfc50255454 Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Wed, 8 Jul 2020 14:11:40 +0300 +Subject: [PATCH] kernfs: do not call fsnotify() with name without a parent +Git-commit: 9991bb84b27a2594187898f261866cfc50255454 +Patch-mainline: v5.9-rc1 +References: bsc#1175770 + +When creating an FS_MODIFY event on inode itself (not on parent) +the file_name argument should be NULL. + +The change to send a non NULL name to inode itself was done on purpuse +as part of another commit, as Tejun writes: "...While at it, supply the +target file name to fsnotify() from kernfs_node->name.". + +But this is wrong practice and inconsistent with inotify behavior when +watching a single file. When a child is being watched (as opposed to the +parent directory) the inotify event should contain the watch descriptor, +but not the file name. + +Fixes: df6a58c5c5aa ("kernfs: don't depend on d_find_any_alias()...") +Link: https://lore.kernel.org/r/20200708111156.24659-5-amir73il@gmail.com +Acked-by: Tejun Heo +Acked-by: Greg Kroah-Hartman +Signed-off-by: Amir Goldstein +Signed-off-by: Jan Kara +Acked-by: Jan Kara + +--- + fs/kernfs/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/kernfs/file.c ++++ b/fs/kernfs/file.c +@@ -914,7 +914,7 @@ repeat: + } + + fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE, +- kn->name, 0); ++ NULL, 0); + iput(inode); + } + diff --git a/patches.suse/l2tp-remove-skb_dst_set-from-l2tp_xmit_skb.patch b/patches.suse/l2tp-remove-skb_dst_set-from-l2tp_xmit_skb.patch new file mode 100644 index 0000000..cada945 --- /dev/null +++ b/patches.suse/l2tp-remove-skb_dst_set-from-l2tp_xmit_skb.patch @@ -0,0 +1,58 @@ +From: Xin Long +Date: Tue, 7 Jul 2020 02:02:32 +0800 +Subject: l2tp: remove skb_dst_set() from l2tp_xmit_skb() +Git-commit: 27d53323664c549b5bb2dfaaf6f7ad6e0376a64e +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +In the tx path of l2tp, l2tp_xmit_skb() calls skb_dst_set() to set +skb's dst. However, it will eventually call inet6_csk_xmit() or +ip_queue_xmit() where skb's dst will be overwritten by: + + skb_dst_set_noref(skb, dst); + +without releasing the old dst in skb. Then it causes dst/dev refcnt leak: + + unregister_netdevice: waiting for eth0 to become free. Usage count = 1 + +This can be reproduced by simply running: + + # modprobe l2tp_eth && modprobe l2tp_ip + # sh ./tools/testing/selftests/net/l2tp.sh + +So before going to inet6_csk_xmit() or ip_queue_xmit(), skb's dst +should be dropped. This patch is to fix it by removing skb_dst_set() +from l2tp_xmit_skb() and moving skb_dst_drop() into l2tp_xmit_core(). + +Fixes: 3557baabf280 ("[L2TP]: PPP over L2TP driver core") +Reported-by: Hangbin Liu +Signed-off-by: Xin Long +Acked-by: James Chapman +Tested-by: James Chapman +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/l2tp/l2tp_core.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -1065,6 +1065,7 @@ static int l2tp_xmit_core(struct l2tp_se + + /* Queue the packet to IP for output */ + skb->ignore_df = 1; ++ skb_dst_drop(skb); + #if IS_ENABLED(CONFIG_IPV6) + if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped) + error = inet6_csk_xmit(tunnel->sock, skb, NULL); +@@ -1129,10 +1130,6 @@ int l2tp_xmit_skb(struct l2tp_session *s + goto out_unlock; + } + +- /* Get routing info from the tunnel socket */ +- skb_dst_drop(skb); +- skb_dst_set(skb, sk_dst_check(sk, 0)); +- + inet = inet_sk(sk); + fl = &inet->cork.fl; + switch (tunnel->encap) { diff --git a/patches.suse/llc-make-sure-applications-use-ARPHRD_ETHER.patch b/patches.suse/llc-make-sure-applications-use-ARPHRD_ETHER.patch new file mode 100644 index 0000000..c576195 --- /dev/null +++ b/patches.suse/llc-make-sure-applications-use-ARPHRD_ETHER.patch @@ -0,0 +1,157 @@ +From: Eric Dumazet +Date: Sat, 27 Jun 2020 13:31:50 -0700 +Subject: llc: make sure applications use ARPHRD_ETHER +Git-commit: a9b1110162357689a34992d5c925852948e5b9fd +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +syzbot was to trigger a bug by tricking AF_LLC with +non sensible addr->sllc_arphrd + +It seems clear LLC requires an Ethernet device. + +Back in commit abf9d537fea2 ("llc: add support for SO_BINDTODEVICE") +Octavian Purdila added possibility for application to use a zero +value for sllc_arphrd, convert it to ARPHRD_ETHER to not cause +regressions on existing applications. + +BUG: KASAN: use-after-free in __read_once_size include/linux/compiler.h:199 [inline] +BUG: KASAN: use-after-free in list_empty include/linux/list.h:268 [inline] +BUG: KASAN: use-after-free in waitqueue_active include/linux/wait.h:126 [inline] +BUG: KASAN: use-after-free in wq_has_sleeper include/linux/wait.h:160 [inline] +BUG: KASAN: use-after-free in skwq_has_sleeper include/net/sock.h:2092 [inline] +BUG: KASAN: use-after-free in sock_def_write_space+0x642/0x670 net/core/sock.c:2813 +Read of size 8 at addr ffff88801e0b4078 by task ksoftirqd/3/27 + +CPU: 3 PID: 27 Comm: ksoftirqd/3 Not tainted 5.5.0-rc1-syzkaller #0 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x197/0x210 lib/dump_stack.c:118 + print_address_description.constprop.0.cold+0xd4/0x30b mm/kasan/report.c:374 + __kasan_report.cold+0x1b/0x41 mm/kasan/report.c:506 + kasan_report+0x12/0x20 mm/kasan/common.c:639 + __asan_report_load8_noabort+0x14/0x20 mm/kasan/generic_report.c:135 + __read_once_size include/linux/compiler.h:199 [inline] + list_empty include/linux/list.h:268 [inline] + waitqueue_active include/linux/wait.h:126 [inline] + wq_has_sleeper include/linux/wait.h:160 [inline] + skwq_has_sleeper include/net/sock.h:2092 [inline] + sock_def_write_space+0x642/0x670 net/core/sock.c:2813 + sock_wfree+0x1e1/0x260 net/core/sock.c:1958 + skb_release_head_state+0xeb/0x260 net/core/skbuff.c:652 + skb_release_all+0x16/0x60 net/core/skbuff.c:663 + __kfree_skb net/core/skbuff.c:679 [inline] + consume_skb net/core/skbuff.c:838 [inline] + consume_skb+0xfb/0x410 net/core/skbuff.c:832 + __dev_kfree_skb_any+0xa4/0xd0 net/core/dev.c:2967 + dev_kfree_skb_any include/linux/netdevice.h:3650 [inline] + e1000_unmap_and_free_tx_resource.isra.0+0x21b/0x3a0 drivers/net/ethernet/intel/e1000/e1000_main.c:1963 + e1000_clean_tx_irq drivers/net/ethernet/intel/e1000/e1000_main.c:3854 [inline] + e1000_clean+0x4cc/0x1d10 drivers/net/ethernet/intel/e1000/e1000_main.c:3796 + napi_poll net/core/dev.c:6532 [inline] + net_rx_action+0x508/0x1120 net/core/dev.c:6600 + __do_softirq+0x262/0x98c kernel/softirq.c:292 + run_ksoftirqd kernel/softirq.c:603 [inline] + run_ksoftirqd+0x8e/0x110 kernel/softirq.c:595 + smpboot_thread_fn+0x6a3/0xa40 kernel/smpboot.c:165 + kthread+0x361/0x430 kernel/kthread.c:255 + ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352 + +Allocated by task 8247: + save_stack+0x23/0x90 mm/kasan/common.c:72 + set_track mm/kasan/common.c:80 [inline] + __kasan_kmalloc mm/kasan/common.c:513 [inline] + __kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:486 + kasan_slab_alloc+0xf/0x20 mm/kasan/common.c:521 + slab_post_alloc_hook mm/slab.h:584 [inline] + slab_alloc mm/slab.c:3320 [inline] + kmem_cache_alloc+0x121/0x710 mm/slab.c:3484 + sock_alloc_inode+0x1c/0x1d0 net/socket.c:240 + alloc_inode+0x68/0x1e0 fs/inode.c:230 + new_inode_pseudo+0x19/0xf0 fs/inode.c:919 + sock_alloc+0x41/0x270 net/socket.c:560 + __sock_create+0xc2/0x730 net/socket.c:1384 + sock_create net/socket.c:1471 [inline] + __sys_socket+0x103/0x220 net/socket.c:1513 + __do_sys_socket net/socket.c:1522 [inline] + __se_sys_socket net/socket.c:1520 [inline] + __ia32_sys_socket+0x73/0xb0 net/socket.c:1520 + do_syscall_32_irqs_on arch/x86/entry/common.c:337 [inline] + do_fast_syscall_32+0x27b/0xe16 arch/x86/entry/common.c:408 + entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139 + +Freed by task 17: + save_stack+0x23/0x90 mm/kasan/common.c:72 + set_track mm/kasan/common.c:80 [inline] + kasan_set_free_info mm/kasan/common.c:335 [inline] + __kasan_slab_free+0x102/0x150 mm/kasan/common.c:474 + kasan_slab_free+0xe/0x10 mm/kasan/common.c:483 + __cache_free mm/slab.c:3426 [inline] + kmem_cache_free+0x86/0x320 mm/slab.c:3694 + sock_free_inode+0x20/0x30 net/socket.c:261 + i_callback+0x44/0x80 fs/inode.c:219 + __rcu_reclaim kernel/rcu/rcu.h:222 [inline] + rcu_do_batch kernel/rcu/tree.c:2183 [inline] + rcu_core+0x570/0x1540 kernel/rcu/tree.c:2408 + rcu_core_si+0x9/0x10 kernel/rcu/tree.c:2417 + __do_softirq+0x262/0x98c kernel/softirq.c:292 + +The buggy address belongs to the object at ffff88801e0b4000 + which belongs to the cache sock_inode_cache of size 1152 +The buggy address is located 120 bytes inside of + 1152-byte region [ffff88801e0b4000, ffff88801e0b4480) +The buggy address belongs to the page: +page:ffffea0000782d00 refcount:1 mapcount:0 mapping:ffff88807aa59c40 index:0xffff88801e0b4ffd +raw: 00fffe0000000200 ffffea00008e6c88 ffffea0000782d48 ffff88807aa59c40 +raw: ffff88801e0b4ffd ffff88801e0b4000 0000000100000003 0000000000000000 +page dumped because: kasan: bad access detected + +Memory state around the buggy address: + ffff88801e0b3f00: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc + ffff88801e0b3f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +>ffff88801e0b4000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ^ + ffff88801e0b4080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ffff88801e0b4100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + +Fixes: abf9d537fea2 ("llc: add support for SO_BINDTODEVICE") +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/llc/af_llc.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/net/llc/af_llc.c ++++ b/net/llc/af_llc.c +@@ -269,6 +269,10 @@ static int llc_ui_autobind(struct socket + + if (!sock_flag(sk, SOCK_ZAPPED)) + goto out; ++ if (!addr->sllc_arphrd) ++ addr->sllc_arphrd = ARPHRD_ETHER; ++ if (addr->sllc_arphrd != ARPHRD_ETHER) ++ goto out; + rc = -ENODEV; + if (sk->sk_bound_dev_if) { + llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); +@@ -326,15 +330,15 @@ static int llc_ui_bind(struct socket *so + if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))) + goto out; + rc = -EAFNOSUPPORT; +- if (unlikely(addr->sllc_family != AF_LLC)) ++ if (!addr->sllc_arphrd) ++ addr->sllc_arphrd = ARPHRD_ETHER; ++ if (unlikely(addr->sllc_family != AF_LLC || addr->sllc_arphrd != ARPHRD_ETHER)) + goto out; + rc = -ENODEV; + rcu_read_lock(); + if (sk->sk_bound_dev_if) { + llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); + if (llc->dev) { +- if (!addr->sllc_arphrd) +- addr->sllc_arphrd = llc->dev->type; + if (is_zero_ether_addr(addr->sllc_mac)) + memcpy(addr->sllc_mac, llc->dev->dev_addr, + IFHWADDRLEN); diff --git a/patches.suse/mld-fix-memory-leak-in-ipv6_mc_destroy_dev.patch b/patches.suse/mld-fix-memory-leak-in-ipv6_mc_destroy_dev.patch new file mode 100644 index 0000000..9bb867b --- /dev/null +++ b/patches.suse/mld-fix-memory-leak-in-ipv6_mc_destroy_dev.patch @@ -0,0 +1,55 @@ +From: Wang Hai +Date: Thu, 11 Jun 2020 15:57:50 +0800 +Subject: mld: fix memory leak in ipv6_mc_destroy_dev() +Git-commit: ea2fce88d2fd678ed9d45354ff49b73f1d5615dd +Patch-mainline: 5.8-rc2 +References: networking-stable-20_06_28 + +Commit a84d01647989 ("mld: fix memory leak in mld_del_delrec()") fixed +the memory leak of MLD, but missing the ipv6_mc_destroy_dev() path, in +which mca_sources are leaked after ma_put(). + +Using ip6_mc_clear_src() to take care of the missing free. + +BUG: memory leak +unreferenced object 0xffff8881113d3180 (size 64): + comm "syz-executor071", pid 389, jiffies 4294887985 (age 17.943s) + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 ff 02 00 00 00 00 00 00 ................ + 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 ................ + backtrace: + [<000000002cbc483c>] kmalloc include/linux/slab.h:555 [inline] + [<000000002cbc483c>] kzalloc include/linux/slab.h:669 [inline] + [<000000002cbc483c>] ip6_mc_add1_src net/ipv6/mcast.c:2237 [inline] + [<000000002cbc483c>] ip6_mc_add_src+0x7f5/0xbb0 net/ipv6/mcast.c:2357 + [<0000000058b8b1ff>] ip6_mc_source+0xe0c/0x1530 net/ipv6/mcast.c:449 + [<000000000bfc4fb5>] do_ipv6_setsockopt.isra.12+0x1b2c/0x3b30 net/ipv6/ipv6_sockglue.c:754 + [<00000000e4e7a722>] ipv6_setsockopt+0xda/0x150 net/ipv6/ipv6_sockglue.c:950 + [<0000000029260d9a>] rawv6_setsockopt+0x45/0x100 net/ipv6/raw.c:1081 + [<000000005c1b46f9>] __sys_setsockopt+0x131/0x210 net/socket.c:2132 + [<000000008491f7db>] __do_sys_setsockopt net/socket.c:2148 [inline] + [<000000008491f7db>] __se_sys_setsockopt net/socket.c:2145 [inline] + [<000000008491f7db>] __x64_sys_setsockopt+0xba/0x150 net/socket.c:2145 + [<00000000c7bc11c5>] do_syscall_64+0xa1/0x530 arch/x86/entry/common.c:295 + [<000000005fb7a3f3>] entry_SYSCALL_64_after_hwframe+0x49/0xb3 + +Fixes: 1666d49e1d41 ("mld: do not remove mld souce list info when set link down") +Reported-by: Hulk Robot +Signed-off-by: Wang Hai +Acked-by: Hangbin Liu +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv6/mcast.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -2600,6 +2600,7 @@ void ipv6_mc_destroy_dev(struct inet6_de + idev->mc_list = i->next; + + write_unlock_bh(&idev->lock); ++ ip6_mc_clear_src(i); + ma_put(i); + write_lock_bh(&idev->lock); + } diff --git a/patches.suse/mm-filemap-clear-idle-flag-for-writes.patch b/patches.suse/mm-filemap-clear-idle-flag-for-writes.patch new file mode 100644 index 0000000..dae4f07 --- /dev/null +++ b/patches.suse/mm-filemap-clear-idle-flag-for-writes.patch @@ -0,0 +1,56 @@ +From b9306a796cad8a65f4d21779524e73fe0745bae1 Mon Sep 17 00:00:00 2001 +From: Yang Shi +Date: Thu, 6 Aug 2020 23:19:55 -0700 +Subject: [PATCH] mm: filemap: clear idle flag for writes +Git-commit: b9306a796cad8a65f4d21779524e73fe0745bae1 +Patch-mainline: v5.9-rc1 +References: bsc#1175769 + +Since commit bbddabe2e436aa ("mm: filemap: only do access activations on +reads"), mark_page_accessed() is called for reads only. But the idle flag +is cleared by mark_page_accessed() so the idle flag won't get cleared if +the page is write accessed only. + +Basically idle page tracking is used to estimate workingset size of +workload, noticeable size of workingset might be missed if the idle flag +is not maintained correctly. + +It seems good enough to just clear idle flag for write operations. + +Fixes: bbddabe2e436 ("mm: filemap: only do access activations on reads") +Reported-by: Gang Deng +Signed-off-by: Yang Shi +Signed-off-by: Andrew Morton +Reviewed-by: Shakeel Butt +Cc: Johannes Weiner +Cc: Rik van Riel +Link: http://lkml.kernel.org/r/1593020612-13051-1-git-send-email-yang.shi@linux.alibaba.com +Signed-off-by: Linus Torvalds +Acked-by: Jan Kara + +--- + mm/filemap.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include "internal.h" + + #define CREATE_TRACE_POINTS +@@ -1634,6 +1635,11 @@ repeat: + + if (page && (fgp_flags & FGP_ACCESSED)) + mark_page_accessed(page); ++ else if (fgp_flags & FGP_WRITE) { ++ /* Clear idle flag for buffer write */ ++ if (page_is_idle(page)) ++ clear_page_idle(page); ++ } + + no_page: + if (!page && (fgp_flags & FGP_CREAT)) { diff --git a/patches.suse/net-Do-not-clear-the-sock-TX-queue-in-sk_set_socket.patch b/patches.suse/net-Do-not-clear-the-sock-TX-queue-in-sk_set_socket.patch new file mode 100644 index 0000000..2187662 --- /dev/null +++ b/patches.suse/net-Do-not-clear-the-sock-TX-queue-in-sk_set_socket.patch @@ -0,0 +1,55 @@ +From: Tariq Toukan +Date: Mon, 22 Jun 2020 23:26:04 +0300 +Subject: net: Do not clear the sock TX queue in sk_set_socket() +Git-commit: 41b14fb8724d5a4b382a63cb4a1a61880347ccb8 +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +Clearing the sock TX queue in sk_set_socket() might cause unexpected +out-of-order transmit when called from sock_orphan(), as outstanding +packets can pick a different TX queue and bypass the ones already queued. + +This is undesired in general. More specifically, it breaks the in-order +scheduling property guarantee for device-offloaded TLS sockets. + +Remove the call to sk_tx_queue_clear() in sk_set_socket(), and add it +explicitly only where needed. + +Fixes: e022f0b4a03f ("net: Introduce sk_tx_queue_mapping") +Signed-off-by: Tariq Toukan +Reviewed-by: Boris Pismenny +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + include/net/sock.h | 1 - + net/core/sock.c | 2 ++ + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1751,7 +1751,6 @@ static inline int sk_rx_queue_get(const + + static inline void sk_set_socket(struct sock *sk, struct socket *sock) + { +- sk_tx_queue_clear(sk); + sk->sk_socket = sock; + } + +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1457,6 +1457,7 @@ struct sock *sk_alloc(struct net *net, i + cgroup_sk_alloc(&sk->sk_cgrp_data); + sock_update_classid(&sk->sk_cgrp_data); + sock_update_netprioidx(&sk->sk_cgrp_data); ++ sk_tx_queue_clear(sk); + } + + return sk; +@@ -1658,6 +1659,7 @@ struct sock *sk_clone_lock(const struct + */ + sk_refcnt_debug_inc(newsk); + sk_set_socket(newsk, NULL); ++ sk_tx_queue_clear(newsk); + newsk->sk_wq = NULL; + + if (newsk->sk_prot->sockets_allocated) diff --git a/patches.suse/net-Fix-the-arp-error-in-some-cases.patch b/patches.suse/net-Fix-the-arp-error-in-some-cases.patch new file mode 100644 index 0000000..94bff01 --- /dev/null +++ b/patches.suse/net-Fix-the-arp-error-in-some-cases.patch @@ -0,0 +1,48 @@ +From: guodeqing +Date: Wed, 17 Jun 2020 10:07:16 +0800 +Subject: net: Fix the arp error in some cases +Git-commit: 5eea3a63ff4aba6a26002e657a6d21934b7e2b96 +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +ie., +$ ifconfig eth0 6.6.6.6 netmask 255.255.255.0 + +$ ip rule add from 6.6.6.6 table 6666 + +$ ip route add 9.9.9.9 via 6.6.6.6 + +$ ping -I 6.6.6.6 9.9.9.9 +PING 9.9.9.9 (9.9.9.9) from 6.6.6.6 : 56(84) bytes of data. + +3 packets transmitted, 0 received, 100% packet loss, time 2079ms + +$ arp +Address HWtype HWaddress Flags Mask Iface +6.6.6.6 (incomplete) eth0 + +The arp request address is error, this is because fib_table_lookup in +fib_check_nh lookup the destnation 9.9.9.9 nexthop, the scope of +the fib result is RT_SCOPE_LINK,the correct scope is RT_SCOPE_HOST. +Here I add a check of whether this is RT_TABLE_MAIN to solve this problem. + +Fixes: 3bfd847203c6 ("net: Use passed in table for nexthop lookups") +Signed-off-by: guodeqing +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv4/fib_semantics.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -773,7 +773,7 @@ static int fib_check_nh(struct fib_confi + if (fl4.flowi4_scope < RT_SCOPE_LINK) + fl4.flowi4_scope = RT_SCOPE_LINK; + +- if (cfg->fc_table) ++ if (cfg->fc_table && cfg->fc_table != RT_TABLE_MAIN) + tbl = fib_get_table(net, cfg->fc_table); + + if (tbl) diff --git a/patches.suse/net-bridge-enfore-alignment-for-ethernet-address.patch b/patches.suse/net-bridge-enfore-alignment-for-ethernet-address.patch new file mode 100644 index 0000000..e8ec76e --- /dev/null +++ b/patches.suse/net-bridge-enfore-alignment-for-ethernet-address.patch @@ -0,0 +1,40 @@ +From: Thomas Martitz +Date: Thu, 25 Jun 2020 14:26:03 +0200 +Subject: net: bridge: enfore alignment for ethernet address +Git-commit: 206e732323c2a8e6d11f4125a62c27e60a50a850 +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +The eth_addr member is passed to ether_addr functions that require +2-byte alignment, therefore the member must be properly aligned +to avoid unaligned accesses. + +The problem is in place since the initial merge of multicast to unicast: +commit 6db6f0eae6052b70885562e1733896647ec1d807 bridge: multicast to unicast + +Fixes: 6db6f0eae605 ("bridge: multicast to unicast") +Cc: Roopa Prabhu +Cc: Nikolay Aleksandrov +Cc: David S. Miller +Cc: Jakub Kicinski +Cc: Felix Fietkau +Signed-off-by: Thomas Martitz +Acked-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/bridge/br_private.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -189,8 +189,8 @@ struct net_bridge_port_group { + struct rcu_head rcu; + struct timer_list timer; + struct br_ip addr; ++ unsigned char eth_addr[ETH_ALEN] __aligned(2); + unsigned char flags; +- unsigned char eth_addr[ETH_ALEN]; + }; + + struct net_bridge_mdb_entry diff --git a/patches.suse/net-core-reduce-recursion-limit-value.patch b/patches.suse/net-core-reduce-recursion-limit-value.patch new file mode 100644 index 0000000..d490fed --- /dev/null +++ b/patches.suse/net-core-reduce-recursion-limit-value.patch @@ -0,0 +1,79 @@ +From: Taehee Yoo +Date: Tue, 16 Jun 2020 15:52:05 +0000 +Subject: net: core: reduce recursion limit value +Git-commit: fb7861d14c8d7edac65b2fcb6e8031cb138457b2 +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +In the current code, ->ndo_start_xmit() can be executed recursively only +10 times because of stack memory. +But, in the case of the vxlan, 10 recursion limit value results in +a stack overflow. +In the current code, the nested interface is limited by 8 depth. +There is no critical reason that the recursion limitation value should +be 10. +So, it would be good to be the same value with the limitation value of +nesting interface depth. + +Test commands: + ip link add vxlan10 type vxlan vni 10 dstport 4789 srcport 4789 4789 + ip link set vxlan10 up + ip a a 192.168.10.1/24 dev vxlan10 + ip n a 192.168.10.2 dev vxlan10 lladdr fc:22:33:44:55:66 nud permanent + + for i in {9..0} + do + let A=$i+1 + ip link add vxlan$i type vxlan vni $i dstport 4789 srcport 4789 4789 + ip link set vxlan$i up + ip a a 192.168.$i.1/24 dev vxlan$i + ip n a 192.168.$i.2 dev vxlan$i lladdr fc:22:33:44:55:66 nud permanent + bridge fdb add fc:22:33:44:55:66 dev vxlan$A dst 192.168.$i.2 self + done + hping3 192.168.10.2 -2 -d 60000 + +Splat looks like: +[ 103.814237][ T1127] ============================================================================= +[ 103.871955][ T1127] BUG kmalloc-2k (Tainted: G B ): Padding overwritten. 0x00000000897a2e4f-0x000 +[ 103.873187][ T1127] ----------------------------------------------------------------------------- +[ 103.873187][ T1127] +[ 103.874252][ T1127] INFO: Slab 0x000000005cccc724 objects=5 used=5 fp=0x0000000000000000 flags=0x10000000001020 +[ 103.881323][ T1127] CPU: 3 PID: 1127 Comm: hping3 Tainted: G B 5.7.0+ #575 +[ 103.882131][ T1127] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 +[ 103.883006][ T1127] Call Trace: +[ 103.883324][ T1127] dump_stack+0x96/0xdb +[ 103.883716][ T1127] slab_err+0xad/0xd0 +[ 103.884106][ T1127] ? _raw_spin_unlock+0x1f/0x30 +[ 103.884620][ T1127] ? get_partial_node.isra.78+0x140/0x360 +[ 103.885214][ T1127] slab_pad_check.part.53+0xf7/0x160 +[ 103.885769][ T1127] ? pskb_expand_head+0x110/0xe10 +[ 103.886316][ T1127] check_slab+0x97/0xb0 +[ 103.886763][ T1127] alloc_debug_processing+0x84/0x1a0 +[ 103.887308][ T1127] ___slab_alloc+0x5a5/0x630 +[ 103.887765][ T1127] ? pskb_expand_head+0x110/0xe10 +[ 103.888265][ T1127] ? lock_downgrade+0x730/0x730 +[ 103.888762][ T1127] ? pskb_expand_head+0x110/0xe10 +[ 103.889244][ T1127] ? __slab_alloc+0x3e/0x80 +[ 103.889675][ T1127] __slab_alloc+0x3e/0x80 +[ 103.890108][ T1127] __kmalloc_node_track_caller+0xc7/0x420 +[ ... ] + +Fixes: 11a766ce915f ("net: Increase xmit RECURSION_LIMIT to 10.") +Signed-off-by: Taehee Yoo +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + include/linux/netdevice.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2618,7 +2618,7 @@ void synchronize_net(void); + int init_dummy_netdev(struct net_device *dev); + + DECLARE_PER_CPU(int, xmit_recursion); +-#define XMIT_RECURSION_LIMIT 10 ++#define XMIT_RECURSION_LIMIT 8 + + static inline int dev_recursion_level(void) + { diff --git a/patches.suse/net-fix-memleak-in-register_netdevice.patch b/patches.suse/net-fix-memleak-in-register_netdevice.patch new file mode 100644 index 0000000..5b91c33 --- /dev/null +++ b/patches.suse/net-fix-memleak-in-register_netdevice.patch @@ -0,0 +1,90 @@ +From: Yang Yingliang +Date: Tue, 16 Jun 2020 09:39:21 +0000 +Subject: net: fix memleak in register_netdevice() +Git-commit: 814152a89ed52c722ab92e9fbabcac3cb8a39245 +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +I got a memleak report when doing some fuzz test: + +unreferenced object 0xffff888112584000 (size 13599): + comm "ip", pid 3048, jiffies 4294911734 (age 343.491s) + hex dump (first 32 bytes): + 74 61 70 30 00 00 00 00 00 00 00 00 00 00 00 00 tap0............ + 00 ee d9 19 81 88 ff ff 00 00 00 00 00 00 00 00 ................ + backtrace: + [<000000002f60ba65>] __kmalloc_node+0x309/0x3a0 + [<0000000075b211ec>] kvmalloc_node+0x7f/0xc0 + [<00000000d3a97396>] alloc_netdev_mqs+0x76/0xfc0 + [<00000000609c3655>] __tun_chr_ioctl+0x1456/0x3d70 + [<000000001127ca24>] ksys_ioctl+0xe5/0x130 + [<00000000b7d5e66a>] __x64_sys_ioctl+0x6f/0xb0 + [<00000000e1023498>] do_syscall_64+0x56/0xa0 + [<000000009ec0eb12>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +unreferenced object 0xffff888111845cc0 (size 8): + comm "ip", pid 3048, jiffies 4294911734 (age 343.491s) + hex dump (first 8 bytes): + 74 61 70 30 00 88 ff ff tap0.... + backtrace: + [<000000004c159777>] kstrdup+0x35/0x70 + [<00000000d8b496ad>] kstrdup_const+0x3d/0x50 + [<00000000494e884a>] kvasprintf_const+0xf1/0x180 + [<0000000097880a2b>] kobject_set_name_vargs+0x56/0x140 + [<000000008fbdfc7b>] dev_set_name+0xab/0xe0 + [<000000005b99e3b4>] netdev_register_kobject+0xc0/0x390 + [<00000000602704fe>] register_netdevice+0xb61/0x1250 + [<000000002b7ca244>] __tun_chr_ioctl+0x1cd1/0x3d70 + [<000000001127ca24>] ksys_ioctl+0xe5/0x130 + [<00000000b7d5e66a>] __x64_sys_ioctl+0x6f/0xb0 + [<00000000e1023498>] do_syscall_64+0x56/0xa0 + [<000000009ec0eb12>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +unreferenced object 0xffff88811886d800 (size 512): + comm "ip", pid 3048, jiffies 4294911734 (age 343.491s) + hex dump (first 32 bytes): + 00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N.......... + ff ff ff ff ff ff ff ff c0 66 3d a3 ff ff ff ff .........f=..... + backtrace: + [<0000000050315800>] device_add+0x61e/0x1950 + [<0000000021008dfb>] netdev_register_kobject+0x17e/0x390 + [<00000000602704fe>] register_netdevice+0xb61/0x1250 + [<000000002b7ca244>] __tun_chr_ioctl+0x1cd1/0x3d70 + [<000000001127ca24>] ksys_ioctl+0xe5/0x130 + [<00000000b7d5e66a>] __x64_sys_ioctl+0x6f/0xb0 + [<00000000e1023498>] do_syscall_64+0x56/0xa0 + [<000000009ec0eb12>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +If call_netdevice_notifiers() failed, then rollback_registered() +calls netdev_unregister_kobject() which holds the kobject. The +reference cannot be put because the netdev won't be add to todo +list, so it will leads a memleak, we need put the reference to +avoid memleak. + +Reported-by: Hulk Robot +Signed-off-by: Yang Yingliang +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/core/dev.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 6bc2388141f6..44a14b41ad82 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -9547,6 +9547,13 @@ int register_netdevice(struct net_device *dev) + rcu_barrier(); + + dev->reg_state = NETREG_UNREGISTERED; ++ /* We should put the kobject that hold in ++ * netdev_unregister_kobject(), otherwise ++ * the net device cannot be freed when ++ * driver calls free_netdev(), because the ++ * kobject is being hold. ++ */ ++ kobject_put(&dev->dev.kobj); + } + /* + * Prevent userspace races by waiting until the network +-- +2.28.0 + diff --git a/patches.suse/net-increment-xmit_recursion-level-in-dev_direct_xmi.patch b/patches.suse/net-increment-xmit_recursion-level-in-dev_direct_xmi.patch new file mode 100644 index 0000000..51c36a2 --- /dev/null +++ b/patches.suse/net-increment-xmit_recursion-level-in-dev_direct_xmi.patch @@ -0,0 +1,112 @@ +From: Eric Dumazet +Date: Wed, 17 Jun 2020 22:23:25 -0700 +Subject: net: increment xmit_recursion level in dev_direct_xmit() +Git-commit: 0ad6f6e767ec2f613418cbc7ebe5ec4c35af540c +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +Back in commit f60e5990d9c1 ("ipv6: protect skb->sk accesses +from recursive dereference inside the stack") Hannes added code +so that IPv6 stack would not trust skb->sk for typical cases +where packet goes through 'standard' xmit path (__dev_queue_xmit()) + +Alas af_packet had a dev_direct_xmit() path that was not +dealing yet with xmit_recursion level. + +Also change sk_mc_loop() to dump a stack once only. + +Without this patch, syzbot was able to trigger : + +[1] +[ 153.567378] WARNING: CPU: 7 PID: 11273 at net/core/sock.c:721 sk_mc_loop+0x51/0x70 +[ 153.567378] Modules linked in: nfnetlink ip6table_raw ip6table_filter iptable_raw iptable_nat nf_nat nf_conntrack nf_defrag_ipv4 nf_defrag_ipv6 iptable_filter macsec macvtap tap macvlan 8021q hsr wireguard libblake2s blake2s_x86_64 libblake2s_generic udp_tunnel ip6_udp_tunnel libchacha20poly1305 poly1305_x86_64 chacha_x86_64 libchacha curve25519_x86_64 libcurve25519_generic netdevsim batman_adv dummy team bridge stp llc w1_therm wire i2c_mux_pca954x i2c_mux cdc_acm ehci_pci ehci_hcd mlx4_en mlx4_ib ib_uverbs ib_core mlx4_core +[ 153.567386] CPU: 7 PID: 11273 Comm: b159172088 Not tainted 5.8.0-smp-DEV #273 +[ 153.567387] RIP: 0010:sk_mc_loop+0x51/0x70 +[ 153.567388] Code: 66 83 f8 0a 75 24 0f b6 4f 12 b8 01 00 00 00 31 d2 d3 e0 a9 bf ef ff ff 74 07 48 8b 97 f0 02 00 00 0f b6 42 3a 83 e0 01 5d c3 <0f> 0b b8 01 00 00 00 5d c3 0f b6 87 18 03 00 00 5d c0 e8 04 83 e0 +[ 153.567388] RSP: 0018:ffff95c69bb93990 EFLAGS: 00010212 +[ 153.567388] RAX: 0000000000000011 RBX: ffff95c6e0ee3e00 RCX: 0000000000000007 +[ 153.567389] RDX: ffff95c69ae50000 RSI: ffff95c6c30c3000 RDI: ffff95c6c30c3000 +[ 153.567389] RBP: ffff95c69bb93990 R08: ffff95c69a77f000 R09: 0000000000000008 +[ 153.567389] R10: 0000000000000040 R11: 00003e0e00026128 R12: ffff95c6c30c3000 +[ 153.567390] R13: ffff95c6cc4fd500 R14: ffff95c6f84500c0 R15: ffff95c69aa13c00 +[ 153.567390] FS: 00007fdc3a283700(0000) GS:ffff95c6ff9c0000(0000) knlGS:0000000000000000 +[ 153.567390] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 153.567391] CR2: 00007ffee758e890 CR3: 0000001f9ba20003 CR4: 00000000001606e0 +[ 153.567391] Call Trace: +[ 153.567391] ip6_finish_output2+0x34e/0x550 +[ 153.567391] __ip6_finish_output+0xe7/0x110 +[ 153.567391] ip6_finish_output+0x2d/0xb0 +[ 153.567392] ip6_output+0x77/0x120 +[ 153.567392] ? __ip6_finish_output+0x110/0x110 +[ 153.567392] ip6_local_out+0x3d/0x50 +[ 153.567392] ipvlan_queue_xmit+0x56c/0x5e0 +[ 153.567393] ? ksize+0x19/0x30 +[ 153.567393] ipvlan_start_xmit+0x18/0x50 +[ 153.567393] dev_direct_xmit+0xf3/0x1c0 +[ 153.567393] packet_direct_xmit+0x69/0xa0 +[ 153.567394] packet_sendmsg+0xbf0/0x19b0 +[ 153.567394] ? plist_del+0x62/0xb0 +[ 153.567394] sock_sendmsg+0x65/0x70 +[ 153.567394] sock_write_iter+0x93/0xf0 +[ 153.567394] new_sync_write+0x18e/0x1a0 +[ 153.567395] __vfs_write+0x29/0x40 +[ 153.567395] vfs_write+0xb9/0x1b0 +[ 153.567395] ksys_write+0xb1/0xe0 +[ 153.567395] __x64_sys_write+0x1a/0x20 +[ 153.567395] do_syscall_64+0x43/0x70 +[ 153.567396] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 153.567396] RIP: 0033:0x453549 +[ 153.567396] Code: Bad RIP value. +[ 153.567396] RSP: 002b:00007fdc3a282cc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 +[ 153.567397] RAX: ffffffffffffffda RBX: 00000000004d32d0 RCX: 0000000000453549 +[ 153.567397] RDX: 0000000000000020 RSI: 0000000020000300 RDI: 0000000000000003 +[ 153.567398] RBP: 00000000004d32d8 R08: 0000000000000000 R09: 0000000000000000 +[ 153.567398] R10: 0000000000000000 R11: 0000000000000246 R12: 00000000004d32dc +[ 153.567398] R13: 00007ffee742260f R14: 00007fdc3a282dc0 R15: 00007fdc3a283700 +[ 153.567399] ---[ end trace c1d5ae2b1059ec62 ]--- + +[js] no helpers for recursion inc/dec. + +f60e5990d9c1 ("ipv6: protect skb->sk accesses from recursive dereference inside the stack") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/core/dev.c | 2 ++ + net/core/sock.c | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 44a14b41ad82..90b59fc50dc9 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4192,10 +4192,12 @@ int dev_direct_xmit(struct sk_buff *skb, u16 queue_id) + + local_bh_disable(); + ++ __this_cpu_inc(xmit_recursion); + HARD_TX_LOCK(dev, txq, smp_processor_id()); + if (!netif_xmit_frozen_or_drv_stopped(txq)) + ret = netdev_start_xmit(skb, dev, txq, false); + HARD_TX_UNLOCK(dev, txq); ++ __this_cpu_dec(xmit_recursion); + + local_bh_enable(); + +diff --git a/net/core/sock.c b/net/core/sock.c +index 6c4acf1f0220..94391da27754 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -718,7 +718,7 @@ bool sk_mc_loop(struct sock *sk) + return inet6_sk(sk)->mc_loop; + #endif + } +- WARN_ON(1); ++ WARN_ON_ONCE(1); + return true; + } + EXPORT_SYMBOL(sk_mc_loop); +-- +2.28.0 + diff --git a/patches.suse/net-usb-ax88179_178a-fix-packet-alignment-padding.patch b/patches.suse/net-usb-ax88179_178a-fix-packet-alignment-padding.patch new file mode 100644 index 0000000..eb49fd6 --- /dev/null +++ b/patches.suse/net-usb-ax88179_178a-fix-packet-alignment-padding.patch @@ -0,0 +1,72 @@ +From: Jeremy Kerr +Date: Mon, 15 Jun 2020 10:54:56 +0800 +Subject: net: usb: ax88179_178a: fix packet alignment padding +Git-commit: e869e7a17798d85829fa7d4f9bbe1eebd4b2d3f6 +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +Using a AX88179 device (0b95:1790), I see two bytes of appended data on +every RX packet. For example, this 48-byte ping, using 0xff as a +payload byte: + + 04:20:22.528472 IP 192.168.1.1 > 192.168.1.2: ICMP echo request, id 2447, seq 1, length 64 + 0x0000: 000a cd35 ea50 000a cd35 ea4f 0800 4500 + 0x0010: 0054 c116 4000 4001 f63e c0a8 0101 c0a8 + 0x0020: 0102 0800 b633 098f 0001 87ea cd5e 0000 + 0x0030: 0000 dcf2 0600 0000 0000 ffff ffff ffff + 0x0040: ffff ffff ffff ffff ffff ffff ffff ffff + 0x0050: ffff ffff ffff ffff ffff ffff ffff ffff + 0x0060: ffff 961f + +Those last two bytes - 96 1f - aren't part of the original packet. + +In the ax88179 RX path, the usbnet rx_fixup function trims a 2-byte +'alignment pseudo header' from the start of the packet, and sets the +length from a per-packet field populated by hardware. It looks like that +length field *includes* the 2-byte header; the current driver assumes +that it's excluded. + +This change trims the 2-byte alignment header after we've set the packet +length, so the resulting packet length is correct. While we're moving +the comment around, this also fixes the spelling of 'pseudo'. + +Signed-off-by: Jeremy Kerr +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + drivers/net/usb/ax88179_178a.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c +index 950711448f39..a38e868e44d4 100644 +--- a/drivers/net/usb/ax88179_178a.c ++++ b/drivers/net/usb/ax88179_178a.c +@@ -1491,10 +1491,10 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + } + + if (pkt_cnt == 0) { +- /* Skip IP alignment psudo header */ +- skb_pull(skb, 2); + skb->len = pkt_len; +- skb_set_tail_pointer(skb, pkt_len); ++ /* Skip IP alignment pseudo header */ ++ skb_pull(skb, 2); ++ skb_set_tail_pointer(skb, skb->len); + skb->truesize = pkt_len + sizeof(struct sk_buff); + ax88179_rx_checksum(skb, pkt_hdr); + return 1; +@@ -1503,8 +1503,9 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + ax_skb = skb_clone(skb, GFP_ATOMIC); + if (ax_skb) { + ax_skb->len = pkt_len; +- ax_skb->data = skb->data + 2; +- skb_set_tail_pointer(ax_skb, pkt_len); ++ /* Skip IP alignment pseudo header */ ++ skb_pull(ax_skb, 2); ++ skb_set_tail_pointer(ax_skb, ax_skb->len); + ax_skb->truesize = pkt_len + sizeof(struct sk_buff); + ax88179_rx_checksum(ax_skb, pkt_hdr); + usbnet_skb_return(dev, ax_skb); +-- +2.28.0 + diff --git a/patches.suse/net-usb-qmi_wwan-add-support-for-Quectel-EG95-LTE-mo.patch b/patches.suse/net-usb-qmi_wwan-add-support-for-Quectel-EG95-LTE-mo.patch new file mode 100644 index 0000000..99e423b --- /dev/null +++ b/patches.suse/net-usb-qmi_wwan-add-support-for-Quectel-EG95-LTE-mo.patch @@ -0,0 +1,42 @@ +From: AceLan Kao +Date: Tue, 7 Jul 2020 16:14:45 +0800 +Subject: net: usb: qmi_wwan: add support for Quectel EG95 LTE modem +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: f815dd5cf48b905eeecf0a2b990e9b7ab048b4f1 +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +Add support for Quectel Wireless Solutions Co., Ltd. EG95 LTE modem + +T: Bus=01 Lev=01 Prnt=01 Port=02 Cnt=02 Dev#= 5 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=2c7c ProdID=0195 Rev=03.18 +S: Manufacturer=Android +S: Product=Android +C: #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA +I: If#=0x0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) +I: If#=0x1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) +I: If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) +I: If#=0x3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) +I: If#=0x4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) + +Signed-off-by: AceLan Kao +Acked-by: Bjørn Mork +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + drivers/net/usb/qmi_wwan.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1358,6 +1358,7 @@ static const struct usb_device_id produc + {QMI_QUIRK_SET_DTR(0x1e0e, 0x9001, 5)}, /* SIMCom 7100E, 7230E, 7600E ++ */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)}, /* Quectel EC21 Mini PCIe */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)}, /* Quectel EG91 */ ++ {QMI_QUIRK_SET_DTR(0x2c7c, 0x0195, 4)}, /* Quectel EG95 */ + {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ + {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ + {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ diff --git a/patches.suse/nvme-multipath-do-not-fall-back-to-__nvme_find_path-.patch b/patches.suse/nvme-multipath-do-not-fall-back-to-__nvme_find_path-.patch index 7745b8c..5c801e2 100644 --- a/patches.suse/nvme-multipath-do-not-fall-back-to-__nvme_find_path-.patch +++ b/patches.suse/nvme-multipath-do-not-fall-back-to-__nvme_find_path-.patch @@ -3,9 +3,8 @@ Date: Mon, 27 Jul 2020 18:08:03 +0200 Subject: [PATCH] nvme-multipath: do not fall back to __nvme_find_path() for non-optimized paths References: bsc#1172108 -Patch-mainline: queued in maintainer subsystem repository +Patch-mainline: v5.9-rc1 Git-commit: fbd6a42d8932e172921c7de10468a2e12c34846b -Git-repo: git://git.infradead.org/nvme.git When nvme_round_robin_path() finds a valid namespace we should be using it; falling back to __nvme_find_path() for non-optimized paths will cause the diff --git a/patches.suse/nvme-multipath-fix-logic-for-non-optimized-paths.patch b/patches.suse/nvme-multipath-fix-logic-for-non-optimized-paths.patch index 1907c93..00265a7 100644 --- a/patches.suse/nvme-multipath-fix-logic-for-non-optimized-paths.patch +++ b/patches.suse/nvme-multipath-fix-logic-for-non-optimized-paths.patch @@ -2,9 +2,8 @@ From: Martin Wilck Date: Mon, 27 Jul 2020 18:08:02 +0200 Subject: [PATCH] nvme-multipath: fix logic for non-optimized paths References: bsc#1172108 -Patch-mainline: queued in maintainer subsystem repository +Patch-mainline: v5.9-rc1 Git-commit: 3f6e3246db0e6f92e784965d9d0edb8abe6c6b74 -Git-repo: git://git.infradead.org/nvme.git Handle the special case where we have exactly one optimized path, which we should keep using in this case. diff --git a/patches.suse/nvme-multipath-round-robin-eliminate-fallback-variable.patch b/patches.suse/nvme-multipath-round-robin-eliminate-fallback-variable.patch index 4fe9656..2320d05 100644 --- a/patches.suse/nvme-multipath-round-robin-eliminate-fallback-variable.patch +++ b/patches.suse/nvme-multipath-round-robin-eliminate-fallback-variable.patch @@ -1,9 +1,8 @@ From: Martin Wilck Date: Thu, 6 Aug 2020 15:19:32 +0200 Subject: nvme: multipath: round-robin: eliminate "fallback" variable -Patch-mainline: Queued in subsystem maintainer repository -Git-commit: 3548f005b0aeddd8e588e09dea269d9069779e37 -Git-repo: git://git.infradead.org/nvme +Patch-mainline: 5.9-rc3 +Git-commit: e398863b75af24103cee69cc8ee8bf4bc9c8913e References: bsc#1172108 If we find an optimized path, we quit the loop immediately. Thus we can use diff --git a/patches.suse/nvme-multipath-round-robin-fix-single-non-optimized-path-case.patch b/patches.suse/nvme-multipath-round-robin-fix-single-non-optimized-path-case.patch index e6055ad..0fd9735 100644 --- a/patches.suse/nvme-multipath-round-robin-fix-single-non-optimized-path-case.patch +++ b/patches.suse/nvme-multipath-round-robin-fix-single-non-optimized-path-case.patch @@ -1,9 +1,8 @@ From: Martin Wilck Date: Thu, 6 Aug 2020 15:19:31 +0200 Subject: nvme: multipath: round-robin: fix single non-optimized path case -Patch-mainline: Queued in subsystem maintainer repository -Git-commit: 62daba565e83a3577242679f61d12a12137300eb -Git-repo: git://git.infradead.org/nvme +Patch-mainline: 5.9-rc3 +Git-commit: 93eb0381e13d249a18ed4aae203291ff977e7ffb References: bsc#1172108 If there's only one usable, non-optimized path, nvme_round_robin_path() diff --git a/patches.suse/ocfs2-change-slot-number-type-s16-to-u16.patch b/patches.suse/ocfs2-change-slot-number-type-s16-to-u16.patch new file mode 100644 index 0000000..9e8a778 --- /dev/null +++ b/patches.suse/ocfs2-change-slot-number-type-s16-to-u16.patch @@ -0,0 +1,95 @@ +From 38d51b2dd171ad973afc1f5faab825ed05a2d5e9 Mon Sep 17 00:00:00 2001 +From: Junxiao Bi +Date: Thu, 6 Aug 2020 23:18:02 -0700 +Subject: [PATCH] ocfs2: change slot number type s16 to u16 +Git-commit: 38d51b2dd171ad973afc1f5faab825ed05a2d5e9 +Patch-mainline: v5.9-rc1 +References: bsc#1175786 + +Dan Carpenter reported the following static checker warning. + + fs/ocfs2/super.c:1269 ocfs2_parse_options() warn: '(-1)' 65535 can't fit into 32767 'mopt->slot' + fs/ocfs2/suballoc.c:859 ocfs2_init_inode_steal_slot() warn: '(-1)' 65535 can't fit into 32767 'osb->s_inode_steal_slot' + fs/ocfs2/suballoc.c:867 ocfs2_init_meta_steal_slot() warn: '(-1)' 65535 can't fit into 32767 'osb->s_meta_steal_slot' + +That's because OCFS2_INVALID_SLOT is (u16)-1. Slot number in ocfs2 can be +never negative, so change s16 to u16. + +Fixes: 9277f8334ffc ("ocfs2: fix value of OCFS2_INVALID_SLOT") +Reported-by: Dan Carpenter +Signed-off-by: Junxiao Bi +Signed-off-by: Andrew Morton +Reviewed-by: Joseph Qi +Reviewed-by: Gang He +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Jun Piao +Cc: +Link: http://lkml.kernel.org/r/20200627001259.19757-1-junxiao.bi@oracle.com +Signed-off-by: Linus Torvalds +Acked-by: Jan Kara + +--- + fs/ocfs2/ocfs2.h | 4 ++-- + fs/ocfs2/suballoc.c | 4 ++-- + fs/ocfs2/super.c | 4 ++-- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h +index 2dd71d626196..7993d527edae 100644 +--- a/fs/ocfs2/ocfs2.h ++++ b/fs/ocfs2/ocfs2.h +@@ -327,8 +327,8 @@ struct ocfs2_super + spinlock_t osb_lock; + u32 s_next_generation; + unsigned long osb_flags; +- s16 s_inode_steal_slot; +- s16 s_meta_steal_slot; ++ u16 s_inode_steal_slot; ++ u16 s_meta_steal_slot; + atomic_t s_num_inodes_stolen; + atomic_t s_num_meta_stolen; + +diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c +index 45745cc3408a..8c8cf7f4eb34 100644 +--- a/fs/ocfs2/suballoc.c ++++ b/fs/ocfs2/suballoc.c +@@ -879,9 +879,9 @@ static void __ocfs2_set_steal_slot(struct ocfs2_super *osb, int slot, int type) + { + spin_lock(&osb->osb_lock); + if (type == INODE_ALLOC_SYSTEM_INODE) +- osb->s_inode_steal_slot = slot; ++ osb->s_inode_steal_slot = (u16)slot; + else if (type == EXTENT_ALLOC_SYSTEM_INODE) +- osb->s_meta_steal_slot = slot; ++ osb->s_meta_steal_slot = (u16)slot; + spin_unlock(&osb->osb_lock); + } + +diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c +index 71ea9ce71a6b..1d91dd1e8711 100644 +--- a/fs/ocfs2/super.c ++++ b/fs/ocfs2/super.c +@@ -78,7 +78,7 @@ struct mount_options + unsigned long commit_interval; + unsigned long mount_opt; + unsigned int atime_quantum; +- signed short slot; ++ unsigned short slot; + int localalloc_opt; + unsigned int resv_level; + int dir_resv_level; +@@ -1349,7 +1349,7 @@ static int ocfs2_parse_options(struct super_block *sb, + goto bail; + } + if (option) +- mopt->slot = (s16)option; ++ mopt->slot = (u16)option; + break; + case Opt_commit: + if (match_int(&args[0], &option)) { +-- +2.16.4 + diff --git a/patches.suse/ocfs2-fix-value-of-OCFS2_INVALID_SLOT.patch b/patches.suse/ocfs2-fix-value-of-OCFS2_INVALID_SLOT.patch new file mode 100644 index 0000000..25b08c3 --- /dev/null +++ b/patches.suse/ocfs2-fix-value-of-OCFS2_INVALID_SLOT.patch @@ -0,0 +1,57 @@ +From 9277f8334ffc719fe922d776444d6e4e884dbf30 Mon Sep 17 00:00:00 2001 +From: Junxiao Bi +Date: Thu, 25 Jun 2020 20:29:40 -0700 +Subject: [PATCH] ocfs2: fix value of OCFS2_INVALID_SLOT +Git-commit: 9277f8334ffc719fe922d776444d6e4e884dbf30 +Patch-mainline: v5.8-rc3 +References: bsc#1175767 + +In the ocfs2 disk layout, slot number is 16 bits, but in ocfs2 +implementation, slot number is 32 bits. Usually this will not cause any +issue, because slot number is converted from u16 to u32, but +OCFS2_INVALID_SLOT was defined as -1, when an invalid slot number from +disk was obtained, its value was (u16)-1, and it was converted to u32. +Then the following checking in get_local_system_inode will be always +Skipped: + + static struct inode **get_local_system_inode(struct ocfs2_super *osb, + int type, + u32 slot) + { + BUG_ON(slot == OCFS2_INVALID_SLOT); + ... + } + +Link: http://lkml.kernel.org/r/20200616183829.87211-5-junxiao.bi@oracle.com +Signed-off-by: Junxiao Bi +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Changwei Ge +Cc: Gang He +Cc: Jun Piao +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Acked-by: Jan Kara + +--- + fs/ocfs2/ocfs2_fs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h +index 3fc99659ed09..19137c6d087b 100644 +--- a/fs/ocfs2/ocfs2_fs.h ++++ b/fs/ocfs2/ocfs2_fs.h +@@ -290,7 +290,7 @@ + #define OCFS2_MAX_SLOTS 255 + + /* Slot map indicator for an empty slot */ +-#define OCFS2_INVALID_SLOT -1 ++#define OCFS2_INVALID_SLOT ((u16)-1) + + #define OCFS2_VOL_UUID_LEN 16 + #define OCFS2_MAX_VOL_LABEL_LEN 64 +-- +2.16.4 + diff --git a/patches.suse/powerpc-64s-Don-t-init-FSCR_DSCR-in-__init_FSCR.patch b/patches.suse/powerpc-64s-Don-t-init-FSCR_DSCR-in-__init_FSCR.patch new file mode 100644 index 0000000..ed70ce7 --- /dev/null +++ b/patches.suse/powerpc-64s-Don-t-init-FSCR_DSCR-in-__init_FSCR.patch @@ -0,0 +1,82 @@ +From 0828137e8f16721842468e33df0460044a0c588b Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Thu, 28 May 2020 00:58:40 +1000 +Subject: [PATCH] powerpc/64s: Don't init FSCR_DSCR in __init_FSCR() + +References: bsc#1065729 +Patch-mainline: v5.8-rc1 +Git-commit: 0828137e8f16721842468e33df0460044a0c588b + +__init_FSCR() was added originally in commit 2468dcf641e4 ("powerpc: +Add support for context switching the TAR register") (Feb 2013), and +only set FSCR_TAR. + +At that point FSCR (Facility Status and Control Register) was not +context switched, so the setting was permanent after boot. + +Later we added initialisation of FSCR_DSCR to __init_FSCR(), in commit +54c9b2253d34 ("powerpc: Set DSCR bit in FSCR setup") (Mar 2013), again +that was permanent after boot. + +Then commit 2517617e0de6 ("powerpc: Fix context switch DSCR on +POWER8") (Aug 2013) added a limited context switch of FSCR, just the +FSCR_DSCR bit was context switched based on thread.dscr_inherit. That +commit said "This clears the H/FSCR DSCR bit initially", but it +didn't, it left the initialisation of FSCR_DSCR in __init_FSCR(). +However the initial context switch from init_task to pid 1 would clear +FSCR_DSCR because thread.dscr_inherit was 0. + +That commit also introduced the requirement that FSCR_DSCR be clear +for user processes, so that we can take the facility unavailable +interrupt in order to manage dscr_inherit. + +Then in commit 152d523e6307 ("powerpc: Create context switch helpers +save_sprs() and restore_sprs()") (Dec 2015) FSCR was added to +thread_struct. However it still wasn't fully context switched, we just +took the existing value and set FSCR_DSCR if the new thread had +dscr_inherit set. FSCR was still initialised at boot to FSCR_DSCR | +FSCR_TAR, but that value was not propagated into the thread_struct, so +the initial context switch set FSCR_DSCR back to 0. + +Finally commit b57bd2de8c6c ("powerpc: Improve FSCR init and context +switching") (Jun 2016) added a full context switch of the FSCR, and +added an initialisation of init_task.thread.fscr to FSCR_TAR | +FSCR_EBB, but omitted FSCR_DSCR. + +The end result is that swapper runs with FSCR_DSCR set because of the +initialisation in __init_FSCR(), but no other processes do, they use +the value from init_task.thread.fscr. + +Having FSCR_DSCR set for swapper allows it to access SPR 3 from +userspace, but swapper never runs userspace, so it has no useful +effect. It's also confusing to have the value initialised in two +places to two different values. + +So remove FSCR_DSCR from __init_FSCR(), this at least gets us to the +point where there's a single value of FSCR, even if it's still set in +two places. + +Signed-off-by: Michael Ellerman +Tested-by: Alistair Popple +Link: https://lore.kernel.org/r/20200527145843.2761782-1-mpe@ellerman.id.au +Acked-by: Michal Suchanek +--- + arch/powerpc/kernel/cpu_setup_power.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S +index a460298c7ddb..f91ecb10d0ae 100644 +--- a/arch/powerpc/kernel/cpu_setup_power.S ++++ b/arch/powerpc/kernel/cpu_setup_power.S +@@ -184,7 +184,7 @@ __init_LPCR_ISA300: + + __init_FSCR: + mfspr r3,SPRN_FSCR +- ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB ++ ori r3,r3,FSCR_TAR|FSCR_EBB + mtspr SPRN_FSCR,r3 + blr + +-- +2.26.2 + diff --git a/patches.suse/powerpc-perf-Fix-missing-is_sier_aviable-during-buil.patch b/patches.suse/powerpc-perf-Fix-missing-is_sier_aviable-during-buil.patch new file mode 100644 index 0000000..3fc637f --- /dev/null +++ b/patches.suse/powerpc-perf-Fix-missing-is_sier_aviable-during-buil.patch @@ -0,0 +1,52 @@ +From 3c9450c053f88e525b2db1e6990cdf34d14e7696 Mon Sep 17 00:00:00 2001 +From: Madhavan Srinivasan +Date: Sun, 14 Jun 2020 14:06:04 +0530 +Subject: [PATCH] powerpc/perf: Fix missing is_sier_aviable() during build + +References: bsc#1065729 +Patch-mainline: v5.9-rc1 +Git-commit: 3c9450c053f88e525b2db1e6990cdf34d14e7696 + +Compilation error: + arch/powerpc/perf/perf_regs.c:80:undefined reference to `.is_sier_available' + +Currently is_sier_available() is part of core-book3s.c, which is added +to build based on CONFIG_PPC_PERF_CTRS. + +A config with CONFIG_PERF_EVENTS and without CONFIG_PPC_PERF_CTRS will +have a build break because of missing is_sier_available(). + +In practice it only breaks when CONFIG_FSL_EMB_PERF_EVENT=n because +that also guards the usage of is_sier_available(). That only happens +with CONFIG_PPC_BOOK3E_64=y and CONFIG_FSL_SOC_BOOKE=n. + +Patch adds is_sier_available() in asm/perf_event.h to fix the build +break for configs missing CONFIG_PPC_PERF_CTRS. + +Fixes: 333804dc3b7a ("powerpc/perf: Update perf_regs structure to include SIER") +Reported-by: Aneesh Kumar K.V +Signed-off-by: Madhavan Srinivasan +[mpe: Add detail about CONFIG_FSL_SOC_BOOKE] +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20200614083604.302611-1-maddy@linux.ibm.com +Acked-by: Michal Suchanek +--- + arch/powerpc/include/asm/perf_event.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h +index eed3954082fa..1e8b2e1ec1db 100644 +--- a/arch/powerpc/include/asm/perf_event.h ++++ b/arch/powerpc/include/asm/perf_event.h +@@ -12,6 +12,8 @@ + + #ifdef CONFIG_PPC_PERF_CTRS + #include ++#else ++static inline bool is_sier_available(void) { return false; } + #endif + + #ifdef CONFIG_FSL_EMB_PERF_EVENT +-- +2.26.2 + diff --git a/patches.suse/powerpc-pseries-hotplug-cpu-wait-indefinitely-for-vC.patch b/patches.suse/powerpc-pseries-hotplug-cpu-wait-indefinitely-for-vC.patch new file mode 100644 index 0000000..fbe1ef9 --- /dev/null +++ b/patches.suse/powerpc-pseries-hotplug-cpu-wait-indefinitely-for-vC.patch @@ -0,0 +1,160 @@ +From 801980f6497946048709b9b09771a1729551d705 Mon Sep 17 00:00:00 2001 +From: Michael Roth +Date: Tue, 11 Aug 2020 11:15:44 -0500 +Subject: [PATCH] powerpc/pseries/hotplug-cpu: wait indefinitely for vCPU death + +References: fate#322438 bsc#1085030 ltC#165630 +Patch-mainline: v5.9-rc2 +Git-commit: 801980f6497946048709b9b09771a1729551d705 + +For a power9 KVM guest with XIVE enabled, running a test loop +where we hotplug 384 vcpus and then unplug them, the following traces +can be seen (generally within a few loops) either from the unplugged +vcpu: + + cpu 65 (hwid 65) Ready to die... + Querying DEAD? cpu 66 (66) shows 2 + list_del corruption. next->prev should be c00a000002470208, but was c00a000002470048 + ------------[ cut here ]------------ + kernel BUG at lib/list_debug.c:56! + Oops: Exception in kernel mode, sig: 5 [#1] + LE SMP NR_CPUS=2048 NUMA pSeries + Modules linked in: fuse nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 ... + CPU: 66 PID: 0 Comm: swapper/66 Kdump: loaded Not tainted 4.18.0-221.el8.ppc64le #1 + NIP: c0000000007ab50c LR: c0000000007ab508 CTR: 00000000000003ac + REGS: c0000009e5a17840 TRAP: 0700 Not tainted (4.18.0-221.el8.ppc64le) + MSR: 800000000282b033 CR: 28000842 XER: 20040000 + ... + NIP __list_del_entry_valid+0xac/0x100 + LR __list_del_entry_valid+0xa8/0x100 + Call Trace: + __list_del_entry_valid+0xa8/0x100 (unreliable) + free_pcppages_bulk+0x1f8/0x940 + free_unref_page+0xd0/0x100 + xive_spapr_cleanup_queue+0x148/0x1b0 + xive_teardown_cpu+0x1bc/0x240 + pseries_mach_cpu_die+0x78/0x2f0 + cpu_die+0x48/0x70 + arch_cpu_idle_dead+0x20/0x40 + do_idle+0x2f4/0x4c0 + cpu_startup_entry+0x38/0x40 + start_secondary+0x7bc/0x8f0 + start_secondary_prolog+0x10/0x14 + +or on the worker thread handling the unplug: + + pseries-hotplug-cpu: Attempting to remove CPU , drc index: 1000013a + Querying DEAD? cpu 314 (314) shows 2 + BUG: Bad page state in process kworker/u768:3 pfn:95de1 + cpu 314 (hwid 314) Ready to die... + page:c00a000002577840 refcount:0 mapcount:-128 mapping:0000000000000000 index:0x0 + flags: 0x5ffffc00000000() + raw: 005ffffc00000000 5deadbeef0000100 5deadbeef0000200 0000000000000000 + raw: 0000000000000000 0000000000000000 00000000ffffff7f 0000000000000000 + page dumped because: nonzero mapcount + Modules linked in: kvm xt_CHECKSUM ipt_MASQUERADE xt_conntrack ... + CPU: 0 PID: 548 Comm: kworker/u768:3 Kdump: loaded Not tainted 4.18.0-224.el8.bz1856588.ppc64le #1 + Workqueue: pseries hotplug workque pseries_hp_work_fn + Call Trace: + dump_stack+0xb0/0xf4 (unreliable) + bad_page+0x12c/0x1b0 + free_pcppages_bulk+0x5bc/0x940 + page_alloc_cpu_dead+0x118/0x120 + cpuhp_invoke_callback.constprop.5+0xb8/0x760 + _cpu_down+0x188/0x340 + cpu_down+0x5c/0xa0 + cpu_subsys_offline+0x24/0x40 + device_offline+0xf0/0x130 + dlpar_offline_cpu+0x1c4/0x2a0 + dlpar_cpu_remove+0xb8/0x190 + dlpar_cpu_remove_by_index+0x12c/0x150 + dlpar_cpu+0x94/0x800 + pseries_hp_work_fn+0x128/0x1e0 + process_one_work+0x304/0x5d0 + worker_thread+0xcc/0x7a0 + kthread+0x1ac/0x1c0 + ret_from_kernel_thread+0x5c/0x80 + +The latter trace is due to the following sequence: + + page_alloc_cpu_dead + drain_pages + drain_pages_zone + free_pcppages_bulk + +where drain_pages() in this case is called under the assumption that +the unplugged cpu is no longer executing. To ensure that is the case, +and early call is made to __cpu_die()->pseries_cpu_die(), which runs a +loop that waits for the cpu to reach a halted state by polling its +status via query-cpu-stopped-state RTAS calls. It only polls for 25 +iterations before giving up, however, and in the trace above this +results in the following being printed only .1 seconds after the +hotplug worker thread begins processing the unplug request: + + pseries-hotplug-cpu: Attempting to remove CPU , drc index: 1000013a + Querying DEAD? cpu 314 (314) shows 2 + +At that point the worker thread assumes the unplugged CPU is in some +unknown/dead state and procedes with the cleanup, causing the race +with the XIVE cleanup code executed by the unplugged CPU. + +Fix this by waiting indefinitely, but also making an effort to avoid +spurious lockup messages by allowing for rescheduling after polling +the CPU status and printing a warning if we wait for longer than 120s. + +Fixes: eac1e731b59ee ("powerpc/xive: guest exploitation of the XIVE interrupt controller") +Suggested-by: Michael Ellerman +Signed-off-by: Michael Roth +Tested-by: Greg Kurz +Reviewed-by: Thiago Jung Bauermann +Reviewed-by: Greg Kurz +[mpe: Trim oopses in change log slightly for readability] +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20200811161544.10513-1-mdroth@linux.vnet.ibm.com +Acked-by: Michal Suchanek +--- + arch/powerpc/platforms/pseries/hotplug-cpu.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c +index c6e0d8abf75e..7a974ed6b240 100644 +--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c ++++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c +@@ -107,22 +107,28 @@ static int pseries_cpu_disable(void) + */ + static void pseries_cpu_die(unsigned int cpu) + { +- int tries; + int cpu_status = 1; + unsigned int pcpu = get_hard_smp_processor_id(cpu); ++ unsigned long timeout = jiffies + msecs_to_jiffies(120000); + +- for (tries = 0; tries < 25; tries++) { ++ while (true) { + cpu_status = smp_query_cpu_stopped(pcpu); + if (cpu_status == QCSS_STOPPED || + cpu_status == QCSS_HARDWARE_ERROR) + break; +- cpu_relax(); + ++ if (time_after(jiffies, timeout)) { ++ pr_warn("CPU %i (hwid %i) didn't die after 120 seconds\n", ++ cpu, pcpu); ++ timeout = jiffies + msecs_to_jiffies(120000); ++ } ++ ++ cond_resched(); + } + +- if (cpu_status != 0) { +- printk("Querying DEAD? cpu %i (%i) shows %i\n", +- cpu, pcpu, cpu_status); ++ if (cpu_status == QCSS_HARDWARE_ERROR) { ++ pr_warn("CPU %i (hwid %i) reported error while dying\n", ++ cpu, pcpu); + } + + /* Isolation and deallocation are definitely done by +-- +2.26.2 + diff --git a/patches.suse/pseries-Fix-64-bit-logical-memory-block-panic.patch b/patches.suse/pseries-Fix-64-bit-logical-memory-block-panic.patch new file mode 100644 index 0000000..7b22ee5 --- /dev/null +++ b/patches.suse/pseries-Fix-64-bit-logical-memory-block-panic.patch @@ -0,0 +1,41 @@ +From 89c140bbaeee7a55ed0360a88f294ead2b95201b Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Wed, 15 Jul 2020 10:08:20 +1000 +Subject: [PATCH] pseries: Fix 64 bit logical memory block panic + +References: bsc#1065729 +Patch-mainline: v5.9-rc1 +Git-commit: 89c140bbaeee7a55ed0360a88f294ead2b95201b + +Booting with a 4GB LMB size causes us to panic: + + qemu-system-ppc64: OS terminated: OS panic: + Memory block size not suitable: 0x0 + +Fix pseries_memory_block_size() to handle 64 bit LMBs. + +Cc: stable@vger.kernel.org +Signed-off-by: Anton Blanchard +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20200715000820.1255764-1-anton@ozlabs.org +Acked-by: Michal Suchanek +--- + arch/powerpc/platforms/pseries/hotplug-memory.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c +index 73a5dcd977e1..5d545b78111f 100644 +--- a/arch/powerpc/platforms/pseries/hotplug-memory.c ++++ b/arch/powerpc/platforms/pseries/hotplug-memory.c +@@ -25,7 +25,7 @@ + unsigned long pseries_memory_block_size(void) + { + struct device_node *np; +- unsigned int memblock_size = MIN_MEMORY_BLOCK_SIZE; ++ u64 memblock_size = MIN_MEMORY_BLOCK_SIZE; + struct resource r; + + np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); +-- +2.26.2 + diff --git a/patches.suse/rocker-fix-incorrect-error-handling-in-dma_rings_ini.patch b/patches.suse/rocker-fix-incorrect-error-handling-in-dma_rings_ini.patch new file mode 100644 index 0000000..a9f169c --- /dev/null +++ b/patches.suse/rocker-fix-incorrect-error-handling-in-dma_rings_ini.patch @@ -0,0 +1,34 @@ +From: Aditya Pakki +Date: Fri, 12 Jun 2020 15:27:55 -0500 +Subject: rocker: fix incorrect error handling in dma_rings_init +Git-commit: 58d0c864e1a759a15c9df78f50ea5a5c32b3989e +Patch-mainline: 5.8-rc2 +References: networking-stable-20_06_28 + +In rocker_dma_rings_init, the goto blocks in case of errors +caused by the functions rocker_dma_cmd_ring_waits_alloc() and +rocker_dma_ring_create() are incorrect. The patch fixes the +order consistent with cleanup in rocker_dma_rings_fini(). + +Signed-off-by: Aditya Pakki +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + drivers/net/ethernet/rocker/rocker_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/rocker/rocker_main.c ++++ b/drivers/net/ethernet/rocker/rocker_main.c +@@ -651,10 +651,10 @@ static int rocker_dma_rings_init(struct + err_dma_event_ring_bufs_alloc: + rocker_dma_ring_destroy(rocker, &rocker->event_ring); + err_dma_event_ring_create: ++ rocker_dma_cmd_ring_waits_free(rocker); ++err_dma_cmd_ring_waits_alloc: + rocker_dma_ring_bufs_free(rocker, &rocker->cmd_ring, + PCI_DMA_BIDIRECTIONAL); +-err_dma_cmd_ring_waits_alloc: +- rocker_dma_cmd_ring_waits_free(rocker); + err_dma_cmd_ring_bufs_alloc: + rocker_dma_ring_destroy(rocker, &rocker->cmd_ring); + return err; diff --git a/patches.suse/sched-consistently-handle-layer3-header-accesses-in-.patch b/patches.suse/sched-consistently-handle-layer3-header-accesses-in-.patch new file mode 100644 index 0000000..f14c5eb --- /dev/null +++ b/patches.suse/sched-consistently-handle-layer3-header-accesses-in-.patch @@ -0,0 +1,361 @@ +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Fri, 3 Jul 2020 22:26:43 +0200 +Subject: sched: consistently handle layer3 header accesses in the presence of + VLANs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: d7bf2ebebc2bd61ab95e2a8e33541ef282f303d4 +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +There are a couple of places in net/sched/ that check skb->protocol and act +on the value there. However, in the presence of VLAN tags, the value stored +in skb->protocol can be inconsistent based on whether VLAN acceleration is +enabled. The commit quoted in the Fixes tag below fixed the users of +skb->protocol to use a helper that will always see the VLAN ethertype. + +However, most of the callers don't actually handle the VLAN ethertype, but +expect to find the IP header type in the protocol field. This means that +things like changing the ECN field, or parsing diffserv values, stops +working if there's a VLAN tag, or if there are multiple nested VLAN +tags (QinQ). + +To fix this, change the helper to take an argument that indicates whether +the caller wants to skip the VLAN tags or not. When skipping VLAN tags, we +make sure to skip all of them, so behaviour is consistent even in QinQ +mode. + +To make the helper usable from the ECN code, move it to if_vlan.h instead +of pkt_sched.h. + +v3: +- Remove empty lines +- Move vlan variable definitions inside loop in skb_protocol() +- Also use skb_protocol() helper in IP{,6}_ECN_decapsulate() and + bpf_skb_ecn_set_ce() + +v2: +- Use eth_type_vlan() helper in skb_protocol() +- Also fix code that reads skb->protocol directly +- Change a couple of 'if/else if' statements to switch constructs to avoid + calling the helper twice + +[js] many hunks removed as the code does not exist in 4.12 yet. + +Reported-by: Ilya Ponetayev +Fixes: d8b9605d2697 ("net: sched: fix skb->protocol use in case of accelerated vlan path") +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + include/linux/if_vlan.h | 28 ++++++++++++++++++++++++++++ + include/net/inet_ecn.h | 25 +++++++++++++++++-------- + include/net/pkt_sched.h | 11 ----------- + net/sched/act_connmark.c | 9 ++++++--- + net/sched/act_csum.c | 2 +- + net/sched/act_skbedit.c | 2 +- + net/sched/cls_api.c | 2 +- + net/sched/cls_flow.c | 8 ++++---- + net/sched/cls_flower.c | 2 +- + net/sched/em_ipset.c | 2 +- + net/sched/em_meta.c | 2 +- + net/sched/sch_dsmark.c | 6 +++--- + net/sched/sch_teql.c | 2 +- + 13 files changed, 65 insertions(+), 36 deletions(-) + +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -290,6 +290,34 @@ static inline bool eth_type_vlan(__be16 + } + } + ++/* A getter for the SKB protocol field which will handle VLAN tags consistently ++ * whether VLAN acceleration is enabled or not. ++ */ ++static inline __be16 skb_protocol(const struct sk_buff *skb, bool skip_vlan) ++{ ++ unsigned int offset = skb_mac_offset(skb) + sizeof(struct ethhdr); ++ __be16 proto = skb->protocol; ++ ++ if (!skip_vlan) ++ /* VLAN acceleration strips the VLAN header from the skb and ++ * moves it to skb->vlan_proto ++ */ ++ return skb_vlan_tag_present(skb) ? skb->vlan_proto : proto; ++ ++ while (eth_type_vlan(proto)) { ++ struct vlan_hdr vhdr, *vh; ++ ++ vh = skb_header_pointer(skb, offset, sizeof(vhdr), &vhdr); ++ if (!vh) ++ break; ++ ++ proto = vh->h_vlan_encapsulated_proto; ++ offset += sizeof(vhdr); ++ } ++ ++ return proto; ++} ++ + static inline bool vlan_hw_offload_capable(netdev_features_t features, + __be16 proto) + { +--- a/include/net/inet_ecn.h ++++ b/include/net/inet_ecn.h +@@ -3,6 +3,7 @@ + + #include + #include ++#include + + #include + #include +@@ -176,7 +177,7 @@ static inline void ipv6_copy_dscp(unsign + + static inline int INET_ECN_set_ce(struct sk_buff *skb) + { +- switch (skb->protocol) { ++ switch (skb_protocol(skb, true)) { + case cpu_to_be16(ETH_P_IP): + if (skb_network_header(skb) + sizeof(struct iphdr) <= + skb_tail_pointer(skb)) +@@ -195,7 +196,7 @@ static inline int INET_ECN_set_ce(struct + + static inline int INET_ECN_set_ect1(struct sk_buff *skb) + { +- switch (skb->protocol) { ++ switch (skb_protocol(skb, true)) { + case cpu_to_be16(ETH_P_IP): + if (skb_network_header(skb) + sizeof(struct iphdr) <= + skb_tail_pointer(skb)) +@@ -276,12 +277,16 @@ static inline int IP_ECN_decapsulate(con + { + __u8 inner; + +- if (skb->protocol == htons(ETH_P_IP)) ++ switch (skb_protocol(skb, true)) { ++ case htons(ETH_P_IP): + inner = ip_hdr(skb)->tos; +- else if (skb->protocol == htons(ETH_P_IPV6)) ++ break; ++ case htons(ETH_P_IPV6): + inner = ipv6_get_dsfield(ipv6_hdr(skb)); +- else ++ break; ++ default: + return 0; ++ } + + return INET_ECN_decapsulate(skb, oiph->tos, inner); + } +@@ -291,12 +296,16 @@ static inline int IP6_ECN_decapsulate(co + { + __u8 inner; + +- if (skb->protocol == htons(ETH_P_IP)) ++ switch (skb_protocol(skb, true)) { ++ case htons(ETH_P_IP): + inner = ip_hdr(skb)->tos; +- else if (skb->protocol == htons(ETH_P_IPV6)) ++ break; ++ case htons(ETH_P_IPV6): + inner = ipv6_get_dsfield(ipv6_hdr(skb)); +- else ++ break; ++ default: + return 0; ++ } + + return INET_ECN_decapsulate(skb, ipv6_get_dsfield(oipv6h), inner); + } +--- a/include/net/pkt_sched.h ++++ b/include/net/pkt_sched.h +@@ -122,17 +122,6 @@ static inline void qdisc_run(struct Qdis + } + } + +-static inline __be16 tc_skb_protocol(const struct sk_buff *skb) +-{ +- /* We need to take extra care in case the skb came via +- * vlan accelerated path. In that case, use skb->vlan_proto +- * as the original vlan header was already stripped. +- */ +- if (skb_vlan_tag_present(skb)) +- return skb->vlan_proto; +- return skb->protocol; +-} +- + /* Calculate maximal size of packet seen by hard_start_xmit + routine of this device. + */ +--- a/net/sched/act_connmark.c ++++ b/net/sched/act_connmark.c +@@ -46,17 +46,20 @@ static int tcf_connmark_act(struct sk_bu + tcf_lastuse_update(&ca->tcf_tm); + bstats_update(&ca->tcf_bstats, skb); + +- if (skb->protocol == htons(ETH_P_IP)) { ++ switch (skb_protocol(skb, true)) { ++ case htons(ETH_P_IP): + if (skb->len < sizeof(struct iphdr)) + goto out; + + proto = NFPROTO_IPV4; +- } else if (skb->protocol == htons(ETH_P_IPV6)) { ++ break; ++ case htons(ETH_P_IPV6): + if (skb->len < sizeof(struct ipv6hdr)) + goto out; + + proto = NFPROTO_IPV6; +- } else { ++ break; ++ default: + goto out; + } + +--- a/net/sched/act_csum.c ++++ b/net/sched/act_csum.c +@@ -573,7 +573,7 @@ static int tcf_csum_act(struct sk_buff * + goto drop; + + update_flags = params->update_flags; +- switch (tc_skb_protocol(skb)) { ++ switch (skb_protocol(skb, false)) { + case cpu_to_be16(ETH_P_IP): + if (!tcf_csum_ipv4(skb, update_flags)) + goto drop; +--- a/net/sched/act_skbedit.c ++++ b/net/sched/act_skbedit.c +@@ -51,7 +51,7 @@ static int tcf_skbedit_act(struct sk_buf + if (params->flags & SKBEDIT_F_INHERITDSFIELD) { + int wlen = skb_network_offset(skb); + +- switch (tc_skb_protocol(skb)) { ++ switch (skb_protocol(skb, true)) { + case htons(ETH_P_IP): + wlen += sizeof(struct iphdr); + if (!pskb_may_pull(skb, wlen)) +--- a/net/sched/cls_api.c ++++ b/net/sched/cls_api.c +@@ -1062,7 +1062,7 @@ int tcf_classify(struct sk_buff *skb, co + reclassify: + #endif + for (; tp; tp = rcu_dereference_bh(tp->next)) { +- __be16 protocol = tc_skb_protocol(skb); ++ __be16 protocol = skb_protocol(skb, false); + int err; + + if (tp->protocol != protocol && +--- a/net/sched/cls_flow.c ++++ b/net/sched/cls_flow.c +@@ -84,7 +84,7 @@ static u32 flow_get_dst(const struct sk_ + if (dst) + return ntohl(dst); + +- return addr_fold(skb_dst(skb)) ^ (__force u16) tc_skb_protocol(skb); ++ return addr_fold(skb_dst(skb)) ^ (__force u16)skb_protocol(skb, true); + } + + static u32 flow_get_proto(const struct sk_buff *skb, +@@ -108,7 +108,7 @@ static u32 flow_get_proto_dst(const stru + if (flow->ports.ports) + return ntohs(flow->ports.dst); + +- return addr_fold(skb_dst(skb)) ^ (__force u16) tc_skb_protocol(skb); ++ return addr_fold(skb_dst(skb)) ^ (__force u16)skb_protocol(skb, true); + } + + static u32 flow_get_iif(const struct sk_buff *skb) +@@ -155,7 +155,7 @@ static u32 flow_get_nfct(const struct sk + static u32 flow_get_nfct_src(const struct sk_buff *skb, + const struct flow_keys *flow) + { +- switch (tc_skb_protocol(skb)) { ++ switch (skb_protocol(skb, true)) { + case htons(ETH_P_IP): + return ntohl(CTTUPLE(skb, src.u3.ip)); + case htons(ETH_P_IPV6): +@@ -168,7 +168,7 @@ fallback: + static u32 flow_get_nfct_dst(const struct sk_buff *skb, + const struct flow_keys *flow) + { +- switch (tc_skb_protocol(skb)) { ++ switch (skb_protocol(skb, true)) { + case htons(ETH_P_IP): + return ntohl(CTTUPLE(skb, dst.u3.ip)); + case htons(ETH_P_IPV6): +--- a/net/sched/cls_flower.c ++++ b/net/sched/cls_flower.c +@@ -203,7 +203,7 @@ static int fl_classify(struct sk_buff *s + /* skb_flow_dissect() does not set n_proto in case an unknown + * protocol, so do it rather here. + */ +- skb_key.basic.n_proto = skb->protocol; ++ skb_key.basic.n_proto = skb_protocol(skb, false); + skb_flow_dissect_tunnel_info(skb, &mask->dissector, &skb_key); + skb_flow_dissect(skb, &mask->dissector, &skb_key, 0); + +--- a/net/sched/em_ipset.c ++++ b/net/sched/em_ipset.c +@@ -62,7 +62,7 @@ static int em_ipset_match(struct sk_buff + }; + int ret, network_offset; + +- switch (tc_skb_protocol(skb)) { ++ switch (skb_protocol(skb, true)) { + case htons(ETH_P_IP): + state.pf = NFPROTO_IPV4; + if (!pskb_network_may_pull(skb, sizeof(struct iphdr))) +--- a/net/sched/em_meta.c ++++ b/net/sched/em_meta.c +@@ -199,7 +199,7 @@ META_COLLECTOR(int_priority) + META_COLLECTOR(int_protocol) + { + /* Let userspace take care of the byte ordering */ +- dst->value = tc_skb_protocol(skb); ++ dst->value = skb_protocol(skb, false); + } + + META_COLLECTOR(int_pkttype) +--- a/net/sched/sch_dsmark.c ++++ b/net/sched/sch_dsmark.c +@@ -208,7 +208,7 @@ static int dsmark_enqueue(struct sk_buff + if (p->set_tc_index) { + int wlen = skb_network_offset(skb); + +- switch (tc_skb_protocol(skb)) { ++ switch (skb_protocol(skb, true)) { + case htons(ETH_P_IP): + wlen += sizeof(struct iphdr); + if (!pskb_may_pull(skb, wlen) || +@@ -301,7 +301,7 @@ static struct sk_buff *dsmark_dequeue(st + index = skb->tc_index & (p->indices - 1); + pr_debug("index %d->%d\n", skb->tc_index, index); + +- switch (tc_skb_protocol(skb)) { ++ switch (skb_protocol(skb, true)) { + case htons(ETH_P_IP): + ipv4_change_dsfield(ip_hdr(skb), p->mv[index].mask, + p->mv[index].value); +@@ -318,7 +318,7 @@ static struct sk_buff *dsmark_dequeue(st + */ + if (p->mv[index].mask != 0xff || p->mv[index].value) + pr_warn("%s: unsupported protocol %d\n", +- __func__, ntohs(tc_skb_protocol(skb))); ++ __func__, ntohs(skb_protocol(skb, true))); + break; + } + +--- a/net/sched/sch_teql.c ++++ b/net/sched/sch_teql.c +@@ -243,7 +243,7 @@ __teql_resolve(struct sk_buff *skb, stru + char haddr[MAX_ADDR_LEN]; + + neigh_ha_snapshot(haddr, n, dev); +- err = dev_hard_header(skb, dev, ntohs(tc_skb_protocol(skb)), ++ err = dev_hard_header(skb, dev, ntohs(skb_protocol(skb, false)), + haddr, NULL, skb->len); + + if (err < 0) diff --git a/patches.suse/sctp-Don-t-advertise-IPv4-addresses-if-ipv6only-is-s.patch b/patches.suse/sctp-Don-t-advertise-IPv4-addresses-if-ipv6only-is-s.patch new file mode 100644 index 0000000..9b41fdc --- /dev/null +++ b/patches.suse/sctp-Don-t-advertise-IPv4-addresses-if-ipv6only-is-s.patch @@ -0,0 +1,86 @@ +From: Marcelo Ricardo Leitner +Date: Wed, 24 Jun 2020 17:34:18 -0300 +Subject: sctp: Don't advertise IPv4 addresses if ipv6only is set on the socket +Git-commit: 471e39df96b9a4c4ba88a2da9e25a126624d7a9c +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +If a socket is set ipv6only, it will still send IPv4 addresses in the +INIT and INIT_ACK packets. This potentially misleads the peer into using +them, which then would cause association termination. + +The fix is to not add IPv4 addresses to ipv6only sockets. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: Corey Minyard +Signed-off-by: Marcelo Ricardo Leitner +Tested-by: Corey Minyard +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + include/net/sctp/constants.h | 8 +++++--- + net/sctp/associola.c | 5 ++++- + net/sctp/bind_addr.c | 1 + + net/sctp/protocol.c | 3 ++- + 4 files changed, 12 insertions(+), 5 deletions(-) + +--- a/include/net/sctp/constants.h ++++ b/include/net/sctp/constants.h +@@ -362,11 +362,13 @@ typedef enum { + ipv4_is_anycast_6to4(a)) + + /* Flags used for the bind address copy functions. */ +-#define SCTP_ADDR6_ALLOWED 0x00000001 /* IPv6 address is allowed by ++#define SCTP_ADDR4_ALLOWED 0x00000001 /* IPv4 address is allowed by + local sock family */ +-#define SCTP_ADDR4_PEERSUPP 0x00000002 /* IPv4 address is supported by ++#define SCTP_ADDR6_ALLOWED 0x00000002 /* IPv6 address is allowed by ++ local sock family */ ++#define SCTP_ADDR4_PEERSUPP 0x00000004 /* IPv4 address is supported by + peer */ +-#define SCTP_ADDR6_PEERSUPP 0x00000004 /* IPv6 address is supported by ++#define SCTP_ADDR6_PEERSUPP 0x00000008 /* IPv6 address is supported by + peer */ + + /* Reasons to retransmit. */ +--- a/net/sctp/associola.c ++++ b/net/sctp/associola.c +@@ -1596,12 +1596,15 @@ void sctp_assoc_rwnd_decrease(struct sct + int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, + sctp_scope_t scope, gfp_t gfp) + { ++ struct sock *sk = asoc->base.sk; + int flags; + + /* Use scoping rules to determine the subset of addresses from + * the endpoint. + */ +- flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0; ++ flags = (PF_INET6 == sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0; ++ if (!inet_v6_ipv6only(sk)) ++ flags |= SCTP_ADDR4_ALLOWED; + if (asoc->peer.ipv4_address) + flags |= SCTP_ADDR4_PEERSUPP; + if (asoc->peer.ipv6_address) +--- a/net/sctp/bind_addr.c ++++ b/net/sctp/bind_addr.c +@@ -454,6 +454,7 @@ static int sctp_copy_one_addr(struct net + * well as the remote peer. + */ + if ((((AF_INET == addr->sa.sa_family) && ++ (flags & SCTP_ADDR4_ALLOWED) && + (flags & SCTP_ADDR4_PEERSUPP))) || + (((AF_INET6 == addr->sa.sa_family) && + (flags & SCTP_ADDR6_ALLOWED) && +--- a/net/sctp/protocol.c ++++ b/net/sctp/protocol.c +@@ -214,7 +214,8 @@ int sctp_copy_local_addr_list(struct net + * sock as well as the remote peer. + */ + if (addr->a.sa.sa_family == AF_INET && +- !(copy_flags & SCTP_ADDR4_PEERSUPP)) ++ (!(copy_flags & SCTP_ADDR4_ALLOWED) || ++ !(copy_flags & SCTP_ADDR4_PEERSUPP))) + continue; + if (addr->a.sa.sa_family == AF_INET6 && + (!(copy_flags & SCTP_ADDR6_ALLOWED) || diff --git a/patches.suse/selftests-livepatch-fix-mem-leaks-in-test-klp-shadow-vars.patch b/patches.suse/selftests-livepatch-fix-mem-leaks-in-test-klp-shadow-vars.patch new file mode 100644 index 0000000..6f860a4 --- /dev/null +++ b/patches.suse/selftests-livepatch-fix-mem-leaks-in-test-klp-shadow-vars.patch @@ -0,0 +1,124 @@ +From: Yannick Cote +Date: Wed, 3 Jun 2020 14:20:58 -0400 +Subject: selftests/livepatch: fix mem leaks in test-klp-shadow-vars +Git-commit: 270f7806d3b91b9c71fa8fe66f7dcc2d6587694e +Patch-mainline: v5.9-rc1 +References: bsc#1071995 + +In some cases, when an error occurs during testing and the main test +routine returns, a memory leak occurs via leaving previously registered +shadow variables allocated in the kernel as well as shadow_ptr list +elements. From now on, in case of error, remove all allocated shadow +variables and shadow_ptr struct elements. + +Signed-off-by: Yannick Cote +Reviewed-by: Petr Mladek +Reviewed-by: Kamalesh Babulal +Acked-by: Miroslav Benes +Acked-by: Joe Lawrence +Signed-off-by: Petr Mladek +Link: https://lore.kernel.org/r/20200603182058.109470-5-ycote@redhat.com +--- + lib/livepatch/test_klp_shadow_vars.c | 43 ++++++++++++++++++++++++++---------- + 1 file changed, 31 insertions(+), 12 deletions(-) + +diff --git a/lib/livepatch/test_klp_shadow_vars.c b/lib/livepatch/test_klp_shadow_vars.c +index a49265e56917..b99116490858 100644 +--- a/lib/livepatch/test_klp_shadow_vars.c ++++ b/lib/livepatch/test_klp_shadow_vars.c +@@ -170,6 +170,7 @@ static int test_klp_shadow_vars_init(void) + char *pndup[NUM_OBJS]; + int nfields2[NUM_OBJS], *pnfields2[NUM_OBJS], **sv2[NUM_OBJS]; + void **sv; ++ int ret; + int i; + + ptr_id(NULL); +@@ -196,31 +197,39 @@ static int test_klp_shadow_vars_init(void) + sizeof(pnfields1[i]), GFP_KERNEL, + shadow_ctor, &pnfields1[i]); + } +- if (!sv1[i]) +- return -ENOMEM; ++ if (!sv1[i]) { ++ ret = -ENOMEM; ++ goto out; ++ } + + pnfields2[i] = &nfields2[i]; + ptr_id(pnfields2[i]); + sv2[i] = shadow_alloc(&objs[i], SV_ID2, sizeof(pnfields2[i]), + GFP_KERNEL, shadow_ctor, &pnfields2[i]); +- if (!sv2[i]) +- return -ENOMEM; ++ if (!sv2[i]) { ++ ret = -ENOMEM; ++ goto out; ++ } + } + + /* pass 2: verify we find allocated svars and where they point to */ + for (i = 0; i < NUM_OBJS; i++) { + /* check the "char" svar for all objects */ + sv = shadow_get(&objs[i], SV_ID1); +- if (!sv) +- return -EINVAL; ++ if (!sv) { ++ ret = -EINVAL; ++ goto out; ++ } + if ((char **)sv == sv1[i] && *sv1[i] == pnfields1[i]) + pr_info(" got expected PTR%d -> PTR%d result\n", + ptr_id(sv1[i]), ptr_id(*sv1[i])); + + /* check the "int" svar for all objects */ + sv = shadow_get(&objs[i], SV_ID2); +- if (!sv) +- return -EINVAL; ++ if (!sv) { ++ ret = -EINVAL; ++ goto out; ++ } + if ((int **)sv == sv2[i] && *sv2[i] == pnfields2[i]) + pr_info(" got expected PTR%d -> PTR%d result\n", + ptr_id(sv2[i]), ptr_id(*sv2[i])); +@@ -233,8 +242,10 @@ static int test_klp_shadow_vars_init(void) + + sv = shadow_get_or_alloc(&objs[i], SV_ID1, sizeof(pndup[i]), + GFP_KERNEL, shadow_ctor, &pndup[i]); +- if (!sv) +- return -EINVAL; ++ if (!sv) { ++ ret = -EINVAL; ++ goto out; ++ } + if ((char **)sv == sv1[i] && *sv1[i] == pnfields1[i]) + pr_info(" got expected PTR%d -> PTR%d result\n", + ptr_id(sv1[i]), ptr_id(*sv1[i])); +@@ -251,8 +262,10 @@ static int test_klp_shadow_vars_init(void) + /* pass 5: check we still find svar pairs */ + for (i = 0; i < NUM_OBJS; i++) { + sv = shadow_get(&objs[i], SV_ID2); /* 'int' pairs */ +- if (!sv) +- return -EINVAL; ++ if (!sv) { ++ ret = -EINVAL; ++ goto out; ++ } + if ((int **)sv == sv2[i] && *sv2[i] == pnfields2[i]) + pr_info(" got expected PTR%d -> PTR%d result\n", + ptr_id(sv2[i]), ptr_id(*sv2[i])); +@@ -269,6 +282,12 @@ static int test_klp_shadow_vars_init(void) + free_ptr_list(); + + return 0; ++out: ++ shadow_free_all(SV_ID1, NULL); /* 'char' pairs */ ++ shadow_free_all(SV_ID2, NULL); /* 'int' pairs */ ++ free_ptr_list(); ++ ++ return ret; + } + + static void test_klp_shadow_vars_exit(void) + diff --git a/patches.suse/selftests-livepatch-more-verification-in-test-klp-shadow-vars.patch b/patches.suse/selftests-livepatch-more-verification-in-test-klp-shadow-vars.patch new file mode 100644 index 0000000..25c51af --- /dev/null +++ b/patches.suse/selftests-livepatch-more-verification-in-test-klp-shadow-vars.patch @@ -0,0 +1,258 @@ +From: Yannick Cote +Date: Wed, 3 Jun 2020 14:20:57 -0400 +Subject: selftests/livepatch: more verification in test-klp-shadow-vars +Git-commit: 76efe6da89d8320e9ba65cebe0b3bcb6e5c29b31 (partial) +Patch-mainline: v5.9-rc1 +References: bsc#1071995 + +This change makes the test feel more familiar with narrowing to a +typical usage by operating on a number of identical structure instances +and populating the same two new shadow variables symmetrically while +keeping the same testing and verification criteria for the extra +variables. + +Signed-off-by: Yannick Cote +Reviewed-by: Kamalesh Babulal +Reviewed-by: Petr Mladek +Acked-by: Miroslav Benes +Acked-by: Joe Lawrence +Signed-off-by: Petr Mladek +Link: https://lore.kernel.org/r/20200603182058.109470-4-ycote@redhat.com +--- + + lib/livepatch/test_klp_shadow_vars.c | 192 ++++++++++++++++------------------- + 1 file changed, 92 insertions(+), 100 deletions(-) + +--- a/lib/livepatch/test_klp_shadow_vars.c ++++ b/lib/livepatch/test_klp_shadow_vars.c +@@ -128,6 +128,11 @@ static int shadow_ctor(void *obj, void *shadow_data, void *ctor_data) + return 0; + } + ++/* ++ * With more than one item to free in the list, order is not determined and ++ * shadow_dtor will not be passed to shadow_free_all() which would make the ++ * test fail. (see pass 6) ++ */ + static void shadow_dtor(void *obj, void *shadow_data) + { + int **sv = shadow_data; +@@ -136,6 +141,9 @@ static void shadow_dtor(void *obj, void *shadow_data) + __func__, ptr_id(obj), ptr_id(sv)); + } + ++/* number of objects we simulate that need shadow vars */ ++#define NUM_OBJS 3 ++ + /* dynamically created obj fields have the following shadow var id values */ + #define SV_ID1 0x1234 + #define SV_ID2 0x1235 +@@ -157,122 +165,106 @@ struct test_object { + + static int test_klp_shadow_vars_init(void) + { +- struct test_object obj1, obj2, obj3; +- char nfield1, nfield2, *pnfield1, *pnfield2, **sv1, **sv2; +- int nfield3, nfield4, *pnfield3, *pnfield4, **sv3, **sv4; ++ struct test_object objs[NUM_OBJS]; ++ char nfields1[NUM_OBJS], *pnfields1[NUM_OBJS], **sv1[NUM_OBJS]; ++ char *pndup[NUM_OBJS]; ++ int nfields2[NUM_OBJS], *pnfields2[NUM_OBJS], **sv2[NUM_OBJS]; + void **sv; +- +- pnfield1 = &nfield1; +- pnfield2 = &nfield2; +- pnfield3 = &nfield3; +- pnfield4 = &nfield4; ++ int i; + + ptr_id(NULL); +- ptr_id(pnfield1); +- ptr_id(pnfield2); +- ptr_id(pnfield3); +- ptr_id(pnfield4); + + /* + * With an empty shadow variable hash table, expect not to find + * any matches. + */ +- sv = shadow_get(&obj1, SV_ID1); ++ sv = shadow_get(&objs[0], SV_ID1); + if (!sv) + pr_info(" got expected NULL result\n"); + +- /* +- * Allocate a few shadow variables with different and . +- */ +- sv1 = shadow_alloc(&obj1, SV_ID1, sizeof(pnfield1), GFP_KERNEL, shadow_ctor, &pnfield1); +- if (!sv1) +- return -ENOMEM; +- +- sv2 = shadow_alloc(&obj2, SV_ID1, sizeof(pnfield2), GFP_KERNEL, shadow_ctor, &pnfield2); +- if (!sv2) +- return -ENOMEM; +- +- sv3 = shadow_alloc(&obj1, SV_ID2, sizeof(pnfield3), GFP_KERNEL, shadow_ctor, &pnfield3); +- if (!sv3) +- return -ENOMEM; +- +- /* +- * Verify we can find our new shadow variables and that they point +- * to expected data. +- */ +- sv = shadow_get(&obj1, SV_ID1); +- if (!sv) +- return -EINVAL; +- if ((char **)sv == sv1 && *sv1 == pnfield1) +- pr_info(" got expected PTR%d -> PTR%d result\n", +- ptr_id(sv1), ptr_id(*sv1)); +- +- sv = shadow_get(&obj2, SV_ID1); +- if (!sv) +- return -EINVAL; +- if ((char **)sv == sv2 && *sv2 == pnfield2) +- pr_info(" got expected PTR%d -> PTR%d result\n", +- ptr_id(sv2), ptr_id(*sv2)); +- +- sv = shadow_get(&obj1, SV_ID2); +- if (!sv) +- return -EINVAL; +- if ((int **)sv == sv3 && *sv3 == pnfield3) +- pr_info(" got expected PTR%d -> PTR%d result\n", +- ptr_id(sv3), ptr_id(*sv3)); +- +- /* +- * Allocate or get a few more, this time with the same , . +- * The second invocation should return the same shadow var. +- */ +- sv4 = shadow_get_or_alloc(&obj3, SV_ID1, sizeof(pnfield4), GFP_KERNEL, shadow_ctor, &pnfield4); +- if (!sv4) +- return -ENOMEM; +- +- sv = shadow_get_or_alloc(&obj3, SV_ID1, sizeof(pnfield4), GFP_KERNEL, shadow_ctor, &pnfield4); +- if (!sv) +- return -EINVAL; +- if ((int **)sv == sv4 && *sv4 == pnfield4) +- pr_info(" got expected PTR%d -> PTR%d result\n", +- ptr_id(sv4), ptr_id(*sv4)); +- +- /* +- * Free the shadow variables and check that we can no +- * longer find them. +- */ +- shadow_free(&obj1, SV_ID1, shadow_dtor); /* sv1 */ +- sv = shadow_get(&obj1, SV_ID1); +- if (!sv) +- pr_info(" got expected NULL result\n"); ++ /* pass 1: init & alloc a char+int pair of svars for each objs */ ++ for (i = 0; i < NUM_OBJS; i++) { ++ pnfields1[i] = &nfields1[i]; ++ ptr_id(pnfields1[i]); ++ ++ if (i % 2) { ++ sv1[i] = shadow_alloc(&objs[i], SV_ID1, ++ sizeof(pnfields1[i]), GFP_KERNEL, ++ shadow_ctor, &pnfields1[i]); ++ } else { ++ sv1[i] = shadow_get_or_alloc(&objs[i], SV_ID1, ++ sizeof(pnfields1[i]), GFP_KERNEL, ++ shadow_ctor, &pnfields1[i]); ++ } ++ if (!sv1[i]) ++ return -ENOMEM; ++ ++ pnfields2[i] = &nfields2[i]; ++ ptr_id(pnfields2[i]); ++ sv2[i] = shadow_alloc(&objs[i], SV_ID2, sizeof(pnfields2[i]), ++ GFP_KERNEL, shadow_ctor, &pnfields2[i]); ++ if (!sv2[i]) ++ return -ENOMEM; ++ } + +- shadow_free(&obj2, SV_ID1, shadow_dtor); /* sv2 */ +- sv = shadow_get(&obj2, SV_ID1); +- if (!sv) +- pr_info(" got expected NULL result\n"); ++ /* pass 2: verify we find allocated svars and where they point to */ ++ for (i = 0; i < NUM_OBJS; i++) { ++ /* check the "char" svar for all objects */ ++ sv = shadow_get(&objs[i], SV_ID1); ++ if (!sv) ++ return -EINVAL; ++ if ((char **)sv == sv1[i] && *sv1[i] == pnfields1[i]) ++ pr_info(" got expected PTR%d -> PTR%d result\n", ++ ptr_id(sv1[i]), ptr_id(*sv1[i])); ++ ++ /* check the "int" svar for all objects */ ++ sv = shadow_get(&objs[i], SV_ID2); ++ if (!sv) ++ return -EINVAL; ++ if ((int **)sv == sv2[i] && *sv2[i] == pnfields2[i]) ++ pr_info(" got expected PTR%d -> PTR%d result\n", ++ ptr_id(sv2[i]), ptr_id(*sv2[i])); ++ } + +- shadow_free(&obj3, SV_ID1, shadow_dtor); /* sv4 */ +- sv = shadow_get(&obj3, SV_ID1); +- if (!sv) +- pr_info(" got expected NULL result\n"); ++ /* pass 3: verify that 'get_or_alloc' returns already allocated svars */ ++ for (i = 0; i < NUM_OBJS; i++) { ++ pndup[i] = &nfields1[i]; ++ ptr_id(pndup[i]); ++ ++ sv = shadow_get_or_alloc(&objs[i], SV_ID1, sizeof(pndup[i]), ++ GFP_KERNEL, shadow_ctor, &pndup[i]); ++ if (!sv) ++ return -EINVAL; ++ if ((char **)sv == sv1[i] && *sv1[i] == pnfields1[i]) ++ pr_info(" got expected PTR%d -> PTR%d result\n", ++ ptr_id(sv1[i]), ptr_id(*sv1[i])); ++ } + +- /* +- * We should still find an variable. +- */ +- sv = shadow_get(&obj1, SV_ID2); +- if (!sv) +- return -EINVAL; +- if ((int **)sv == sv3 && *sv3 == pnfield3) +- pr_info(" got expected PTR%d -> PTR%d result\n", +- ptr_id(sv3), ptr_id(*sv3)); ++ /* pass 4: free pairs of svars, verify removal */ ++ for (i = 0; i < NUM_OBJS; i++) { ++ shadow_free(&objs[i], SV_ID1, shadow_dtor); /* 'char' pairs */ ++ sv = shadow_get(&objs[i], SV_ID1); ++ if (!sv) ++ pr_info(" got expected NULL result\n"); ++ } + +- /* +- * Free all the variables, too. +- */ +- shadow_free_all(SV_ID2, shadow_dtor); /* sv3 */ +- sv = shadow_get(&obj1, SV_ID1); +- if (!sv) +- pr_info(" shadow_get() got expected NULL result\n"); ++ /* pass 5: check we still find svar pairs */ ++ for (i = 0; i < NUM_OBJS; i++) { ++ sv = shadow_get(&objs[i], SV_ID2); /* 'int' pairs */ ++ if (!sv) ++ return -EINVAL; ++ if ((int **)sv == sv2[i] && *sv2[i] == pnfields2[i]) ++ pr_info(" got expected PTR%d -> PTR%d result\n", ++ ptr_id(sv2[i]), ptr_id(*sv2[i])); ++ } + ++ /* pass 6: free all the svar pairs too. */ ++ shadow_free_all(SV_ID2, NULL); /* 'int' pairs */ ++ for (i = 0; i < NUM_OBJS; i++) { ++ sv = shadow_get(&objs[i], SV_ID2); ++ if (!sv) ++ pr_info(" got expected NULL result\n"); ++ } + + free_ptr_list(); + + + diff --git a/patches.suse/selftests-livepatch-rework-test-klp-shadow-vars.patch b/patches.suse/selftests-livepatch-rework-test-klp-shadow-vars.patch new file mode 100644 index 0000000..4a37490 --- /dev/null +++ b/patches.suse/selftests-livepatch-rework-test-klp-shadow-vars.patch @@ -0,0 +1,235 @@ +From: Yannick Cote +Date: Wed, 3 Jun 2020 14:20:56 -0400 +Subject: selftests/livepatch: rework test-klp-shadow-vars +Git-commit: 6a26a9df169d81aba244d6496e4381401d04e281 +Patch-mainline: v5.9-rc1 +References: bsc#1071995 + +The initial idea was to make a change to please cppcheck and remove void +pointer arithmetics found a few times: + + portability: 'obj' is of type 'void *'. When using void pointers + in calculations, the behaviour is undefined. + [arithOperationsOnVoidPointer] + +The rest of the changes are to help make the test read as an example +while continuing to verify the shadow variable code. The logic of the +test is unchanged but restructured to use descriptive names. + +Signed-off-by: Yannick Cote +Reviewed-by: Petr Mladek +Reviewed-by: Kamalesh Babulal +Acked-by: Miroslav Benes +Acked-by: Joe Lawrence +Signed-off-by: Petr Mladek +Link: https://lore.kernel.org/r/20200603182058.109470-3-ycote@redhat.com +--- + lib/livepatch/test_klp_shadow_vars.c | 101 ++++++++++++++++++++--------------- + 1 file changed, 57 insertions(+), 44 deletions(-) + +diff --git a/lib/livepatch/test_klp_shadow_vars.c b/lib/livepatch/test_klp_shadow_vars.c +index f0b5a1d24e55..ec2635cff974 100644 +--- a/lib/livepatch/test_klp_shadow_vars.c ++++ b/lib/livepatch/test_klp_shadow_vars.c +@@ -109,8 +109,7 @@ static void shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor) + static void shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor) + { + klp_shadow_free_all(id, dtor); +- pr_info("klp_%s(id=0x%lx, dtor=PTR%d)\n", +- __func__, id, ptr_id(dtor)); ++ pr_info("klp_%s(id=0x%lx, dtor=PTR%d)\n", __func__, id, ptr_id(dtor)); + } + + +@@ -124,8 +123,7 @@ static int shadow_ctor(void *obj, void *shadow_data, void *ctor_data) + return -EINVAL; + + *sv = *var; +- pr_info("%s: PTR%d -> PTR%d\n", +- __func__, ptr_id(sv), ptr_id(*var)); ++ pr_info("%s: PTR%d -> PTR%d\n", __func__, ptr_id(sv), ptr_id(*var)); + + return 0; + } +@@ -138,49 +136,63 @@ static void shadow_dtor(void *obj, void *shadow_data) + __func__, ptr_id(obj), ptr_id(sv)); + } + +-static int test_klp_shadow_vars_init(void) +-{ +- void *obj = THIS_MODULE; +- int id = 0x1234; +- gfp_t gfp_flags = GFP_KERNEL; ++/* dynamically created obj fields have the following shadow var id values */ ++#define SV_ID1 0x1234 ++#define SV_ID2 0x1235 + +- int var1, var2, var3, var4; +- int *pv1, *pv2, *pv3, *pv4; +- int **sv1, **sv2, **sv3, **sv4; ++/* ++ * The main test case adds/removes new fields (shadow var) to each of these ++ * test structure instances. The last group of fields in the struct represent ++ * the idea that shadow variables may be added and removed to and from the ++ * struct during execution. ++ */ ++struct test_object { ++ /* add anything here below and avoid to define an empty struct */ ++ struct shadow_ptr sp; + +- int **sv; ++ /* these represent shadow vars added and removed with SV_ID{1,2} */ ++ /* char nfield1; */ ++ /* int nfield2; */ ++}; + +- pv1 = &var1; +- pv2 = &var2; +- pv3 = &var3; +- pv4 = &var4; ++static int test_klp_shadow_vars_init(void) ++{ ++ struct test_object obj1, obj2, obj3; ++ char nfield1, nfield2, *pnfield1, *pnfield2, **sv1, **sv2; ++ int nfield3, nfield4, *pnfield3, *pnfield4, **sv3, **sv4; ++ void **sv; ++ ++ pnfield1 = &nfield1; ++ pnfield2 = &nfield2; ++ pnfield3 = &nfield3; ++ pnfield4 = &nfield4; + + ptr_id(NULL); +- ptr_id(pv1); +- ptr_id(pv2); +- ptr_id(pv3); +- ptr_id(pv4); ++ ptr_id(pnfield1); ++ ptr_id(pnfield2); ++ ptr_id(pnfield3); ++ ptr_id(pnfield4); + + /* + * With an empty shadow variable hash table, expect not to find + * any matches. + */ +- sv = shadow_get(obj, id); ++ sv = shadow_get(&obj1, SV_ID1); + if (!sv) + pr_info(" got expected NULL result\n"); + + /* + * Allocate a few shadow variables with different and . + */ +- sv1 = shadow_alloc(obj, id, sizeof(pv1), gfp_flags, shadow_ctor, &pv1); ++ sv1 = shadow_alloc(&obj1, SV_ID1, sizeof(pnfield1), GFP_KERNEL, shadow_ctor, &pnfield1); + if (!sv1) + return -ENOMEM; + +- sv2 = shadow_alloc(obj + 1, id, sizeof(pv2), gfp_flags, shadow_ctor, &pv2); ++ sv2 = shadow_alloc(&obj2, SV_ID1, sizeof(pnfield2), GFP_KERNEL, shadow_ctor, &pnfield2); + if (!sv2) + return -ENOMEM; + +- sv3 = shadow_alloc(obj, id + 1, sizeof(pv3), gfp_flags, shadow_ctor, &pv3); ++ sv3 = shadow_alloc(&obj1, SV_ID2, sizeof(pnfield3), GFP_KERNEL, shadow_ctor, &pnfield3); + if (!sv3) + return -ENOMEM; + +@@ -188,23 +200,24 @@ static int test_klp_shadow_vars_init(void) + * Verify we can find our new shadow variables and that they point + * to expected data. + */ +- sv = shadow_get(obj, id); ++ sv = shadow_get(&obj1, SV_ID1); + if (!sv) + return -EINVAL; +- if (sv == sv1 && *sv1 == pv1) ++ if ((char **)sv == sv1 && *sv1 == pnfield1) + pr_info(" got expected PTR%d -> PTR%d result\n", + ptr_id(sv1), ptr_id(*sv1)); + +- sv = shadow_get(obj + 1, id); ++ sv = shadow_get(&obj2, SV_ID1); + if (!sv) + return -EINVAL; +- if (sv == sv2 && *sv2 == pv2) ++ if ((char **)sv == sv2 && *sv2 == pnfield2) + pr_info(" got expected PTR%d -> PTR%d result\n", + ptr_id(sv2), ptr_id(*sv2)); +- sv = shadow_get(obj, id + 1); ++ ++ sv = shadow_get(&obj1, SV_ID2); + if (!sv) + return -EINVAL; +- if (sv == sv3 && *sv3 == pv3) ++ if ((int **)sv == sv3 && *sv3 == pnfield3) + pr_info(" got expected PTR%d -> PTR%d result\n", + ptr_id(sv3), ptr_id(*sv3)); + +@@ -212,14 +225,14 @@ static int test_klp_shadow_vars_init(void) + * Allocate or get a few more, this time with the same , . + * The second invocation should return the same shadow var. + */ +- sv4 = shadow_get_or_alloc(obj + 2, id, sizeof(pv4), gfp_flags, shadow_ctor, &pv4); ++ sv4 = shadow_get_or_alloc(&obj3, SV_ID1, sizeof(pnfield4), GFP_KERNEL, shadow_ctor, &pnfield4); + if (!sv4) + return -ENOMEM; + +- sv = shadow_get_or_alloc(obj + 2, id, sizeof(pv4), gfp_flags, shadow_ctor, &pv4); ++ sv = shadow_get_or_alloc(&obj3, SV_ID1, sizeof(pnfield4), GFP_KERNEL, shadow_ctor, &pnfield4); + if (!sv) + return -EINVAL; +- if (sv == sv4 && *sv4 == pv4) ++ if ((int **)sv == sv4 && *sv4 == pnfield4) + pr_info(" got expected PTR%d -> PTR%d result\n", + ptr_id(sv4), ptr_id(*sv4)); + +@@ -227,36 +240,36 @@ static int test_klp_shadow_vars_init(void) + * Free the shadow variables and check that we can no + * longer find them. + */ +- shadow_free(obj, id, shadow_dtor); /* sv1 */ +- sv = shadow_get(obj, id); ++ shadow_free(&obj1, SV_ID1, shadow_dtor); /* sv1 */ ++ sv = shadow_get(&obj1, SV_ID1); + if (!sv) + pr_info(" got expected NULL result\n"); + +- shadow_free(obj + 1, id, shadow_dtor); /* sv2 */ +- sv = shadow_get(obj + 1, id); ++ shadow_free(&obj2, SV_ID1, shadow_dtor); /* sv2 */ ++ sv = shadow_get(&obj2, SV_ID1); + if (!sv) + pr_info(" got expected NULL result\n"); + +- shadow_free(obj + 2, id, shadow_dtor); /* sv4 */ +- sv = shadow_get(obj + 2, id); ++ shadow_free(&obj3, SV_ID1, shadow_dtor); /* sv4 */ ++ sv = shadow_get(&obj3, SV_ID1); + if (!sv) + pr_info(" got expected NULL result\n"); + + /* + * We should still find an variable. + */ +- sv = shadow_get(obj, id + 1); ++ sv = shadow_get(&obj1, SV_ID2); + if (!sv) + return -EINVAL; +- if (sv == sv3 && *sv3 == pv3) ++ if ((int **)sv == sv3 && *sv3 == pnfield3) + pr_info(" got expected PTR%d -> PTR%d result\n", + ptr_id(sv3), ptr_id(*sv3)); + + /* + * Free all the variables, too. + */ +- shadow_free_all(id + 1, shadow_dtor); /* sv3 */ +- sv = shadow_get(obj, id); ++ shadow_free_all(SV_ID2, shadow_dtor); /* sv3 */ ++ sv = shadow_get(&obj1, SV_ID1); + if (!sv) + pr_info(" shadow_get() got expected NULL result\n"); + + diff --git a/patches.suse/selftests-livepatch-simplify-test-klp-callbacks-busy-target-tests.patch b/patches.suse/selftests-livepatch-simplify-test-klp-callbacks-busy-target-tests.patch new file mode 100644 index 0000000..534c8c2 --- /dev/null +++ b/patches.suse/selftests-livepatch-simplify-test-klp-callbacks-busy-target-tests.patch @@ -0,0 +1,93 @@ +From: Joe Lawrence +Date: Wed, 3 Jun 2020 14:20:55 -0400 +Subject: selftests/livepatch: simplify test-klp-callbacks busy target tests +Git-commit: 547840bd5ae52a9d864abddcb91ea491a78d8199 (partial) +Patch-mainline: v5.9-rc1 +References: bsc#1071995 + +The test-klp-callbacks script includes a few tests which rely on kernel +task timings that may not always execute as expected under system load. +These may generate out of sequence kernel log messages that result in +test failure. + +Instead of using sleep timing windows to orchestrate these tests, add a +block_transition module parameter to communicate the test purpose and +utilize flush_queue() to serialize the test module's task output. + +Signed-off-by: Joe Lawrence +Reviewed-by: Petr Mladek +Acked-by: Miroslav Benes +Signed-off-by: Petr Mladek +Link: https://lore.kernel.org/r/20200603182058.109470-2-ycote@redhat.com +--- + + lib/livepatch/test_klp_callbacks_busy.c | 37 ++++++++++++++++++++++++-------- + 1 file changed, 28 insertions(+), 9 deletions(-) + +--- a/lib/livepatch/test_klp_callbacks_busy.c ++++ b/lib/livepatch/test_klp_callbacks_busy.c +@@ -5,34 +5,53 @@ + + #include + #include ++#include + #include + #include + +-static int sleep_secs; +-module_param(sleep_secs, int, 0644); +-MODULE_PARM_DESC(sleep_secs, "sleep_secs (default=0)"); ++/* load/run-time control from sysfs writer */ ++static bool block_transition; ++module_param(block_transition, bool, 0644); ++MODULE_PARM_DESC(block_transition, "block_transition (default=false)"); + + static void busymod_work_func(struct work_struct *work); +-static DECLARE_DELAYED_WORK(work, busymod_work_func); ++static DECLARE_WORK(work, busymod_work_func); + + static void busymod_work_func(struct work_struct *work) + { +- pr_info("%s, sleeping %d seconds ...\n", __func__, sleep_secs); +- msleep(sleep_secs * 1000); ++ pr_info("%s enter\n", __func__); ++ ++ while (READ_ONCE(block_transition)) { ++ /* ++ * Busy-wait until the sysfs writer has acknowledged a ++ * blocked transition and clears the flag. ++ */ ++ msleep(20); ++ } ++ + pr_info("%s exit\n", __func__); + } + + static int test_klp_callbacks_busy_init(void) + { + pr_info("%s\n", __func__); +- schedule_delayed_work(&work, +- msecs_to_jiffies(1000 * 0)); ++ schedule_work(&work); ++ ++ if (!block_transition) { ++ /* ++ * Serialize output: print all messages from the work ++ * function before returning from init(). ++ */ ++ flush_work(&work); ++ } ++ + return 0; + } + + static void test_klp_callbacks_busy_exit(void) + { +- cancel_delayed_work_sync(&work); ++ WRITE_ONCE(block_transition, false); ++ flush_work(&work); + pr_info("%s\n", __func__); + } + + + diff --git a/patches.suse/soc-fsl-qbman-allow-registering-a-device-link-for-th.patch b/patches.suse/soc-fsl-qbman-allow-registering-a-device-link-for-th.patch new file mode 100644 index 0000000..3c39533 --- /dev/null +++ b/patches.suse/soc-fsl-qbman-allow-registering-a-device-link-for-th.patch @@ -0,0 +1,82 @@ +From: Madalin Bucur +Date: Thu, 31 Oct 2019 16:37:58 +0200 +Subject: soc: fsl: qbman: allow registering a device link for the portal user + +Git-commit: a2d00f3db73dc4f6f6afcc95c1db809ea9019306 +Patch-mainline: v5.5-rc1 +References: bsc#1174550 + +Introduce the API required to make sure that the devices that use +the QMan portal are unbound when the portal is unbound. + +Signed-off-by: Madalin Bucur +Signed-off-by: David S. Miller +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/soc/fsl/qbman/qman.c | 13 +++++++++++++ + include/soc/fsl/qman.h | 18 ++++++++++++++++++ + 2 files changed, 31 insertions(+) + +diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c +index bf68d86d80ee..bc75a5882b9e 100644 +--- a/drivers/soc/fsl/qbman/qman.c ++++ b/drivers/soc/fsl/qbman/qman.c +@@ -1749,6 +1749,19 @@ struct qman_portal *qman_get_affine_portal(int cpu) + } + EXPORT_SYMBOL(qman_get_affine_portal); + ++int qman_start_using_portal(struct qman_portal *p, struct device *dev) ++{ ++ return (!device_link_add(dev, p->config->dev, ++ DL_FLAG_AUTOREMOVE)) ? -EINVAL : 0; ++} ++EXPORT_SYMBOL(qman_start_using_portal); ++ ++void qman_stop_using_portal(struct qman_portal *p, struct device *dev) ++{ ++ device_link_remove(dev, p->config->dev); ++} ++EXPORT_SYMBOL(qman_stop_using_portal); ++ + int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit) + { + return __poll_portal_fast(p, limit); +diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h +index aa31c05a103a..c499c5cfa7c9 100644 +--- a/include/soc/fsl/qman.h ++++ b/include/soc/fsl/qman.h +@@ -32,6 +32,7 @@ + #define __FSL_QMAN_H + + #include ++#include + + /* Hardware constants */ + #define QM_CHANNEL_SWPORTAL0 0 +@@ -914,6 +915,23 @@ u16 qman_affine_channel(int cpu); + */ + struct qman_portal *qman_get_affine_portal(int cpu); + ++/** ++ * qman_start_using_portal - register a device link for the portal user ++ * @p: the portal that will be in use ++ * @dev: the device that will use the portal ++ * ++ * Makes sure that the devices that use the portal are unbound when the ++ * portal is unbound ++ */ ++int qman_start_using_portal(struct qman_portal *p, struct device *dev); ++ ++/** ++ * qman_stop_using_portal - deregister a device link for the portal user ++ * @p: the portal that will no longer be in use ++ * @dev: the device that uses the portal ++ */ ++void qman_stop_using_portal(struct qman_portal *p, struct device *dev); ++ + /** + * qman_p_poll_dqrr - process DQRR (fast-path) entries + * @limit: the maximum number of DQRR entries to process +-- +2.26.2 + diff --git a/patches.suse/soc-fsl-qbman_portals-add-APIs-to-retrieve-the-probi.patch b/patches.suse/soc-fsl-qbman_portals-add-APIs-to-retrieve-the-probi.patch new file mode 100644 index 0000000..0b3bb57 --- /dev/null +++ b/patches.suse/soc-fsl-qbman_portals-add-APIs-to-retrieve-the-probi.patch @@ -0,0 +1,235 @@ +From: Laurentiu Tudor +Date: Sat, 27 Apr 2019 10:10:24 +0300 +Subject: soc: fsl: qbman_portals: add APIs to retrieve the probing status + +Git-commit: 5d1d046e2868fc876a69231eb2f24f000b521f1c +Patch-mainline: v5.3-rc1 +References: bsc#1174550 + +Add a couple of new APIs to check the probing status of the required +cpu bound qman and bman portals: + 'int bman_portals_probed()' and 'int qman_portals_probed()'. +They return the following values. + * 1 if qman/bman portals were all probed correctly + * 0 if qman/bman portals were not yet probed + * -1 if probing of qman/bman portals failed +Portals are considered successful probed if no error occurred during +the probing of any of the portals and if enough portals were probed +to have one available for each cpu. +The error handling paths were slightly rearranged in order to fit this +new functionality without being too intrusive. +Drivers that use qman/bman portal driver services are required to use +these APIs before calling any functions exported by these drivers or +otherwise they will crash the kernel. +First user will be the dpaa1 ethernet driver, coming in a subsequent +patch. + +Signed-off-by: Laurentiu Tudor +Signed-off-by: Li Yang +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/soc/fsl/qbman/bman_portal.c | 20 ++++++++++++++++---- + drivers/soc/fsl/qbman/qman_portal.c | 21 +++++++++++++++++---- + include/soc/fsl/bman.h | 8 ++++++++ + include/soc/fsl/qman.h | 9 +++++++++ + 4 files changed, 50 insertions(+), 8 deletions(-) + +--- a/drivers/soc/fsl/qbman/bman_portal.c ++++ b/drivers/soc/fsl/qbman/bman_portal.c +@@ -32,6 +32,7 @@ + + static struct bman_portal *affine_bportals[NR_CPUS]; + static struct cpumask portal_cpus; ++static int __bman_portals_probed; + /* protect bman global registers and global data shared among portals */ + static DEFINE_SPINLOCK(bman_lock); + +@@ -87,6 +88,12 @@ static int bman_online_cpu(unsigned int + return 0; + } + ++int bman_portals_probed(void) ++{ ++ return __bman_portals_probed; ++} ++EXPORT_SYMBOL_GPL(bman_portals_probed); ++ + static int bman_portal_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -104,8 +111,10 @@ static int bman_portal_probe(struct plat + } + + pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL); +- if (!pcfg) ++ if (!pcfg) { ++ __bman_portals_probed = -1; + return -ENOMEM; ++ } + + pcfg->dev = dev; + +@@ -114,7 +123,7 @@ static int bman_portal_probe(struct plat + if (!addr_phys[0]) { + dev_err(dev, "Can't get %s property 'reg::CE'\n", + node->full_name); +- return -ENXIO; ++ goto err_ioremap1; + } + + addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM, +@@ -122,7 +131,7 @@ static int bman_portal_probe(struct plat + if (!addr_phys[1]) { + dev_err(dev, "Can't get %s property 'reg::CI'\n", + node->full_name); +- return -ENXIO; ++ goto err_ioremap1; + } + + pcfg->cpu = -1; +@@ -130,7 +139,7 @@ static int bman_portal_probe(struct plat + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { + dev_err(dev, "Can't get %s IRQ'\n", node->full_name); +- return -ENXIO; ++ goto err_ioremap1; + } + pcfg->irq = irq; + +@@ -152,6 +161,7 @@ static int bman_portal_probe(struct plat + spin_lock(&bman_lock); + cpu = cpumask_next_zero(-1, &portal_cpus); + if (cpu >= nr_cpu_ids) { ++ __bman_portals_probed = 1; + /* unassigned portal, skip init */ + spin_unlock(&bman_lock); + return 0; +@@ -177,6 +187,8 @@ err_portal_init: + err_ioremap2: + memunmap(pcfg->addr_virt_ce); + err_ioremap1: ++ __bman_portals_probed = -1; ++ + return -ENXIO; + } + +--- a/drivers/soc/fsl/qbman/qman_portal.c ++++ b/drivers/soc/fsl/qbman/qman_portal.c +@@ -38,6 +38,7 @@ EXPORT_SYMBOL(qman_dma_portal); + #define CONFIG_FSL_DPA_PIRQ_FAST 1 + + static struct cpumask portal_cpus; ++static int __qman_portals_probed; + /* protect qman global registers and global data shared among portals */ + static DEFINE_SPINLOCK(qman_lock); + +@@ -220,6 +221,12 @@ static int qman_online_cpu(unsigned int + return 0; + } + ++int qman_portals_probed(void) ++{ ++ return __qman_portals_probed; ++} ++EXPORT_SYMBOL_GPL(qman_portals_probed); ++ + static int qman_portal_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -238,8 +245,10 @@ static int qman_portal_probe(struct plat + } + + pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL); +- if (!pcfg) ++ if (!pcfg) { ++ __qman_portals_probed = -1; + return -ENOMEM; ++ } + + pcfg->dev = dev; + +@@ -248,7 +257,7 @@ static int qman_portal_probe(struct plat + if (!addr_phys[0]) { + dev_err(dev, "Can't get %s property 'reg::CE'\n", + node->full_name); +- return -ENXIO; ++ goto err_ioremap1; + } + + addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM, +@@ -256,13 +265,14 @@ static int qman_portal_probe(struct plat + if (!addr_phys[1]) { + dev_err(dev, "Can't get %s property 'reg::CI'\n", + node->full_name); +- return -ENXIO; ++ goto err_ioremap1; + } + + err = of_property_read_u32(node, "cell-index", &val); + if (err) { + dev_err(dev, "Can't get %s property 'cell-index'\n", + node->full_name); ++ __qman_portals_probed = -1; + return err; + } + pcfg->channel = val; +@@ -270,7 +280,7 @@ static int qman_portal_probe(struct plat + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { + dev_err(dev, "Can't get %s IRQ\n", node->full_name); +- return -ENXIO; ++ goto err_ioremap1; + } + pcfg->irq = irq; + +@@ -294,6 +304,7 @@ static int qman_portal_probe(struct plat + spin_lock(&qman_lock); + cpu = cpumask_next_zero(-1, &portal_cpus); + if (cpu >= nr_cpu_ids) { ++ __qman_portals_probed = 1; + /* unassigned portal, skip init */ + spin_unlock(&qman_lock); + return 0; +@@ -324,6 +335,8 @@ err_portal_init: + err_ioremap2: + memunmap(pcfg->addr_virt_ce); + err_ioremap1: ++ __qman_portals_probed = -1; ++ + return -ENXIO; + } + +--- a/include/soc/fsl/bman.h ++++ b/include/soc/fsl/bman.h +@@ -133,5 +133,13 @@ int bman_acquire(struct bman_pool *pool, + * failed to probe or 0 if the bman driver did not probed yet. + */ + int bman_is_probed(void); ++/** ++ * bman_portals_probed - Check if all cpu bound bman portals are probed ++ * ++ * Returns 1 if all the required cpu bound bman portals successfully probed, ++ * -1 if probe errors appeared or 0 if the bman portals did not yet finished ++ * probing. ++ */ ++int bman_portals_probed(void); + + #endif /* __FSL_BMAN_H */ +--- a/include/soc/fsl/qman.h ++++ b/include/soc/fsl/qman.h +@@ -1195,6 +1195,15 @@ int qman_release_cgrid(u32 id); + int qman_is_probed(void); + + /** ++ * qman_portals_probed - Check if all cpu bound qman portals are probed ++ * ++ * Returns 1 if all the required cpu bound qman portals successfully probed, ++ * -1 if probe errors appeared or 0 if the qman portals did not yet finished ++ * probing. ++ */ ++int qman_portals_probed(void); ++ ++/** + * qman_dqrr_get_ithresh - Get coalesce interrupt threshold + * @portal: portal to get the value for + * @ithresh: threshold pointer diff --git a/patches.suse/tcp-grow-window-for-OOO-packets-only-for-SACK-flows.patch b/patches.suse/tcp-grow-window-for-OOO-packets-only-for-SACK-flows.patch new file mode 100644 index 0000000..fef7820 --- /dev/null +++ b/patches.suse/tcp-grow-window-for-OOO-packets-only-for-SACK-flows.patch @@ -0,0 +1,97 @@ +From: Eric Dumazet +Date: Mon, 15 Jun 2020 20:37:07 -0700 +Subject: tcp: grow window for OOO packets only for SACK flows +Git-commit: 662051215c758ae8545451628816204ed6cd372d +Patch-mainline: 5.8-rc2 +References: networking-stable-20_06_28 + +Back in 2013, we made a change that broke fast retransmit +for non SACK flows. + +Indeed, for these flows, a sender needs to receive three duplicate +ACK before starting fast retransmit. Sending ACK with different +receive window do not count. + +Even if enabling SACK is strongly recommended these days, +there still are some cases where it has to be disabled. + +Not increasing the window seems better than having to +rely on RTO. + +After the fix, following packetdrill test gives : + +// Initialize connection + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 + +0 bind(3, ..., ...) = 0 + +0 listen(3, 1) = 0 + + +0 < S 0:0(0) win 32792 + +0 > S. 0:0(0) ack 1 + +0 < . 1:1(0) ack 1 win 514 + + +0 accept(3, ..., ...) = 4 + + +0 < . 1:1001(1000) ack 1 win 514 +// Quick ack + +0 > . 1:1(0) ack 1001 win 264 + + +0 < . 2001:3001(1000) ack 1 win 514 +// DUPACK : Normally we should not change the window + +0 > . 1:1(0) ack 1001 win 264 + + +0 < . 3001:4001(1000) ack 1 win 514 +// DUPACK : Normally we should not change the window + +0 > . 1:1(0) ack 1001 win 264 + + +0 < . 4001:5001(1000) ack 1 win 514 +// DUPACK : Normally we should not change the window + +0 > . 1:1(0) ack 1001 win 264 + + +0 < . 1001:2001(1000) ack 1 win 514 +// Hole is repaired. + +0 > . 1:1(0) ack 5001 win 272 + +Fixes: 4e4f1fc22681 ("tcp: properly increase rcv_ssthresh for ofo packets") +Signed-off-by: Eric Dumazet +Reported-by: Venkat Venkatsubra +Acked-by: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv4/tcp_input.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 83330a6cb242..12fda8f27b08 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -4605,7 +4605,11 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) + if (tcp_ooo_try_coalesce(sk, tp->ooo_last_skb, + skb, &fragstolen)) { + coalesce_done: +- tcp_grow_window(sk, skb); ++ /* For non sack flows, do not grow window to force DUPACK ++ * and trigger fast retransmit. ++ */ ++ if (tcp_is_sack(tp)) ++ tcp_grow_window(sk, skb); + kfree_skb_partial(skb, fragstolen); + skb = NULL; + goto add_sack; +@@ -4689,7 +4693,11 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) + tcp_sack_new_ofo_skb(sk, seq, end_seq); + end: + if (skb) { +- tcp_grow_window(sk, skb); ++ /* For non sack flows, do not grow window to force DUPACK ++ * and trigger fast retransmit. ++ */ ++ if (tcp_is_sack(tp)) ++ tcp_grow_window(sk, skb); + skb_condense(skb); + skb_set_owner_r(skb, sk); + } +-- +2.28.0 + diff --git a/patches.suse/tcp-make-sure-listeners-don-t-initialize-congestion-.patch b/patches.suse/tcp-make-sure-listeners-don-t-initialize-congestion-.patch new file mode 100644 index 0000000..6789b22 --- /dev/null +++ b/patches.suse/tcp-make-sure-listeners-don-t-initialize-congestion-.patch @@ -0,0 +1,143 @@ +From: Christoph Paasch +Date: Wed, 8 Jul 2020 16:18:34 -0700 +Subject: tcp: make sure listeners don't initialize congestion-control state +Git-commit: ce69e563b325f620863830c246a8698ccea52048 +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +syzkaller found its way into setsockopt with TCP_CONGESTION "cdg". +tcp_cdg_init() does a kcalloc to store the gradients. As sk_clone_lock +just copies all the memory, the allocated pointer will be copied as +well, if the app called setsockopt(..., TCP_CONGESTION) on the listener. +If now the socket will be destroyed before the congestion-control +has properly been initialized (through a call to tcp_init_transfer), we +will end up freeing memory that does not belong to that particular +socket, opening the door to a double-free: + +[ 11.413102] ================================================================== +[ 11.414181] BUG: KASAN: double-free or invalid-free in tcp_cleanup_congestion_control+0x58/0xd0 +[ 11.415329] +[ 11.415560] CPU: 3 PID: 4884 Comm: syz-executor.5 Not tainted 5.8.0-rc2 #80 +[ 11.416544] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 +[ 11.418148] Call Trace: +[ 11.418534] +[ 11.418834] dump_stack+0x7d/0xb0 +[ 11.419297] print_address_description.constprop.0+0x1a/0x210 +[ 11.422079] kasan_report_invalid_free+0x51/0x80 +[ 11.423433] __kasan_slab_free+0x15e/0x170 +[ 11.424761] kfree+0x8c/0x230 +[ 11.425157] tcp_cleanup_congestion_control+0x58/0xd0 +[ 11.425872] tcp_v4_destroy_sock+0x57/0x5a0 +[ 11.426493] inet_csk_destroy_sock+0x153/0x2c0 +[ 11.427093] tcp_v4_syn_recv_sock+0xb29/0x1100 +[ 11.427731] tcp_get_cookie_sock+0xc3/0x4a0 +[ 11.429457] cookie_v4_check+0x13d0/0x2500 +[ 11.433189] tcp_v4_do_rcv+0x60e/0x780 +[ 11.433727] tcp_v4_rcv+0x2869/0x2e10 +[ 11.437143] ip_protocol_deliver_rcu+0x23/0x190 +[ 11.437810] ip_local_deliver+0x294/0x350 +[ 11.439566] __netif_receive_skb_one_core+0x15d/0x1a0 +[ 11.441995] process_backlog+0x1b1/0x6b0 +[ 11.443148] net_rx_action+0x37e/0xc40 +[ 11.445361] __do_softirq+0x18c/0x61a +[ 11.445881] asm_call_on_stack+0x12/0x20 +[ 11.446409] +[ 11.446716] do_softirq_own_stack+0x34/0x40 +[ 11.447259] do_softirq.part.0+0x26/0x30 +[ 11.447827] __local_bh_enable_ip+0x46/0x50 +[ 11.448406] ip_finish_output2+0x60f/0x1bc0 +[ 11.450109] __ip_queue_xmit+0x71c/0x1b60 +[ 11.451861] __tcp_transmit_skb+0x1727/0x3bb0 +[ 11.453789] tcp_rcv_state_process+0x3070/0x4d3a +[ 11.456810] tcp_v4_do_rcv+0x2ad/0x780 +[ 11.457995] __release_sock+0x14b/0x2c0 +[ 11.458529] release_sock+0x4a/0x170 +[ 11.459005] __inet_stream_connect+0x467/0xc80 +[ 11.461435] inet_stream_connect+0x4e/0xa0 +[ 11.462043] __sys_connect+0x204/0x270 +[ 11.465515] __x64_sys_connect+0x6a/0xb0 +[ 11.466088] do_syscall_64+0x3e/0x70 +[ 11.466617] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 11.467341] RIP: 0033:0x7f56046dc469 +[ 11.467844] Code: Bad RIP value. +[ 11.468282] RSP: 002b:00007f5604dccdd8 EFLAGS: 00000246 ORIG_RAX: 000000000000002a +[ 11.469326] RAX: ffffffffffffffda RBX: 000000000068bf00 RCX: 00007f56046dc469 +[ 11.470379] RDX: 0000000000000010 RSI: 0000000020000000 RDI: 0000000000000004 +[ 11.471311] RBP: 00000000ffffffff R08: 0000000000000000 R09: 0000000000000000 +[ 11.472286] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +[ 11.473341] R13: 000000000041427c R14: 00007f5604dcd5c0 R15: 0000000000000003 +[ 11.474321] +[ 11.474527] Allocated by task 4884: +[ 11.475031] save_stack+0x1b/0x40 +[ 11.475548] __kasan_kmalloc.constprop.0+0xc2/0xd0 +[ 11.476182] tcp_cdg_init+0xf0/0x150 +[ 11.476744] tcp_init_congestion_control+0x9b/0x3a0 +[ 11.477435] tcp_set_congestion_control+0x270/0x32f +[ 11.478088] do_tcp_setsockopt.isra.0+0x521/0x1a00 +[ 11.478744] __sys_setsockopt+0xff/0x1e0 +[ 11.479259] __x64_sys_setsockopt+0xb5/0x150 +[ 11.479895] do_syscall_64+0x3e/0x70 +[ 11.480395] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 11.481097] +[ 11.481321] Freed by task 4872: +[ 11.481783] save_stack+0x1b/0x40 +[ 11.482230] __kasan_slab_free+0x12c/0x170 +[ 11.482839] kfree+0x8c/0x230 +[ 11.483240] tcp_cleanup_congestion_control+0x58/0xd0 +[ 11.483948] tcp_v4_destroy_sock+0x57/0x5a0 +[ 11.484502] inet_csk_destroy_sock+0x153/0x2c0 +[ 11.485144] tcp_close+0x932/0xfe0 +[ 11.485642] inet_release+0xc1/0x1c0 +[ 11.486131] __sock_release+0xc0/0x270 +[ 11.486697] sock_close+0xc/0x10 +[ 11.487145] __fput+0x277/0x780 +[ 11.487632] task_work_run+0xeb/0x180 +[ 11.488118] __prepare_exit_to_usermode+0x15a/0x160 +[ 11.488834] do_syscall_64+0x4a/0x70 +[ 11.489326] entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Wei Wang fixed a part of these CDG-malloc issues with commit c12014440750 +("tcp: memset ca_priv data to 0 properly"). + +This patch here fixes the listener-scenario: We make sure that listeners +setting the congestion-control through setsockopt won't initialize it +(thus CDG never allocates on listeners). For those who use AF_UNSPEC to +reuse a socket, tcp_disconnect() is changed to cleanup afterwards. + +(The issue can be reproduced at least down to v4.4.x.) + +Cc: Wei Wang +Cc: Eric Dumazet +Fixes: 2b0a8c9eee81 ("tcp: add CDG congestion control") +Signed-off-by: Christoph Paasch +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv4/tcp.c | 3 +++ + net/ipv4/tcp_cong.c | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2294,6 +2294,9 @@ int tcp_disconnect(struct sock *sk, int + tp->snd_cwnd_cnt = 0; + tp->window_clamp = 0; + tp->delivered = 0; ++ if (icsk->icsk_ca_ops->release) ++ icsk->icsk_ca_ops->release(sk); ++ memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); + tcp_set_ca_state(sk, TCP_CA_Open); + tp->is_sack_reneg = 0; + tcp_clear_retrans(tp); +--- a/net/ipv4/tcp_cong.c ++++ b/net/ipv4/tcp_cong.c +@@ -199,7 +199,7 @@ static void tcp_reinit_congestion_contro + icsk->icsk_ca_setsockopt = 1; + memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); + +- if (sk->sk_state != TCP_CLOSE) ++ if (!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) + tcp_init_congestion_control(sk); + } + diff --git a/patches.suse/tcp-md5-add-missing-memory-barriers-in-tcp_md5_do_ad.patch b/patches.suse/tcp-md5-add-missing-memory-barriers-in-tcp_md5_do_ad.patch new file mode 100644 index 0000000..23df157 --- /dev/null +++ b/patches.suse/tcp-md5-add-missing-memory-barriers-in-tcp_md5_do_ad.patch @@ -0,0 +1,63 @@ +From: Eric Dumazet +Date: Tue, 30 Jun 2020 16:41:01 -0700 +Subject: tcp: md5: add missing memory barriers in + tcp_md5_do_add()/tcp_md5_hash_key() +Git-commit: 6a2febec338df7e7699a52d00b2e1207dcf65b28 +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +MD5 keys are read with RCU protection, and tcp_md5_do_add() +might update in-place a prior key. + +Normally, typical RCU updates would allocate a new piece +of memory. In this case only key->key and key->keylen might +be updated, and we do not care if an incoming packet could +see the old key, the new one, or some intermediate value, +since changing the key on a live flow is known to be problematic +anyway. + +We only want to make sure that in the case key->keylen +is changed, cpus in tcp_md5_hash_key() wont try to use +uninitialized data, or crash because key->keylen was +read twice to feed sg_init_one() and ahash_request_set_crypt() + +Fixes: 9ea88a153001 ("tcp: md5: check md5 signature without socket lock") +Signed-off-by: Eric Dumazet +Cc: Mathieu Desnoyers +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv4/tcp.c | 7 +++++-- + net/ipv4/tcp_ipv4.c | 3 +++ + 2 files changed, 8 insertions(+), 2 deletions(-) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3306,10 +3306,13 @@ EXPORT_SYMBOL(tcp_md5_hash_skb_data); + + int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, const struct tcp_md5sig_key *key) + { ++ u8 keylen = key->keylen; + struct scatterlist sg; + +- sg_init_one(&sg, key->key, key->keylen); +- ahash_request_set_crypt(hp->md5_req, &sg, NULL, key->keylen); ++ smp_rmb(); /* paired with smp_wmb() in tcp_md5_do_add() */ ++ ++ sg_init_one(&sg, key->key, keylen); ++ ahash_request_set_crypt(hp->md5_req, &sg, NULL, keylen); + return crypto_ahash_update(hp->md5_req); + } + EXPORT_SYMBOL(tcp_md5_hash_key); +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -968,6 +968,9 @@ int tcp_md5_do_add(struct sock *sk, cons + if (key) { + /* Pre-existing entry - just update that one. */ + memcpy(key->key, newkey, newkeylen); ++ ++ smp_wmb(); /* pairs with smp_rmb() in tcp_md5_hash_key() */ ++ + key->keylen = newkeylen; + return 0; + } diff --git a/patches.suse/tcp-md5-do-not-send-silly-options-in-SYNCOOKIES.patch b/patches.suse/tcp-md5-do-not-send-silly-options-in-SYNCOOKIES.patch new file mode 100644 index 0000000..3641eff --- /dev/null +++ b/patches.suse/tcp-md5-do-not-send-silly-options-in-SYNCOOKIES.patch @@ -0,0 +1,80 @@ +From: Eric Dumazet +Date: Wed, 1 Jul 2020 12:41:23 -0700 +Subject: tcp: md5: do not send silly options in SYNCOOKIES +Git-commit: e114e1e8ac9d31f25b9dd873bab5d80c1fc482ca +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +Whenever cookie_init_timestamp() has been used to encode +ECN,SACK,WSCALE options, we can not remove the TS option in the SYNACK. + +Otherwise, tcp_synack_options() will still advertize options like WSCALE +that we can not deduce later when receiving the packet from the client +to complete 3WHS. + +Note that modern linux TCP stacks wont use MD5+TS+SACK in a SYN packet, +but we can not know for sure that all TCP stacks have the same logic. + +Before the fix a tcpdump would exhibit this wrong exchange : + +10:12:15.464591 IP C > S: Flags [S], seq 4202415601, win 65535, options [nop,nop,md5 valid,mss 1400,sackOK,TS val 456965269 ecr 0,nop,wscale 8], length 0 +10:12:15.464602 IP S > C: Flags [S.], seq 253516766, ack 4202415602, win 65535, options [nop,nop,md5 valid,mss 1400,nop,nop,sackOK,nop,wscale 8], length 0 +10:12:15.464611 IP C > S: Flags [.], ack 1, win 256, options [nop,nop,md5 valid], length 0 +10:12:15.464678 IP C > S: Flags [P.], seq 1:13, ack 1, win 256, options [nop,nop,md5 valid], length 12 +10:12:15.464685 IP S > C: Flags [.], ack 13, win 65535, options [nop,nop,md5 valid], length 0 + +After this patch the exchange looks saner : + +11:59:59.882990 IP C > S: Flags [S], seq 517075944, win 65535, options [nop,nop,md5 valid,mss 1400,sackOK,TS val 1751508483 ecr 0,nop,wscale 8], length 0 +11:59:59.883002 IP S > C: Flags [S.], seq 1902939253, ack 517075945, win 65535, options [nop,nop,md5 valid,mss 1400,sackOK,TS val 1751508479 ecr 1751508483,nop,wscale 8], length 0 +11:59:59.883012 IP C > S: Flags [.], ack 1, win 256, options [nop,nop,md5 valid,nop,nop,TS val 1751508483 ecr 1751508479], length 0 +11:59:59.883114 IP C > S: Flags [P.], seq 1:13, ack 1, win 256, options [nop,nop,md5 valid,nop,nop,TS val 1751508483 ecr 1751508479], length 12 +11:59:59.883122 IP S > C: Flags [.], ack 13, win 256, options [nop,nop,md5 valid,nop,nop,TS val 1751508483 ecr 1751508483], length 0 +11:59:59.883152 IP S > C: Flags [P.], seq 1:13, ack 13, win 256, options [nop,nop,md5 valid,nop,nop,TS val 1751508484 ecr 1751508483], length 12 +11:59:59.883170 IP C > S: Flags [.], ack 13, win 256, options [nop,nop,md5 valid,nop,nop,TS val 1751508484 ecr 1751508484], length 0 + +Of course, no SACK block will ever be added later, but nothing should break. +Technically, we could remove the 4 nops included in MD5+TS options, +but again some stacks could break seeing not conventional alignment. + +Fixes: 4957faade11b ("TCPCT part 1g: Responder Cookie => Initiator") +Signed-off-by: Eric Dumazet +Cc: Florian Westphal +Cc: Mathieu Desnoyers +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv4/tcp_output.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -671,7 +671,8 @@ static unsigned int tcp_synack_options(c + unsigned int mss, struct sk_buff *skb, + struct tcp_out_options *opts, + const struct tcp_md5sig_key *md5, +- struct tcp_fastopen_cookie *foc) ++ struct tcp_fastopen_cookie *foc, ++ enum tcp_synack_type synack_type) + { + struct inet_request_sock *ireq = inet_rsk(req); + unsigned int remaining = MAX_TCP_OPTION_SPACE; +@@ -686,7 +687,8 @@ static unsigned int tcp_synack_options(c + * rather than TS in order to fit in better with old, + * buggy kernels, but that was deemed to be unnecessary. + */ +- ireq->tstamp_ok &= !ireq->sack_ok; ++ if (synack_type != TCP_SYNACK_COOKIE) ++ ireq->tstamp_ok &= !ireq->sack_ok; + } + #endif + +@@ -3310,7 +3312,7 @@ struct sk_buff *tcp_make_synack(const st + #endif + skb_set_hash(skb, tcp_rsk(req)->txhash, PKT_HASH_TYPE_L4); + tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5, +- foc) + sizeof(*th); ++ foc, synack_type) + sizeof(*th); + + skb_push(skb, tcp_header_size); + skb_reset_transport_header(skb); diff --git a/patches.suse/tcp-md5-refine-tcp_md5_do_add-tcp_md5_hash_key-barri.patch b/patches.suse/tcp-md5-refine-tcp_md5_do_add-tcp_md5_hash_key-barri.patch new file mode 100644 index 0000000..0a54c7f --- /dev/null +++ b/patches.suse/tcp-md5-refine-tcp_md5_do_add-tcp_md5_hash_key-barri.patch @@ -0,0 +1,89 @@ +From: Eric Dumazet +Date: Wed, 1 Jul 2020 11:43:04 -0700 +Subject: tcp: md5: refine tcp_md5_do_add()/tcp_md5_hash_key() barriers +Git-commit: e6ced831ef11a2a06e8d00aad9d4fc05b610bf38 +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +My prior fix went a bit too far, according to Herbert and Mathieu. + +Since we accept that concurrent TCP MD5 lookups might see inconsistent +keys, we can use READ_ONCE()/WRITE_ONCE() instead of smp_rmb()/smp_wmb() + +Clearing all key->key[] is needed to avoid possible KMSAN reports, +if key->keylen is increased. Since tcp_md5_do_add() is not fast path, +using __GFP_ZERO to clear all struct tcp_md5sig_key is simpler. + +data_race() was added in linux-5.8 and will prevent KCSAN reports, +this can safely be removed in stable backports, if data_race() is +not yet backported. + +v2: use data_race() both in tcp_md5_hash_key() and tcp_md5_do_add() + +[js] remove data_race. + +Fixes: 6a2febec338d ("tcp: md5: add missing memory barriers in tcp_md5_do_add()/tcp_md5_hash_key()") +Signed-off-by: Eric Dumazet +Cc: Mathieu Desnoyers +Cc: Herbert Xu +Cc: Marco Elver +Reviewed-by: Mathieu Desnoyers +Acked-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv4/tcp.c | 5 ++--- + net/ipv4/tcp_ipv4.c | 14 ++++++++++---- + 2 files changed, 12 insertions(+), 7 deletions(-) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3306,13 +3306,12 @@ EXPORT_SYMBOL(tcp_md5_hash_skb_data); + + int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, const struct tcp_md5sig_key *key) + { +- u8 keylen = key->keylen; ++ u8 keylen = READ_ONCE(key->keylen); /* paired with WRITE_ONCE() in tcp_md5_do_add */ + struct scatterlist sg; + +- smp_rmb(); /* paired with smp_wmb() in tcp_md5_do_add() */ +- + sg_init_one(&sg, key->key, keylen); + ahash_request_set_crypt(hp->md5_req, &sg, NULL, keylen); ++ + return crypto_ahash_update(hp->md5_req); + } + EXPORT_SYMBOL(tcp_md5_hash_key); +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -966,12 +966,18 @@ int tcp_md5_do_add(struct sock *sk, cons + + key = tcp_md5_do_lookup(sk, addr, family); + if (key) { +- /* Pre-existing entry - just update that one. */ ++ /* Pre-existing entry - just update that one. ++ * Note that the key might be used concurrently. ++ */ + memcpy(key->key, newkey, newkeylen); + +- smp_wmb(); /* pairs with smp_rmb() in tcp_md5_hash_key() */ ++ /* Pairs with READ_ONCE() in tcp_md5_hash_key(). ++ * Also note that a reader could catch new key->keylen value ++ * but old key->key[], this is the reason we use __GFP_ZERO ++ * at sock_kmalloc() time below these lines. ++ */ ++ WRITE_ONCE(key->keylen, newkeylen); + +- key->keylen = newkeylen; + return 0; + } + +@@ -987,7 +993,7 @@ int tcp_md5_do_add(struct sock *sk, cons + rcu_assign_pointer(tp->md5sig_info, md5sig); + } + +- key = sock_kmalloc(sk, sizeof(*key), gfp); ++ key = sock_kmalloc(sk, sizeof(*key), gfp | __GFP_ZERO); + if (!key) + return -ENOMEM; + if (!tcp_alloc_md5sig_pool()) { diff --git a/patches.suse/tcp_cubic-fix-spurious-HYSTART_DELAY-exit-upon-drop-.patch b/patches.suse/tcp_cubic-fix-spurious-HYSTART_DELAY-exit-upon-drop-.patch new file mode 100644 index 0000000..5ac5dc6 --- /dev/null +++ b/patches.suse/tcp_cubic-fix-spurious-HYSTART_DELAY-exit-upon-drop-.patch @@ -0,0 +1,52 @@ +From: Neal Cardwell +Date: Wed, 24 Jun 2020 12:42:02 -0400 +Subject: tcp_cubic: fix spurious HYSTART_DELAY exit upon drop in min RTT +Git-commit: b344579ca8478598937215f7005d6c7b84d28aee +Patch-mainline: 5.8-rc3 +References: networking-stable-20_06_28 + +Mirja Kuehlewind reported a bug in Linux TCP CUBIC Hystart, where +Hystart HYSTART_DELAY mechanism can exit Slow Start spuriously on an +ACK when the minimum rtt of a connection goes down. From inspection it +is clear from the existing code that this could happen in an example +like the following: + +o The first 8 RTT samples in a round trip are 150ms, resulting in a + curr_rtt of 150ms and a delay_min of 150ms. + +o The 9th RTT sample is 100ms. The curr_rtt does not change after the + first 8 samples, so curr_rtt remains 150ms. But delay_min can be + lowered at any time, so delay_min falls to 100ms. The code executes + the HYSTART_DELAY comparison between curr_rtt of 150ms and delay_min + of 100ms, and the curr_rtt is declared far enough above delay_min to + force a (spurious) exit of Slow start. + +The fix here is simple: allow every RTT sample in a round trip to +lower the curr_rtt. + +Fixes: ae27e98a5152 ("[TCP] CUBIC v2.3") +Reported-by: Mirja Kuehlewind +Signed-off-by: Neal Cardwell +Signed-off-by: Eric Dumazet +Acked-by: Soheil Hassas Yeganeh +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + net/ipv4/tcp_cubic.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/net/ipv4/tcp_cubic.c ++++ b/net/ipv4/tcp_cubic.c +@@ -414,10 +414,9 @@ static void hystart_update(struct sock * + + if (hystart_detect & HYSTART_DELAY) { + /* obtain the minimum delay of more than sampling packets */ ++ if (ca->curr_rtt == 0 || ca->curr_rtt > delay) ++ ca->curr_rtt = delay; + if (ca->sample_cnt < HYSTART_MIN_SAMPLES) { +- if (ca->curr_rtt == 0 || ca->curr_rtt > delay) +- ca->curr_rtt = delay; +- + ca->sample_cnt++; + } else { + if (ca->curr_rtt > ca->delay_min + diff --git a/patches.suse/tracepoint-mark-_tracepoint_string-s-_used.patch b/patches.suse/tracepoint-mark-_tracepoint_string-s-_used.patch new file mode 100644 index 0000000..ed76b8f --- /dev/null +++ b/patches.suse/tracepoint-mark-_tracepoint_string-s-_used.patch @@ -0,0 +1,50 @@ +From: Nick Desaulniers +Date: Thu, 30 Jul 2020 15:45:54 -0700 +Subject: tracepoint: Mark __tracepoint_string's __used +Git-commit: f3751ad0116fb6881f2c3c957d66a9327f69cefb +Patch-mainline: v5.9-rc1 +References: git-fixes + +__tracepoint_string's have their string data stored in .rodata, and an +address to that data stored in the "__tracepoint_str" section. Functions +that refer to those strings refer to the symbol of the address. Compiler +optimization can replace those address references with references +directly to the string data. If the address doesn't appear to have other +uses, then it appears dead to the compiler and is removed. This can +break the /tracing/printk_formats sysfs node which iterates the +addresses stored in the "__tracepoint_str" section. + +Like other strings stored in custom sections in this header, mark these +__used to inform the compiler that there are other non-obvious users of +the address, so they should still be emitted. + +Link: https://lkml.kernel.org/r/20200730224555.2142154-2-ndesaulniers@google.com + +Cc: Ingo Molnar +Cc: Miguel Ojeda +Cc: stable@vger.kernel.org +Fixes: 102c9323c35a8 ("tracing: Add __tracepoint_string() to export string pointers") +Reported-by: Tim Murray +Reported-by: Simon MacMullen +Suggested-by: Greg Hackmann +Signed-off-by: Nick Desaulniers +Signed-off-by: Steven Rostedt (VMware) +Acked-by: Miroslav Benes +--- + include/linux/tracepoint.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h +index a1fecf311621..3a5b717d92e8 100644 +--- a/include/linux/tracepoint.h ++++ b/include/linux/tracepoint.h +@@ -361,7 +361,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) + static const char *___tp_str __tracepoint_string = str; \ + ___tp_str; \ + }) +-#define __tracepoint_string __attribute__((section("__tracepoint_str"))) ++#define __tracepoint_string __attribute__((section("__tracepoint_str"), used)) + #else + /* + * tracepoint_string() is used to save the string address for userspace + diff --git a/patches.suse/tracing-use-trace_sched_process_free-instead-of-exit-for-pid-tracing.patch b/patches.suse/tracing-use-trace_sched_process_free-instead-of-exit-for-pid-tracing.patch new file mode 100644 index 0000000..5f6405b --- /dev/null +++ b/patches.suse/tracing-use-trace_sched_process_free-instead-of-exit-for-pid-tracing.patch @@ -0,0 +1,75 @@ +From: "Steven Rostedt (VMware)" +Date: Tue, 4 Aug 2020 20:00:02 -0400 +Subject: tracing: Use trace_sched_process_free() instead of exit() for pid + tracing +Git-commit: afcab636657421f7ebfa0783a91f90256bba0091 +Patch-mainline: v5.9-rc1 +References: git-fixes + +On exit, if a process is preempted after the trace_sched_process_exit() +tracepoint but before the process is done exiting, then when it gets +scheduled in, the function tracers will not filter it properly against the +function tracing pid filters. + +That is because the function tracing pid filters hooks to the +sched_process_exit() tracepoint to remove the exiting task's pid from the +filter list. Because the filtering happens at the sched_switch tracepoint, +when the exiting task schedules back in to finish up the exit, it will no +longer be in the function pid filtering tables. + +This was noticeable in the notrace self tests on a preemptable kernel, as +the tests would fail as it exits and preempted after being taken off the +notrace filter table and on scheduling back in it would not be in the +notrace list, and then the ending of the exit function would trace. The test +detected this and would fail. + +Cc: stable@vger.kernel.org +Cc: Namhyung Kim +Fixes: 1e10486ffee0a ("ftrace: Add 'function-fork' trace option") +Fixes: c37775d57830a ("tracing: Add infrastructure to allow set_event_pid to follow children" +Signed-off-by: Steven Rostedt (VMware) +Acked-by: Miroslav Benes +--- + kernel/trace/ftrace.c | 4 ++-- + kernel/trace/trace_events.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 4e3a5d79c078..76f2dd6fd414 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -6985,12 +6985,12 @@ void ftrace_pid_follow_fork(struct trace_array *tr, bool enable) + if (enable) { + register_trace_sched_process_fork(ftrace_pid_follow_sched_process_fork, + tr); +- register_trace_sched_process_exit(ftrace_pid_follow_sched_process_exit, ++ register_trace_sched_process_free(ftrace_pid_follow_sched_process_exit, + tr); + } else { + unregister_trace_sched_process_fork(ftrace_pid_follow_sched_process_fork, + tr); +- unregister_trace_sched_process_exit(ftrace_pid_follow_sched_process_exit, ++ unregister_trace_sched_process_free(ftrace_pid_follow_sched_process_exit, + tr); + } + } +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index f6f55682d3e2..a85effb2373b 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -538,12 +538,12 @@ void trace_event_follow_fork(struct trace_array *tr, bool enable) + if (enable) { + register_trace_prio_sched_process_fork(event_filter_pid_sched_process_fork, + tr, INT_MIN); +- register_trace_prio_sched_process_exit(event_filter_pid_sched_process_exit, ++ register_trace_prio_sched_process_free(event_filter_pid_sched_process_exit, + tr, INT_MAX); + } else { + unregister_trace_sched_process_fork(event_filter_pid_sched_process_fork, + tr); +- unregister_trace_sched_process_exit(event_filter_pid_sched_process_exit, ++ unregister_trace_sched_process_free(event_filter_pid_sched_process_exit, + tr); + } + } + diff --git a/patches.suse/tty-serial-fsl_lpuart-add-imx8qxp-support.patch b/patches.suse/tty-serial-fsl_lpuart-add-imx8qxp-support.patch new file mode 100644 index 0000000..670dab0 --- /dev/null +++ b/patches.suse/tty-serial-fsl_lpuart-add-imx8qxp-support.patch @@ -0,0 +1,243 @@ +From: Fugang Duan +Date: Thu, 4 Jul 2019 21:40:07 +0800 +Subject: tty: serial: fsl_lpuart: add imx8qxp support + +Git-commit: 35a4ed0164e992c9c7b82eb1370081a292131904 +Patch-mainline: v5.3-rc1 +References: bsc#1175670 + +The lpuart of imx8ulp is basically the same as imx7ulp, but it +has new feature support based on imx7ulp, like it can assert a +DMA request on EOP(end-of-packet). imx8ulp lpuart use two clocks, +one is ipg bus clock that is used to access registers, the other +is baud clock that is used to transmit-receive data. + +Signed-off-by: Fugang Duan +Link: https://lore.kernel.org/r/20190704134007.2316-1-fugang.duan@nxp.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/tty/serial/fsl_lpuart.c | 106 ++++++++++++++++++++++++++------ + 1 file changed, 86 insertions(+), 20 deletions(-) + +diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c +index 2f24d9796d20..92dad2b4ec36 100644 +--- a/drivers/tty/serial/fsl_lpuart.c ++++ b/drivers/tty/serial/fsl_lpuart.c +@@ -234,9 +234,18 @@ + + static DEFINE_IDA(fsl_lpuart_ida); + ++enum lpuart_type { ++ VF610_LPUART, ++ LS1021A_LPUART, ++ IMX7ULP_LPUART, ++ IMX8QXP_LPUART, ++}; ++ + struct lpuart_port { + struct uart_port port; +- struct clk *clk; ++ enum lpuart_type devtype; ++ struct clk *ipg_clk; ++ struct clk *baud_clk; + unsigned int txfifo_size; + unsigned int rxfifo_size; + +@@ -261,19 +270,29 @@ struct lpuart_port { + }; + + struct lpuart_soc_data { +- char iotype; +- u8 reg_off; ++ enum lpuart_type devtype; ++ char iotype; ++ u8 reg_off; + }; + + static const struct lpuart_soc_data vf_data = { ++ .devtype = VF610_LPUART, + .iotype = UPIO_MEM, + }; + + static const struct lpuart_soc_data ls_data = { ++ .devtype = LS1021A_LPUART, + .iotype = UPIO_MEM32BE, + }; + +-static struct lpuart_soc_data imx_data = { ++static struct lpuart_soc_data imx7ulp_data = { ++ .devtype = IMX7ULP_LPUART, ++ .iotype = UPIO_MEM32, ++ .reg_off = IMX_REG_OFF, ++}; ++ ++static struct lpuart_soc_data imx8qxp_data = { ++ .devtype = IMX8QXP_LPUART, + .iotype = UPIO_MEM32, + .reg_off = IMX_REG_OFF, + }; +@@ -281,7 +300,8 @@ static struct lpuart_soc_data imx_data = { + static const struct of_device_id lpuart_dt_ids[] = { + { .compatible = "fsl,vf610-lpuart", .data = &vf_data, }, + { .compatible = "fsl,ls1021a-lpuart", .data = &ls_data, }, +- { .compatible = "fsl,imx7ulp-lpuart", .data = &imx_data, }, ++ { .compatible = "fsl,imx7ulp-lpuart", .data = &imx7ulp_data, }, ++ { .compatible = "fsl,imx8qxp-lpuart", .data = &imx8qxp_data, }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, lpuart_dt_ids); +@@ -289,6 +309,11 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids); + /* Forward declare this for the dma callbacks*/ + static void lpuart_dma_tx_complete(void *arg); + ++static inline bool is_imx8qxp_lpuart(struct lpuart_port *sport) ++{ ++ return sport->devtype == IMX8QXP_LPUART; ++} ++ + static inline u32 lpuart32_read(struct uart_port *port, u32 off) + { + switch (port->iotype) { +@@ -314,6 +339,39 @@ static inline void lpuart32_write(struct uart_port *port, u32 val, + } + } + ++static int __lpuart_enable_clks(struct lpuart_port *sport, bool is_en) ++{ ++ int ret = 0; ++ ++ if (is_en) { ++ ret = clk_prepare_enable(sport->ipg_clk); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare_enable(sport->baud_clk); ++ if (ret) { ++ clk_disable_unprepare(sport->ipg_clk); ++ return ret; ++ } ++ } else { ++ clk_disable_unprepare(sport->baud_clk); ++ clk_disable_unprepare(sport->ipg_clk); ++ } ++ ++ return 0; ++} ++ ++static unsigned int lpuart_get_baud_clk_rate(struct lpuart_port *sport) ++{ ++ if (is_imx8qxp_lpuart(sport)) ++ return clk_get_rate(sport->baud_clk); ++ ++ return clk_get_rate(sport->ipg_clk); ++} ++ ++#define lpuart_enable_clks(x) __lpuart_enable_clks(x, true) ++#define lpuart_disable_clks(x) __lpuart_enable_clks(x, false) ++ + static void lpuart_stop_tx(struct uart_port *port) + { + unsigned char temp; +@@ -2069,7 +2127,7 @@ lpuart_console_get_options(struct lpuart_port *sport, int *baud, + brfa = readb(sport->port.membase + UARTCR4); + brfa &= UARTCR4_BRFA_MASK; + +- uartclk = clk_get_rate(sport->clk); ++ uartclk = lpuart_get_baud_clk_rate(sport); + /* + * baud = mod_clk/(16*(sbr[13]+(brfa)/32) + */ +@@ -2112,7 +2170,7 @@ lpuart32_console_get_options(struct lpuart_port *sport, int *baud, + bd = lpuart32_read(&sport->port, UARTBAUD); + bd &= UARTBAUD_SBR_MASK; + sbr = bd; +- uartclk = clk_get_rate(sport->clk); ++ uartclk = lpuart_get_baud_clk_rate(sport); + /* + * baud = mod_clk/(16*(sbr[13]+(brfa)/32) + */ +@@ -2286,6 +2344,7 @@ static int lpuart_probe(struct platform_device *pdev) + sport->port.mapbase = res->start; + sport->port.dev = &pdev->dev; + sport->port.type = PORT_LPUART; ++ sport->devtype = sdata->devtype; + ret = platform_get_irq(pdev, 0); + if (ret < 0) { + dev_err(&pdev->dev, "cannot obtain irq\n"); +@@ -2301,20 +2360,27 @@ static int lpuart_probe(struct platform_device *pdev) + + sport->port.rs485_config = lpuart_config_rs485; + +- sport->clk = devm_clk_get(&pdev->dev, "ipg"); +- if (IS_ERR(sport->clk)) { +- ret = PTR_ERR(sport->clk); +- dev_err(&pdev->dev, "failed to get uart clk: %d\n", ret); ++ sport->ipg_clk = devm_clk_get(&pdev->dev, "ipg"); ++ if (IS_ERR(sport->ipg_clk)) { ++ ret = PTR_ERR(sport->ipg_clk); ++ dev_err(&pdev->dev, "failed to get uart ipg clk: %d\n", ret); + return ret; + } + +- ret = clk_prepare_enable(sport->clk); +- if (ret) { +- dev_err(&pdev->dev, "failed to enable uart clk: %d\n", ret); +- return ret; ++ sport->baud_clk = NULL; ++ if (is_imx8qxp_lpuart(sport)) { ++ sport->baud_clk = devm_clk_get(&pdev->dev, "baud"); ++ if (IS_ERR(sport->baud_clk)) { ++ ret = PTR_ERR(sport->baud_clk); ++ dev_err(&pdev->dev, "failed to get uart baud clk: %d\n", ret); ++ return ret; ++ } + } + +- sport->port.uartclk = clk_get_rate(sport->clk); ++ ret = lpuart_enable_clks(sport); ++ if (ret) ++ return ret; ++ sport->port.uartclk = lpuart_get_baud_clk_rate(sport); + + lpuart_ports[sport->port.line] = sport; + +@@ -2362,7 +2428,7 @@ static int lpuart_probe(struct platform_device *pdev) + + failed_attach_port: + failed_irq_request: +- clk_disable_unprepare(sport->clk); ++ lpuart_disable_clks(sport); + return ret; + } + +@@ -2374,7 +2440,7 @@ static int lpuart_remove(struct platform_device *pdev) + + ida_simple_remove(&fsl_lpuart_ida, sport->port.line); + +- clk_disable_unprepare(sport->clk); ++ lpuart_disable_clks(sport); + + if (sport->dma_tx_chan) + dma_release_channel(sport->dma_tx_chan); +@@ -2439,7 +2505,7 @@ static int lpuart_suspend(struct device *dev) + } + + if (sport->port.suspended && !irq_wake) +- clk_disable_unprepare(sport->clk); ++ lpuart_disable_clks(sport); + + return 0; + } +@@ -2451,7 +2517,7 @@ static int lpuart_resume(struct device *dev) + unsigned long temp; + + if (sport->port.suspended && !irq_wake) +- clk_prepare_enable(sport->clk); ++ lpuart_enable_clks(sport); + + if (lpuart_is_32(sport)) { + lpuart32_setup_watermark(sport); +-- +2.26.2 + diff --git a/patches.suse/tty-serial-fsl_lpuart-free-IDs-allocated-by-IDA.patch b/patches.suse/tty-serial-fsl_lpuart-free-IDs-allocated-by-IDA.patch new file mode 100644 index 0000000..089cdf6 --- /dev/null +++ b/patches.suse/tty-serial-fsl_lpuart-free-IDs-allocated-by-IDA.patch @@ -0,0 +1,108 @@ +From: Michael Walle +Date: Tue, 3 Mar 2020 18:42:59 +0100 +Subject: tty: serial: fsl_lpuart: free IDs allocated by IDA + +Git-commit: 2b2e71fe657510a6f71aa16ef0309fa6bc20ab3d +Patch-mainline: v5.6-rc5 +References: bsc#1175670 + +Since commit 3bc3206e1c0f ("serial: fsl_lpuart: Remove the alias node +dependence") the port line number can also be allocated by IDA, but in +case of an error the ID will no be removed again. More importantly, any +ID will be freed in remove(), even if it wasn't allocated but instead +fetched by of_alias_get_id(). If it was not allocated by IDA there will +be a warning: + WARN(1, "ida_free called for id=%d which is not allocated.\n", id); + +Move the ID allocation more to the end of the probe() so that we still +can use plain return in the first error cases. + +Fixes: 3bc3206e1c0f ("serial: fsl_lpuart: Remove the alias node dependence") +Signed-off-by: Michael Walle +Cc: stable +Link: https://lore.kernel.org/r/20200303174306.6015-3-michael@walle.cc +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Mian Yousaf Kaukab +--- + drivers/tty/serial/fsl_lpuart.c | 39 ++++++++++++++++++++++++--------------- + 1 file changed, 24 insertions(+), 15 deletions(-) + +--- a/drivers/tty/serial/fsl_lpuart.c ++++ b/drivers/tty/serial/fsl_lpuart.c +@@ -271,6 +271,7 @@ struct lpuart_port { + int rx_dma_rng_buf_len; + unsigned int dma_tx_nents; + wait_queue_head_t dma_wait; ++ bool id_allocated; + }; + + struct lpuart_soc_data { +@@ -2210,19 +2211,6 @@ static int lpuart_probe(struct platform_ + + pdev->dev.coherent_dma_mask = 0; + +- ret = of_alias_get_id(np, "serial"); +- if (ret < 0) { +- ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL); +- if (ret < 0) { +- dev_err(&pdev->dev, "port line is full, add device failed\n"); +- return ret; +- } +- } +- if (ret >= ARRAY_SIZE(lpuart_ports)) { +- dev_err(&pdev->dev, "serial%d out of range\n", ret); +- return -EINVAL; +- } +- sport->port.line = ret; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + sport->port.membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(sport->port.membase)) +@@ -2265,9 +2253,25 @@ static int lpuart_probe(struct platform_ + } + } + ++ ret = of_alias_get_id(np, "serial"); ++ if (ret < 0) { ++ ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "port line is full, add device failed\n"); ++ return ret; ++ } ++ sport->id_allocated = true; ++ } ++ if (ret >= ARRAY_SIZE(lpuart_ports)) { ++ dev_err(&pdev->dev, "serial%d out of range\n", ret); ++ ret = -EINVAL; ++ goto failed_out_of_range; ++ } ++ sport->port.line = ret; ++ + ret = lpuart_enable_clks(sport); + if (ret) +- return ret; ++ goto failed_clock_enable; + sport->port.uartclk = lpuart_get_baud_clk_rate(sport); + + lpuart_ports[sport->port.line] = sport; +@@ -2312,6 +2316,10 @@ static int lpuart_probe(struct platform_ + failed_attach_port: + failed_irq_request: + lpuart_disable_clks(sport); ++failed_clock_enable: ++failed_out_of_range: ++ if (sport->id_allocated) ++ ida_simple_remove(&fsl_lpuart_ida, sport->port.line); + return ret; + } + +@@ -2321,7 +2329,8 @@ static int lpuart_remove(struct platform + + uart_remove_one_port(&lpuart_reg, &sport->port); + +- ida_simple_remove(&fsl_lpuart_ida, sport->port.line); ++ if (sport->id_allocated) ++ ida_simple_remove(&fsl_lpuart_ida, sport->port.line); + + lpuart_disable_clks(sport); + + diff --git a/patches.suse/vlan-consolidate-VLAN-parsing-code-and-limit-max-par.patch b/patches.suse/vlan-consolidate-VLAN-parsing-code-and-limit-max-par.patch new file mode 100644 index 0000000..512c435 --- /dev/null +++ b/patches.suse/vlan-consolidate-VLAN-parsing-code-and-limit-max-par.patch @@ -0,0 +1,137 @@ +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Tue, 7 Jul 2020 13:03:25 +0200 +Subject: vlan: consolidate VLAN parsing code and limit max parsing depth +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: 469aceddfa3ed16e17ee30533fae45e90f62efd8 +Patch-mainline: 5.8-rc5 +References: networking-stable-20_07_17 + +Toshiaki pointed out that we now have two very similar functions to extract +the L3 protocol number in the presence of VLAN tags. And Daniel pointed out +that the unbounded parsing loop makes it possible for maliciously crafted +packets to loop through potentially hundreds of tags. + +Fix both of these issues by consolidating the two parsing functions and +limiting the VLAN tag parsing to a max depth of 8 tags. As part of this, +switch over __vlan_get_protocol() to use skb_header_pointer() instead of +pskb_may_pull(), to avoid the possible side effects of the latter and keep +the skb pointer 'const' through all the parsing functions. + +v2: +- Use limit of 8 tags instead of 32 (matching XMIT_RECURSION_LIMIT) + +Reported-by: Toshiaki Makita +Reported-by: Daniel Borkmann +Fixes: d7bf2ebebc2b ("sched: consistently handle layer3 header accesses in the presence of VLANs") +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +--- + include/linux/if_vlan.h | 57 ++++++++++++++++++------------------------------ + 1 file changed, 22 insertions(+), 35 deletions(-) + +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -30,6 +30,8 @@ + #define VLAN_ETH_DATA_LEN 1500 /* Max. octets in payload */ + #define VLAN_ETH_FRAME_LEN 1518 /* Max. octets in frame sans FCS */ + ++#define VLAN_MAX_DEPTH 8 /* Max. number of nested VLAN tags parsed */ ++ + /* + * struct vlan_hdr - vlan header + * @h_vlan_TCI: priority and VLAN ID +@@ -290,34 +292,6 @@ static inline bool eth_type_vlan(__be16 + } + } + +-/* A getter for the SKB protocol field which will handle VLAN tags consistently +- * whether VLAN acceleration is enabled or not. +- */ +-static inline __be16 skb_protocol(const struct sk_buff *skb, bool skip_vlan) +-{ +- unsigned int offset = skb_mac_offset(skb) + sizeof(struct ethhdr); +- __be16 proto = skb->protocol; +- +- if (!skip_vlan) +- /* VLAN acceleration strips the VLAN header from the skb and +- * moves it to skb->vlan_proto +- */ +- return skb_vlan_tag_present(skb) ? skb->vlan_proto : proto; +- +- while (eth_type_vlan(proto)) { +- struct vlan_hdr vhdr, *vh; +- +- vh = skb_header_pointer(skb, offset, sizeof(vhdr), &vhdr); +- if (!vh) +- break; +- +- proto = vh->h_vlan_encapsulated_proto; +- offset += sizeof(vhdr); +- } +- +- return proto; +-} +- + static inline bool vlan_hw_offload_capable(netdev_features_t features, + __be16 proto) + { +@@ -508,10 +482,10 @@ static inline int vlan_get_tag(const str + * Returns the EtherType of the packet, regardless of whether it is + * vlan encapsulated (normal or hardware accelerated) or not. + */ +-static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type, ++static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type, + int *depth) + { +- unsigned int vlan_depth = skb->mac_len; ++ unsigned int vlan_depth = skb->mac_len, parse_depth = VLAN_MAX_DEPTH; + + /* if type is 802.1Q/AD then the header should already be + * present at mac_len - VLAN_HLEN (if mac_len > 0), or at +@@ -526,13 +500,12 @@ static inline __be16 __vlan_get_protocol + vlan_depth = ETH_HLEN; + } + do { +- struct vlan_hdr *vh; ++ struct vlan_hdr vhdr, *vh; + +- if (unlikely(!pskb_may_pull(skb, +- vlan_depth + VLAN_HLEN))) ++ vh = skb_header_pointer(skb, vlan_depth, sizeof(vhdr), &vhdr); ++ if (unlikely(!vh || !--parse_depth)) + return 0; + +- vh = (struct vlan_hdr *)(skb->data + vlan_depth); + type = vh->h_vlan_encapsulated_proto; + vlan_depth += VLAN_HLEN; + } while (eth_type_vlan(type)); +@@ -551,11 +524,25 @@ static inline __be16 __vlan_get_protocol + * Returns the EtherType of the packet, regardless of whether it is + * vlan encapsulated (normal or hardware accelerated) or not. + */ +-static inline __be16 vlan_get_protocol(struct sk_buff *skb) ++static inline __be16 vlan_get_protocol(const struct sk_buff *skb) + { + return __vlan_get_protocol(skb, skb->protocol, NULL); + } + ++/* A getter for the SKB protocol field which will handle VLAN tags consistently ++ * whether VLAN acceleration is enabled or not. ++ */ ++static inline __be16 skb_protocol(const struct sk_buff *skb, bool skip_vlan) ++{ ++ if (!skip_vlan) ++ /* VLAN acceleration strips the VLAN header from the skb and ++ * moves it to skb->vlan_proto ++ */ ++ return skb_vlan_tag_present(skb) ? skb->vlan_proto : skb->protocol; ++ ++ return vlan_get_protocol(skb); ++} ++ + static inline void vlan_set_encap_proto(struct sk_buff *skb, + struct vlan_hdr *vhdr) + { diff --git a/series.conf b/series.conf index 42c920c..56c179d 100644 --- a/series.conf +++ b/series.conf @@ -29356,6 +29356,8 @@ patches.suse/KVM-arm64-Avoid-storing-the-vcpu-pointer-on-the-stac.patch patches.suse/KVM-arm-arm64-Add-kvm_vcpu_load_sysregs-and-kvm_vcpu.patch patches.suse/KVM-arm-arm64-Introduce-vcpu_el1_is_32bit.patch + patches.suse/KVM-arm-arm64-Get-rid-of-vgic_elrsr.patch + patches.suse/KVM-arm-arm64-Handle-VGICv2-save-restore-from-the-ma.patch patches.suse/KVM-arm-arm64-Move-arm64-only-vgic-v2-sr.c-file-to-a.patch patches.suse/0002-arm64-alternatives-Add-dynamic-patching-feature.patch patches.suse/KVM-arm-arm64-Do-not-use-kern_hyp_va-with-kvm_vgic_g.patch @@ -45795,6 +45797,7 @@ patches.suse/pci-iov-factor-out-sriov_add_vfs patches.suse/pci-iov-add-flag-so-platforms-can-skip-vf-scanning patches.suse/s390-pci-skip-vf-scanning + patches.suse/PCI-dwc-Move-interrupt-acking-into-the-proper-callba.patch patches.suse/i2c-imx-don-t-print-error-message-on-probe-defer.patch patches.suse/i2c-sh_mobile-add-support-for-r8a77990-R-Car-E3.patch patches.suse/i2c-axxia-check-for-error-conditions-first.patch @@ -50480,6 +50483,7 @@ patches.suse/serial-uartps-Remove-useless-return-from-cdns_uart_p.patch patches.suse/tty-serial_core-Set-port-active-bit-in-uart_port_act.patch patches.suse/Revert-serial-8250-Don-t-service-RX-FIFO-if-interrup.patch + patches.suse/tty-serial-fsl_lpuart-add-imx8qxp-support.patch patches.suse/usb-core-hub-Disable-hub-initiated-U1-U2.patch patches.suse/usb-gadget-Zero-ffs_io_data.patch patches.suse/usb-gadget-ether-Fix-race-between-gether_disconnect-.patch @@ -50800,6 +50804,7 @@ patches.suse/drm-nouveau-i2c-Enable-i2c-pads-busses-during-preini.patch patches.suse/drm-nouveau-fix-memory-leak-in-nouveau_conn_reset.patch patches.suse/0003-soc-fsl-guts-Add-definition-for-LX2160A.patch + patches.suse/soc-fsl-qbman_portals-add-APIs-to-retrieve-the-probi.patch patches.suse/firmware-ti_sci-Always-request-response-from-firmwar.patch patches.suse/scsi-megaraid_sas-fix-calculation-of-target-id patches.suse/scsi-zfcp-fix-request-object-use-after-free-in-send-path-causing-wrong-traces @@ -52512,14 +52517,32 @@ patches.suse/net-ena-make-ethtool-l-show-correct-max-number-of-qu.patch patches.suse/net-ena-remove-redundant-print-of-number-of-queues.patch patches.suse/net-ena-ethtool-support-set_channels-callback.patch + patches.suse/fsl-fman-don-t-touch-liodn-base-regs-reserved-on-non.patch + patches.suse/dpaa_eth-defer-probing-after-qbman.patch + patches.suse/dpaa_eth-remove-redundant-code.patch + patches.suse/fsl-fman-add-API-to-get-the-device-behind-a-fman-por.patch + patches.suse/dpaa_eth-change-DMA-device.patch + patches.suse/fsl-fman-remove-unused-struct-member.patch + patches.suse/dpaa_eth-add-newline-in-dev_err-msg.patch patches.suse/Bluetooth-hci_core-fix-init-for-HCI_USER_CHANNEL.patch patches.suse/bpf-stackmap-Fix-deadlock-with-rq_lock-in-bpf_get_st.patch patches.suse/e1000e-Add-support-for-Comet-Lake.patch patches.suse/e1000e-Use-rtnl_lock-to-prevent-race-conditions-betw.patch patches.suse/e1000e-Drop-unnecessary-__E1000_DOWN-bit-twiddling.patch patches.suse/e1000e-Add-support-for-Tiger-Lake.patch + patches.suse/dpaa_eth-use-only-one-buffer-pool-per-interface.patch + patches.suse/dpaa_eth-use-page-backed-rx-buffers.patch patches.suse/dpaa_eth-perform-DMA-unmapping-before-read.patch patches.suse/dpaa_eth-avoid-timestamp-read-on-error-paths.patch + patches.suse/dpaa_eth-simplify-variables-used-in-dpaa_cleanup_tx_.patch + patches.suse/dpaa_eth-use-fd-information-in-dpaa_cleanup_tx_fd.patch + patches.suse/dpaa_eth-cleanup-skb_to_contig_fd.patch + patches.suse/dpaa_eth-use-a-page-to-store-the-SGT.patch + patches.suse/dpaa_eth-add-dropped-frames-to-percpu-ethtool-stats.patch + patches.suse/dpaa_eth-remove-netdev_err-for-user-errors.patch + patches.suse/dpaa_eth-extend-delays-in-ndo_stop.patch + patches.suse/soc-fsl-qbman-allow-registering-a-device-link-for-th.patch + patches.suse/dpaa_eth-register-a-device-link-for-the-qman-portal-.patch patches.suse/uaccess-Add-non-pagefault-user-space-write-function.patch patches.suse/bpf-Make-use-of-probe_user_write-in-probe-write-help.patch patches.suse/i40e-enable-X710-support.patch @@ -53156,6 +53179,7 @@ patches.suse/s390-qeth-fix-qdio-teardown-after-early-init-error patches.suse/s390-qeth-lock-the-card-while-changing-its-hsuid patches.suse/net-mlxfw-Fix-out-of-memory-error-in-mfa2-flash-burn.patch + patches.suse/dpaa_eth-fix-DMA-mapping-leak.patch patches.suse/ptp-fix-the-race-between-the-release-of-ptp_clock-an.patch patches.suse/pstore-ram-Write-new-dumps-to-start-of-recycled-zone.patch patches.suse/0001-drm-sun4i-hdmi-Remove-duplicate-cleanup-calls.patch @@ -53336,6 +53360,8 @@ patches.suse/livepatch-samples-selftest-use-klp_shadow_alloc-api-correctly.patch patches.suse/spi-dw-use-smp_mb-to-avoid-sending-spi-data-error.patch patches.suse/regulator-rk808-Lower-log-level-on-optional-GPIOs-be.patch + patches.suse/PM-devfreq-rk3399_dmc-Add-missing-of_node_put.patch + patches.suse/PM-devfreq-rk3399_dmc-Disable-devfreq-event-device-w.patch patches.suse/apei-ghes-Do-not-delay-GHES-polling.patch patches.suse/ACPI-video-Do-not-export-a-non-working-backlight-int.patch patches.suse/0087-md-bitmap-small-cleanups.patch @@ -53716,6 +53742,7 @@ patches.suse/smb3-print-warning-once-if-posix-context-returned-on-open.patch patches.suse/smb3-Add-defines-for-new-information-level-FileIdInformation.patch patches.suse/kconfig-fix-broken-dependency-in-randconfig-generate.patch + patches.suse/arm64-ssbs-Fix-context-switch-when-SSBS-is-present-o.patch patches.suse/drm-msm-Set-dma-maximum-segment-size-for-mdss.patch patches.suse/ALSA-usb-audio-Apply-48kHz-fixed-rate-playback-for-J.patch patches.suse/ALSA-usb-audio-Fix-UAC2-3-effect-unit-parsing.patch @@ -53910,6 +53937,7 @@ patches.suse/0001-usb-core-port-do-error-out-if-usb_autopm_get_interfa.patch patches.suse/vt-selection-push-console-lock-down.patch patches.suse/vt-selection-push-sel_lock-up.patch + patches.suse/tty-serial-fsl_lpuart-free-IDs-allocated-by-IDA.patch patches.suse/firmware-imx-scu-ensure-sequential-tx.patch patches.suse/firmware-imx-misc-align-imx-sc-msg-structs-to-4.patch patches.suse/firmware-imx-scu-pd-align-imx-sc-msg-structs-to-4.patch @@ -53938,6 +53966,8 @@ patches.suse/net-hns3-fix-a-not-link-up-issue-when-fibre-port-sup.patch patches.suse/iwlwifi-mvm-Do-not-require-PHY_SKU-NVM-section-for-3.patch patches.suse/net-nfc-fix-bounds-checking-bugs-on-pipe.patch + patches.suse/fsl-fman-detect-FMan-erratum-A050385.patch + patches.suse/dpaa_eth-FMan-erratum-A050385-workaround.patch patches.suse/bonding-alb-make-sure-arp-header-is-pulled-before-ac.patch patches.suse/ipvlan-do-not-add-hardware-address-of-master-to-its-.patch patches.suse/gre-fix-uninit-value-in-__iptunnel_pull_header.patch @@ -54877,6 +54907,7 @@ patches.suse/powerpc-64s-Fix-early_init_mmu-section-mismatch.patch patches.suse/powerpc-xive-Clear-the-page-tables-for-the-ESB-IO-ma.patch patches.suse/input-i8042-Remove-special-PowerPC-handling.patch + patches.suse/powerpc-64s-Don-t-init-FSCR_DSCR-in-__init_FSCR.patch patches.suse/powerpc-64s-Don-t-let-DT-CPU-features-set-FSCR_DSCR.patch patches.suse/powerpc-64s-Save-FSCR-to-init_task.thread.fscr-after.patch patches.suse/vfio-type1-support-faulting-pfnmap-vmas @@ -54984,6 +55015,9 @@ patches.suse/ext4-jbd2-ensure-panic-by-fix-a-race-between-jbd2-ab.patch patches.suse/ibmvnic-Harden-device-login-requests.patch patches.suse/bnxt_en-Fix-AER-reset-logic-on-57500-chips.patch + patches.suse/mld-fix-memory-leak-in-ipv6_mc_destroy_dev.patch + patches.suse/rocker-fix-incorrect-error-handling-in-dma_rings_ini.patch + patches.suse/tcp-grow-window-for-OOO-packets-only-for-SACK-flows.patch patches.suse/e1000e-Do-not-wake-up-the-system-via-WOL-if-device-w.patch patches.suse/libceph-don-t-omit-recovery_deletes-in-target_copy.patch patches.suse/0001-drm-i915-icl-Fix-hotplug-interrupt-disabling-after-s.patch @@ -55008,9 +55042,16 @@ patches.suse/ALSA-hda-realtek-Add-mute-LED-and-micmute-LED-suppor.patch patches.suse/RDMA-efa-Set-maximum-pkeys-device-attribute.patch patches.suse/tracing-fix-event-trigger-to-accept-redundant-spaces.patch + patches.suse/net-usb-ax88179_178a-fix-packet-alignment-padding.patch + patches.suse/net-fix-memleak-in-register_netdevice.patch + patches.suse/net-core-reduce-recursion-limit-value.patch + patches.suse/ip6_gre-fix-use-after-free-in-ip6gre_tunnel_lookup.patch + patches.suse/ip_tunnel-fix-use-after-free-in-ip_tunnel_lookup.patch + patches.suse/net-Fix-the-arp-error-in-some-cases.patch patches.suse/s390-qeth-fix-error-handling-for-isolation-mode-cmds patches.suse/tg3-driver-sleeps-indefinitely-when-EEH-errors-excee.patch patches.suse/net-dsa-bcm_sf2-Fix-node-reference-count.patch + patches.suse/net-increment-xmit_recursion-level-in-dev_direct_xmi.patch patches.suse/net-phy-Check-harder-for-errors-in-get_phy_id.patch patches.suse/ibmveth-Fix-max-MTU-limit.patch patches.suse/ibmvnic-continue-to-init-in-CRQ-reset-returns-H_CLOS.patch @@ -55018,9 +55059,14 @@ patches.suse/net-qede-stop-adding-events-on-an-already-destroyed-.patch patches.suse/net-qed-fix-NVMe-login-fails-over-VFs.patch patches.suse/net-qed-fix-excessive-QM-ILT-lines-consumption.patch + patches.suse/net-Do-not-clear-the-sock-TX-queue-in-sk_set_socket.patch + patches.suse/net-bridge-enfore-alignment-for-ethernet-address.patch + patches.suse/tcp_cubic-fix-spurious-HYSTART_DELAY-exit-upon-drop-.patch + patches.suse/sctp-Don-t-advertise-IPv4-addresses-if-ipv6only-is-s.patch patches.suse/0001-ocfs2-avoid-inode-removal-while-nfsd-is-accessing-it.patch patches.suse/0002-ocfs2-load-global_inode_alloc.patch patches.suse/0003-ocfs2-fix-panic-on-nfs-server-over-ocfs2.patch + patches.suse/ocfs2-fix-value-of-OCFS2_INVALID_SLOT.patch patches.suse/drm-tegra-hub-Do-not-enable-orphaned-window-group.patch patches.suse/gpu-host1x-Detach-driver-on-unregister.patch patches.suse/0001-drm-radeon-fix-fb_div-check-in-ni_init_smc_spll_tabl.patch @@ -55071,8 +55117,19 @@ patches.suse/0001-drm-radeon-fix-double-free.patch patches.suse/IB-hfi1-Do-not-destroy-hfi1_wq-when-the-device-is-sh.patch patches.suse/IB-hfi1-Do-not-destroy-link_wq-when-the-device-is-sh.patch + patches.suse/llc-make-sure-applications-use-ARPHRD_ETHER.patch + patches.suse/tcp-md5-add-missing-memory-barriers-in-tcp_md5_do_ad.patch + patches.suse/genetlink-remove-genl_bind.patch + patches.suse/tcp-md5-refine-tcp_md5_do_add-tcp_md5_hash_key-barri.patch + patches.suse/tcp-md5-do-not-send-silly-options-in-SYNCOOKIES.patch + patches.suse/sched-consistently-handle-layer3-header-accesses-in-.patch + patches.suse/net-usb-qmi_wwan-add-support-for-Quectel-EG95-LTE-mo.patch patches.suse/cgroup-fix-cgroup_sk_alloc-for-sk_clone_lock.patch + patches.suse/ipv4-fill-fl4_icmp_-type-code-in-ping_v4_sendmsg.patch patches.suse/0012-net-Added-pointer-check-for-dst-ops-neigh_lookup-in-.patch + patches.suse/vlan-consolidate-VLAN-parsing-code-and-limit-max-par.patch + patches.suse/l2tp-remove-skb_dst_set-from-l2tp_xmit_skb.patch + patches.suse/tcp-make-sure-listeners-don-t-initialize-congestion-.patch patches.suse/cgroup-fix-sock_cgroup_data-on-big-endian.patch patches.suse/bnxt_en-fix-NULL-dereference-in-case-SR-IOV-configur.patch patches.suse/mlxsw-spectrum_router-Remove-inappropriate-usage-of-.patch @@ -55120,9 +55177,11 @@ patches.suse/btrfs-qgroup-fix-data-leak-caused-by-race-between-wr.patch patches.suse/btrfs-fix-page-leaks-after-failure-to-lock-page-for-.patch patches.suse/io-mapping-indicate-mapping-failure.patch + patches.suse/ip6_gre-fix-null-ptr-deref-in-ip6gre_init_net.patch patches.suse/ax88172a-fix-ax88172a_unbind-failures.patch patches.suse/rtnetlink-Fix-memory-net_device-leak-when-newlink-fa.patch patches.suse/nfc-nci-add-missed-destroy_workqueue-in-nci_register.patch + patches.suse/dpaa_eth-Fix-one-possible-memleak-in-dpaa_eth_probe.patch patches.suse/0011-net-udp-Fix-wrong-clean-up-for-IS_UDPLITE-macro.patch patches.suse/AX.25-Fix-out-of-bounds-read-in-ax25_connect.patch patches.suse/AX.25-Prevent-out-of-bounds-read-in-ax25_sendmsg.patch @@ -55177,12 +55236,16 @@ patches.suse/regulator-gpio-Honor-regulator-boot-on-property.patch patches.suse/spi-lantiq-fix-Rx-overflow-error-in-full-duplex-mode.patch patches.suse/spi-sun4i-update-max-transfer-size-reported.patch + patches.suse/PM-devfreq-rk3399_dmc-Fix-kernel-oops-when-rockchip-.patch patches.suse/PCI-hotplug-ACPI-Fix-context-refcounting-in-acpiphp_.patch patches.suse/b43-Remove-uninitialized_var-usage.patch patches.suse/rtlwifi-rtl8192cu-Remove-uninitialized_var-usage.patch patches.suse/spi-davinci-Remove-uninitialized_var-usage.patch patches.suse/clk-st-Remove-uninitialized_var-usage.patch patches.suse/clk-spear-Remove-uninitialized_var-usage.patch + patches.suse/KVM-PPC-Book3S-PR-Remove-uninitialized_var-usage.patch + patches.suse/nvme-multipath-fix-logic-for-non-optimized-paths.patch + patches.suse/nvme-multipath-do-not-fall-back-to-__nvme_find_path-.patch patches.suse/md-raid5-Fix-Force-reconstruct-write-io-stuck-in-deg.patch patches.suse/devres-keep-both-device-name-and-resource-name-in-pr.patch patches.suse/driver-core-Avoid-binding-drivers-to-dead-devices.patch @@ -55250,6 +55313,10 @@ patches.suse/liquidio-Fix-wrong-return-value-in-cn23xx_get_pf_num.patch patches.suse/wl1251-fix-always-return-0-error.patch patches.suse/dpaa2-eth-Fix-passing-zero-to-PTR_ERR-warning.patch + patches.suse/selftests-livepatch-simplify-test-klp-callbacks-busy-target-tests.patch + patches.suse/selftests-livepatch-rework-test-klp-shadow-vars.patch + patches.suse/selftests-livepatch-more-verification-in-test-klp-shadow-vars.patch + patches.suse/selftests-livepatch-fix-mem-leaks-in-test-klp-shadow-vars.patch patches.suse/integrity-remove-redundant-initialization-of-variabl.patch patches.suse/ALSA-hda-realtek-Add-alc269-alc662-pin-tables-for-Lo.patch patches.suse/ALSA-core-pcm_iec958-fix-kernel-doc.patch @@ -55292,12 +55359,16 @@ patches.suse/cifs-fix-double-free-error-on-share-and-prefix.patch patches.suse/cifs-only-update-prefix-path-of-DFS-links-in-cifs_tree_connect-.patch patches.suse/cifs-document-and-cleanup-dfs-mount.patch + patches.suse/kernfs-do-not-call-fsnotify-with-name-without-a-pare.patch + patches.suse/dlm-Fix-kobject-memleak.patch patches.suse/powerpc-xmon-Reset-RCU-and-soft-lockup-watchdogs.patch patches.suse/powerpc-pseries-remove-cede-offline-state-for-CPUs.patch patches.suse/powerpc-rtas-don-t-online-CPUs-for-partition-suspend.patch patches.suse/powerpc-fadump-fix-race-between-pstore-write-and-fad.patch + patches.suse/pseries-Fix-64-bit-logical-memory-block-panic.patch patches.suse/powerpc-vdso-Fix-vdso-cpu-truncation.patch patches.suse/powerpc-book3s64-pkeys-Use-PVR-check-instead-of-cpu-.patch + patches.suse/powerpc-perf-Fix-missing-is_sier_aviable-during-buil.patch patches.suse/powerpc-pseries-PCIE-PHB-reset.patch patches.suse/powerpc-Allow-4224-bytes-of-stack-expansion-for-the-.patch patches.suse/powerpc-boot-Fix-CONFIG_PPC_MPC52XX-references.patch @@ -55305,10 +55376,14 @@ patches.suse/xfs-fix-reflink-quota-reservation-accounting-error.patch patches.suse/xfs-fix-inode-allocation-block-res-calculation-prece.patch patches.suse/ocfs2-fix-remounting-needed-after-setfacl-command.patch + patches.suse/ocfs2-change-slot-number-type-s16-to-u16.patch + patches.suse/mm-filemap-clear-idle-flag-for-writes.patch patches.suse/media-omap3isp-Add-missed-v4l2_ctrl_handler_free-for.patch patches.suse/media-firewire-Using-uninitialized-values-in-node_pr.patch patches.suse/media-exynos4-is-Add-missed-check-for-pinctrl_lookup.patch patches.suse/go7007-add-sanity-checking-for-endpoints.patch + patches.suse/tracepoint-mark-_tracepoint_string-s-_used.patch + patches.suse/tracing-use-trace_sched_process_free-instead-of-exit-for-pid-tracing.patch patches.suse/PCI-ASPM-Add-missing-newline-in-sysfs-policy.patch patches.suse/PCI-Fix-pci_cfg_wait-queue-locking-problem.patch patches.suse/PCI-Release-IVRS-table-in-AMD-ACS-quirk.patch @@ -55368,13 +55443,22 @@ patches.suse/ALSA-hda-realtek-Add-model-alc298-samsung-headphone.patch patches.suse/ALSA-usb-audio-ignore-broken-processing-extension-un.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-Samsung-Galaxy-Book-I.patch + patches.suse/ext4-fix-potential-negative-array-index-in-do_split.patch + patches.suse/jbd2-add-the-missing-unlock_buffer-in-the-error-path.patch + patches.suse/ext4-handle-error-of-ext4_setup_system_zone-on-remou.patch + patches.suse/ext4-don-t-allow-overlapping-system-zones.patch + patches.suse/ext4-check-journal-inode-extents-more-carefully.patch + patches.suse/ext4-fix-checking-of-directory-entry-validity-for-in.patch patches.suse/mm-vunmap-add-cond_resched-in-vunmap_pmd_range.patch patches.suse/bonding-fix-active-backup-failover-for-current-ARP-s.patch patches.suse/net-ena-Prevent-reset-after-device-destruction.patch patches.suse/net-ena-Change-WARN_ON-expression-in-ena_del_napi_in.patch patches.suse/net-ena-Make-missed_tx-stat-incremental.patch patches.suse/net-dsa-b53-check-for-timeout.patch + patches.suse/powerpc-pseries-hotplug-cpu-wait-indefinitely-for-vC.patch patches.suse/powerpc-pseries-Do-not-initiate-shutdown-when-system.patch + patches.suse/nvme-multipath-round-robin-fix-single-non-optimized-path-case.patch + patches.suse/nvme-multipath-round-robin-eliminate-fallback-variable.patch # jejb/scsi for-next patches.suse/scsi-smartpqi-identify-physical-devices-without-issuing-inquiry.patch @@ -55846,12 +55930,6 @@ # bsc#1173060 patches.suse/lpfc-synchronize-nvme-transport-and-lpfc-driver-devloss_tmo.patch - # bsc#1172108 - patches.suse/nvme-multipath-fix-logic-for-non-optimized-paths.patch - patches.suse/nvme-multipath-do-not-fall-back-to-__nvme_find_path-.patch - patches.suse/nvme-multipath-round-robin-fix-single-non-optimized-path-case.patch - patches.suse/nvme-multipath-round-robin-eliminate-fallback-variable.patch - ######################################################## # DRM/Video ######################################################## @@ -56217,6 +56295,7 @@ patches.kabi/pcie-revive-__aer_firmware_first_valid.patch patches.kabi/SUNRPC-defer-slow-parts-of-rpc_free_client-to-a-work-kabi.patch patches.kabi/sock_cgroup_data-kabi-fix.patch + patches.kabi/genetlink-remove-genl_bind.patch ######################################################## # You'd better have a good reason for adding a patch