diff mbox series

[for-next,v3] RDMA/efa: Add EFA query MR support

Message ID 20231211174715.7369-1-mrgolin@amazon.com (mailing list archive)
State Superseded
Headers show
Series [for-next,v3] RDMA/efa: Add EFA query MR support | expand

Commit Message

Michael Margolin Dec. 11, 2023, 5:47 p.m. UTC
Add EFA driver uapi definitions and register a new query MR method that
currently returns the physical PCI buses' IDs the device is using to
reach the MR. Update admin definitions and efa-abi accordingly.

Reviewed-by: Anas Mousa <anasmous@amazon.com>
Reviewed-by: Firas Jahjah <firasj@amazon.com>
Signed-off-by: Michael Margolin <mrgolin@amazon.com>
---
 drivers/infiniband/hw/efa/efa.h               | 12 +++-
 .../infiniband/hw/efa/efa_admin_cmds_defs.h   | 31 +++++++++
 drivers/infiniband/hw/efa/efa_com_cmd.c       |  9 +++
 drivers/infiniband/hw/efa/efa_com_cmd.h       | 10 +++
 drivers/infiniband/hw/efa/efa_main.c          |  5 ++
 drivers/infiniband/hw/efa/efa_verbs.c         | 69 +++++++++++++++++++
 include/uapi/rdma/efa-abi.h                   | 19 +++++
 7 files changed, 154 insertions(+), 1 deletion(-)

Comments

