mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Kernel

Threads by month
  • ----- 2025 -----
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
kernel@openeuler.org

  • 70 participants
  • 19493 discussions
[openeuler:OLK-6.6] BUILD SUCCESS dc3e480568627c27f13878766588cc8c32213af5
by kernel test robot 09 Aug '24

09 Aug '24
tree/branch: https://gitee.com/openeuler/kernel.git OLK-6.6 branch HEAD: dc3e480568627c27f13878766588cc8c32213af5 !10816 sched/cputime: Fix mul_u64_u64_div_u64() precision for cputime Warning ids grouped by kconfigs: recent_errors |-- arm64-allmodconfig | |-- arch-arm64-kvm-arm.c:warning:variable-r-is-used-uninitialized-whenever-if-condition-is-false | |-- arch-arm64-kvm-tmi.c:warning:no-previous-prototype-for-function-tmi_tmm_inf_test | |-- arch-arm64-kvm-virtcca_cvm.c:warning:no-previous-prototype-for-function-kvm_cvm_create_ttt_levels | |-- arch-arm64-kvm-virtcca_cvm.c:warning:no-previous-prototype-for-function-kvm_cvm_get_num_brps | |-- arch-arm64-kvm-virtcca_cvm.c:warning:no-previous-prototype-for-function-kvm_cvm_get_num_wrps | |-- arch-arm64-kvm-virtcca_cvm.c:warning:no-previous-prototype-for-function-kvm_cvm_ipa_limit | |-- arch-arm64-kvm-virtcca_cvm.c:warning:no-previous-prototype-for-function-kvm_cvm_populate_par_region | |-- arch-arm64-kvm-virtcca_cvm.c:warning:no-previous-prototype-for-function-kvm_cvm_supports_pmu | `-- arch-arm64-kvm-virtcca_cvm.c:warning:no-previous-prototype-for-function-kvm_cvm_supports_sve |-- arm64-randconfig-051-20240808 | |-- arch-arm64-boot-dts-freescale-imx8mp-beacon-kit.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-beacon-kit.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-beacon-kit.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-beacon-kit.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-data-modul-edm-sbc.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-data-modul-edm-sbc.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-data-modul-edm-sbc.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-data-modul-edm-sbc.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-debix-model-a.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-debix-model-a.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-debix-model-a.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-debix-model-a.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-debix-som-a-bmb-.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-debix-som-a-bmb-.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-debix-som-a-bmb-.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-debix-som-a-bmb-.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-dhcom-pdk2.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-dhcom-pdk2.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-dhcom-pdk2.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-dhcom-pdk2.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-dhcom-pdk3.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-dhcom-pdk3.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-dhcom-pdk3.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-dhcom-pdk3.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-evk.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-evk.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-evk.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-evk.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-icore-mx8mp-edimm2..dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-icore-mx8mp-edimm2..dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-icore-mx8mp-edimm2..dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-icore-mx8mp-edimm2..dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-msc-sm2s-ep1.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-msc-sm2s-ep1.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-msc-sm2s-ep1.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-msc-sm2s-ep1.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-phyboard-pollux-rdk.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-phyboard-pollux-rdk.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-phyboard-pollux-rdk.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-phyboard-pollux-rdk.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw71xx-2x.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw71xx-2x.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw71xx-2x.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw71xx-2x.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw72xx-2x.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw72xx-2x.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw72xx-2x.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw72xx-2x.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw73xx-2x.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw73xx-2x.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw73xx-2x.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw73xx-2x.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw74xx.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw74xx.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw74xx.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw74xx.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw7905-2x.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw7905-2x.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw7905-2x.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-venice-gw7905-2x.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-dahlia.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-dahlia.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-dahlia.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-dahlia.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-dev.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-dev.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-dev.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-dev.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-yavia.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-yavia.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-yavia.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-nonwifi-yavia.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-dahlia.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-dahlia.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-dahlia.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-dahlia.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-dev.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-dev.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-dev.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-dev.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-yavia.dtb:blk-ctrl-32fc0000:clock-names:apb-axi-ref_266m-ref_24m-fdcc-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-yavia.dtb:blk-ctrl-32fc0000:clocks:is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-yavia.dtb:blk-ctrl-32fc0000:power-domain-names:bus-irqsteer-lcdif-pai-pvi-trng-hdmi-tx-hdmi-tx-phy-hdcp-hrv-is-too-long | |-- arch-arm64-boot-dts-freescale-imx8mp-verdin-wifi-yavia.dtb:blk-ctrl-32fc0000:power-domains:is-too-long | |-- arch-arm64-boot-dts-qcom-sa8775p-ride.dtb:ethernet:Unevaluated-properties-are-not-allowed-(-dma-coherent-mdio-phy-handle-phy-mode-power-domains-rx-fifo-depth-rx-queues-config-snps-mtl-rx-config-snps-m | `-- arch-arm64-boot-dts-qcom-sa8775p-ride.dtb:ethernet:Unevaluated-properties-are-not-allowed-(-dma-coherent-phy-handle-phy-mode-power-domains-rx-fifo-depth-rx-queues-config-snps-mtl-rx-config-snps-mtl-tx |-- loongarch-allmodconfig | `-- arch-loongarch-kvm-..-..-..-virt-kvm-kvm_main.c:warning:kvmalloc_array-sizes-specified-with-sizeof-in-the-earlier-argument-and-not-in-the-later-argument |-- loongarch-randconfig-001-20240809 | `-- drivers-char-virtio_console.c:warning:u-directive-output-may-be-truncated-writing-between-and-bytes-into-a-region-of-size-between-and `-- x86_64-allyesconfig `-- drivers-gpu-drm-amd-amdgpu-..-amdkfd-kfd_topology.c:warning:stack-frame-size-()-exceeds-limit-()-in-kfd_topology_add_device elapsed time: 731m configs tested: 14 configs skipped: 124 The following configs have been built successfully. More configs may be tested in the coming days. tested configs: arm64 allmodconfig clang-20 arm64 allnoconfig gcc-14.1.0 arm64 randconfig-001-20240809 clang-20 arm64 randconfig-002-20240809 clang-15 arm64 randconfig-003-20240809 clang-15 arm64 randconfig-004-20240809 clang-20 loongarch allmodconfig gcc-14.1.0 loongarch allnoconfig gcc-14.1.0 loongarch randconfig-001-20240809 gcc-14.1.0 loongarch randconfig-002-20240809 gcc-14.1.0 x86_64 allnoconfig clang-18 x86_64 allyesconfig clang-18 x86_64 defconfig gcc-11 x86_64 rhel-8.3-rust clang-18 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
1 0
0 0
[PATCH 1/4] RDMA/hns: Register notifier block of bonding events in bond_grp
by Chengchang Tang 08 Aug '24

