lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aJNEXjmbpTryJiBJ@soc-5CG4396X81.clients.intel.com>
Date: Wed, 6 Aug 2025 14:02:38 +0200
From: Larysa Zaremba <larysa.zaremba@...el.com>
To: Tatyana Nikolova <tatyana.e.nikolova@...el.com>,
	<anthony.l.nguyen@...el.com>
CC: <intel-wired-lan@...ts.osuosl.org>, <jgg@...dia.com>, <leon@...nel.org>,
	<linux-rdma@...r.kernel.org>, <netdev@...r.kernel.org>, <kuba@...nel.org>,
	Joshua Hay <joshua.a.hay@...el.com>
Subject: Re: [iwl-next v2 2/6] idpf: implement core RDMA auxiliary dev
 create, init, and destroy

On Thu, Jun 12, 2025 at 04:59:58PM -0500, Tatyana Nikolova wrote:
> From: Joshua Hay <joshua.a.hay@...el.com>
> 
> Add the initial idpf_idc.c file with the functions to kick off the IDC
> initialization, create and initialize a core RDMA auxiliary device, and
> destroy said device.
> 
> The RDMA core has a dependency on the vports being created by the
> control plane before it can be initialized. Therefore, once all the
> vports are up after a hard reset (either during driver load a function
> level reset), the core RDMA device info will be created. It is populated
> with the function type (as distinguished by the IDC initialization
> function pointer), the core idc_ops function points (just stubs for
> now), the reserved RDMA MSIX table, and various other info the core RDMA
> auxiliary driver will need. It is then plugged on to the bus.
> 
> During a function level reset or driver unload, the device will be
> unplugged from the bus and destroyed.

Hello,

I am developing some changes using the current dev-queue and have noticed the 
following KASAN warning when doing rmmod idpf without any of my changes on top.

[  +6.231036] ==================================================================
[  +0.000065] BUG: KASAN: slab-use-after-free in idpf_idc_deinit_core_aux_device+0xf5/0x110 [idpf]
[  +0.000059] Read of size 4 at addr ff11001086758ae8 by task rmmod/2025

[  +0.000046] CPU: 40 UID: 0 PID: 2025 Comm: rmmod Not tainted 6.16.0-korg-netnext-standard+ #30 PREEMPT(full)
[  +0.000010] Hardware name: Intel Corporation M50CYP2SBSTD/M50CYP2SBSTD, BIOS SE5C620.86B.01.01.0008.2305172341 05/17/2023
[  +0.000005] Call Trace:
[  +0.000003]  <TASK>
[  +0.000003]  dump_stack_lvl+0x5f/0x80
[  +0.000016]  print_report+0xd1/0x640
[  +0.000014]  ? __pfx__raw_spin_lock_irqsave+0x10/0x10
[  +0.000012]  ? kasan_complete_mode_report_info+0x64/0x200
[  +0.000009]  kasan_report+0xe5/0x120
[  +0.000007]  ? idpf_idc_deinit_core_aux_device+0xf5/0x110 [idpf]
[  +0.000017]  ? idpf_idc_deinit_core_aux_device+0xf5/0x110 [idpf]
[  +0.000016]  __asan_report_load4_noabort+0x18/0x20
[  +0.000010]  idpf_idc_deinit_core_aux_device+0xf5/0x110 [idpf]
[  +0.000014]  idpf_vc_core_deinit+0xbf/0x3a0 [idpf]
[  +0.000019]  idpf_remove+0xb0/0x7f0 [idpf]
[  +0.000017]  ? __kasan_check_write+0x18/0x20
[  +0.000009]  pci_device_remove+0xad/0x1d0
[  +0.000013]  device_remove+0xc4/0x170
[  +0.000012]  device_release_driver_internal+0x37e/0x540
[  +0.000011]  driver_detach+0xc7/0x1a0
[  +0.000008]  bus_remove_driver+0x127/0x2a0
[  +0.000008]  driver_unregister+0x71/0xa0
[  +0.000008]  pci_unregister_driver+0x2d/0x250
[  +0.000009]  idpf_driver_exit+0x14/0xe60 [idpf]
[  +0.000014]  __do_sys_delete_module.isra.0+0x2b7/0x500
[  +0.000012]  ? __pfx___do_sys_delete_module.isra.0+0x10/0x10
[  +0.000011]  __x64_sys_delete_module+0x35/0x50
[  +0.000008]  x64_sys_call+0x5c3/0x20d0
[  +0.000011]  do_syscall_64+0x7a/0x320
[  +0.000008]  ? clear_bhb_loop+0x60/0xb0
[  +0.000006]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  +0.000006] RIP: 0033:0x7f6c41b34abb
[  +0.000015] Code: 73 01 c3 48 8b 0d 55 13 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 b0 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 25 13 0c 00 f7 d8 64 89 01 48
[  +0.000006] RSP: 002b:00007ffe4797b118 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0
[  +0.000010] RAX: ffffffffffffffda RBX: 000055cbd564f700 RCX: 00007f6c41b34abb
[  +0.000005] RDX: 0000000000000000 RSI: 0000000000000800 RDI: 000055cbd564f768
[  +0.000004] RBP: 00007ffe4797b140 R08: 1999999999999999 R09: 0000000000000000
[  +0.000005] R10: 00007f6c41ba5ac0 R11: 0000000000000206 R12: 0000000000000000
[  +0.000004] R13: 00007ffe4797b3a0 R14: 000055cbd564f700 R15: 0000000000000000
[  +0.000007]  </TASK>