Jason Gunthorpe Dec. 11, 2023, 5:50 p.m. UTC | #1
On Mon, Dec 11, 2023 at 05:47:15PM +0000, Michael Margolin wrote:
> diff --git a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
> index 9c65bd27bae0..597f7ca6f31d 100644
> --- a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
> +++ b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
> @@ -415,6 +415,32 @@ struct efa_admin_reg_mr_resp {
>  	 * memory region
>  	 */
>  	u32 r_key;
> +
> +	/*
> +	 * Mask indicating which fields have valid values
> +	 * 0 : recv_pci_bus_id
> +	 * 1 : rdma_read_pci_bus_id
> +	 * 2 : rdma_recv_pci_bus_id
> +	 */
> +	u8 validity;
> +
> +	/*
> +	 * Physical PCIe bus used by the device to reach the MR for receive
> +	 * operation
> +	 */
> +	u8 recv_pci_bus_id;
> +
> +	/*
> +	 * Physical PCIe bus used by the device to reach the MR for RDMA read
> +	 * operation
> +	 */
> +	u8 rdma_read_pci_bus_id;
> +
> +	/*
> +	 * Physical PCIe bus used by the device to reach the MR for RDMA write
> +	 * receive
> +	 */
> +	u8 rdma_recv_pci_bus_id;

What driver is bound to this other PCIe bus and how did the iommu get
setup for it?

Jason
Michael Margolin Dec. 13, 2023, 5:05 p.m. UTC | #2
On 12/11/2023 7:50 PM, Jason Gunthorpe wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you can confirm the sender and know the content is safe.
>
>
>
> On Mon, Dec 11, 2023 at 05:47:15PM +0000, Michael Margolin wrote:
>> diff --git a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
>> index 9c65bd27bae0..597f7ca6f31d 100644
>> --- a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
>> +++ b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
>> @@ -415,6 +415,32 @@ struct efa_admin_reg_mr_resp {
>>        * memory region
>>        */
>>       u32 r_key;
>> +
>> +     /*
>> +      * Mask indicating which fields have valid values
>> +      * 0 : recv_pci_bus_id
>> +      * 1 : rdma_read_pci_bus_id
>> +      * 2 : rdma_recv_pci_bus_id
>> +      */
>> +     u8 validity;
>> +
>> +     /*
>> +      * Physical PCIe bus used by the device to reach the MR for receive
>> +      * operation
>> +      */
>> +     u8 recv_pci_bus_id;
>> +
>> +     /*
>> +      * Physical PCIe bus used by the device to reach the MR for RDMA read
>> +      * operation
>> +      */
>> +     u8 rdma_read_pci_bus_id;
>> +
>> +     /*
>> +      * Physical PCIe bus used by the device to reach the MR for RDMA write
>> +      * receive
>> +      */
>> +     u8 rdma_recv_pci_bus_id;
> What driver is bound to this other PCIe bus and how did the iommu get
> setup for it?
>
> Jason

It's internal bus that is not directly exposed to the host. Addresses
mapping is acquired from accelerator's driver as for any MR residing in
accelerator memory, and the translation is owned by devices on that bus.


Michael
Michael Margolin Dec. 21, 2023, 1:45 p.m. UTC | #3
On 12/13/2023 7:05 PM, Margolin, Michael wrote:

> On 12/11/2023 7:50 PM, Jason Gunthorpe wrote:
>> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you can confirm the sender and know the content is safe.
>>
>>
>>
>> On Mon, Dec 11, 2023 at 05:47:15PM +0000, Michael Margolin wrote:
>>> diff --git a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
>>> index 9c65bd27bae0..597f7ca6f31d 100644
>>> --- a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
>>> +++ b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
>>> @@ -415,6 +415,32 @@ struct efa_admin_reg_mr_resp {
>>>        * memory region
>>>        */
>>>       u32 r_key;
>>> +
>>> +     /*
>>> +      * Mask indicating which fields have valid values
>>> +      * 0 : recv_pci_bus_id
>>> +      * 1 : rdma_read_pci_bus_id
>>> +      * 2 : rdma_recv_pci_bus_id
>>> +      */
>>> +     u8 validity;
>>> +
>>> +     /*
>>> +      * Physical PCIe bus used by the device to reach the MR for receive
>>> +      * operation
>>> +      */
>>> +     u8 recv_pci_bus_id;
>>> +
>>> +     /*
>>> +      * Physical PCIe bus used by the device to reach the MR for RDMA read
>>> +      * operation
>>> +      */
>>> +     u8 rdma_read_pci_bus_id;
>>> +
>>> +     /*
>>> +      * Physical PCIe bus used by the device to reach the MR for RDMA write
>>> +      * receive
>>> +      */
>>> +     u8 rdma_recv_pci_bus_id;
>> What driver is bound to this other PCIe bus and how did the iommu get
>> setup for it?
>>
>> Jason
> It's internal bus that is not directly exposed to the host. Addresses
> mapping is acquired from accelerator's driver as for any MR residing in
> accelerator memory, and the translation is owned by devices on that bus.
>
>
> Michael

Hi,

Just want to make sure if there are any questions / comments regarding
to this patch that haven't been addressed?


Michael
Leon Romanovsky Dec. 25, 2023, 11:26 a.m. UTC | #4
On Thu, Dec 21, 2023 at 03:45:56PM +0200, Margolin, Michael wrote:
> On 12/13/2023 7:05 PM, Margolin, Michael wrote:
> 
> > On 12/11/2023 7:50 PM, Jason Gunthorpe wrote:
> >> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you can confirm the sender and know the content is safe.
> >>
> >>
> >>
> >> On Mon, Dec 11, 2023 at 05:47:15PM +0000, Michael Margolin wrote:
> >>> diff --git a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
> >>> index 9c65bd27bae0..597f7ca6f31d 100644
> >>> --- a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
> >>> +++ b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
> >>> @@ -415,6 +415,32 @@ struct efa_admin_reg_mr_resp {
> >>>        * memory region
> >>>        */
> >>>       u32 r_key;
> >>> +
> >>> +     /*
> >>> +      * Mask indicating which fields have valid values
> >>> +      * 0 : recv_pci_bus_id
> >>> +      * 1 : rdma_read_pci_bus_id
> >>> +      * 2 : rdma_recv_pci_bus_id
> >>> +      */
> >>> +     u8 validity;
> >>> +
> >>> +     /*
> >>> +      * Physical PCIe bus used by the device to reach the MR for receive
> >>> +      * operation
> >>> +      */
> >>> +     u8 recv_pci_bus_id;
> >>> +
> >>> +     /*
> >>> +      * Physical PCIe bus used by the device to reach the MR for RDMA read
> >>> +      * operation
> >>> +      */
> >>> +     u8 rdma_read_pci_bus_id;
> >>> +
> >>> +     /*
> >>> +      * Physical PCIe bus used by the device to reach the MR for RDMA write
> >>> +      * receive
> >>> +      */
> >>> +     u8 rdma_recv_pci_bus_id;
> >> What driver is bound to this other PCIe bus and how did the iommu get
> >> setup for it?
> >>
> >> Jason
> > It's internal bus that is not directly exposed to the host. Addresses
> > mapping is acquired from accelerator's driver as for any MR residing in
> > accelerator memory, and the translation is owned by devices on that bus.
> >
> >
> > Michael
> 
> Hi,
> 
> Just want to make sure if there are any questions / comments regarding
> to this patch that haven't been addressed?

I'm waiting from Jason ack/nack on this patch as he was the one who
asked the question.

Thanks

> 
> 
> Michael
>
Jason Gunthorpe Jan. 2, 2024, 11:47 p.m. UTC | #5
On Wed, Dec 13, 2023 at 07:05:24PM +0200, Margolin, Michael wrote:
> > On Mon, Dec 11, 2023 at 05:47:15PM +0000, Michael Margolin wrote:
> >> diff --git a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
> >> index 9c65bd27bae0..597f7ca6f31d 100644
> >> --- a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
> >> +++ b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
> >> @@ -415,6 +415,32 @@ struct efa_admin_reg_mr_resp {
> >>        * memory region
> >>        */
> >>       u32 r_key;
> >> +
> >> +     /*
> >> +      * Mask indicating which fields have valid values
> >> +      * 0 : recv_pci_bus_id
> >> +      * 1 : rdma_read_pci_bus_id
> >> +      * 2 : rdma_recv_pci_bus_id
> >> +      */
> >> +     u8 validity;
> >> +
> >> +     /*
> >> +      * Physical PCIe bus used by the device to reach the MR for receive
> >> +      * operation
> >> +      */
> >> +     u8 recv_pci_bus_id;
> >> +
> >> +     /*
> >> +      * Physical PCIe bus used by the device to reach the MR for RDMA read
> >> +      * operation
> >> +      */
> >> +     u8 rdma_read_pci_bus_id;
> >> +
> >> +     /*
> >> +      * Physical PCIe bus used by the device to reach the MR for RDMA write
> >> +      * receive
> >> +      */
> >> +     u8 rdma_recv_pci_bus_id;
> > What driver is bound to this other PCIe bus and how did the iommu get
> > setup for it?
> 
> It's internal bus that is not directly exposed to the host. Addresses
> mapping is acquired from accelerator's driver as for any MR residing in
> accelerator memory, and the translation is owned by devices on that bus.

So if it isn't visible to the host, or connectable to anything Linux
would call a PCI RID, why are you giving it such specific names? Just
call it 'interconnect path id' or something and make it opaque?

Jason
Michael Margolin Jan. 3, 2024, 1:33 p.m. UTC | #6
On 1/3/2024 1:47 AM, Jason Gunthorpe wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you can confirm the sender and know the content is safe.
>
>
>
> On Wed, Dec 13, 2023 at 07:05:24PM +0200, Margolin, Michael wrote:
>>> On Mon, Dec 11, 2023 at 05:47:15PM +0000, Michael Margolin wrote:
>>>> diff --git a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
>>>> index 9c65bd27bae0..597f7ca6f31d 100644
>>>> --- a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
>>>> +++ b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
>>>> @@ -415,6 +415,32 @@ struct efa_admin_reg_mr_resp {
>>>>         * memory region
>>>>         */
>>>>        u32 r_key;
>>>> +
>>>> +     /*
>>>> +      * Mask indicating which fields have valid values
>>>> +      * 0 : recv_pci_bus_id
>>>> +      * 1 : rdma_read_pci_bus_id
>>>> +      * 2 : rdma_recv_pci_bus_id
>>>> +      */
>>>> +     u8 validity;
>>>> +
>>>> +     /*
>>>> +      * Physical PCIe bus used by the device to reach the MR for receive
>>>> +      * operation
>>>> +      */
>>>> +     u8 recv_pci_bus_id;
>>>> +
>>>> +     /*
>>>> +      * Physical PCIe bus used by the device to reach the MR for RDMA read
>>>> +      * operation
>>>> +      */
>>>> +     u8 rdma_read_pci_bus_id;
>>>> +
>>>> +     /*
>>>> +      * Physical PCIe bus used by the device to reach the MR for RDMA write
>>>> +      * receive
>>>> +      */
>>>> +     u8 rdma_recv_pci_bus_id;
>>> What driver is bound to this other PCIe bus and how did the iommu get
>>> setup for it?
>> It's internal bus that is not directly exposed to the host. Addresses
>> mapping is acquired from accelerator's driver as for any MR residing in
>> accelerator memory, and the translation is owned by devices on that bus.
> So if it isn't visible to the host, or connectable to anything Linux
> would call a PCI RID, why are you giving it such specific names? Just
> call it 'interconnect path id' or something and make it opaque?
>
> Jason

I would like it to be as opaque as possible but on the other hand to 
express that the mentioned 'interconnect path' relates specifically to 
PCI path.

I think that except of this, since 'bus_id' is quite general term that 
cannot be used without proper context, it isn't likely to cause any 
unintended use of those fields.

Michael
Jason Gunthorpe Jan. 3, 2024, 1:37 p.m. UTC | #7
On Wed, Jan 03, 2024 at 03:33:41PM +0200, Margolin, Michael wrote:

> I would like it to be as opaque as possible but on the other hand to express
> that the mentioned 'interconnect path' relates specifically to PCI path.

Who cares it is a "PCI path" if the the thing is totally invisible? It
is some hidden implementation detail of your device that today happens
to be PCI.

There are many ways to get interconnect multipath coming, including
PCIe UIO.

Jason
Michael Margolin Jan. 4, 2024, 9:50 a.m. UTC | #8
On 1/3/2024 3:37 PM, Jason Gunthorpe wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you can confirm the sender and know the content is safe.
>
>
>
> On Wed, Jan 03, 2024 at 03:33:41PM +0200, Margolin, Michael wrote:
>
>> I would like it to be as opaque as possible but on the other hand to express
>> that the mentioned 'interconnect path' relates specifically to PCI path.
> Who cares it is a "PCI path" if the the thing is totally invisible? It
> is some hidden implementation detail of your device that today happens
> to be PCI.
>
> There are many ways to get interconnect multipath coming, including
> PCIe UIO.
>
> Jason

Ok, changed according to your suggestion.

Michael
diff mbox series

Patch

diff --git a/drivers/infiniband/hw/efa/efa.h b/drivers/infiniband/hw/efa/efa.h
index 7352a1f5d811..81f5aaf07091 100644
--- a/drivers/infiniband/hw/efa/efa.h
+++ b/drivers/infiniband/hw/efa/efa.h
@@ -1,6 +1,6 @@ 
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
 /*
- * Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved.
+ * Copyright 2018-2023 Amazon.com, Inc. or its affiliates. All rights reserved.
  */
 
 #ifndef _EFA_H_
@@ -80,9 +80,19 @@  struct efa_pd {
 	u16 pdn;
 };
 
+struct efa_mr_pci_info {
+	u16 recv_pci_bus_id;
+	u16 rdma_read_pci_bus_id;
+	u16 rdma_recv_pci_bus_id;
+	u8 recv_pci_bus_id_valid : 1;
+	u8 rdma_read_pci_bus_id_valid : 1;
+	u8 rdma_recv_pci_bus_id_valid : 1;
+};
+
 struct efa_mr {
 	struct ib_mr ibmr;
 	struct ib_umem *umem;
+	struct efa_mr_pci_info pci_info;
 };
 
 struct efa_cq {
diff --git a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
index 9c65bd27bae0..597f7ca6f31d 100644
--- a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
+++ b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
@@ -415,6 +415,32 @@  struct efa_admin_reg_mr_resp {
 	 * memory region
 	 */
 	u32 r_key;
+
+	/*
+	 * Mask indicating which fields have valid values
+	 * 0 : recv_pci_bus_id
+	 * 1 : rdma_read_pci_bus_id
+	 * 2 : rdma_recv_pci_bus_id
+	 */
+	u8 validity;
+
+	/*
+	 * Physical PCIe bus used by the device to reach the MR for receive
+	 * operation
+	 */
+	u8 recv_pci_bus_id;
+
+	/*
+	 * Physical PCIe bus used by the device to reach the MR for RDMA read
+	 * operation
+	 */
+	u8 rdma_read_pci_bus_id;
+
+	/*
+	 * Physical PCIe bus used by the device to reach the MR for RDMA write
+	 * receive
+	 */
+	u8 rdma_recv_pci_bus_id;
 };
 
 struct efa_admin_dereg_mr_cmd {
@@ -999,6 +1025,11 @@  struct efa_admin_host_info {
 #define EFA_ADMIN_REG_MR_CMD_REMOTE_WRITE_ENABLE_MASK       BIT(1)
 #define EFA_ADMIN_REG_MR_CMD_REMOTE_READ_ENABLE_MASK        BIT(2)
 
+/* reg_mr_resp */
+#define EFA_ADMIN_REG_MR_RESP_RECV_PCI_BUS_ID_MASK          BIT(0)
+#define EFA_ADMIN_REG_MR_RESP_RDMA_READ_PCI_BUS_ID_MASK     BIT(1)
+#define EFA_ADMIN_REG_MR_RESP_RDMA_RECV_PCI_BUS_ID_MASK     BIT(2)
+
 /* create_cq_cmd */
 #define EFA_ADMIN_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_MASK BIT(5)
 #define EFA_ADMIN_CREATE_CQ_CMD_VIRT_MASK                   BIT(6)
diff --git a/drivers/infiniband/hw/efa/efa_com_cmd.c b/drivers/infiniband/hw/efa/efa_com_cmd.c
index 576811885d59..4801640f9f4f 100644
--- a/drivers/infiniband/hw/efa/efa_com_cmd.c
+++ b/drivers/infiniband/hw/efa/efa_com_cmd.c
@@ -270,6 +270,15 @@  int efa_com_register_mr(struct efa_com_dev *edev,
 
 	result->l_key = cmd_completion.l_key;
 	result->r_key = cmd_completion.r_key;
+	result->pci_info.recv_pci_bus_id = cmd_completion.recv_pci_bus_id;
+	result->pci_info.rdma_read_pci_bus_id = cmd_completion.rdma_read_pci_bus_id;
+	result->pci_info.rdma_recv_pci_bus_id = cmd_completion.rdma_recv_pci_bus_id;
+	result->pci_info.recv_pci_bus_id_valid = EFA_GET(&cmd_completion.validity,
+							 EFA_ADMIN_REG_MR_RESP_RECV_PCI_BUS_ID);
+	result->pci_info.rdma_read_pci_bus_id_valid = EFA_GET(&cmd_completion.validity,
+							      EFA_ADMIN_REG_MR_RESP_RDMA_READ_PCI_BUS_ID);
+	result->pci_info.rdma_recv_pci_bus_id_valid = EFA_GET(&cmd_completion.validity,
+							      EFA_ADMIN_REG_MR_RESP_RDMA_RECV_PCI_BUS_ID);
 
 	return 0;
 }
diff --git a/drivers/infiniband/hw/efa/efa_com_cmd.h b/drivers/infiniband/hw/efa/efa_com_cmd.h
index fc97f37bb39b..00635575c3b0 100644
--- a/drivers/infiniband/hw/efa/efa_com_cmd.h
+++ b/drivers/infiniband/hw/efa/efa_com_cmd.h
@@ -199,6 +199,15 @@  struct efa_com_reg_mr_params {
 	u8 indirect;
 };
 
+struct efa_com_mr_pci_info {
+	u16 recv_pci_bus_id;
+	u16 rdma_read_pci_bus_id;
+	u16 rdma_recv_pci_bus_id;
+	u8 recv_pci_bus_id_valid : 1;
+	u8 rdma_read_pci_bus_id_valid : 1;
+	u8 rdma_recv_pci_bus_id_valid : 1;
+};
+
 struct efa_com_reg_mr_result {
 	/*
 	 * To be used in conjunction with local buffers references in SQ and
@@ -210,6 +219,7 @@  struct efa_com_reg_mr_result {
 	 * accessed memory region
 	 */
 	u32 r_key;
+	struct efa_com_mr_pci_info pci_info;
 };
 
 struct efa_com_dereg_mr_params {
diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
index 15ee92081118..da4f378c7c16 100644
--- a/drivers/infiniband/hw/efa/efa_main.c
+++ b/drivers/infiniband/hw/efa/efa_main.c
@@ -9,6 +9,7 @@ 
 #include <linux/version.h>
 
 #include <rdma/ib_user_verbs.h>
+#include <rdma/uverbs_ioctl.h>
 
 #include "efa.h"
 
@@ -36,6 +37,8 @@  MODULE_DEVICE_TABLE(pci, efa_pci_tbl);
 	(BIT(EFA_ADMIN_FATAL_ERROR) | BIT(EFA_ADMIN_WARNING) | \
 	 BIT(EFA_ADMIN_NOTIFICATION) | BIT(EFA_ADMIN_KEEP_ALIVE))
 
+extern const struct uapi_definition efa_uapi_defs[];
+
 /* This handler will called for unknown event group or unimplemented handlers */
 static void unimplemented_aenq_handler(void *data,
 				       struct efa_admin_aenq_entry *aenq_e)
@@ -432,6 +435,8 @@  static int efa_ib_device_add(struct efa_dev *dev)
 
 	ib_set_device_ops(&dev->ibdev, &efa_dev_ops);
 
+	dev->ibdev.driver_def = efa_uapi_defs;
+
 	err = ib_register_device(&dev->ibdev, "efa_%d", &pdev->dev);
 	if (err)
 		goto err_destroy_eqs;
diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c
index 0f8ca99d0827..408dc7fa3a4a 100644
--- a/drivers/infiniband/hw/efa/efa_verbs.c
+++ b/drivers/infiniband/hw/efa/efa_verbs.c
@@ -13,6 +13,9 @@ 
 #include <rdma/ib_user_verbs.h>
 #include <rdma/ib_verbs.h>
 #include <rdma/uverbs_ioctl.h>
+#define UVERBS_MODULE_NAME efa_ib
+#include <rdma/uverbs_named_ioctl.h>
+#include <rdma/ib_user_ioctl_cmds.h>
 
 #include "efa.h"
 #include "efa_io_defs.h"
@@ -1653,6 +1656,12 @@  static int efa_register_mr(struct ib_pd *ibpd, struct efa_mr *mr, u64 start,
 	mr->ibmr.lkey = result.l_key;
 	mr->ibmr.rkey = result.r_key;
 	mr->ibmr.length = length;
+	mr->pci_info.recv_pci_bus_id = result.pci_info.recv_pci_bus_id;
+	mr->pci_info.rdma_read_pci_bus_id = result.pci_info.rdma_read_pci_bus_id;
+	mr->pci_info.rdma_recv_pci_bus_id = result.pci_info.rdma_recv_pci_bus_id;
+	mr->pci_info.recv_pci_bus_id_valid = result.pci_info.recv_pci_bus_id_valid;
+	mr->pci_info.rdma_read_pci_bus_id_valid = result.pci_info.rdma_read_pci_bus_id_valid;
+	mr->pci_info.rdma_recv_pci_bus_id_valid = result.pci_info.rdma_recv_pci_bus_id_valid;
 	ibdev_dbg(&dev->ibdev, "Registered mr[%d]\n", mr->ibmr.lkey);
 
 	return 0;
@@ -1735,6 +1744,39 @@  struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
 	return ERR_PTR(err);
 }
 
+static int UVERBS_HANDLER(EFA_IB_METHOD_MR_QUERY)(struct uverbs_attr_bundle *attrs)
+{
+	struct ib_mr *ibmr = uverbs_attr_get_obj(attrs, EFA_IB_ATTR_QUERY_MR_HANDLE);
+	struct efa_mr *mr = to_emr(ibmr);
+	u16 pci_bus_id_validity;
+	int ret;
+
+	ret = uverbs_copy_to(attrs, EFA_IB_ATTR_QUERY_MR_RESP_RECV_PCI_BUS_ID,
+			     &mr->pci_info.recv_pci_bus_id, sizeof(mr->pci_info.recv_pci_bus_id));
+	if (ret)
+		return ret;
+
+	ret = uverbs_copy_to(attrs, EFA_IB_ATTR_QUERY_MR_RESP_RDMA_READ_PCI_BUS_ID,
+			     &mr->pci_info.rdma_read_pci_bus_id, sizeof(mr->pci_info.rdma_read_pci_bus_id));
+	if (ret)
+		return ret;
+
+	ret = uverbs_copy_to(attrs, EFA_IB_ATTR_QUERY_MR_RESP_RDMA_RECV_PCI_BUS_ID,
+			     &mr->pci_info.rdma_recv_pci_bus_id, sizeof(mr->pci_info.rdma_recv_pci_bus_id));
+	if (ret)
+		return ret;
+
+	pci_bus_id_validity = (mr->pci_info.recv_pci_bus_id_valid ?
+			       EFA_QUERY_MR_VALIDITY_RECV_PCI_BUS_ID : 0) |
+			      (mr->pci_info.rdma_read_pci_bus_id_valid ?
+			       EFA_QUERY_MR_VALIDITY_RDMA_READ_PCI_BUS_ID : 0) |
+			      (mr->pci_info.rdma_recv_pci_bus_id_valid ?
+			       EFA_QUERY_MR_VALIDITY_RDMA_RECV_PCI_BUS_ID : 0);
+
+	return uverbs_copy_to(attrs, EFA_IB_ATTR_QUERY_MR_RESP_PCI_BUS_ID_VALIDITY,
+			      &pci_bus_id_validity, sizeof(pci_bus_id_validity));
+}
+
 int efa_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
 {
 	struct efa_dev *dev = to_edev(ibmr->device);
@@ -2157,3 +2199,30 @@  enum rdma_link_layer efa_port_link_layer(struct ib_device *ibdev,
 	return IB_LINK_LAYER_UNSPECIFIED;
 }
 
+DECLARE_UVERBS_NAMED_METHOD(EFA_IB_METHOD_MR_QUERY,
+			    UVERBS_ATTR_IDR(EFA_IB_ATTR_QUERY_MR_HANDLE,
+					    UVERBS_OBJECT_MR,
+					    UVERBS_ACCESS_READ,
+					    UA_MANDATORY),
+			    UVERBS_ATTR_PTR_OUT(EFA_IB_ATTR_QUERY_MR_RESP_PCI_BUS_ID_VALIDITY,
+						UVERBS_ATTR_TYPE(u16),
+						UA_MANDATORY),
+			    UVERBS_ATTR_PTR_OUT(EFA_IB_ATTR_QUERY_MR_RESP_RECV_PCI_BUS_ID,
+						UVERBS_ATTR_TYPE(u16),
+						UA_MANDATORY),
+			    UVERBS_ATTR_PTR_OUT(EFA_IB_ATTR_QUERY_MR_RESP_RDMA_READ_PCI_BUS_ID,
+						UVERBS_ATTR_TYPE(u16),
+						UA_MANDATORY),
+			    UVERBS_ATTR_PTR_OUT(EFA_IB_ATTR_QUERY_MR_RESP_RDMA_RECV_PCI_BUS_ID,
+						UVERBS_ATTR_TYPE(u16),
+						UA_MANDATORY));
+
+ADD_UVERBS_METHODS(efa_mr,
+		   UVERBS_OBJECT_MR,
+		   &UVERBS_METHOD(EFA_IB_METHOD_MR_QUERY));
+
+const struct uapi_definition efa_uapi_defs[] = {
+	UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_MR,
+				&efa_mr),
+	{},
+};
diff --git a/include/uapi/rdma/efa-abi.h b/include/uapi/rdma/efa-abi.h
index d94c32f28804..7ced04ca2ad9 100644
--- a/include/uapi/rdma/efa-abi.h
+++ b/include/uapi/rdma/efa-abi.h
@@ -7,6 +7,7 @@ 
 #define EFA_ABI_USER_H
 
 #include <linux/types.h>
+#include <rdma/ib_user_ioctl_cmds.h>
 
 /*
  * Increment this value if any changes that break userspace ABI
@@ -134,4 +135,22 @@  struct efa_ibv_ex_query_device_resp {
 	__u32 device_caps;
 };
 
+enum {
+	EFA_QUERY_MR_VALIDITY_RECV_PCI_BUS_ID = 1 << 0,
+	EFA_QUERY_MR_VALIDITY_RDMA_READ_PCI_BUS_ID = 1 << 1,
+	EFA_QUERY_MR_VALIDITY_RDMA_RECV_PCI_BUS_ID = 1 << 2,
+};
+
+enum efa_query_mr_attrs {
+	EFA_IB_ATTR_QUERY_MR_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+	EFA_IB_ATTR_QUERY_MR_RESP_PCI_BUS_ID_VALIDITY,
+	EFA_IB_ATTR_QUERY_MR_RESP_RECV_PCI_BUS_ID,
+	EFA_IB_ATTR_QUERY_MR_RESP_RDMA_READ_PCI_BUS_ID,
+	EFA_IB_ATTR_QUERY_MR_RESP_RDMA_RECV_PCI_BUS_ID,
+};
+
+enum efa_mr_methods {
+	EFA_IB_METHOD_MR_QUERY = (1U << UVERBS_ID_NS_SHIFT),
+};
+
 #endif /* EFA_ABI_USER_H */