08 Aug '24
From: Junxian Huang <huangjunxian6(a)hisilicon.com> driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAH10J ---------------------------------------------------------------------- Currently the notifier block of bonding events is in the hr_dev structure. bond_grp is dynamic allocated in the event handler. Since all these hr_dev would response bonding events, we had to add complicated filter to choose a suitable hr_dev to handle the events. Besides we also had to concern about the validity of bond_grp pointers in many concurrency cases as they may have been freed. Refactor the bonding event handler by: 1. allocating/deallocating bond_grp structures when driver inits/exits; 2. registering notifier block of bonding events in bond_grp Signed-off-by: Junxian Huang <huangjunxian6(a)hisilicon.com> Signed-off-by: Xinghai Cen <cenxinghai(a)h-partners.com> --- drivers/infiniband/hw/hns/hns_roce_bond.c | 415 +++++++++++--------- drivers/infiniband/hw/hns/hns_roce_bond.h | 3 + drivers/infiniband/hw/hns/hns_roce_device.h | 1 - drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 9 +- drivers/infiniband/hw/hns/hns_roce_main.c | 2 +- 5 files changed, 247 insertions(+), 183 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_bond.c b/drivers/infiniband/hw/hns/hns_roce_bond.c index 4b2b5538c918..c5b30d7dab67 100644 --- a/drivers/infiniband/hw/hns/hns_roce_bond.c +++ b/drivers/infiniband/hw/hns/hns_roce_bond.c @@ -52,32 +52,6 @@ static int get_netdev_bond_slave_id(struct net_device *net_dev, return -ENOENT; } -static bool is_hrdev_bond_slave(struct hns_roce_dev *hr_dev, - struct net_device *upper_dev) -{ - struct hns_roce_bond_group *bond_grp; - struct net_device *net_dev; - u8 bus_num; - - if (!hr_dev || !upper_dev) - return false; - - if (!netif_is_lag_master(upper_dev)) - return false; - - net_dev = get_hr_netdev(hr_dev, 0); - bus_num = get_hr_bus_num(hr_dev); - - if (upper_dev == get_upper_dev_from_ndev(net_dev)) - return true; - - bond_grp = hns_roce_get_bond_grp(net_dev, bus_num); - if (bond_grp && upper_dev == bond_grp->upper_dev) - return true; - - return false; -} - struct hns_roce_bond_group *hns_roce_get_bond_grp(struct net_device *net_dev, u8 bus_num) { @@ -92,8 +66,10 @@ struct hns_roce_bond_group *hns_roce_get_bond_grp(struct net_device *net_dev, bond_grp = die_info->bgrps[i]; if (!bond_grp) continue; - if (get_netdev_bond_slave_id(net_dev, bond_grp) >= 0 || - (bond_grp->upper_dev == get_upper_dev_from_ndev(net_dev))) + if (get_netdev_bond_slave_id(net_dev, bond_grp) >= 0) + return bond_grp; + if (bond_grp->upper_dev && + bond_grp->upper_dev == get_upper_dev_from_ndev(net_dev)) return bond_grp; } @@ -107,8 +83,8 @@ bool hns_roce_bond_is_active(struct hns_roce_dev *hr_dev) u8 bus_num = get_hr_bus_num(hr_dev); bond_grp = hns_roce_get_bond_grp(net_dev, bus_num); - - if (bond_grp && bond_grp->bond_state != HNS_ROCE_BOND_NOT_BONDED) + if (bond_grp && bond_grp->bond_state != HNS_ROCE_BOND_NOT_BONDED && + bond_grp->bond_state != HNS_ROCE_BOND_NOT_ATTACHED) return true; return false; @@ -507,39 +483,6 @@ static void hns_roce_do_bond_work(struct work_struct *work) hns_roce_queue_bond_work(bond_grp, HZ); } -int hns_roce_bond_init(struct hns_roce_dev *hr_dev) -{ - struct net_device *net_dev = get_hr_netdev(hr_dev, 0); - struct hns_roce_v2_priv *priv = hr_dev->priv; - struct hns_roce_bond_group *bond_grp; - u8 bus_num = get_hr_bus_num(hr_dev); - int ret; - - bond_grp = hns_roce_get_bond_grp(net_dev, bus_num); - if (priv->handle->rinfo.reset_state == HNS_ROCE_STATE_RST_INIT && - bond_grp) { - bond_grp->main_hr_dev = hr_dev; - ret = hns_roce_recover_bond(bond_grp); - if (ret) { - ibdev_err(&hr_dev->ib_dev, - "failed to recover RoCE bond, ret = %d.\n", - ret); - return ret; - } - } - - hr_dev->bond_nb.notifier_call = hns_roce_bond_event; - ret = register_netdevice_notifier(&hr_dev->bond_nb); - if (ret) { - ibdev_err(&hr_dev->ib_dev, - "failed to register notifier for RoCE bond, ret = %d.\n", - ret); - hr_dev->bond_nb.notifier_call = NULL; - } - - return ret; -} - static struct hns_roce_die_info *alloc_die_info(int bus_num) { struct hns_roce_die_info *die_info; @@ -611,67 +554,116 @@ static int remove_bond_id(int bus_num, u8 bond_id) return 0; } -int hns_roce_cleanup_bond(struct hns_roce_bond_group *bond_grp) +static int hns_roce_alloc_bond_grp(struct hns_roce_dev *hr_dev) { - bool completion_no_waiter; + struct hns_roce_bond_group *bgrps[ROCE_BOND_NUM_MAX]; + struct hns_roce_bond_group *bond_grp; int ret; + int i; - ret = bond_grp->main_hr_dev ? - hns_roce_cmd_bond(bond_grp, HNS_ROCE_CLEAR_BOND) : -EIO; - if (ret) - BOND_ERR_LOG("failed to clear RoCE bond, ret = %d.\n", ret); - - cancel_delayed_work(&bond_grp->bond_work); - ret = remove_bond_id(bond_grp->bus_num, bond_grp->bond_id); - if (ret) - BOND_ERR_LOG("failed to remove bond id %u, ret = %d.\n", - bond_grp->bond_id, ret); + for (i = 0; i < ROCE_BOND_NUM_MAX; i++) { + bond_grp = kvzalloc(sizeof(*bond_grp), GFP_KERNEL); + if (!bond_grp) { + ret = -ENOMEM; + goto mem_err; + } - completion_no_waiter = completion_done(&bond_grp->bond_work_done); - complete(&bond_grp->bond_work_done); - mutex_destroy(&bond_grp->bond_mutex); - if (completion_no_waiter) - kfree(bond_grp); + mutex_init(&bond_grp->bond_mutex); + INIT_DELAYED_WORK(&bond_grp->bond_work, hns_roce_do_bond_work); + init_completion(&bond_grp->bond_work_done); - return ret; -} + bond_grp->bond_ready = false; + bond_grp->bond_state = HNS_ROCE_BOND_NOT_ATTACHED; + bond_grp->bus_num = get_hr_bus_num(hr_dev); -static bool hns_roce_bond_lowerstate_event(struct hns_roce_dev *hr_dev, - struct hns_roce_bond_group *bond_grp, - struct netdev_notifier_changelowerstate_info *info) -{ - struct net_device *net_dev = - netdev_notifier_info_to_dev((struct netdev_notifier_info *)info); + ret = alloc_bond_id(bond_grp); + if (ret) { + ibdev_err(&hr_dev->ib_dev, + "failed to alloc bond ID, ret = %d.\n", ret); + goto alloc_id_err; + } - if (!netif_is_lag_port(net_dev) || - (!bond_grp || hr_dev != bond_grp->main_hr_dev)) - return false; + bond_grp->bond_nb.notifier_call = hns_roce_bond_event; + ret = register_netdevice_notifier(&bond_grp->bond_nb); + if (ret) { + ibdev_err(&hr_dev->ib_dev, + "failed to register bond nb, ret = %d.\n", ret); + goto register_nb_err; + } + bgrps[i] = bond_grp; + } - mutex_lock(&bond_grp->bond_mutex); + return 0; - if (bond_grp->bond_ready && - bond_grp->bond_state == HNS_ROCE_BOND_IS_BONDED) - bond_grp->bond_state = HNS_ROCE_BOND_SLAVE_CHANGESTATE; +register_nb_err: + remove_bond_id(bond_grp->bus_num, bond_grp->bond_id); +alloc_id_err: + mutex_destroy(&bond_grp->bond_mutex); + kvfree(bond_grp); +mem_err: + for (i--; i >= 0; i--) { + unregister_netdevice_notifier(&bgrps[i]->bond_nb); + cancel_delayed_work_sync(&bgrps[i]->bond_work); + complete(&bgrps[i]->bond_work_done); + remove_bond_id(bgrps[i]->bus_num, bgrps[i]->bond_id); + mutex_destroy(&bgrps[i]->bond_mutex); + kvfree(bgrps[i]); + } + return ret; +} - mutex_unlock(&bond_grp->bond_mutex); +void hns_roce_dealloc_bond_grp(void) +{ + struct hns_roce_bond_group *bond_grp; + struct hns_roce_die_info *die_info; + unsigned long id; + int i; - return true; + xa_for_each(&roce_bond_xa, id, die_info) { + for (i = 0; i < ROCE_BOND_NUM_MAX; i++) { + bond_grp = die_info->bgrps[i]; + if (!bond_grp) + continue; + unregister_netdevice_notifier(&bond_grp->bond_nb); + cancel_delayed_work_sync(&bond_grp->bond_work); + remove_bond_id(bond_grp->bus_num, bond_grp->bond_id); + mutex_destroy(&bond_grp->bond_mutex); + kvfree(bond_grp); + } + } } -static bool is_bond_setting_supported(struct netdev_lag_upper_info *bond_info) +int hns_roce_bond_init(struct hns_roce_dev *hr_dev) { - if (!bond_info) - return false; + struct net_device *net_dev = get_hr_netdev(hr_dev, 0); + struct hns_roce_v2_priv *priv = hr_dev->priv; + struct hns_roce_bond_group *bond_grp; + u8 bus_num = get_hr_bus_num(hr_dev); + int ret = 0; - if (bond_info->tx_type != NETDEV_LAG_TX_TYPE_ACTIVEBACKUP && - bond_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) - return false; + if (priv->handle->rinfo.reset_state == HNS_ROCE_STATE_RST_INIT) { + bond_grp = hns_roce_get_bond_grp(net_dev, bus_num); + if (!bond_grp) + return 0; - if (bond_info->tx_type == NETDEV_LAG_TX_TYPE_HASH && - bond_info->hash_type > NETDEV_LAG_HASH_L23) - return false; + bond_grp->main_hr_dev = hr_dev; + ret = hns_roce_recover_bond(bond_grp); + if (ret) + ibdev_err(&hr_dev->ib_dev, + "failed to recover RoCE bond, ret = %d.\n", + ret); + return ret; + } - return true; + if (!xa_load(&roce_bond_xa, bus_num)) { + ret = hns_roce_alloc_bond_grp(hr_dev); + if (ret) + ibdev_err(&hr_dev->ib_dev, + "failed to alloc RoCE bond, ret = %d.\n", + ret); + } + + return ret; } static void hns_roce_bond_info_update(struct hns_roce_bond_group *bond_grp, @@ -716,6 +708,80 @@ static void hns_roce_bond_info_update(struct hns_roce_bond_group *bond_grp, rcu_read_unlock(); } +static void hns_roce_attach_bond_grp(struct hns_roce_bond_group *bond_grp, + struct hns_roce_dev *hr_dev, + struct net_device *upper_dev) +{ + bond_grp->upper_dev = upper_dev; + bond_grp->main_hr_dev = hr_dev; + bond_grp->bond_state = HNS_ROCE_BOND_NOT_BONDED; + bond_grp->bond_ready = false; + hns_roce_bond_info_update(bond_grp, upper_dev, true); +} + +static void hns_roce_detach_bond_grp(struct hns_roce_bond_group *bond_grp) +{ + cancel_delayed_work(&bond_grp->bond_work); + bond_grp->upper_dev = NULL; + bond_grp->main_hr_dev = NULL; + bond_grp->bond_ready = false; + bond_grp->bond_state = HNS_ROCE_BOND_NOT_ATTACHED; + bond_grp->slave_map = 0; + bond_grp->slave_map_diff = 0; + memset(bond_grp->bond_func_info, 0, sizeof(bond_grp->bond_func_info)); +} + +int hns_roce_cleanup_bond(struct hns_roce_bond_group *bond_grp) +{ + int ret; + + ret = bond_grp->main_hr_dev ? + hns_roce_cmd_bond(bond_grp, HNS_ROCE_CLEAR_BOND) : -EIO; + if (ret) + BOND_ERR_LOG("failed to clear RoCE bond, ret = %d.\n", ret); + + hns_roce_detach_bond_grp(bond_grp); + complete(&bond_grp->bond_work_done); + + return ret; +} + +static bool hns_roce_bond_lowerstate_event(struct hns_roce_bond_group *bond_grp, + struct netdev_notifier_changelowerstate_info *info) +{ + struct net_device *net_dev = + netdev_notifier_info_to_dev((struct netdev_notifier_info *)info); + + if (!netif_is_lag_port(net_dev)) + return false; + + mutex_lock(&bond_grp->bond_mutex); + + if (bond_grp->bond_ready && + bond_grp->bond_state == HNS_ROCE_BOND_IS_BONDED) + bond_grp->bond_state = HNS_ROCE_BOND_SLAVE_CHANGESTATE; + + mutex_unlock(&bond_grp->bond_mutex); + + return true; +} + +static bool is_bond_setting_supported(struct netdev_lag_upper_info *bond_info) +{ + if (!bond_info) + return false; + + if (bond_info->tx_type != NETDEV_LAG_TX_TYPE_ACTIVEBACKUP && + bond_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) + return false; + + if (bond_info->tx_type == NETDEV_LAG_TX_TYPE_HASH && + bond_info->hash_type > NETDEV_LAG_HASH_L23) + return false; + + return true; +} + static bool hns_roce_bond_upper_event(struct hns_roce_bond_group *bond_grp, struct netdev_notifier_changeupper_info *info) { @@ -755,44 +821,8 @@ static bool hns_roce_bond_upper_event(struct hns_roce_bond_group *bond_grp, return changed; } -static struct hns_roce_bond_group *hns_roce_alloc_bond_grp(struct hns_roce_dev *main_hr_dev, - struct net_device *upper_dev) -{ - struct hns_roce_bond_group *bond_grp; - int ret; - - bond_grp = kzalloc(sizeof(*bond_grp), GFP_KERNEL); - if (!bond_grp) - return NULL; - - mutex_init(&bond_grp->bond_mutex); - - INIT_DELAYED_WORK(&bond_grp->bond_work, hns_roce_do_bond_work); - - init_completion(&bond_grp->bond_work_done); - - bond_grp->upper_dev = upper_dev; - bond_grp->main_hr_dev = main_hr_dev; - bond_grp->bond_ready = false; - bond_grp->bond_state = HNS_ROCE_BOND_NOT_BONDED; - bond_grp->bus_num = main_hr_dev->pci_dev->bus->number; - - ret = alloc_bond_id(bond_grp); - if (ret) { - ibdev_err(&main_hr_dev->ib_dev, - "failed to alloc bond ID, ret = %d.\n", ret); - mutex_destroy(&bond_grp->bond_mutex); - kfree(bond_grp); - return NULL; - } - - hns_roce_bond_info_update(bond_grp, upper_dev, true); - - return bond_grp; -} - static bool is_dev_bond_supported(struct hns_roce_bond_group *bond_grp, - struct net_device *net_dev, int bus_num) + struct net_device *net_dev) { struct hns_roce_dev *hr_dev = hns_roce_get_hrdev_by_netdev(net_dev); @@ -810,7 +840,7 @@ static bool is_dev_bond_supported(struct hns_roce_bond_group *bond_grp, if (hr_dev->is_vf || pci_num_vf(hr_dev->pci_dev) > 0) return false; - if (bus_num != get_hr_bus_num(hr_dev)) + if (bond_grp->bus_num != get_hr_bus_num(hr_dev)) return false; return true; @@ -833,8 +863,7 @@ static bool check_unlinking_bond_support(struct hns_roce_bond_group *bond_grp) static bool check_linking_bond_support(struct netdev_lag_upper_info *bond_info, struct hns_roce_bond_group *bond_grp, - struct net_device *upper_dev, - int bus_num) + struct net_device *upper_dev) { struct net_device *net_dev; u8 slave_num = 0; @@ -844,7 +873,7 @@ static bool check_linking_bond_support(struct netdev_lag_upper_info *bond_info, rcu_read_lock(); for_each_netdev_in_bond_rcu(upper_dev, net_dev) { - if (is_dev_bond_supported(bond_grp, net_dev, bus_num)) { + if (is_dev_bond_supported(bond_grp, net_dev)) { slave_num++; } else { rcu_read_unlock(); @@ -857,19 +886,14 @@ static bool check_linking_bond_support(struct netdev_lag_upper_info *bond_info, } static enum bond_support_type - check_bond_support(struct hns_roce_dev *hr_dev, - struct net_device **upper_dev, + check_bond_support(struct hns_roce_bond_group *bond_grp, + struct net_device *upper_dev, struct netdev_notifier_changeupper_info *info) { - struct net_device *net_dev = get_hr_netdev(hr_dev, 0); - struct hns_roce_bond_group *bond_grp; - int bus_num = get_hr_bus_num(hr_dev); bool bond_grp_exist = false; bool support; - *upper_dev = info->upper_dev; - bond_grp = hns_roce_get_bond_grp(net_dev, bus_num); - if (bond_grp && *upper_dev == bond_grp->upper_dev) + if (upper_dev == bond_grp->upper_dev) bond_grp_exist = true; if (!info->linking && !bond_grp_exist) @@ -877,7 +901,7 @@ static enum bond_support_type if (info->linking) support = check_linking_bond_support(info->upper_info, bond_grp, - *upper_dev, bus_num); + upper_dev); else support = check_unlinking_bond_support(bond_grp); @@ -887,16 +911,56 @@ static enum bond_support_type return bond_grp_exist ? BOND_EXISTING_NOT_SUPPORT : BOND_NOT_SUPPORT; } +static bool upper_event_filter(struct netdev_notifier_changeupper_info *info, + struct hns_roce_bond_group *bond_grp, + struct net_device *net_dev) +{ + struct net_device *upper_dev = info->upper_dev; + struct hns_roce_bond_group *bond_grp_tmp; + struct hns_roce_dev *hr_dev; + u8 bus_num; + + if (!info->linking) + return bond_grp->upper_dev == upper_dev; + + hr_dev = hns_roce_get_hrdev_by_netdev(net_dev); + if (!hr_dev) + return false; + + bus_num = get_hr_bus_num(hr_dev); + if (bond_grp->bus_num != bus_num) + return false; + + bond_grp_tmp = hns_roce_get_bond_grp(net_dev, bus_num); + if (bond_grp_tmp && bond_grp_tmp != bond_grp) + return false; + + if (bond_grp->bond_state != HNS_ROCE_BOND_NOT_ATTACHED && + bond_grp->upper_dev != upper_dev) + return false; + + return true; +} + +static bool lowerstate_event_filter(struct hns_roce_bond_group *bond_grp, + struct net_device *net_dev) +{ + struct hns_roce_bond_group *bond_grp_tmp; + + bond_grp_tmp = hns_roce_get_bond_grp(net_dev, bond_grp->bus_num); + return bond_grp_tmp == bond_grp; +} + int hns_roce_bond_event(struct notifier_block *self, unsigned long event, void *ptr) { + struct hns_roce_bond_group *bond_grp = + container_of(self, struct hns_roce_bond_group, bond_nb); struct net_device *net_dev = netdev_notifier_info_to_dev(ptr); - struct hns_roce_dev *hr_dev = - container_of(self, struct hns_roce_dev, bond_nb); + struct netdev_notifier_changeupper_info *info; enum bond_support_type support = BOND_SUPPORT; - struct hns_roce_bond_group *bond_grp; - u8 bus_num = get_hr_bus_num(hr_dev); struct net_device *upper_dev; + struct hns_roce_dev *hr_dev; bool changed; int slave_id; @@ -904,30 +968,27 @@ int hns_roce_bond_event(struct notifier_block *self, return NOTIFY_DONE; if (event == NETDEV_CHANGEUPPER) { - support = check_bond_support(hr_dev, &upper_dev, ptr); + if (!upper_event_filter(ptr, bond_grp, net_dev)) + return NOTIFY_DONE; + info = (struct netdev_notifier_changeupper_info *)ptr; + upper_dev = info->upper_dev; + support = check_bond_support(bond_grp, upper_dev, ptr); if (support == BOND_NOT_SUPPORT) return NOTIFY_DONE; } else { + if (!lowerstate_event_filter(bond_grp, net_dev)) + return NOTIFY_DONE; upper_dev = get_upper_dev_from_ndev(net_dev); } - if (upper_dev && !is_hrdev_bond_slave(hr_dev, upper_dev)) - return NOTIFY_DONE; - else if (!upper_dev && hr_dev != hns_roce_get_hrdev_by_netdev(net_dev)) - return NOTIFY_DONE; - - bond_grp = hns_roce_get_bond_grp(get_hr_netdev(hr_dev, 0), bus_num); if (event == NETDEV_CHANGEUPPER) { - if (!bond_grp) { - bond_grp = hns_roce_alloc_bond_grp(hr_dev, upper_dev); - if (!bond_grp) { - ibdev_err(&hr_dev->ib_dev, - "failed to alloc RoCE bond_grp!\n"); + if (bond_grp->bond_state == HNS_ROCE_BOND_NOT_ATTACHED) { + hr_dev = hns_roce_get_hrdev_by_netdev(net_dev); + if (!hr_dev) return NOTIFY_DONE; - } - } else if (hr_dev != bond_grp->main_hr_dev) { - return NOTIFY_DONE; + hns_roce_attach_bond_grp(bond_grp, hr_dev, upper_dev); } + /* In the case of netdev being unregistered, the roce * instance shouldn't be inited. */ @@ -944,7 +1005,7 @@ int hns_roce_bond_event(struct notifier_block *self, } changed = hns_roce_bond_upper_event(bond_grp, ptr); } else { - changed = hns_roce_bond_lowerstate_event(hr_dev, bond_grp, ptr); + changed = hns_roce_bond_lowerstate_event(bond_grp, ptr); } if (changed) hns_roce_queue_bond_work(bond_grp, HZ); diff --git a/drivers/infiniband/hw/hns/hns_roce_bond.h b/drivers/infiniband/hw/hns/hns_roce_bond.h index 75c9d670de7c..ba82ec12e4e5 100644 --- a/drivers/infiniband/hw/hns/hns_roce_bond.h +++ b/drivers/infiniband/hw/hns/hns_roce_bond.h @@ -33,6 +33,7 @@ enum bond_support_type { }; enum hns_roce_bond_state { + HNS_ROCE_BOND_NOT_ATTACHED, HNS_ROCE_BOND_NOT_BONDED, HNS_ROCE_BOND_IS_BONDED, HNS_ROCE_BOND_REGISTERING, @@ -72,6 +73,7 @@ struct hns_roce_bond_group { struct hns_roce_func_info bond_func_info[ROCE_BOND_FUNC_MAX]; struct delayed_work bond_work; struct completion bond_work_done; + struct notifier_block bond_nb; }; struct hns_roce_die_info { @@ -88,5 +90,6 @@ struct net_device *hns_roce_get_bond_netdev(struct hns_roce_dev *hr_dev); struct hns_roce_bond_group *hns_roce_get_bond_grp(struct net_device *net_dev, u8 bus_num); bool is_bond_slave_in_reset(struct hns_roce_bond_group *bond_grp); +void hns_roce_dealloc_bond_grp(void); #endif diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 0f1b87f8c75b..8add4742c094 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -1154,7 +1154,6 @@ struct hns_roce_dev { struct hns_roce_dev_debugfs dbgfs; atomic64_t *dfx_cnt; struct hns_roce_scc_param *scc_param; - struct notifier_block bond_nb; struct list_head mtr_unfree_list; /* list of unfree mtr on this dev */ struct mutex mtr_unfree_list_mutex; /* protect mtr_unfree_list */ diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 2568609edb60..54ea073db0d0 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -2388,6 +2388,9 @@ static int hns_roce_query_caps(struct hns_roce_dev *hr_dev) caps->flags |= le16_to_cpu(resp_d->cap_flags_ex) << HNS_ROCE_CAP_FLAGS_EX_SHIFT; + if (hr_dev->is_vf) + caps->flags &= ~HNS_ROCE_CAP_FLAG_BOND; + caps->num_cqs = 1 << hr_reg_read(resp_c, PF_CAPS_C_NUM_CQS); caps->gid_table_len[0] = hr_reg_read(resp_c, PF_CAPS_C_MAX_GID); caps->max_cqes = 1 << hr_reg_read(resp_c, PF_CAPS_C_CQ_DEPTH); @@ -7460,11 +7463,8 @@ static void hns_roce_hw_v2_uninit_instance(struct hnae3_handle *handle, if (handle->rinfo.instance_state == HNS_ROCE_STATE_BOND_UNINIT) { bond_grp = hns_roce_get_bond_grp(handle->rinfo.netdev, handle->pdev->bus->number); - if (bond_grp) { + if (bond_grp) wait_for_completion(&bond_grp->bond_work_done); - if (bond_grp->bond_state == HNS_ROCE_BOND_NOT_BONDED) - kfree(bond_grp); - } } if (handle->rinfo.instance_state != HNS_ROCE_STATE_INITED) @@ -7705,6 +7705,7 @@ static int __init hns_roce_hw_v2_init(void) static void __exit hns_roce_hw_v2_exit(void) { + hns_roce_dealloc_bond_grp(); hnae3_unregister_client(&hns_roce_hw_v2_client); hns_roce_cleanup_debugfs(); } diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 3628dbb250ab..725f2f08cb0b 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -856,7 +856,6 @@ static void hns_roce_unregister_device(struct hns_roce_dev *hr_dev, if (!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_BOND)) goto normal_unregister; - unregister_netdevice_notifier(&hr_dev->bond_nb); bond_grp = hns_roce_get_bond_grp(net_dev, bus_num); if (!bond_grp) goto normal_unregister; @@ -866,6 +865,7 @@ static void hns_roce_unregister_device(struct hns_roce_dev *hr_dev, * is unregistered, re-initialized the remaining slaves before * the bond resources cleanup. */ + cancel_delayed_work_sync(&bond_grp->bond_work); bond_grp->bond_state = HNS_ROCE_BOND_NOT_BONDED; for (i = 0; i < ROCE_BOND_FUNC_MAX; i++) { net_dev = bond_grp->bond_func_info[i].net_dev; -- 2.33.0
1 3
0 0
[PATCH openEuler-22.03-LTS-SP1] netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data registers
by Wang Hai 08 Aug '24

08 Aug '24
From: Pablo Neira Ayuso <pablo(a)netfilter.org> stable inclusion from stable-v5.10.221 commit 5d43d789b57943720dca4181a05f6477362b94cf category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAGEO4 CVE: CVE-2024-42070 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit 7931d32955e09d0a11b1fe0b6aac1bfa061c005c ] register store validation for NFT_DATA_VALUE is conditional, however, the datatype is always either NFT_DATA_VALUE or NFT_DATA_VERDICT. This only requires a new helper function to infer the register type from the set datatype so this conditional check can be removed. Otherwise, pointer to chain object can be leaked through the registers. Fixes: 96518518cc41 ("netfilter: add nftables") Reported-by: Linus Torvalds <torvalds(a)linuxfoundation.org> Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Conflicts: include/net/netfilter/nf_tables.h [just context conflict] Signed-off-by: Wang Hai <wanghai38(a)huawei.com> --- include/net/netfilter/nf_tables.h | 5 +++++ net/netfilter/nf_tables_api.c | 8 ++++---- net/netfilter/nft_lookup.c | 3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 7550328080bf..6ab0312e3f28 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -475,6 +475,11 @@ static inline void *nft_set_priv(const struct nft_set *set) return (void *)set->data; } +static inline enum nft_data_types nft_set_datatype(const struct nft_set *set) +{ + return set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE; +} + static inline struct nft_set *nft_set_container_of(const void *priv) { return (void *)priv - offsetof(struct nft_set, data); diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 990fdecca0d2..f3492376bf74 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -4896,8 +4896,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) && nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext), - set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE, - set->dlen) < 0) + nft_set_datatype(set), set->dlen) < 0) goto nla_put_failure; if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) && @@ -8841,6 +8840,9 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, return 0; default: + if (type != NFT_DATA_VALUE) + return -EINVAL; + if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE) return -EINVAL; if (len == 0) @@ -8849,8 +8851,6 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, sizeof_field(struct nft_regs, data)) return -ERANGE; - if (data != NULL && type != NFT_DATA_VALUE) - return -EINVAL; return 0; } } diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c index 8bc008ff00cb..d2f8131edaf1 100644 --- a/net/netfilter/nft_lookup.c +++ b/net/netfilter/nft_lookup.c @@ -101,7 +101,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx, return -EINVAL; err = nft_parse_register_store(ctx, tb[NFTA_LOOKUP_DREG], - &priv->dreg, NULL, set->dtype, + &priv->dreg, NULL, + nft_set_datatype(set), set->dlen); if (err < 0) return err; -- 2.17.1
2 1
0 0
[PATCH OLK-5.10] netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data registers
by Wang Hai 08 Aug '24