[  +0.008179] Allocated by task 416:
[  +0.001205]  kasan_save_stack+0x3d/0x60
[  +0.000021]  kasan_save_track+0x18/0x40
[  +0.000011]  kasan_save_alloc_info+0x3b/0x50
[  +0.000013]  __kasan_kmalloc+0xb7/0xc0
[  +0.000010]  __kmalloc_cache_noprof+0x1ca/0x450
[  +0.000016]  idpf_idc_init_aux_core_dev+0x4f9/0xc80 [idpf]
[  +0.000027]  idpf_idc_register+0x14/0x20 [idpf]
[  +0.000025]  idpf_idc_init+0x5c/0xd0 [idpf]
[  +0.000025]  idpf_vc_event_task+0x658/0xdd0 [idpf]
[  +0.000026]  process_one_work+0x67b/0x1030
[  +0.000014]  worker_thread+0x65b/0xf40
[  +0.000009]  kthread+0x3a3/0x860
[  +0.000010]  ret_from_fork+0x24c/0x420
[  +0.000016]  ret_from_fork_asm+0x1a/0x30

[  +0.001183] Freed by task 2025:
[  +0.001070]  kasan_save_stack+0x3d/0x60
[  +0.000010]  kasan_save_track+0x18/0x40
[  +0.000007]  kasan_save_free_info+0x3f/0x60
[  +0.000008]  __kasan_slab_free+0x56/0x70
[  +0.000007]  kfree+0x12a/0x3d0
[  +0.000010]  idpf_core_adev_release+0x12/0x20 [idpf]
[  +0.000017]  device_release+0xa1/0x220
[  +0.000010]  kobject_put+0x18e/0x4f0
[  +0.000013]  put_device+0x17/0x30
[  +0.000006]  idpf_idc_deinit_core_aux_device+0x54/0x110 [idpf]
[  +0.000016]  idpf_vc_core_deinit+0xbf/0x3a0 [idpf]
[  +0.000018]  idpf_remove+0xb0/0x7f0 [idpf]
[  +0.000017]  pci_device_remove+0xad/0x1d0
[  +0.000011]  device_remove+0xc4/0x170
[  +0.000010]  device_release_driver_internal+0x37e/0x540
[  +0.000009]  driver_detach+0xc7/0x1a0
[  +0.000007]  bus_remove_driver+0x127/0x2a0
[  +0.000007]  driver_unregister+0x71/0xa0
[  +0.000008]  pci_unregister_driver+0x2d/0x250
[  +0.000008]  idpf_driver_exit+0x14/0xe60 [idpf]
[  +0.000017]  __do_sys_delete_module.isra.0+0x2b7/0x500
[  +0.000012]  __x64_sys_delete_module+0x35/0x50
[  +0.000008]  x64_sys_call+0x5c3/0x20d0
[  +0.000010]  do_syscall_64+0x7a/0x320
[  +0.000010]  entry_SYSCALL_64_after_hwframe+0x76/0x7e