08 Aug '24
From: Pablo Neira Ayuso <pablo(a)netfilter.org> stable inclusion from stable-v5.10.221 commit 5d43d789b57943720dca4181a05f6477362b94cf category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAGEO4 CVE: CVE-2024-42070 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit 7931d32955e09d0a11b1fe0b6aac1bfa061c005c ] register store validation for NFT_DATA_VALUE is conditional, however, the datatype is always either NFT_DATA_VALUE or NFT_DATA_VERDICT. This only requires a new helper function to infer the register type from the set datatype so this conditional check can be removed. Otherwise, pointer to chain object can be leaked through the registers. Fixes: 96518518cc41 ("netfilter: add nftables") Reported-by: Linus Torvalds <torvalds(a)linuxfoundation.org> Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Wang Hai <wanghai38(a)huawei.com> --- include/net/netfilter/nf_tables.h | 5 +++++ net/netfilter/nf_tables_api.c | 8 ++++---- net/netfilter/nft_lookup.c | 3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 5e3529c73e61..17659138e15a 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -504,6 +504,11 @@ static inline void *nft_set_priv(const struct nft_set *set) return (void *)set->data; } +static inline enum nft_data_types nft_set_datatype(const struct nft_set *set) +{ + return set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE; +} + static inline bool nft_set_gc_is_pending(const struct nft_set *s) { return refcount_read(&s->refs) != 1; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 79fe3743502b..f990851709a3 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -5019,8 +5019,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) && nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext), - set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE, - set->dlen) < 0) + nft_set_datatype(set), set->dlen) < 0) goto nla_put_failure; if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) && @@ -9277,6 +9276,9 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, return 0; default: + if (type != NFT_DATA_VALUE) + return -EINVAL; + if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE) return -EINVAL; if (len == 0) @@ -9285,8 +9287,6 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, sizeof_field(struct nft_regs, data)) return -ERANGE; - if (data != NULL && type != NFT_DATA_VALUE) - return -EINVAL; return 0; } } diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c index c2dd1d3ac328..f6ea1b32dae1 100644 --- a/net/netfilter/nft_lookup.c +++ b/net/netfilter/nft_lookup.c @@ -101,7 +101,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx, return -EINVAL; err = nft_parse_register_store(ctx, tb[NFTA_LOOKUP_DREG], - &priv->dreg, NULL, set->dtype, + &priv->dreg, NULL, + nft_set_datatype(set), set->dlen); if (err < 0) return err; -- 2.17.1
2 1
0 0
[PATCH openEuler-1.0-LTS] netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data registers
by Wang Hai 08 Aug '24

08 Aug '24
From: Pablo Neira Ayuso <pablo(a)netfilter.org> stable inclusion from stable-v4.19.317 commit 40188a25a9847dbeb7ec67517174a835a677752f category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ CVE: CVE-2024-42070 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit 7931d32955e09d0a11b1fe0b6aac1bfa061c005c ] register store validation for NFT_DATA_VALUE is conditional, however, the datatype is always either NFT_DATA_VALUE or NFT_DATA_VERDICT. This only requires a new helper function to infer the register type from the set datatype so this conditional check can be removed. Otherwise, pointer to chain object can be leaked through the registers. Fixes: 96518518cc41 ("netfilter: add nftables") Reported-by: Linus Torvalds <torvalds(a)linuxfoundation.org> Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Conflicts: include/net/netfilter/nf_tables.h net/netfilter/nft_lookup.c [nf_tables.h conflicts due to context, nft_lookup.c conflicts because e1c59f90e1a6 ("netfilter: nftables: add nft_parse_register_store() and use it") is not merged.] Signed-off-by: Wang Hai <wanghai38(a)huawei.com> --- include/net/netfilter/nf_tables.h | 5 +++++ net/netfilter/nf_tables_api.c | 8 ++++---- net/netfilter/nft_lookup.c | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index ecc301ee1556..247e4637b458 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -438,6 +438,11 @@ static inline void *nft_set_priv(const struct nft_set *set) return (void *)set->data; } +static inline enum nft_data_types nft_set_datatype(const struct nft_set *set) +{ + return set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE; +} + static inline struct nft_set *nft_set_container_of(const void *priv) { return (void *)priv - offsetof(struct nft_set, data); diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 97e56cadb4bf..133cff3a3f77 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3961,8 +3961,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) && nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext), - set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE, - set->dlen) < 0) + nft_set_datatype(set), set->dlen) < 0) goto nla_put_failure; if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) && @@ -7174,6 +7173,9 @@ int nft_validate_register_store(const struct nft_ctx *ctx, return 0; default: + if (type != NFT_DATA_VALUE) + return -EINVAL; + if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE) return -EINVAL; if (len == 0) @@ -7182,8 +7184,6 @@ int nft_validate_register_store(const struct nft_ctx *ctx, FIELD_SIZEOF(struct nft_regs, data)) return -ERANGE; - if (data != NULL && type != NFT_DATA_VALUE) - return -EINVAL; return 0; } } diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c index cb9e937a5ce0..0d7a21ec9b11 100644 --- a/net/netfilter/nft_lookup.c +++ b/net/netfilter/nft_lookup.c @@ -102,7 +102,7 @@ static int nft_lookup_init(const struct nft_ctx *ctx, priv->dreg = nft_parse_register(tb[NFTA_LOOKUP_DREG]); err = nft_validate_register_store(ctx, priv->dreg, NULL, - set->dtype, set->dlen); + nft_set_datatype(set), set->dlen); if (err < 0) return err; } else if (set->flags & NFT_SET_MAP) -- 2.17.1
2 1
0 0
[PATCH openEuler-22.03-LTS-SP1] netfilter: nf_tables: prefer nft_chain_validate
by Wang Hai 08 Aug '24