[  +0.000749] The buggy address belongs to the object at ff11001086758800
               which belongs to the cache kmalloc-1k of size 1024
[  +0.001509] The buggy address is located 744 bytes inside of
               freed 1024-byte region [ff11001086758800, ff11001086758c00)

[  +0.002163] The buggy address belongs to the physical page:
[  +0.000739] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1086758
[  +0.000010] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
[  +0.000006] flags: 0x6fffc0000000040(head|node=1|zone=2|lastcpupid=0x3fff)
[  +0.000009] page_type: f5(slab)
[  +0.000009] raw: 06fffc0000000040 ff11000100038dc0 dead000000000122 0000000000000000
[  +0.000007] raw: 0000000000000000 0000000080100010 00000000f5000000 0000000000000000
[  +0.000006] head: 06fffc0000000040 ff11000100038dc0 dead000000000122 0000000000000000
[  +0.000006] head: 0000000000000000 0000000080100010 00000000f5000000 0000000000000000
[  +0.000006] head: 06fffc0000000003 ffd400004219d601 00000000ffffffff 00000000ffffffff
[  +0.000006] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
[  +0.000004] page dumped because: kasan: bad access detected

[  +0.000732] Memory state around the buggy address:
[  +0.000744]  ff11001086758980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  +0.000764]  ff11001086758a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  +0.000750] >ff11001086758a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  +0.000735]                                                           ^
[  +0.000756]  ff11001086758b00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  +0.000641]  ff11001086758b80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  +0.000513] ==================================================================
[  +0.001104] Disabling lock debugging due to kernel taint