08 Aug '24
From: Florian Westphal <fw(a)strlen.de> mainline inclusion from mainline-v6.10 commit cff3bd012a9512ac5ed858d38e6ed65f6391008c category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAGEMR CVE: CVE-2024-41042 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- nft_chain_validate already performs loop detection because a cycle will result in a call stack overflow (ctx->level >= NFT_JUMP_STACK_SIZE). It also follows maps via ->validate callback in nft_lookup, so there appears no reason to iterate the maps again. nf_tables_check_loops() and all its helper functions can be removed. This improves ruleset load time significantly, from 23s down to 12s. This also fixes a crash bug. Old loop detection code can result in unbounded recursion: BUG: TASK stack guard page was hit at .... Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN CPU: 4 PID: 1539 Comm: nft Not tainted 6.10.0-rc5+ #1 [..] with a suitable ruleset during validation of register stores. I can't see any actual reason to attempt to check for this from nft_validate_register_store(), at this point the transaction is still in progress, so we don't have a full picture of the rule graph. For nf-next it might make sense to either remove it or make this depend on table->validate_state in case we could catch an error earlier (for improved error reporting to userspace). Fixes: 20a69341f2d0 ("netfilter: nf_tables: add netlink set API") Signed-off-by: Florian Westphal <fw(a)strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org> Conflicts: net/netfilter/nf_tables_api.c [Because the deleted function had some patches that were not merged in, resulting in conflicts] Signed-off-by: Wang Hai <wanghai38(a)huawei.com> --- net/netfilter/nf_tables_api.c | 115 ++++------------------------------ 1 file changed, 13 insertions(+), 102 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 6105149b9e1a..990fdecca0d2 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3288,6 +3288,15 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r nf_tables_rule_destroy(ctx, rule); } +/** nft_chain_validate - loop detection and hook validation + * + * @ctx: context containing call depth and base chain + * @chain: chain to validate + * + * Walk through the rules of the given chain and chase all jumps/gotos + * and set lookups until either the jump limit is hit or all reachable + * chains have been validated. + */ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) { struct nft_expr *expr, *last; @@ -3306,6 +3315,9 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) if (!expr->ops->validate) continue; + /* This may call nft_chain_validate() recursively, + * callers that do so must increment ctx->level. + */ err = expr->ops->validate(ctx, expr, &data); if (err < 0) return err; @@ -8677,107 +8689,6 @@ int nft_chain_validate_hooks(const struct nft_chain *chain, } EXPORT_SYMBOL_GPL(nft_chain_validate_hooks); -/* - * Loop detection - walk through the ruleset beginning at the destination chain - * of a new jump until either the source chain is reached (loop) or all - * reachable chains have been traversed. - * - * The loop check is performed whenever a new jump verdict is added to an - * expression or verdict map or a verdict map is bound to a new chain. - */ - -static int nf_tables_check_loops(const struct nft_ctx *ctx, - const struct nft_chain *chain); - -static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx, - struct nft_set *set, - const struct nft_set_iter *iter, - struct nft_set_elem *elem) -{ - const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); - const struct nft_data *data; - - if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) && - *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END) - return 0; - - data = nft_set_ext_data(ext); - switch (data->verdict.code) { - case NFT_JUMP: - case NFT_GOTO: - return nf_tables_check_loops(ctx, data->verdict.chain); - default: - return 0; - } -} - -static int nf_tables_check_loops(const struct nft_ctx *ctx, - const struct nft_chain *chain) -{ - const struct nft_rule *rule; - const struct nft_expr *expr, *last; - struct nft_set *set; - struct nft_set_binding *binding; - struct nft_set_iter iter; - - if (ctx->chain == chain) - return -ELOOP; - - list_for_each_entry(rule, &chain->rules, list) { - nft_rule_for_each_expr(expr, last, rule) { - struct nft_immediate_expr *priv; - const struct nft_data *data; - int err; - - if (strcmp(expr->ops->type->name, "immediate")) - continue; - - priv = nft_expr_priv(expr); - if (priv->dreg != NFT_REG_VERDICT) - continue; - - data = &priv->data; - switch (data->verdict.code) { - case NFT_JUMP: - case NFT_GOTO: - err = nf_tables_check_loops(ctx, - data->verdict.chain); - if (err < 0) - return err; - break; - default: - break; - } - } - } - - list_for_each_entry(set, &ctx->table->sets, list) { - if (!nft_is_active_next(ctx->net, set)) - continue; - if (!(set->flags & NFT_SET_MAP) || - set->dtype != NFT_DATA_VERDICT) - continue; - - list_for_each_entry(binding, &set->bindings, list) { - if (!(binding->flags & NFT_SET_MAP) || - binding->chain != chain) - continue; - - iter.genmask = nft_genmask_next(ctx->net); - iter.skip = 0; - iter.count = 0; - iter.err = 0; - iter.fn = nf_tables_loop_check_setelem; - - set->ops->walk(ctx, set, &iter); - if (iter.err < 0) - return iter.err; - } - } - - return 0; -} - /** * nft_parse_u32_check - fetch u32 attribute and check for maximum value * @@ -8923,7 +8834,7 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, if (data != NULL && (data->verdict.code == NFT_GOTO || data->verdict.code == NFT_JUMP)) { - err = nf_tables_check_loops(ctx, data->verdict.chain); + err = nft_chain_validate(ctx, data->verdict.chain); if (err < 0) return err; } -- 2.17.1
2 1
0 0
[PATCH OLK-6.6] netfilter: nf_tables: prefer nft_chain_validate
by Wang Hai 08 Aug '24

08 Aug '24
From: Florian Westphal <fw(a)strlen.de> mainline inclusion from mainline-v6.10 commit cff3bd012a9512ac5ed858d38e6ed65f6391008c category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAGEMR CVE: CVE-2024-41042 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- nft_chain_validate already performs loop detection because a cycle will result in a call stack overflow (ctx->level >= NFT_JUMP_STACK_SIZE). It also follows maps via ->validate callback in nft_lookup, so there appears no reason to iterate the maps again. nf_tables_check_loops() and all its helper functions can be removed. This improves ruleset load time significantly, from 23s down to 12s. This also fixes a crash bug. Old loop detection code can result in unbounded recursion: BUG: TASK stack guard page was hit at .... Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN CPU: 4 PID: 1539 Comm: nft Not tainted 6.10.0-rc5+ #1 [..] with a suitable ruleset during validation of register stores. I can't see any actual reason to attempt to check for this from nft_validate_register_store(), at this point the transaction is still in progress, so we don't have a full picture of the rule graph. For nf-next it might make sense to either remove it or make this depend on table->validate_state in case we could catch an error earlier (for improved error reporting to userspace). Fixes: 20a69341f2d0 ("netfilter: nf_tables: add netlink set API") Signed-off-by: Florian Westphal <fw(a)strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org> Conflicts: net/netfilter/nf_tables_api.c [Because the deleted function had some patches that were not merged in, resulting in conflicts] Signed-off-by: Wang Hai <wanghai38(a)huawei.com> --- net/netfilter/nf_tables_api.c | 154 +++------------------------------- 1 file changed, 13 insertions(+), 141 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index dd044a47c872..ea139fca74cb 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3743,6 +3743,15 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r nf_tables_rule_destroy(ctx, rule); } +/** nft_chain_validate - loop detection and hook validation + * + * @ctx: context containing call depth and base chain + * @chain: chain to validate + * + * Walk through the rules of the given chain and chase all jumps/gotos + * and set lookups until either the jump limit is hit or all reachable + * chains have been validated. + */ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) { struct nft_expr *expr, *last; @@ -3764,6 +3773,9 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) if (!expr->ops->validate) continue; + /* This may call nft_chain_validate() recursively, + * callers that do so must increment ctx->level. + */ err = expr->ops->validate(ctx, expr, &data); if (err < 0) return err; @@ -10621,146 +10633,6 @@ int nft_chain_validate_hooks(const struct nft_chain *chain, } EXPORT_SYMBOL_GPL(nft_chain_validate_hooks); -/* - * Loop detection - walk through the ruleset beginning at the destination chain - * of a new jump until either the source chain is reached (loop) or all - * reachable chains have been traversed. - * - * The loop check is performed whenever a new jump verdict is added to an - * expression or verdict map or a verdict map is bound to a new chain. - */ - -static int nf_tables_check_loops(const struct nft_ctx *ctx, - const struct nft_chain *chain); - -static int nft_check_loops(const struct nft_ctx *ctx, - const struct nft_set_ext *ext) -{ - const struct nft_data *data; - int ret; - - data = nft_set_ext_data(ext); - switch (data->verdict.code) { - case NFT_JUMP: - case NFT_GOTO: - ret = nf_tables_check_loops(ctx, data->verdict.chain); - break; - default: - ret = 0; - break; - } - - return ret; -} - -static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx, - struct nft_set *set, - const struct nft_set_iter *iter, - struct nft_set_elem *elem) -{ - const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); - - if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) && - *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END) - return 0; - - return nft_check_loops(ctx, ext); -} - -static int nft_set_catchall_loops(const struct nft_ctx *ctx, - struct nft_set *set) -{ - u8 genmask = nft_genmask_next(ctx->net); - struct nft_set_elem_catchall *catchall; - struct nft_set_ext *ext; - int ret = 0; - - list_for_each_entry_rcu(catchall, &set->catchall_list, list) { - ext = nft_set_elem_ext(set, catchall->elem); - if (!nft_set_elem_active(ext, genmask)) - continue; - - ret = nft_check_loops(ctx, ext); - if (ret < 0) - return ret; - } - - return ret; -} - -static int nf_tables_check_loops(const struct nft_ctx *ctx, - const struct nft_chain *chain) -{ - const struct nft_rule *rule; - const struct nft_expr *expr, *last; - struct nft_set *set; - struct nft_set_binding *binding; - struct nft_set_iter iter; - - if (ctx->chain == chain) - return -ELOOP; - - if (fatal_signal_pending(current)) - return -EINTR; - - list_for_each_entry(rule, &chain->rules, list) { - nft_rule_for_each_expr(expr, last, rule) { - struct nft_immediate_expr *priv; - const struct nft_data *data; - int err; - - if (strcmp(expr->ops->type->name, "immediate")) - continue; - - priv = nft_expr_priv(expr); - if (priv->dreg != NFT_REG_VERDICT) - continue; - - data = &priv->data; - switch (data->verdict.code) { - case NFT_JUMP: - case NFT_GOTO: - err = nf_tables_check_loops(ctx, - data->verdict.chain); - if (err < 0) - return err; - break; - default: - break; - } - } - } - - list_for_each_entry(set, &ctx->table->sets, list) { - if (!nft_is_active_next(ctx->net, set)) - continue; - if (!(set->flags & NFT_SET_MAP) || - set->dtype != NFT_DATA_VERDICT) - continue; - - list_for_each_entry(binding, &set->bindings, list) { - if (!(binding->flags & NFT_SET_MAP) || - binding->chain != chain) - continue; - - iter.genmask = nft_genmask_next(ctx->net); - iter.skip = 0; - iter.count = 0; - iter.err = 0; - iter.fn = nf_tables_loop_check_setelem; - - set->ops->walk(ctx, set, &iter); - if (!iter.err) - iter.err = nft_set_catchall_loops(ctx, set); - - if (iter.err < 0) - return iter.err; - } - } - - return 0; -} - /** * nft_parse_u32_check - fetch u32 attribute and check for maximum value * @@ -10873,7 +10745,7 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, if (data != NULL && (data->verdict.code == NFT_GOTO || data->verdict.code == NFT_JUMP)) { - err = nf_tables_check_loops(ctx, data->verdict.chain); + err = nft_chain_validate(ctx, data->verdict.chain); if (err < 0) return err; } -- 2.17.1
2 1
0 0
[PATCH OLK-5.10] netfilter: nf_tables: prefer nft_chain_validate
by Wang Hai 08 Aug '24