> 
> Reviewed-by: Madhu Chittim <madhu.chittim@...el.com>
> Signed-off-by: Joshua Hay <joshua.a.hay@...el.com>
> Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@...el.com>
> ---
> 
> v2:
> - initialize cdev_info earlier to properly free it in error path
> 
> Changes since split (v1):
> - replace core dev_ops with exported symbols
> - align with new header split scheme (idc_rdma->iidc_rdma and
>   iidc_rdma_idpf specific header)
> 
> [3]:
> - use signed ret value from ida_alloc and only assign
>   unsigned id if no err
> - capitalize some abbreviations
> - add missing field descriptions
> 
>  drivers/net/ethernet/intel/idpf/Makefile      |   1 +
>  drivers/net/ethernet/intel/idpf/idpf.h        |  11 +
>  drivers/net/ethernet/intel/idpf/idpf_dev.c    |  13 +
>  drivers/net/ethernet/intel/idpf/idpf_idc.c    | 223 ++++++++++++++++++
>  drivers/net/ethernet/intel/idpf/idpf_lib.c    |   4 +
>  drivers/net/ethernet/intel/idpf/idpf_vf_dev.c |  13 +
>  .../net/ethernet/intel/idpf/idpf_virtchnl.c   |  20 ++
>  .../net/ethernet/intel/idpf/idpf_virtchnl.h   |   3 +
>  include/linux/net/intel/iidc_rdma_idpf.h      |  28 +++
>  9 files changed, 316 insertions(+)
>  create mode 100644 drivers/net/ethernet/intel/idpf/idpf_idc.c
>  create mode 100644 include/linux/net/intel/iidc_rdma_idpf.h
> 
> diff --git a/drivers/net/ethernet/intel/idpf/Makefile b/drivers/net/ethernet/intel/idpf/Makefile
> index 83ac5e296382..4ef4b2b5e37a 100644
> --- a/drivers/net/ethernet/intel/idpf/Makefile
> +++ b/drivers/net/ethernet/intel/idpf/Makefile
> @@ -10,6 +10,7 @@ idpf-y := \
>  	idpf_controlq_setup.o	\
>  	idpf_dev.o		\
>  	idpf_ethtool.o		\
> +	idpf_idc.o		\
>  	idpf_lib.o		\
>  	idpf_main.o		\
>  	idpf_txrx.o		\
> diff --git a/drivers/net/ethernet/intel/idpf/idpf.h b/drivers/net/ethernet/intel/idpf/idpf.h
> index d9f06764aba0..6b1cc55e34a3 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf.h
> +++ b/drivers/net/ethernet/intel/idpf/idpf.h
> @@ -17,6 +17,8 @@ struct idpf_vport_max_q;
>  #include <linux/sctp.h>
>  #include <linux/ethtool_netlink.h>
>  #include <net/gro.h>
> +#include <linux/net/intel/iidc_rdma.h>
> +#include <linux/net/intel/iidc_rdma_idpf.h>
>  
>  #include "virtchnl2.h"
>  #include "idpf_txrx.h"
> @@ -206,9 +208,12 @@ struct idpf_reg_ops {
>  /**
>   * struct idpf_dev_ops - Device specific operations
>   * @reg_ops: Register operations
> + * @idc_init: IDC initialization
>   */
>  struct idpf_dev_ops {
>  	struct idpf_reg_ops reg_ops;
> +
> +	int (*idc_init)(struct idpf_adapter *adapter);
>  };
>  
>  /**
> @@ -540,6 +545,7 @@ struct idpf_vc_xn_manager;
>   * @caps: Negotiated capabilities with device
>   * @vcxn_mngr: Virtchnl transaction manager
>   * @dev_ops: See idpf_dev_ops
> + * @cdev_info: IDC core device info pointer
>   * @num_vfs: Number of allocated VFs through sysfs. PF does not directly talk
>   *	     to VFs but is used to initialize them
>   * @crc_enable: Enable CRC insertion offload
> @@ -599,6 +605,7 @@ struct idpf_adapter {
>  	struct idpf_vc_xn_manager *vcxn_mngr;
>  
>  	struct idpf_dev_ops dev_ops;
> +	struct iidc_rdma_core_dev_info *cdev_info;
>  	int num_vfs;
>  	bool crc_enable;
>  	bool req_tx_splitq;
> @@ -877,5 +884,9 @@ int idpf_sriov_configure(struct pci_dev *pdev, int num_vfs);
>  
>  u8 idpf_vport_get_hsplit(const struct idpf_vport *vport);
>  bool idpf_vport_set_hsplit(const struct idpf_vport *vport, u8 val);
> +int idpf_idc_init(struct idpf_adapter *adapter);
> +int idpf_idc_init_aux_core_dev(struct idpf_adapter *adapter,
> +			       enum iidc_function_type ftype);
> +void idpf_idc_deinit_core_aux_device(struct iidc_rdma_core_dev_info *cdev_info);
>  
>  #endif /* !_IDPF_H_ */
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_dev.c b/drivers/net/ethernet/intel/idpf/idpf_dev.c
> index 3fae81f1f988..dd227a4368fb 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_dev.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_dev.c
> @@ -161,6 +161,17 @@ static void idpf_ptp_reg_init(const struct idpf_adapter *adapter)
>  	adapter->ptp->cmd.exec_cmd_mask = PF_GLTSYN_CMD_SYNC_EXEC_CMD_M;
>  }
>  
> +/**
> + * idpf_idc_register - register for IDC callbacks
> + * @adapter: Driver specific private structure
> + *
> + * Return: 0 on success or error code on failure.
> + */
> +static int idpf_idc_register(struct idpf_adapter *adapter)
> +{
> +	return idpf_idc_init_aux_core_dev(adapter, IIDC_FUNCTION_TYPE_PF);
> +}
> +
>  /**
>   * idpf_reg_ops_init - Initialize register API function pointers
>   * @adapter: Driver specific private structure
> @@ -182,4 +193,6 @@ static void idpf_reg_ops_init(struct idpf_adapter *adapter)
>  void idpf_dev_ops_init(struct idpf_adapter *adapter)
>  {
>  	idpf_reg_ops_init(adapter);
> +
> +	adapter->dev_ops.idc_init = idpf_idc_register;
>  }
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_idc.c b/drivers/net/ethernet/intel/idpf/idpf_idc.c
> new file mode 100644
> index 000000000000..5550802a3a7d
> --- /dev/null
> +++ b/drivers/net/ethernet/intel/idpf/idpf_idc.c
> @@ -0,0 +1,223 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/* Copyright (C) 2025 Intel Corporation */
> +
> +#include "idpf.h"
> +#include "idpf_virtchnl.h"
> +
> +static DEFINE_IDA(idpf_idc_ida);
> +
> +#define IDPF_IDC_MAX_ADEV_NAME_LEN	15
> +
> +/**
> + * idpf_idc_init - Called to initialize IDC
> + * @adapter: driver private data structure
> + *
> + * Return: 0 on success or cap not enabled, error code on failure.
> + */
> +int idpf_idc_init(struct idpf_adapter *adapter)
> +{
> +	int err;
> +
> +	if (!idpf_is_rdma_cap_ena(adapter) ||
> +	    !adapter->dev_ops.idc_init)
> +		return 0;
> +
> +	err = adapter->dev_ops.idc_init(adapter);
> +	if (err)
> +		dev_err(&adapter->pdev->dev, "failed to initialize idc: %d\n",
> +			err);
> +
> +	return err;
> +}
> +
> +/**
> + * idpf_core_adev_release - function to be mapped to aux dev's release op
> + * @dev: pointer to device to free
> + */
> +static void idpf_core_adev_release(struct device *dev)
> +{
> +	struct iidc_rdma_core_auxiliary_dev *iadev;
> +
> +	iadev = container_of(dev, struct iidc_rdma_core_auxiliary_dev, adev.dev);
> +	kfree(iadev);
> +	iadev = NULL;
> +}
> +
> +/* idpf_plug_core_aux_dev - allocate and register an Auxiliary device
> + * @cdev_info: IDC core device info pointer
> + *
> + * Return: 0 on success or error code on failure.
> + */
> +static int idpf_plug_core_aux_dev(struct iidc_rdma_core_dev_info *cdev_info)
> +{
> +	struct iidc_rdma_core_auxiliary_dev *iadev;
> +	char name[IDPF_IDC_MAX_ADEV_NAME_LEN];
> +	struct auxiliary_device *adev;
> +	int ret;
> +
> +	iadev = kzalloc(sizeof(*iadev), GFP_KERNEL);
> +	if (!iadev)
> +		return -ENOMEM;
> +
> +	adev = &iadev->adev;
> +	cdev_info->adev = adev;
> +	iadev->cdev_info = cdev_info;
> +
> +	ret = ida_alloc(&idpf_idc_ida, GFP_KERNEL);
> +	if (ret < 0) {
> +		pr_err("failed to allocate unique device ID for Auxiliary driver\n");
> +		goto err_ida_alloc;
> +	}
> +	adev->id = ret;
> +	adev->dev.release = idpf_core_adev_release;
> +	adev->dev.parent = &cdev_info->pdev->dev;
> +	sprintf(name, "%04x.rdma.core", cdev_info->pdev->vendor);
> +	adev->name = name;
> +
> +	ret = auxiliary_device_init(adev);
> +	if (ret)
> +		goto err_aux_dev_init;
> +
> +	ret = auxiliary_device_add(adev);
> +	if (ret)
> +		goto err_aux_dev_add;
> +
> +	return 0;
> +
> +err_aux_dev_add:
> +	cdev_info->adev = NULL;
> +	auxiliary_device_uninit(adev);
> +err_aux_dev_init:
> +	ida_free(&idpf_idc_ida, adev->id);
> +err_ida_alloc:
> +	kfree(iadev);
> +
> +	return ret;
> +}
> +
> +/* idpf_unplug_aux_dev - unregister and free an Auxiliary device
> + * @adev: auxiliary device struct
> + */
> +static void idpf_unplug_aux_dev(struct auxiliary_device *adev)
> +{
> +	auxiliary_device_delete(adev);
> +	auxiliary_device_uninit(adev);
> +
> +	ida_free(&idpf_idc_ida, adev->id);
> +}
> +
> +/**
> + * idpf_idc_vport_dev_ctrl - Called by an Auxiliary Driver
> + * @cdev_info: IDC core device info pointer
> + * @up: RDMA core driver status
> + *
> + * This callback function is accessed by an Auxiliary Driver to indicate
> + * whether core driver is ready to support vport driver load or if vport
> + * drivers need to be taken down.
> + *
> + * Return: 0 on success or error code on failure.
> + */
> +int idpf_idc_vport_dev_ctrl(struct iidc_rdma_core_dev_info *cdev_info, bool up)
> +{
> +	return -EOPNOTSUPP;
> +}
> +EXPORT_SYMBOL_GPL(idpf_idc_vport_dev_ctrl);
> +
> +/**
> + * idpf_idc_request_reset - Called by an Auxiliary Driver
> + * @cdev_info: IDC core device info pointer
> + * @reset_type: function, core or other
> + *
> + * This callback function is accessed by an Auxiliary Driver to request a reset
> + * on the Auxiliary Device.
> + *
> + * Return: 0 on success or error code on failure.
> + */
> +int idpf_idc_request_reset(struct iidc_rdma_core_dev_info *cdev_info,
> +			   enum iidc_rdma_reset_type __always_unused reset_type)
> +{
> +	return -EOPNOTSUPP;
> +}
> +EXPORT_SYMBOL_GPL(idpf_idc_request_reset);
> +
> +/**
> + * idpf_idc_init_msix_data - initialize MSIX data for the cdev_info structure
> + * @adapter: driver private data structure
> + */
> +static void
> +idpf_idc_init_msix_data(struct idpf_adapter *adapter)
> +{
> +	struct iidc_rdma_core_dev_info *cdev_info;
> +	struct iidc_rdma_priv_dev_info *privd;
> +
> +	if (!adapter->rdma_msix_entries)
> +		return;
> +
> +	cdev_info = adapter->cdev_info;
> +	privd = cdev_info->iidc_priv;
> +
> +	privd->msix_entries = adapter->rdma_msix_entries;
> +	privd->msix_count = adapter->num_rdma_msix_entries;
> +}
> +
> +/**
> + * idpf_idc_init_aux_core_dev - initialize Auxiliary Device(s)
> + * @adapter: driver private data structure
> + * @ftype: PF or VF
> + *
> + * Return: 0 on success or error code on failure.
> + */
> +int idpf_idc_init_aux_core_dev(struct idpf_adapter *adapter,
> +			       enum iidc_function_type ftype)
> +{
> +	struct iidc_rdma_core_dev_info *cdev_info;
> +	struct iidc_rdma_priv_dev_info *privd;
> +	int err;
> +
> +	adapter->cdev_info = kzalloc(sizeof(*cdev_info), GFP_KERNEL);
> +	if (!adapter->cdev_info)
> +		return -ENOMEM;
> +	cdev_info = adapter->cdev_info;
> +
> +	privd = kzalloc(sizeof(*privd), GFP_KERNEL);
> +	if (!privd) {
> +		err = -ENOMEM;
> +		goto err_privd_alloc;
> +	}
> +
> +	cdev_info->iidc_priv = privd;
> +	cdev_info->pdev = adapter->pdev;
> +	cdev_info->rdma_protocol = IIDC_RDMA_PROTOCOL_ROCEV2;
> +	privd->ftype = ftype;
> +
> +	idpf_idc_init_msix_data(adapter);
> +
> +	err = idpf_plug_core_aux_dev(cdev_info);
> +	if (err)
> +		goto err_plug_aux_dev;
> +
> +	return 0;
> +
> +err_plug_aux_dev:
> +	kfree(privd);
> +err_privd_alloc:
> +	kfree(cdev_info);
> +	adapter->cdev_info = NULL;
> +
> +	return err;
> +}
> +
> +/**
> + * idpf_idc_deinit_core_aux_device - de-initialize Auxiliary Device(s)
> + * @cdev_info: IDC core device info pointer
> + */
> +void idpf_idc_deinit_core_aux_device(struct iidc_rdma_core_dev_info *cdev_info)
> +{
> +	if (!cdev_info)
> +		return;
> +
> +	idpf_unplug_aux_dev(cdev_info->adev);
> +
> +	kfree(cdev_info->iidc_priv);
> +	kfree(cdev_info);
> +}
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c
> index 71d1577ca9e4..2c9fda5783f8 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_lib.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c
> @@ -1834,6 +1834,10 @@ static int idpf_init_hard_reset(struct idpf_adapter *adapter)
>  unlock_mutex:
>  	mutex_unlock(&adapter->vport_ctrl_lock);
>  
> +	/* Wait until all vports are created to init RDMA CORE AUX */
> +	if (!err)
> +		err = idpf_idc_init(adapter);
> +
>  	return err;
>  }
>  
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c b/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c
> index aba828abcb17..2f84bd596ae4 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c
> @@ -147,6 +147,17 @@ static void idpf_vf_trigger_reset(struct idpf_adapter *adapter,
>  		idpf_send_mb_msg(adapter, VIRTCHNL2_OP_RESET_VF, 0, NULL, 0);
>  }
>  
> +/**
> + * idpf_idc_vf_register - register for IDC callbacks
> + * @adapter: Driver specific private structure
> + *
> + * Return: 0 on success or error code on failure.
> + */
> +static int idpf_idc_vf_register(struct idpf_adapter *adapter)
> +{
> +	return idpf_idc_init_aux_core_dev(adapter, IIDC_FUNCTION_TYPE_VF);
> +}
> +
>  /**
>   * idpf_vf_reg_ops_init - Initialize register API function pointers
>   * @adapter: Driver specific private structure
> @@ -167,4 +178,6 @@ static void idpf_vf_reg_ops_init(struct idpf_adapter *adapter)
>  void idpf_vf_dev_ops_init(struct idpf_adapter *adapter)
>  {
>  	idpf_vf_reg_ops_init(adapter);
> +
> +	adapter->dev_ops.idc_init = idpf_idc_vf_register;
>  }
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> index 24febaaa8fbb..c6fa4644fd3c 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> @@ -868,6 +868,7 @@ static int idpf_send_get_caps_msg(struct idpf_adapter *adapter)
>  
>  	caps.other_caps =
>  		cpu_to_le64(VIRTCHNL2_CAP_SRIOV			|
> +			    VIRTCHNL2_CAP_RDMA                  |
>  			    VIRTCHNL2_CAP_MACFILTER		|
>  			    VIRTCHNL2_CAP_SPLITQ_QSCHED		|
>  			    VIRTCHNL2_CAP_PROMISC		|
> @@ -3070,6 +3071,7 @@ void idpf_vc_core_deinit(struct idpf_adapter *adapter)
>  
>  	idpf_ptp_release(adapter);
>  	idpf_deinit_task(adapter);
> +	idpf_idc_deinit_core_aux_device(adapter->cdev_info);
>  	idpf_intr_rel(adapter);
>  
>  	if (remove_in_prog)
> @@ -3728,3 +3730,21 @@ int idpf_set_promiscuous(struct idpf_adapter *adapter,
>  
>  	return reply_sz < 0 ? reply_sz : 0;
>  }
> +
> +/**
> + * idpf_idc_rdma_vc_send_sync - virtchnl send callback for IDC registered drivers
> + * @cdev_info: IDC core device info pointer
> + * @send_msg: message to send
> + * @msg_size: size of message to send
> + * @recv_msg: message to populate on reception of response
> + * @recv_len: length of message copied into recv_msg or 0 on error
> + *
> + * Return: 0 on success or error code on failure.
> + */
> +int idpf_idc_rdma_vc_send_sync(struct iidc_rdma_core_dev_info *cdev_info,
> +			       u8 *send_msg, u16 msg_size,
> +			       u8 *recv_msg, u16 *recv_len)
> +{
> +	return -EOPNOTSUPP;
> +}
> +EXPORT_SYMBOL_GPL(idpf_idc_rdma_vc_send_sync);
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
> index 77578206bada..7bae09483aed 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
> +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
> @@ -151,5 +151,8 @@ int idpf_send_set_sriov_vfs_msg(struct idpf_adapter *adapter, u16 num_vfs);
>  int idpf_send_get_set_rss_key_msg(struct idpf_vport *vport, bool get);
>  int idpf_send_get_set_rss_lut_msg(struct idpf_vport *vport, bool get);
>  void idpf_vc_xn_shutdown(struct idpf_vc_xn_manager *vcxn_mngr);
> +int idpf_idc_rdma_vc_send_sync(struct iidc_rdma_core_dev_info *cdev_info,
> +			       u8 *send_msg, u16 msg_size,
> +			       u8 *recv_msg, u16 *recv_len);
>  
>  #endif /* _IDPF_VIRTCHNL_H_ */
> diff --git a/include/linux/net/intel/iidc_rdma_idpf.h b/include/linux/net/intel/iidc_rdma_idpf.h
> new file mode 100644
> index 000000000000..f2fe1844f660
> --- /dev/null
> +++ b/include/linux/net/intel/iidc_rdma_idpf.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (C) 2025 Intel Corporation. */
> +
> +#ifndef _IIDC_RDMA_IDPF_H_
> +#define _IIDC_RDMA_IDPF_H_
> +
> +#include <linux/auxiliary_bus.h>
> +
> +/* struct to be populated by core LAN PCI driver */
> +enum iidc_function_type {
> +	IIDC_FUNCTION_TYPE_PF,
> +	IIDC_FUNCTION_TYPE_VF,
> +};
> +
> +struct iidc_rdma_priv_dev_info {
> +	struct msix_entry *msix_entries;
> +	u16 msix_count; /* How many vectors are reserved for this device */
> +	enum iidc_function_type ftype;
> +};
> +
> +int idpf_idc_vport_dev_ctrl(struct iidc_rdma_core_dev_info *cdev_info, bool up);
> +int idpf_idc_request_reset(struct iidc_rdma_core_dev_info *cdev_info,
> +			   enum iidc_rdma_reset_type __always_unused reset_type);
> +int idpf_idc_rdma_vc_send_sync(struct iidc_rdma_core_dev_info *cdev_info,
> +			       u8 *send_msg, u16 msg_size,
> +			       u8 *recv_msg, u16 *recv_len);
> +
> +#endif /* _IIDC_RDMA_IDPF_H_ */
> -- 
> 2.31.1
> 
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