08 Aug '24
From: Florian Westphal <fw(a)strlen.de> mainline inclusion from mainline-v6.10 commit cff3bd012a9512ac5ed858d38e6ed65f6391008c category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAGEMR CVE: CVE-2024-41042 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- nft_chain_validate already performs loop detection because a cycle will result in a call stack overflow (ctx->level >= NFT_JUMP_STACK_SIZE). It also follows maps via ->validate callback in nft_lookup, so there appears no reason to iterate the maps again. nf_tables_check_loops() and all its helper functions can be removed. This improves ruleset load time significantly, from 23s down to 12s. This also fixes a crash bug. Old loop detection code can result in unbounded recursion: BUG: TASK stack guard page was hit at .... Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN CPU: 4 PID: 1539 Comm: nft Not tainted 6.10.0-rc5+ #1 [..] with a suitable ruleset during validation of register stores. I can't see any actual reason to attempt to check for this from nft_validate_register_store(), at this point the transaction is still in progress, so we don't have a full picture of the rule graph. For nf-next it might make sense to either remove it or make this depend on table->validate_state in case we could catch an error earlier (for improved error reporting to userspace). Fixes: 20a69341f2d0 ("netfilter: nf_tables: add netlink set API") Signed-off-by: Florian Westphal <fw(a)strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org> Conflicts: net/netfilter/nf_tables_api.c [Because the deleted function had some patches that were not merged in, resulting in conflicts] Signed-off-by: Wang Hai <wanghai38(a)huawei.com> --- net/netfilter/nf_tables_api.c | 131 ++++------------------------------ 1 file changed, 13 insertions(+), 118 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 09e7a123c16c..79fe3743502b 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3355,6 +3355,15 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r nf_tables_rule_destroy(ctx, rule); } +/** nft_chain_validate - loop detection and hook validation + * + * @ctx: context containing call depth and base chain + * @chain: chain to validate + * + * Walk through the rules of the given chain and chase all jumps/gotos + * and set lookups until either the jump limit is hit or all reachable + * chains have been validated. + */ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) { struct nft_expr *expr, *last; @@ -3373,6 +3382,9 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) if (!expr->ops->validate) continue; + /* This may call nft_chain_validate() recursively, + * callers that do so must increment ctx->level. + */ err = expr->ops->validate(ctx, expr, &data); if (err < 0) return err; @@ -9113,123 +9125,6 @@ int nft_chain_validate_hooks(const struct nft_chain *chain, } EXPORT_SYMBOL_GPL(nft_chain_validate_hooks); -/* - * Loop detection - walk through the ruleset beginning at the destination chain - * of a new jump until either the source chain is reached (loop) or all - * reachable chains have been traversed. - * - * The loop check is performed whenever a new jump verdict is added to an - * expression or verdict map or a verdict map is bound to a new chain. - */ - -static int nf_tables_check_loops(const struct nft_ctx *ctx, - const struct nft_chain *chain); - -static int nft_check_loops(const struct nft_ctx *ctx, - const struct nft_set_ext *ext) -{ - const struct nft_data *data; - int ret; - - data = nft_set_ext_data(ext); - switch (data->verdict.code) { - case NFT_JUMP: - case NFT_GOTO: - ret = nf_tables_check_loops(ctx, data->verdict.chain); - break; - default: - ret = 0; - break; - } - - return ret; -} - -static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx, - struct nft_set *set, - const struct nft_set_iter *iter, - struct nft_set_elem *elem) -{ - const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); - - if (!nft_set_elem_active(ext, iter->genmask)) - return 0; - - if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) && - *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END) - return 0; - - return nft_check_loops(ctx, ext); -} - -static int nf_tables_check_loops(const struct nft_ctx *ctx, - const struct nft_chain *chain) -{ - const struct nft_rule *rule; - const struct nft_expr *expr, *last; - struct nft_set *set; - struct nft_set_binding *binding; - struct nft_set_iter iter; - - if (ctx->chain == chain) - return -ELOOP; - - list_for_each_entry(rule, &chain->rules, list) { - nft_rule_for_each_expr(expr, last, rule) { - struct nft_immediate_expr *priv; - const struct nft_data *data; - int err; - - if (strcmp(expr->ops->type->name, "immediate")) - continue; - - priv = nft_expr_priv(expr); - if (priv->dreg != NFT_REG_VERDICT) - continue; - - data = &priv->data; - switch (data->verdict.code) { - case NFT_JUMP: - case NFT_GOTO: - err = nf_tables_check_loops(ctx, - data->verdict.chain); - if (err < 0) - return err; - break; - default: - break; - } - } - } - - list_for_each_entry(set, &ctx->table->sets, list) { - if (!nft_is_active_next(ctx->net, set)) - continue; - if (!(set->flags & NFT_SET_MAP) || - set->dtype != NFT_DATA_VERDICT) - continue; - - list_for_each_entry(binding, &set->bindings, list) { - if (!(binding->flags & NFT_SET_MAP) || - binding->chain != chain) - continue; - - iter.genmask = nft_genmask_next(ctx->net); - iter.type = NFT_ITER_UPDATE; - iter.skip = 0; - iter.count = 0; - iter.err = 0; - iter.fn = nf_tables_loop_check_setelem; - - set->ops->walk(ctx, set, &iter); - if (iter.err < 0) - return iter.err; - } - } - - return 0; -} - /** * nft_parse_u32_check - fetch u32 attribute and check for maximum value * @@ -9375,7 +9270,7 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, if (data != NULL && (data->verdict.code == NFT_GOTO || data->verdict.code == NFT_JUMP)) { - err = nf_tables_check_loops(ctx, data->verdict.chain); + err = nft_chain_validate(ctx, data->verdict.chain); if (err < 0) return err; } -- 2.17.1
2 1
0 0
[PATCH openEuler-1.0-LTS] ALSA: gus: fix null pointer dereference on pointer block
by Kaixiong Yu 08 Aug '24

08 Aug '24
From: Chengfeng Ye <cyeaa(a)connect.ust.hk> stable inclusion from stable-v4.19.218 commit ab4c1ebc40f699f48346f634d7b72b9c5193f315 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9FNFE CVE: CVE-2021-47207 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit a0d21bb3279476c777434c40d969ea88ca64f9aa ] The pointer block return from snd_gf1_dma_next_block could be null, so there is a potential null pointer dereference issue. Fix this by adding a null check before dereference. Signed-off-by: Chengfeng Ye <cyeaa(a)connect.ust.hk> Link: https://lore.kernel.org/r/20211024104611.9919-1-cyeaa@connect.ust.hk Signed-off-by: Takashi Iwai <tiwai(a)suse.de> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Kaixiong Yu <yukaixiong(a)huawei.com> --- sound/isa/gus/gus_dma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c index 7f95f452f106..48e76b8fede4 100644 --- a/sound/isa/gus/gus_dma.c +++ b/sound/isa/gus/gus_dma.c @@ -141,6 +141,8 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus) } block = snd_gf1_dma_next_block(gus); spin_unlock(&gus->dma_lock); + if (!block) + return; snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd); kfree(block); #if 0 -- 2.25.1
2 1
0 0
[PATCH openEuler-22.03-LTS-SP1] bnx2x: Fix multiple UBSAN array-index-out-of-bounds
by Wang Hai 08 Aug '24

08 Aug '24
From: Ghadi Elie Rahme <ghadi.rahme(a)canonical.com> stable inclusion from stable-v5.10.222 commit 8b17cec33892a66bbd71f8d9a70a45e2072ae84f category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAGPSP CVE: CVE-2024-42148 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- commit 134061163ee5ca4759de5c24ca3bd71608891ba7 upstream. Fix UBSAN warnings that occur when using a system with 32 physical cpu cores or more, or when the user defines a number of Ethernet queues greater than or equal to FP_SB_MAX_E1x using the num_queues module parameter. Currently there is a read/write out of bounds that occurs on the array "struct stats_query_entry query" present inside the "bnx2x_fw_stats_req" struct in "drivers/net/ethernet/broadcom/bnx2x/bnx2x.h". Looking at the definition of the "struct stats_query_entry query" array: struct stats_query_entry query[FP_SB_MAX_E1x+ BNX2X_FIRST_QUEUE_QUERY_IDX]; FP_SB_MAX_E1x is defined as the maximum number of fast path interrupts and has a value of 16, while BNX2X_FIRST_QUEUE_QUERY_IDX has a value of 3 meaning the array has a total size of 19. Since accesses to "struct stats_query_entry query" are offset-ted by BNX2X_FIRST_QUEUE_QUERY_IDX, that means that the total number of Ethernet queues should not exceed FP_SB_MAX_E1x (16). However one of these queues is reserved for FCOE and thus the number of Ethernet queues should be set to [FP_SB_MAX_E1x -1] (15) if FCOE is enabled or [FP_SB_MAX_E1x] (16) if it is not. This is also described in a comment in the source code in drivers/net/ethernet/broadcom/bnx2x/bnx2x.h just above the Macro definition of FP_SB_MAX_E1x. Below is the part of this explanation that it important for this patch /* * The total number of L2 queues, MSIX vectors and HW contexts (CIDs) is * control by the number of fast-path status blocks supported by the * device (HW/FW). Each fast-path status block (FP-SB) aka non-default * status block represents an independent interrupts context that can * serve a regular L2 networking queue. However special L2 queues such * as the FCoE queue do not require a FP-SB and other components like * the CNIC may consume FP-SB reducing the number of possible L2 queues * * If the maximum number of FP-SB available is X then: * a. If CNIC is supported it consumes 1 FP-SB thus the max number of * regular L2 queues is Y=X-1 * b. In MF mode the actual number of L2 queues is Y= (X-1/MF_factor) * c. If the FCoE L2 queue is supported the actual number of L2 queues * is Y+1 * d. The number of irqs (MSIX vectors) is either Y+1 (one extra for * slow-path interrupts) or Y+2 if CNIC is supported (one additional * FP interrupt context for the CNIC). * e. The number of HW context (CID count) is always X or X+1 if FCoE * L2 queue is supported. The cid for the FCoE L2 queue is always X. */ However this driver also supports NICs that use the E2 controller which can handle more queues due to having more FP-SB represented by FP_SB_MAX_E2. Looking at the commits when the E2 support was added, it was originally using the E1x parameters: commit f2e0899f0f27 ("bnx2x: Add 57712 support"). Back then FP_SB_MAX_E2 was set to 16 the same as E1x. However the driver was later updated to take full advantage of the E2 instead of having it be limited to the capabilities of the E1x. But as far as we can tell, the array "stats_query_entry query" was still limited to using the FP-SB available to the E1x cards as part of an oversignt when the driver was updated to take full advantage of the E2, and now with the driver being aware of the greater queue size supported by E2 NICs, it causes the UBSAN warnings seen in the stack traces below. This patch increases the size of the "stats_query_entry query" array by replacing FP_SB_MAX_E1x with FP_SB_MAX_E2 to be large enough to handle both types of NICs. Stack traces: UBSAN: array-index-out-of-bounds in drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c:1529:11 index 20 is out of range for type 'stats_query_entry [19]' CPU: 12 PID: 858 Comm: systemd-network Not tainted 6.9.0-060900rc7-generic #202405052133 Hardware name: HP ProLiant DL360 Gen9/ProLiant DL360 Gen9, BIOS P89 10/21/2019 Call Trace: <TASK> dump_stack_lvl+0x76/0xa0 dump_stack+0x10/0x20 __ubsan_handle_out_of_bounds+0xcb/0x110 bnx2x_prep_fw_stats_req+0x2e1/0x310 [bnx2x] bnx2x_stats_init+0x156/0x320 [bnx2x] bnx2x_post_irq_nic_init+0x81/0x1a0 [bnx2x] bnx2x_nic_load+0x8e8/0x19e0 [bnx2x] bnx2x_open+0x16b/0x290 [bnx2x] __dev_open+0x10e/0x1d0 RIP: 0033:0x736223927a0a Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3 0f 1e fa 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 15 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 7e c3 0f 1f 44 00 00 41 54 48 83 ec 30 44 89 RSP: 002b:00007ffc0bb2ada8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 0000583df50f9c78 RCX: 0000736223927a0a RDX: 0000000000000020 RSI: 0000583df50ee510 RDI: 0000000000000003 RBP: 0000583df50d4940 R08: 00007ffc0bb2adb0 R09: 0000000000000080 R10: 0000000000000000 R11: 0000000000000246 R12: 0000583df5103ae0 R13: 000000000000035a R14: 0000583df50f9c30 R15: 0000583ddddddf00 </TASK> ---[ end trace ]--- ------------[ cut here ]------------ UBSAN: array-index-out-of-bounds in drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c:1546:11 index 28 is out of range for type 'stats_query_entry [19]' CPU: 12 PID: 858 Comm: systemd-network Not tainted 6.9.0-060900rc7-generic #202405052133 Hardware name: HP ProLiant DL360 Gen9/ProLiant DL360 Gen9, BIOS P89 10/21/2019 Call Trace: <TASK> dump_stack_lvl+0x76/0xa0 dump_stack+0x10/0x20 __ubsan_handle_out_of_bounds+0xcb/0x110 bnx2x_prep_fw_stats_req+0x2fd/0x310 [bnx2x] bnx2x_stats_init+0x156/0x320 [bnx2x] bnx2x_post_irq_nic_init+0x81/0x1a0 [bnx2x] bnx2x_nic_load+0x8e8/0x19e0 [bnx2x] bnx2x_open+0x16b/0x290 [bnx2x] __dev_open+0x10e/0x1d0 RIP: 0033:0x736223927a0a Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3 0f 1e fa 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 15 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 7e c3 0f 1f 44 00 00 41 54 48 83 ec 30 44 89 RSP: 002b:00007ffc0bb2ada8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 0000583df50f9c78 RCX: 0000736223927a0a RDX: 0000000000000020 RSI: 0000583df50ee510 RDI: 0000000000000003 RBP: 0000583df50d4940 R08: 00007ffc0bb2adb0 R09: 0000000000000080 R10: 0000000000000000 R11: 0000000000000246 R12: 0000583df5103ae0 R13: 000000000000035a R14: 0000583df50f9c30 R15: 0000583ddddddf00 </TASK> ---[ end trace ]--- ------------[ cut here ]------------ UBSAN: array-index-out-of-bounds in drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c:1895:8 index 29 is out of range for type 'stats_query_entry [19]' CPU: 13 PID: 163 Comm: kworker/u96:1 Not tainted 6.9.0-060900rc7-generic #202405052133 Hardware name: HP ProLiant DL360 Gen9/ProLiant DL360 Gen9, BIOS P89 10/21/2019 Workqueue: bnx2x bnx2x_sp_task [bnx2x] Call Trace: <TASK> dump_stack_lvl+0x76/0xa0 dump_stack+0x10/0x20 __ubsan_handle_out_of_bounds+0xcb/0x110 bnx2x_iov_adjust_stats_req+0x3c4/0x3d0 [bnx2x] bnx2x_storm_stats_post.part.0+0x4a/0x330 [bnx2x] ? bnx2x_hw_stats_post+0x231/0x250 [bnx2x] bnx2x_stats_start+0x44/0x70 [bnx2x] bnx2x_stats_handle+0x149/0x350 [bnx2x] bnx2x_attn_int_asserted+0x998/0x9b0 [bnx2x] bnx2x_sp_task+0x491/0x5c0 [bnx2x] process_one_work+0x18d/0x3f0 </TASK> ---[ end trace ]--- Fixes: 50f0a562f8cc ("bnx2x: add fcoe statistics") Signed-off-by: Ghadi Elie Rahme <ghadi.rahme(a)canonical.com> Cc: stable(a)vger.kernel.org Link: https://patch.msgid.link/20240627111405.1037812-1-ghadi.rahme@canonical.com Signed-off-by: Jakub Kicinski <kuba(a)kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Signed-off-by: Wang Hai <wanghai38(a)huawei.com> --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 2a61229d3f97..c1fe9bcbb955 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1262,7 +1262,7 @@ enum { struct bnx2x_fw_stats_req { struct stats_query_header hdr; - struct stats_query_entry query[FP_SB_MAX_E1x+ + struct stats_query_entry query[FP_SB_MAX_E2 + BNX2X_FIRST_QUEUE_QUERY_IDX]; }; -- 2.17.1
2 1
0 0
  • ← Newer
  • 1
  • ...
  • 777
  • 778
  • 779
  • 780
  • 781
  • 782
  • 783
  • ...
  • 1950
  • Older →

HyperKitty Powered by HyperKitty