From patchwork Thu Aug 22 05:05:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haiyang Zhang X-Patchwork-Id: 11108419 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6704E1399 for ; Thu, 22 Aug 2019 05:05:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2FC2C2339E for ; Thu, 22 Aug 2019 05:05:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=microsoft.com header.i=@microsoft.com header.b="JAz1wkrq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731269AbfHVFF4 (ORCPT ); Thu, 22 Aug 2019 01:05:56 -0400 Received: from mail-eopbgr810109.outbound.protection.outlook.com ([40.107.81.109]:28619 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729109AbfHVFF4 (ORCPT ); Thu, 22 Aug 2019 01:05:56 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=S9FBkxMJypzcahEIApoKnMZVJkVainIOqDmLLWr+aDxMVHArvJprlwDp5rsA0k2ygb0zOtaIy2k/zv+TZTCb4i3oEWsR14QvBZ/ZpxhnMUvpgsod5XCMKBaxgrkgyPfRXJQUxEWkYIWgapmDv88OqiGwi5tmS1L5kjmSLvrW2PI2qBZXXno09uv+L99CuO5ngvNOt1YNoXo0g0hQgKIJxKMpyIOcf+gVhceIGaZnkx9LJw1gA0f9zO3z3L2r9xPd9IKk2g8Zn+yLyLLWEq+0Awquq8/K9fHL1qYD0z4YT88I9r6K5+USU4+P+Bm5W1kf68wUw73iaRr+34N4MN0ZEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=r8//GOpJEL/Hp72jQ11NhDe6pU7e08emO3MeJRroTew=; b=eqOwVe+KEslB8rjUoUypwkJRGgKaMVbFjOLv46XuYmnDX90/I08QmnQGB6++bRdbYk2IWX2Kb/jYT4Xt5cnWz4bO9D2ha5w2hYW2nuEWrxudTyHt6pXvUPResTfOmt0W3Dyqo5DvLxRhcDbRM+Hq/Ntq+dUFn1uAoIoWClhQ1s/xuV8P6V2wIeEp+KMje/U+qquVlpQZ8jPt81ZW3Y8jH46/zolZfSTbIKOk6ER4VdjuE4aaJJ0ZJ7smwN9Jyds8I2HSbcDLDziUQbrW1xwmAd5gaitkSuvOCyZBlyNXi+D6x4xfT/Lpnn5zvPPizUOCM8nXqQ5CbG+jaJH1RIoRbA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=r8//GOpJEL/Hp72jQ11NhDe6pU7e08emO3MeJRroTew=; b=JAz1wkrqRqnVFyMxNWwZyj18Y9S74vHWLbIkLneZs5c/WBpdF5VTi+fVhWUnlmLYUWr7sjS6M4yUeHWZpk0ZR1tNENRPQl6w0UpftJ882wJNAvCSUboXFvukLIeXG/gn9CJPT4rYqdzn7LM8NGNz8R88JPg/8UGAQnFNb7ZP2dM= Received: from MN2PR21MB1248.namprd21.prod.outlook.com (20.179.20.225) by MN2PR21MB1279.namprd21.prod.outlook.com (20.179.21.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2220.4; Thu, 22 Aug 2019 05:05:37 +0000 Received: from MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e]) by MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e%3]) with mapi id 15.20.2199.011; Thu, 22 Aug 2019 05:05:37 +0000 From: Haiyang Zhang To: "sashal@kernel.org" , "davem@davemloft.net" , "saeedm@mellanox.com" , "leon@kernel.org" , "eranbe@mellanox.com" , "lorenzo.pieralisi@arm.com" , "bhelgaas@google.com" , "linux-pci@vger.kernel.org" , "linux-hyperv@vger.kernel.org" , "netdev@vger.kernel.org" CC: Haiyang Zhang , KY Srinivasan , Stephen Hemminger , "linux-kernel@vger.kernel.org" , Dexuan Cui , Jake Oshins Subject: [PATCH net-next,v4, 1/6] PCI: hv: Add a paravirtual backchannel in software Thread-Topic: [PATCH net-next,v4, 1/6] PCI: hv: Add a paravirtual backchannel in software Thread-Index: AQHVWKc83iT/YpoADUiNZ5UEXPjwBA== Date: Thu, 22 Aug 2019 05:05:37 +0000 Message-ID: <1566450236-36757-2-git-send-email-haiyangz@microsoft.com> References: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> In-Reply-To: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: MWHPR14CA0039.namprd14.prod.outlook.com (2603:10b6:300:12b::25) To MN2PR21MB1248.namprd21.prod.outlook.com (2603:10b6:208:3b::33) authentication-results: spf=none (sender IP is ) smtp.mailfrom=lkmlhyz@microsoft.com; x-ms-exchange-messagesentrepresentingtype: 2 x-mailer: git-send-email 1.8.3.1 x-originating-ip: [13.77.154.182] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 1d18c032-35b6-448b-6532-08d726be5eeb x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(5600158)(711020)(4605104)(1401327)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020);SRVR:MN2PR21MB1279; x-ms-traffictypediagnostic: MN2PR21MB1279:|MN2PR21MB1279: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:8882; x-forefront-prvs: 01371B902F x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(4636009)(39860400002)(396003)(136003)(366004)(376002)(346002)(189003)(199004)(71200400001)(71190400001)(186003)(446003)(66066001)(2616005)(4326008)(36756003)(6392003)(6436002)(256004)(53936002)(7846003)(7416002)(6512007)(26005)(6486002)(14444005)(11346002)(316002)(2906002)(2201001)(110136005)(22452003)(54906003)(10090500001)(476003)(30864003)(25786009)(386003)(7736002)(64756008)(81156014)(66946007)(66446008)(8936002)(10290500003)(478600001)(66476007)(2501003)(102836004)(4720700003)(6116002)(3846002)(107886003)(6506007)(305945005)(5660300002)(486006)(99286004)(66556008)(81166006)(14454004)(50226002)(8676002)(52116002)(76176011)(142933001)(921003)(1121003);DIR:OUT;SFP:1102;SCL:1;SRVR:MN2PR21MB1279;H:MN2PR21MB1248.namprd21.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: JSOk1zA7+C+RjVtVR34AN7950HyeqJ0L9mvd1Of1vXrPsMVYvXmM9K/5FIDoEstOXLdcDIPdYJhqjGBUb4hPKNZLDA7NRjIcbAB+OTLnUvHn7uRaWrTwQoR5KE8tQ4x6vxuuTIXZfJ69uc8rrqtf7rjPInjKzcKR3H+kGlqooLbUf5rfyW2N0SyimUH9GZtBtOgfVuwXzaXAhks/Nc9pdYN5+5J4ZW8vS3pE6G9u5Siof0QfF7jf3LiQWo6EWptP80xSQ+LTGpk/A6+p3IUs/pSee8gvUUAumfsniYVwCRnlNAKXWe3ZzD1J2SjBkoGwDW7fCwM5z8seTb8qYZ1YfkvPFg/SppOVZTPLhxqKIi3GC/bhL1GinGhT/yKRuFiHMRg9C04A7NrZTj6Rs8nEYokkUK7+HNlg2gI4VU71G3k= MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1d18c032-35b6-448b-6532-08d726be5eeb X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Aug 2019 05:05:37.5830 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: inzsoMqKWIfgZA8isE1ec53onSznhiCw7nqc8oXYOlXtD42yjOPSQRu/6hndhGkCw8po6AFvLXkuQztdo9Ur8A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR21MB1279 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Dexuan Cui Windows SR-IOV provides a backchannel mechanism in software for communication between a VF driver and a PF driver. These "configuration blocks" are similar in concept to PCI configuration space, but instead of doing reads and writes in 32-bit chunks through a very slow path, packets of up to 128 bytes can be sent or received asynchronously. Nearly every SR-IOV device contains just such a communications channel in hardware, so using this one in software is usually optional. Using the software channel, however, allows driver implementers to leverage software tools that fuzz the communications channel looking for vulnerabilities. The usage model for these packets puts the responsibility for reading or writing on the VF driver. The VF driver sends a read or a write packet, indicating which "block" is being referred to by number. If the PF driver wishes to initiate communication, it can "invalidate" one or more of the first 64 blocks. This invalidation is delivered via a callback supplied by the VF driver by this driver. No protocol is implied, except that supplied by the PF and VF drivers. Signed-off-by: Jake Oshins Signed-off-by: Dexuan Cui Cc: Haiyang Zhang Cc: K. Y. Srinivasan Cc: Stephen Hemminger Signed-off-by: Saeed Mahameed Signed-off-by: Haiyang Zhang --- drivers/pci/controller/pci-hyperv.c | 302 ++++++++++++++++++++++++++++++++++++ include/linux/hyperv.h | 15 ++ 2 files changed, 317 insertions(+) diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 40b6254..57adeca 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -365,6 +365,39 @@ struct pci_delete_interrupt { struct tran_int_desc int_desc; } __packed; +/* + * Note: the VM must pass a valid block id, wslot and bytes_requested. + */ +struct pci_read_block { + struct pci_message message_type; + u32 block_id; + union win_slot_encoding wslot; + u32 bytes_requested; +} __packed; + +struct pci_read_block_response { + struct vmpacket_descriptor hdr; + u32 status; + u8 bytes[HV_CONFIG_BLOCK_SIZE_MAX]; +} __packed; + +/* + * Note: the VM must pass a valid block id, wslot and byte_count. + */ +struct pci_write_block { + struct pci_message message_type; + u32 block_id; + union win_slot_encoding wslot; + u32 byte_count; + u8 bytes[HV_CONFIG_BLOCK_SIZE_MAX]; +} __packed; + +struct pci_dev_inval_block { + struct pci_incoming_message incoming; + union win_slot_encoding wslot; + u64 block_mask; +} __packed; + struct pci_dev_incoming { struct pci_incoming_message incoming; union win_slot_encoding wslot; @@ -499,6 +532,9 @@ struct hv_pci_dev { struct hv_pcibus_device *hbus; struct work_struct wrk; + void (*block_invalidate)(void *context, u64 block_mask); + void *invalidate_context; + /* * What would be observed if one wrote 0xFFFFFFFF to a BAR and then * read it back, for each of the BAR offsets within config space. @@ -817,6 +853,256 @@ static int hv_pcifront_write_config(struct pci_bus *bus, unsigned int devfn, .write = hv_pcifront_write_config, }; +/* + * Paravirtual backchannel + * + * Hyper-V SR-IOV provides a backchannel mechanism in software for + * communication between a VF driver and a PF driver. These + * "configuration blocks" are similar in concept to PCI configuration space, + * but instead of doing reads and writes in 32-bit chunks through a very slow + * path, packets of up to 128 bytes can be sent or received asynchronously. + * + * Nearly every SR-IOV device contains just such a communications channel in + * hardware, so using this one in software is usually optional. Using the + * software channel, however, allows driver implementers to leverage software + * tools that fuzz the communications channel looking for vulnerabilities. + * + * The usage model for these packets puts the responsibility for reading or + * writing on the VF driver. The VF driver sends a read or a write packet, + * indicating which "block" is being referred to by number. + * + * If the PF driver wishes to initiate communication, it can "invalidate" one or + * more of the first 64 blocks. This invalidation is delivered via a callback + * supplied by the VF driver by this driver. + * + * No protocol is implied, except that supplied by the PF and VF drivers. + */ + +struct hv_read_config_compl { + struct hv_pci_compl comp_pkt; + void *buf; + unsigned int len; + unsigned int bytes_returned; +}; + +/** + * hv_pci_read_config_compl() - Invoked when a response packet + * for a read config block operation arrives. + * @context: Identifies the read config operation + * @resp: The response packet itself + * @resp_packet_size: Size in bytes of the response packet + */ +static void hv_pci_read_config_compl(void *context, struct pci_response *resp, + int resp_packet_size) +{ + struct hv_read_config_compl *comp = context; + struct pci_read_block_response *read_resp = + (struct pci_read_block_response *)resp; + unsigned int data_len, hdr_len; + + hdr_len = offsetof(struct pci_read_block_response, bytes); + if (resp_packet_size < hdr_len) { + comp->comp_pkt.completion_status = -1; + goto out; + } + + data_len = resp_packet_size - hdr_len; + if (data_len > 0 && read_resp->status == 0) { + comp->bytes_returned = min(comp->len, data_len); + memcpy(comp->buf, read_resp->bytes, comp->bytes_returned); + } else { + comp->bytes_returned = 0; + } + + comp->comp_pkt.completion_status = read_resp->status; +out: + complete(&comp->comp_pkt.host_event); +} + +/** + * hv_read_config_block() - Sends a read config block request to + * the back-end driver running in the Hyper-V parent partition. + * @pdev: The PCI driver's representation for this device. + * @buf: Buffer into which the config block will be copied. + * @len: Size in bytes of buf. + * @block_id: Identifies the config block which has been requested. + * @bytes_returned: Size which came back from the back-end driver. + * + * Return: 0 on success, -errno on failure + */ +int hv_read_config_block(struct pci_dev *pdev, void *buf, unsigned int len, + unsigned int block_id, unsigned int *bytes_returned) +{ + struct hv_pcibus_device *hbus = + container_of(pdev->bus->sysdata, struct hv_pcibus_device, + sysdata); + struct { + struct pci_packet pkt; + char buf[sizeof(struct pci_read_block)]; + } pkt; + struct hv_read_config_compl comp_pkt; + struct pci_read_block *read_blk; + int ret; + + if (len == 0 || len > HV_CONFIG_BLOCK_SIZE_MAX) + return -EINVAL; + + init_completion(&comp_pkt.comp_pkt.host_event); + comp_pkt.buf = buf; + comp_pkt.len = len; + + memset(&pkt, 0, sizeof(pkt)); + pkt.pkt.completion_func = hv_pci_read_config_compl; + pkt.pkt.compl_ctxt = &comp_pkt; + read_blk = (struct pci_read_block *)&pkt.pkt.message; + read_blk->message_type.type = PCI_READ_BLOCK; + read_blk->wslot.slot = devfn_to_wslot(pdev->devfn); + read_blk->block_id = block_id; + read_blk->bytes_requested = len; + + ret = vmbus_sendpacket(hbus->hdev->channel, read_blk, + sizeof(*read_blk), (unsigned long)&pkt.pkt, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret) + return ret; + + ret = wait_for_response(hbus->hdev, &comp_pkt.comp_pkt.host_event); + if (ret) + return ret; + + if (comp_pkt.comp_pkt.completion_status != 0 || + comp_pkt.bytes_returned == 0) { + dev_err(&hbus->hdev->device, + "Read Config Block failed: 0x%x, bytes_returned=%d\n", + comp_pkt.comp_pkt.completion_status, + comp_pkt.bytes_returned); + return -EIO; + } + + *bytes_returned = comp_pkt.bytes_returned; + return 0; +} +EXPORT_SYMBOL(hv_read_config_block); + +/** + * hv_pci_write_config_compl() - Invoked when a response packet for a write + * config block operation arrives. + * @context: Identifies the write config operation + * @resp: The response packet itself + * @resp_packet_size: Size in bytes of the response packet + */ +static void hv_pci_write_config_compl(void *context, struct pci_response *resp, + int resp_packet_size) +{ + struct hv_pci_compl *comp_pkt = context; + + comp_pkt->completion_status = resp->status; + complete(&comp_pkt->host_event); +} + +/** + * hv_write_config_block() - Sends a write config block request to the + * back-end driver running in the Hyper-V parent partition. + * @pdev: The PCI driver's representation for this device. + * @buf: Buffer from which the config block will be copied. + * @len: Size in bytes of buf. + * @block_id: Identifies the config block which is being written. + * + * Return: 0 on success, -errno on failure + */ +int hv_write_config_block(struct pci_dev *pdev, void *buf, unsigned int len, + unsigned int block_id) +{ + struct hv_pcibus_device *hbus = + container_of(pdev->bus->sysdata, struct hv_pcibus_device, + sysdata); + struct { + struct pci_packet pkt; + char buf[sizeof(struct pci_write_block)]; + u32 reserved; + } pkt; + struct hv_pci_compl comp_pkt; + struct pci_write_block *write_blk; + u32 pkt_size; + int ret; + + if (len == 0 || len > HV_CONFIG_BLOCK_SIZE_MAX) + return -EINVAL; + + init_completion(&comp_pkt.host_event); + + memset(&pkt, 0, sizeof(pkt)); + pkt.pkt.completion_func = hv_pci_write_config_compl; + pkt.pkt.compl_ctxt = &comp_pkt; + write_blk = (struct pci_write_block *)&pkt.pkt.message; + write_blk->message_type.type = PCI_WRITE_BLOCK; + write_blk->wslot.slot = devfn_to_wslot(pdev->devfn); + write_blk->block_id = block_id; + write_blk->byte_count = len; + memcpy(write_blk->bytes, buf, len); + pkt_size = offsetof(struct pci_write_block, bytes) + len; + /* + * This quirk is required on some hosts shipped around 2018, because + * these hosts don't check the pkt_size correctly (new hosts have been + * fixed since early 2019). The quirk is also safe on very old hosts + * and new hosts, because, on them, what really matters is the length + * specified in write_blk->byte_count. + */ + pkt_size += sizeof(pkt.reserved); + + ret = vmbus_sendpacket(hbus->hdev->channel, write_blk, pkt_size, + (unsigned long)&pkt.pkt, VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret) + return ret; + + ret = wait_for_response(hbus->hdev, &comp_pkt.host_event); + if (ret) + return ret; + + if (comp_pkt.completion_status != 0) { + dev_err(&hbus->hdev->device, + "Write Config Block failed: 0x%x\n", + comp_pkt.completion_status); + return -EIO; + } + + return 0; +} +EXPORT_SYMBOL(hv_write_config_block); + +/** + * hv_register_block_invalidate() - Invoked when a config block invalidation + * arrives from the back-end driver. + * @pdev: The PCI driver's representation for this device. + * @context: Identifies the device. + * @block_invalidate: Identifies all of the blocks being invalidated. + * + * Return: 0 on success, -errno on failure + */ +int hv_register_block_invalidate(struct pci_dev *pdev, void *context, + void (*block_invalidate)(void *context, + u64 block_mask)) +{ + struct hv_pcibus_device *hbus = + container_of(pdev->bus->sysdata, struct hv_pcibus_device, + sysdata); + struct hv_pci_dev *hpdev; + + hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn)); + if (!hpdev) + return -ENODEV; + + hpdev->block_invalidate = block_invalidate; + hpdev->invalidate_context = context; + + put_pcichild(hpdev); + return 0; + +} +EXPORT_SYMBOL(hv_register_block_invalidate); + /* Interrupt management hooks */ static void hv_int_desc_free(struct hv_pci_dev *hpdev, struct tran_int_desc *int_desc) @@ -1968,6 +2254,7 @@ static void hv_pci_onchannelcallback(void *context) struct pci_response *response; struct pci_incoming_message *new_message; struct pci_bus_relations *bus_rel; + struct pci_dev_inval_block *inval; struct pci_dev_incoming *dev_message; struct hv_pci_dev *hpdev; @@ -2045,6 +2332,21 @@ static void hv_pci_onchannelcallback(void *context) } break; + case PCI_INVALIDATE_BLOCK: + + inval = (struct pci_dev_inval_block *)buffer; + hpdev = get_pcichild_wslot(hbus, + inval->wslot.slot); + if (hpdev) { + if (hpdev->block_invalidate) { + hpdev->block_invalidate( + hpdev->invalidate_context, + inval->block_mask); + } + put_pcichild(hpdev); + } + break; + default: dev_warn(&hbus->hdev->device, "Unimplemented protocol message %x\n", diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 6256cc3..9d37f8c 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1578,4 +1578,19 @@ struct vmpacket_descriptor * for (pkt = hv_pkt_iter_first(channel); pkt; \ pkt = hv_pkt_iter_next(channel, pkt)) +/* + * Functions for passing data between SR-IOV PF and VF drivers. The VF driver + * sends requests to read and write blocks. Each block must be 128 bytes or + * smaller. Optionally, the VF driver can register a callback function which + * will be invoked when the host says that one or more of the first 64 block + * IDs is "invalid" which means that the VF driver should reread them. + */ +#define HV_CONFIG_BLOCK_SIZE_MAX 128 +int hv_read_config_block(struct pci_dev *dev, void *buf, unsigned int buf_len, + unsigned int block_id, unsigned int *bytes_returned); +int hv_write_config_block(struct pci_dev *dev, void *buf, unsigned int len, + unsigned int block_id); +int hv_register_block_invalidate(struct pci_dev *dev, void *context, + void (*block_invalidate)(void *context, + u64 block_mask)); #endif /* _HYPERV_H */ From patchwork Thu Aug 22 05:05:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haiyang Zhang X-Patchwork-Id: 11108429 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4DC871399 for ; Thu, 22 Aug 2019 05:06:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1888A22CE3 for ; Thu, 22 Aug 2019 05:06:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=microsoft.com header.i=@microsoft.com header.b="LJSQO+uY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731133AbfHVFF6 (ORCPT ); Thu, 22 Aug 2019 01:05:58 -0400 Received: from mail-eopbgr810109.outbound.protection.outlook.com ([40.107.81.109]:28619 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731265AbfHVFF6 (ORCPT ); Thu, 22 Aug 2019 01:05:58 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TkPtwYFnYZI/Tw4k7pPQtxCvNqnyyON489wgbNGDI4jV+JLfNPEWztCdk6Ui4j0tM+Tay7vr4Oi/eZtI6YNGcZcgUtrUnw7WkL3sDGiZw4h636wbwiFCPWXf6a6LnWfXBei5ilfpsJDu0fYvrqM+7SF2Xb9BFXgEMXMlEAYvZHnMqV8kRCqeNnZZqlWsBgOVQ4hUKdx+v4dj+gKOKzpeQQ7Yz1BM7EbJQIBT3FwqHLqAkd066GZTRU9suBSff3yrgbtdBR+1xbndQ4/Th4iOHY7BJQIzfm528ZenNivK1+kRGpwcaqd1ThYxnq2Nw/JEndYGsCAXSpqJVW4B9ekicg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=49pCCLY0UQGnJr+msFhZ/lhUbgof+155r2+qubA1C+M=; b=jDoBaVB25UbAHKXDbaMS/agrHDlkKxo9EizbOS3w9cp8acb5OPGxn/QBboR4NLXPVLhmWqECsUEhFYZwftwWv8WRVr8gvs0G5Il/vzd74lLwjv32baK9C3ZdC96SlFzfeGVsxMtZnaz5WdM264tpQsHIpapOQnB7QcG/2hrebrFEYEcH17QCNTjrOJmPyvf1eAkka9sPnrJgA40lFXaa/zYZ4r7rLxvqR9ABCE56FDVko92Lj34sjOeY8c1yZAxIl9qMbuiNOVnuh5Ptq6hzkQ2exfx/oYlB9l9Ip/e1TLWQV7y9jtHF2H29hBHztjgctqQ1F4dItZvaDwFAtl55lw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=49pCCLY0UQGnJr+msFhZ/lhUbgof+155r2+qubA1C+M=; b=LJSQO+uYHJpdU/1w7GHsK3EaRQe99OQFpEF7x57EbR5z7QfUltwzd2sRqVfH+frDVGUAFfF7Q5U44TqNHYVYgW+SJRI5wiP3uT070qsL3+aFrh0BrwOjgmPV4ktLnSXaImGJURCDHCakCgcAqO4//G8o3q+nvo8wYU5z1pPBSmY= Received: from MN2PR21MB1248.namprd21.prod.outlook.com (20.179.20.225) by MN2PR21MB1279.namprd21.prod.outlook.com (20.179.21.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2220.4; Thu, 22 Aug 2019 05:05:41 +0000 Received: from MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e]) by MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e%3]) with mapi id 15.20.2199.011; Thu, 22 Aug 2019 05:05:41 +0000 From: Haiyang Zhang To: "sashal@kernel.org" , "davem@davemloft.net" , "saeedm@mellanox.com" , "leon@kernel.org" , "eranbe@mellanox.com" , "lorenzo.pieralisi@arm.com" , "bhelgaas@google.com" , "linux-pci@vger.kernel.org" , "linux-hyperv@vger.kernel.org" , "netdev@vger.kernel.org" CC: Haiyang Zhang , KY Srinivasan , Stephen Hemminger , "linux-kernel@vger.kernel.org" Subject: [PATCH net-next,v4, 2/6] PCI: hv: Add a Hyper-V PCI interface driver for software backchannel interface Thread-Topic: [PATCH net-next,v4, 2/6] PCI: hv: Add a Hyper-V PCI interface driver for software backchannel interface Thread-Index: AQHVWKc+GNFRZDxadEKTuhFzjn601Q== Date: Thu, 22 Aug 2019 05:05:41 +0000 Message-ID: <1566450236-36757-3-git-send-email-haiyangz@microsoft.com> References: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> In-Reply-To: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: MWHPR14CA0039.namprd14.prod.outlook.com (2603:10b6:300:12b::25) To MN2PR21MB1248.namprd21.prod.outlook.com (2603:10b6:208:3b::33) authentication-results: spf=none (sender IP is ) smtp.mailfrom=lkmlhyz@microsoft.com; x-ms-exchange-messagesentrepresentingtype: 2 x-mailer: git-send-email 1.8.3.1 x-originating-ip: [13.77.154.182] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 6cc3dabc-c434-4b75-a945-08d726be60fb x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(5600158)(711020)(4605104)(1401327)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020);SRVR:MN2PR21MB1279; x-ms-traffictypediagnostic: MN2PR21MB1279:|MN2PR21MB1279: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:7691; x-forefront-prvs: 01371B902F x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(4636009)(39860400002)(396003)(136003)(366004)(376002)(346002)(189003)(199004)(71200400001)(71190400001)(186003)(446003)(66066001)(2616005)(4326008)(36756003)(6392003)(6436002)(256004)(53936002)(7846003)(7416002)(6512007)(26005)(6486002)(11346002)(316002)(2906002)(2201001)(110136005)(22452003)(54906003)(10090500001)(476003)(25786009)(386003)(7736002)(64756008)(81156014)(66946007)(66446008)(8936002)(10290500003)(478600001)(66476007)(2501003)(102836004)(4720700003)(6116002)(3846002)(6506007)(305945005)(5660300002)(486006)(99286004)(66556008)(81166006)(14454004)(50226002)(8676002)(52116002)(76176011)(142933001)(921003)(1121003);DIR:OUT;SFP:1102;SCL:1;SRVR:MN2PR21MB1279;H:MN2PR21MB1248.namprd21.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: 72v0/CFGN8vThzVMTEhTdEdxs/E/tKB6nRzM6iykUNo4cEGmzfBkG9uF25cFTlpQBf7pgSjHhbE73mEExtYpLJPOAx+uYf4s2e/TZ17OPQiIjrlj2eV/78M9hY8DN09KhP/cXSQQc9KhsyIm9qiiHm5++wH+2WBITzUBp58mGRNPKpXMHmvsHlX3k5HEx/Bk3KcWX8XqOwddGHeVWpQTMD+bS3F/7luEjeYEjQUYcYkywg9mf+LLodiqZT35KcA0Eqkuv8sQK5PRaHHYK7JDMRIney95HOrsjVbnSBrqaQmxbbT9gz8ZdlQWacYoCMXFCHe/DRDDploZAWPVL+x+zOrDJ5B/vFCd5e/aKe5xm9/h+puwY4erTioe4Ard4OshjHTxPwl2JcSJLpzF6sP8672jC9JZy/HeZJ2oCN+OPik= MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6cc3dabc-c434-4b75-a945-08d726be60fb X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Aug 2019 05:05:41.1020 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: TaUir6IjTJRJOpq7UNeP5OJE0+rky/6WYXoU0LxdrcCIgK3zTTLhYb+hFOCFUP3ESxTrOyN1zw3kAKEWegWTqA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR21MB1279 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org This interface driver is a helper driver allows other drivers to have a common interface with the Hyper-V PCI frontend driver. Signed-off-by: Haiyang Zhang Signed-off-by: Saeed Mahameed --- MAINTAINERS | 1 + drivers/pci/Kconfig | 1 + drivers/pci/controller/Kconfig | 7 ++++ drivers/pci/controller/Makefile | 1 + drivers/pci/controller/pci-hyperv-intf.c | 67 ++++++++++++++++++++++++++++++++ drivers/pci/controller/pci-hyperv.c | 12 ++++-- include/linux/hyperv.h | 30 ++++++++++---- 7 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 drivers/pci/controller/pci-hyperv-intf.c diff --git a/MAINTAINERS b/MAINTAINERS index a406947..9860853 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7469,6 +7469,7 @@ F: drivers/hid/hid-hyperv.c F: drivers/hv/ F: drivers/input/serio/hyperv-keyboard.c F: drivers/pci/controller/pci-hyperv.c +F: drivers/pci/controller/pci-hyperv-intf.c F: drivers/net/hyperv/ F: drivers/scsi/storvsc_drv.c F: drivers/uio/uio_hv_generic.c diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 2ab9240..c313de9 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -182,6 +182,7 @@ config PCI_LABEL config PCI_HYPERV tristate "Hyper-V PCI Frontend" depends on X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && X86_64 + select PCI_HYPERV_INTERFACE help The PCI device frontend driver allows the kernel to import arbitrary PCI devices from a PCI backend to support PCI driver domains. diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig index fe9f9f1..70e0782 100644 --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig @@ -281,5 +281,12 @@ config VMD To compile this driver as a module, choose M here: the module will be called vmd. +config PCI_HYPERV_INTERFACE + tristate "Hyper-V PCI Interface" + depends on X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && X86_64 + help + The Hyper-V PCI Interface is a helper driver allows other drivers to + have a common interface with the Hyper-V PCI frontend driver. + source "drivers/pci/controller/dwc/Kconfig" endmenu diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile index d56a507..a2a22c9 100644 --- a/drivers/pci/controller/Makefile +++ b/drivers/pci/controller/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o +obj-$(CONFIG_PCI_HYPERV_INTERFACE) += pci-hyperv-intf.o obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o diff --git a/drivers/pci/controller/pci-hyperv-intf.c b/drivers/pci/controller/pci-hyperv-intf.c new file mode 100644 index 0000000..cc96be4 --- /dev/null +++ b/drivers/pci/controller/pci-hyperv-intf.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Microsoft Corporation. + * + * Author: + * Haiyang Zhang + * + * This small module is a helper driver allows other drivers to + * have a common interface with the Hyper-V PCI frontend driver. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include + +struct hyperv_pci_block_ops hvpci_block_ops; +EXPORT_SYMBOL_GPL(hvpci_block_ops); + +int hyperv_read_cfg_blk(struct pci_dev *dev, void *buf, unsigned int buf_len, + unsigned int block_id, unsigned int *bytes_returned) +{ + if (!hvpci_block_ops.read_block) + return -EOPNOTSUPP; + + return hvpci_block_ops.read_block(dev, buf, buf_len, block_id, + bytes_returned); +} +EXPORT_SYMBOL_GPL(hyperv_read_cfg_blk); + +int hyperv_write_cfg_blk(struct pci_dev *dev, void *buf, unsigned int len, + unsigned int block_id) +{ + if (!hvpci_block_ops.write_block) + return -EOPNOTSUPP; + + return hvpci_block_ops.write_block(dev, buf, len, block_id); +} +EXPORT_SYMBOL_GPL(hyperv_write_cfg_blk); + +int hyperv_reg_block_invalidate(struct pci_dev *dev, void *context, + void (*block_invalidate)(void *context, + u64 block_mask)) +{ + if (!hvpci_block_ops.reg_blk_invalidate) + return -EOPNOTSUPP; + + return hvpci_block_ops.reg_blk_invalidate(dev, context, + block_invalidate); +} +EXPORT_SYMBOL_GPL(hyperv_reg_block_invalidate); + +static void __exit exit_hv_pci_intf(void) +{ +} + +static int __init init_hv_pci_intf(void) +{ + return 0; +} + +module_init(init_hv_pci_intf); +module_exit(exit_hv_pci_intf); + +MODULE_DESCRIPTION("Hyper-V PCI Interface"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 57adeca..9c93ac2 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -983,7 +983,6 @@ int hv_read_config_block(struct pci_dev *pdev, void *buf, unsigned int len, *bytes_returned = comp_pkt.bytes_returned; return 0; } -EXPORT_SYMBOL(hv_read_config_block); /** * hv_pci_write_config_compl() - Invoked when a response packet for a write @@ -1070,7 +1069,6 @@ int hv_write_config_block(struct pci_dev *pdev, void *buf, unsigned int len, return 0; } -EXPORT_SYMBOL(hv_write_config_block); /** * hv_register_block_invalidate() - Invoked when a config block invalidation @@ -1101,7 +1099,6 @@ int hv_register_block_invalidate(struct pci_dev *pdev, void *context, return 0; } -EXPORT_SYMBOL(hv_register_block_invalidate); /* Interrupt management hooks */ static void hv_int_desc_free(struct hv_pci_dev *hpdev, @@ -3045,10 +3042,19 @@ static int hv_pci_remove(struct hv_device *hdev) static void __exit exit_hv_pci_drv(void) { vmbus_driver_unregister(&hv_pci_drv); + + hvpci_block_ops.read_block = NULL; + hvpci_block_ops.write_block = NULL; + hvpci_block_ops.reg_blk_invalidate = NULL; } static int __init init_hv_pci_drv(void) { + /* Initialize PCI block r/w interface */ + hvpci_block_ops.read_block = hv_read_config_block; + hvpci_block_ops.write_block = hv_write_config_block; + hvpci_block_ops.reg_blk_invalidate = hv_register_block_invalidate; + return vmbus_driver_register(&hv_pci_drv); } diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 9d37f8c..2afe6fd 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1579,18 +1579,32 @@ struct vmpacket_descriptor * pkt = hv_pkt_iter_next(channel, pkt)) /* - * Functions for passing data between SR-IOV PF and VF drivers. The VF driver + * Interface for passing data between SR-IOV PF and VF drivers. The VF driver * sends requests to read and write blocks. Each block must be 128 bytes or * smaller. Optionally, the VF driver can register a callback function which * will be invoked when the host says that one or more of the first 64 block * IDs is "invalid" which means that the VF driver should reread them. */ #define HV_CONFIG_BLOCK_SIZE_MAX 128 -int hv_read_config_block(struct pci_dev *dev, void *buf, unsigned int buf_len, - unsigned int block_id, unsigned int *bytes_returned); -int hv_write_config_block(struct pci_dev *dev, void *buf, unsigned int len, - unsigned int block_id); -int hv_register_block_invalidate(struct pci_dev *dev, void *context, - void (*block_invalidate)(void *context, - u64 block_mask)); + +int hyperv_read_cfg_blk(struct pci_dev *dev, void *buf, unsigned int buf_len, + unsigned int block_id, unsigned int *bytes_returned); +int hyperv_write_cfg_blk(struct pci_dev *dev, void *buf, unsigned int len, + unsigned int block_id); +int hyperv_reg_block_invalidate(struct pci_dev *dev, void *context, + void (*block_invalidate)(void *context, + u64 block_mask)); + +struct hyperv_pci_block_ops { + int (*read_block)(struct pci_dev *dev, void *buf, unsigned int buf_len, + unsigned int block_id, unsigned int *bytes_returned); + int (*write_block)(struct pci_dev *dev, void *buf, unsigned int len, + unsigned int block_id); + int (*reg_blk_invalidate)(struct pci_dev *dev, void *context, + void (*block_invalidate)(void *context, + u64 block_mask)); +}; + +extern struct hyperv_pci_block_ops hvpci_block_ops; + #endif /* _HYPERV_H */ From patchwork Thu Aug 22 05:05:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haiyang Zhang X-Patchwork-Id: 11108421 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7CAE81399 for ; Thu, 22 Aug 2019 05:06:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 46CC322CE3 for ; Thu, 22 Aug 2019 05:06:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=microsoft.com header.i=@microsoft.com header.b="ZhjIMyj7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731329AbfHVFGA (ORCPT ); Thu, 22 Aug 2019 01:06:00 -0400 Received: from mail-eopbgr810109.outbound.protection.outlook.com ([40.107.81.109]:28619 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729109AbfHVFF7 (ORCPT ); Thu, 22 Aug 2019 01:05:59 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MOC0k64VcqJ6G955mBpNWt2hpPxCnoUI+Hwqk+vpx0zGzLPj793QDXAie+2wdOJcXAqy9wfXhLzCzq01EsvfdKpz3/OWFAz6aDsMjRSmwMLgWKfdtTmjTzKpCkuMgx9qe3pr2c9mtMqhMR5eHShysHzi6jJ7DEJOpc4E9qEhk7do+L7EfoiIcLhm73Ej5IAQlovMWZGBj9azAi/F621xfGnzx79niMI/W8OJwxTKeV4t9pbCe+xP1J4crNAoR7DYndjaiR7y7gHnyHrhcFFblrVFg5zyDZb6aVIuqMM91+x5FVLjJK5R20+MWzt41KXJMAj35NDYB1Be4P8iR2xCBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=W/t4pIzRFPa12ok2+YyJfBuO/icDpX+o8XSe5rTFbEY=; b=apQO9nEXIzvpkggNQDCfug0+QwUQdziPNSWkxPjb4zYZiP3CG8sDJZf7QTO8WsJ1t2+oyenYrlCksaEp7YDwa7JvHuLpfOYQJ8WSpqMb9PonHzxn2CS4yLQKqN5Rv46D/gOHHlc0FqOkqrUOs88O9ID+j7N3ohr2QpeqzahMAzH3JHE34vtz2yMavCFC6ne1XMd2K4Zwg4IaQw4vOFyNNzH3bsRnCq6uFpfbFfDx3XY4xYO52hj3srwBy1+bvNCp42/LchgUzIHCTMg+jnJ+pEyzJTAd0FJLDbnh9S6xtFNewvQppKFGZGiWGOVYx1aQvYZI0GriK5vllA0qKErghA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=W/t4pIzRFPa12ok2+YyJfBuO/icDpX+o8XSe5rTFbEY=; b=ZhjIMyj76Av5Op/QmpX2ah84QsAI72fd3VJRFOAhOPvNtIDl941l2UJ14x7pKfUVxhn7KhvA2WLKSqWOHnqxH3P21EgWlfOaXFgfuQDHyxMZ7Ngurc+G5vrQ7alJsoO+if3hUKdh/rsjU7R3sK0MlGAscPG8pcfUm0Xr3zpmSpE= Received: from MN2PR21MB1248.namprd21.prod.outlook.com (20.179.20.225) by MN2PR21MB1279.namprd21.prod.outlook.com (20.179.21.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2220.4; Thu, 22 Aug 2019 05:05:47 +0000 Received: from MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e]) by MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e%3]) with mapi id 15.20.2199.011; Thu, 22 Aug 2019 05:05:47 +0000 From: Haiyang Zhang To: "sashal@kernel.org" , "davem@davemloft.net" , "saeedm@mellanox.com" , "leon@kernel.org" , "eranbe@mellanox.com" , "lorenzo.pieralisi@arm.com" , "bhelgaas@google.com" , "linux-pci@vger.kernel.org" , "linux-hyperv@vger.kernel.org" , "netdev@vger.kernel.org" CC: Haiyang Zhang , KY Srinivasan , Stephen Hemminger , "linux-kernel@vger.kernel.org" Subject: [PATCH net-next,v4, 3/6] net/mlx5: Add wrappers for HyperV PCIe operations Thread-Topic: [PATCH net-next,v4, 3/6] net/mlx5: Add wrappers for HyperV PCIe operations Thread-Index: AQHVWKdC+LfkKjDVuEa1rKdzWh1oFA== Date: Thu, 22 Aug 2019 05:05:47 +0000 Message-ID: <1566450236-36757-4-git-send-email-haiyangz@microsoft.com> References: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> In-Reply-To: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: MWHPR14CA0039.namprd14.prod.outlook.com (2603:10b6:300:12b::25) To MN2PR21MB1248.namprd21.prod.outlook.com (2603:10b6:208:3b::33) authentication-results: spf=none (sender IP is ) smtp.mailfrom=lkmlhyz@microsoft.com; x-ms-exchange-messagesentrepresentingtype: 2 x-mailer: git-send-email 1.8.3.1 x-originating-ip: [13.77.154.182] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: d02e305d-e3af-4260-33bc-08d726be64bb x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(5600158)(711020)(4605104)(1401327)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020);SRVR:MN2PR21MB1279; x-ms-traffictypediagnostic: MN2PR21MB1279:|MN2PR21MB1279: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:2449; x-forefront-prvs: 01371B902F x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(4636009)(39860400002)(396003)(136003)(366004)(376002)(346002)(189003)(199004)(71200400001)(71190400001)(186003)(446003)(66066001)(2616005)(4326008)(36756003)(6392003)(6436002)(256004)(53936002)(7846003)(7416002)(6512007)(26005)(6486002)(11346002)(316002)(2906002)(2201001)(110136005)(22452003)(54906003)(10090500001)(476003)(25786009)(386003)(7736002)(64756008)(81156014)(66946007)(66446008)(8936002)(10290500003)(478600001)(66476007)(2501003)(102836004)(4720700003)(6116002)(3846002)(6506007)(305945005)(5660300002)(486006)(99286004)(66556008)(81166006)(14454004)(50226002)(8676002)(52116002)(76176011)(142933001)(921003)(1121003);DIR:OUT;SFP:1102;SCL:1;SRVR:MN2PR21MB1279;H:MN2PR21MB1248.namprd21.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: e6EfDSFjMJWc5CXfvhe7UnA4zoinHJwxFs5JR/zi0xyNzf9Mm4eI72TKe6rhsJ875YfhsOu2/tIjHOOcOonxjPMnEphutxr4WHqWK/BoL5dXLidgia8BIKZWVqPXiqB27Tf61OTUG23PIHjO3NEYwpXTUcU0nmeb4Fa1HbIcb3Rfsp9I4aTXOLaKgWryePNSqBe7l+MGQdSjoLuSQ/+19CQkyNUFaCO+HDiZbqsi9WTBV7IzuU2eDYUiIeeOUfTWhwV9mrq/EDJMi+t64Hnh+NgegXDNvsMJjy0d28TrjfpfAlOSkNvAEKo6oEStCIkKarjnYR9zsGCPvuotZIXl5Er0mFnwI8zZrpsp1boXtClFlyfyEwdU6bUcNTikWsirXFNJv7uadNFvfGtaY6y9xHCl9tgSJFxJ5xJrsYYTDxA= MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: d02e305d-e3af-4260-33bc-08d726be64bb X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Aug 2019 05:05:47.3945 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: qB4LYSMUczPlE/pQgjYddxDbu82GvF5vxkdJcL8I74erF1VCBU2SbkgPil6EHuvumJZA1eHDi4JXgvqO4A+jbA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR21MB1279 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Eran Ben Elisha Add wrapper functions for HyperV PCIe read / write / block_invalidate_register operations. This will be used as an infrastructure in the downstream patch for software communication. This will be enabled by default if CONFIG_PCI_HYPERV_INTERFACE is set. Signed-off-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed Signed-off-by: Haiyang Zhang --- drivers/net/ethernet/mellanox/mlx5/core/Makefile | 1 + drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c | 64 ++++++++++++++++++++++++ drivers/net/ethernet/mellanox/mlx5/core/lib/hv.h | 22 ++++++++ 3 files changed, 87 insertions(+) create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/hv.h diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile index bcf3655..fd32a5b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile +++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile @@ -45,6 +45,7 @@ mlx5_core-$(CONFIG_MLX5_ESWITCH) += eswitch.o eswitch_offloads.o eswitch_offlo mlx5_core-$(CONFIG_MLX5_MPFS) += lib/mpfs.o mlx5_core-$(CONFIG_VXLAN) += lib/vxlan.o mlx5_core-$(CONFIG_PTP_1588_CLOCK) += lib/clock.o +mlx5_core-$(CONFIG_PCI_HYPERV_INTERFACE) += lib/hv.o # # Ipoib netdev diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c new file mode 100644 index 0000000..cf08d02 --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +// Copyright (c) 2018 Mellanox Technologies + +#include +#include "mlx5_core.h" +#include "lib/hv.h" + +static int mlx5_hv_config_common(struct mlx5_core_dev *dev, void *buf, int len, + int offset, bool read) +{ + int rc = -EOPNOTSUPP; + int bytes_returned; + int block_id; + + if (offset % HV_CONFIG_BLOCK_SIZE_MAX || len % HV_CONFIG_BLOCK_SIZE_MAX) + return -EINVAL; + + block_id = offset / HV_CONFIG_BLOCK_SIZE_MAX; + + rc = read ? + hyperv_read_cfg_blk(dev->pdev, buf, + HV_CONFIG_BLOCK_SIZE_MAX, block_id, + &bytes_returned) : + hyperv_write_cfg_blk(dev->pdev, buf, + HV_CONFIG_BLOCK_SIZE_MAX, block_id); + + /* Make sure len bytes were read successfully */ + if (read) + rc |= !(len == bytes_returned); + + if (rc) { + mlx5_core_err(dev, "Failed to %s hv config, err = %d, len = %d, offset = %d\n", + read ? "read" : "write", rc, len, + offset); + return rc; + } + + return 0; +} + +int mlx5_hv_read_config(struct mlx5_core_dev *dev, void *buf, int len, + int offset) +{ + return mlx5_hv_config_common(dev, buf, len, offset, true); +} + +int mlx5_hv_write_config(struct mlx5_core_dev *dev, void *buf, int len, + int offset) +{ + return mlx5_hv_config_common(dev, buf, len, offset, false); +} + +int mlx5_hv_register_invalidate(struct mlx5_core_dev *dev, void *context, + void (*block_invalidate)(void *context, + u64 block_mask)) +{ + return hyperv_reg_block_invalidate(dev->pdev, context, + block_invalidate); +} + +void mlx5_hv_unregister_invalidate(struct mlx5_core_dev *dev) +{ + hyperv_reg_block_invalidate(dev->pdev, NULL, NULL); +} diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.h new file mode 100644 index 0000000..f9a4557 --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ +/* Copyright (c) 2019 Mellanox Technologies. */ + +#ifndef __LIB_HV_H__ +#define __LIB_HV_H__ + +#if IS_ENABLED(CONFIG_PCI_HYPERV_INTERFACE) + +#include +#include + +int mlx5_hv_read_config(struct mlx5_core_dev *dev, void *buf, int len, + int offset); +int mlx5_hv_write_config(struct mlx5_core_dev *dev, void *buf, int len, + int offset); +int mlx5_hv_register_invalidate(struct mlx5_core_dev *dev, void *context, + void (*block_invalidate)(void *context, + u64 block_mask)); +void mlx5_hv_unregister_invalidate(struct mlx5_core_dev *dev); +#endif + +#endif /* __LIB_HV_H__ */ From patchwork Thu Aug 22 05:05:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haiyang Zhang X-Patchwork-Id: 11108425 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EB91514DE for ; Thu, 22 Aug 2019 05:06:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id ACDB0233A2 for ; Thu, 22 Aug 2019 05:06:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=microsoft.com header.i=@microsoft.com header.b="RtKiG9KN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731350AbfHVFGD (ORCPT ); Thu, 22 Aug 2019 01:06:03 -0400 Received: from mail-eopbgr810109.outbound.protection.outlook.com ([40.107.81.109]:28619 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731265AbfHVFGB (ORCPT ); Thu, 22 Aug 2019 01:06:01 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=jnuMUoYlDV32/MToHA3YPMKWuO8VVkJcigetk3TbEArsj983EsQ5qhssfh35mBsqyI3R+5/fu2XQqJ5fGiTN50/jDwLG16tG1rI3/lZ+xoFJCl0UXPWuVbw7Kz4ONDp8tVFa/PYMLntIkwmSqmMVQQbfJpx1wD/lAqj3ChkuafKVRc28dIVeyDJgkIAjNa7PdgglllNWOl1dpUjog4YG3TJ/Btq9cjq6oWpPiDBEW+Nsb+D85vD4h+yv1KplD9ryGzIsPIPTJe998+MMDTIMDs7MJinLoYPktqrifTI/1WNzSkHA/O8bcQNRYUglYrJg609cR2JhG1sms+Dl1XqS3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=t0HVgZLcz4H2uUhaSYwmdiAfey8AfB4Y1QFMPHTHRE4=; b=Cdxum2ivjcoMOQtvRtTPcGpSy0+xTUu9GCXcPNYybxaQ7UYAqUBPdsTz8IG8WzX/dh9iUeUyD6LZYaZq51jNnWJTVpjyGCXgaiY4nnWUvZEFN89IcSbf2ONdvg0gu/lyrxEeEtOLMLNURmorwVUyoD4woLrNr/aiMIdEDUfxOzIwxveSRG0KjBG85KhYs20GMXCw7uIqfjLgS+j4uipxsqRpyiSMGwgk3CYFxif+E97VC6DKuX1GVjiY87ooz9elbyePCHOsMHFI4hSTusqEG91PDVXQFPrb7iXyejPoyI140Gv4CexJTGMefdayQQX14th6V+TMVTeiEHVnUJ+alA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=t0HVgZLcz4H2uUhaSYwmdiAfey8AfB4Y1QFMPHTHRE4=; b=RtKiG9KNlR791moOCykteyzqW8a9MscJwMn9xKeQHgFAydt6VKRzM3xVQhTGwJ7duw9EgpzcUMM25qEdLHS5V3JvpeSBGCYNxAq7vR39dtGXmIaD5HqGdt7m07efHfvK8Kn9JGfrz3G/FoPj/LuMhUo6XC0u+G+VH8JSXTbSmnY= Received: from MN2PR21MB1248.namprd21.prod.outlook.com (20.179.20.225) by MN2PR21MB1279.namprd21.prod.outlook.com (20.179.21.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2220.4; Thu, 22 Aug 2019 05:05:51 +0000 Received: from MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e]) by MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e%3]) with mapi id 15.20.2199.011; Thu, 22 Aug 2019 05:05:51 +0000 From: Haiyang Zhang To: "sashal@kernel.org" , "davem@davemloft.net" , "saeedm@mellanox.com" , "leon@kernel.org" , "eranbe@mellanox.com" , "lorenzo.pieralisi@arm.com" , "bhelgaas@google.com" , "linux-pci@vger.kernel.org" , "linux-hyperv@vger.kernel.org" , "netdev@vger.kernel.org" CC: Haiyang Zhang , KY Srinivasan , Stephen Hemminger , "linux-kernel@vger.kernel.org" Subject: [PATCH net-next,v4, 4/6] net/mlx5: Add HV VHCA infrastructure Thread-Topic: [PATCH net-next,v4, 4/6] net/mlx5: Add HV VHCA infrastructure Thread-Index: AQHVWKdE9IMeMzawTEODKtd9TuiDDA== Date: Thu, 22 Aug 2019 05:05:51 +0000 Message-ID: <1566450236-36757-5-git-send-email-haiyangz@microsoft.com> References: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> In-Reply-To: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: MWHPR14CA0039.namprd14.prod.outlook.com (2603:10b6:300:12b::25) To MN2PR21MB1248.namprd21.prod.outlook.com (2603:10b6:208:3b::33) authentication-results: spf=none (sender IP is ) smtp.mailfrom=lkmlhyz@microsoft.com; x-ms-exchange-messagesentrepresentingtype: 2 x-mailer: git-send-email 1.8.3.1 x-originating-ip: [13.77.154.182] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 0e523aea-3b8e-495e-b83b-08d726be6754 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(5600158)(711020)(4605104)(1401327)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020);SRVR:MN2PR21MB1279; x-ms-traffictypediagnostic: MN2PR21MB1279:|MN2PR21MB1279: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:4714; x-forefront-prvs: 01371B902F x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(4636009)(39860400002)(396003)(136003)(366004)(376002)(346002)(189003)(199004)(71200400001)(71190400001)(186003)(446003)(66066001)(2616005)(4326008)(36756003)(6392003)(6436002)(256004)(53936002)(7846003)(7416002)(6512007)(26005)(6486002)(14444005)(11346002)(316002)(2906002)(2201001)(110136005)(22452003)(54906003)(10090500001)(476003)(30864003)(25786009)(386003)(7736002)(64756008)(81156014)(66946007)(66446008)(8936002)(10290500003)(478600001)(66476007)(2501003)(102836004)(4720700003)(6116002)(3846002)(6506007)(305945005)(5660300002)(486006)(99286004)(66556008)(81166006)(14454004)(50226002)(8676002)(52116002)(76176011)(142933001)(921003)(1121003);DIR:OUT;SFP:1102;SCL:1;SRVR:MN2PR21MB1279;H:MN2PR21MB1248.namprd21.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: ljB1ZoykO6GZ5FKQLPYiF3GVpbVu65q/vkK2p+zZfvOUbH1/XypTQY0m0iOdh6XfX0m7tQ/Idd6jIiHeq4D0v7GAURPX653D3TpkW4B5ebZYqICGuHDgvkewuO52VvWiylO1gMCE53+Hk9oR9z5v5Z5YsUDWncyDTSHw8Xppqa5p7cVOsHJPAkvi2Z2FxNRnML9FGkWSgrBZgndm4eSW+drDCBKvayPhG2HBhdEFl/H8q6YmBsWS60MvMypwNjTELTOP5kOMC6cFkBQxVmVVzt0Hl2o+QRAteSrytgGuzt52vt7+YH7QD9qu48sU1lgXStXJEgo82EEmirhL8kvLI8ly0TZwEIIRjcporpH13G5Vm36vjnD70UdYWxKjioOhSwmXv0ZPmbdJiHH25+cJtwMFc6Eu990HlnfYxHXQF3U= MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0e523aea-3b8e-495e-b83b-08d726be6754 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Aug 2019 05:05:51.6750 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: DhQN+Z56XYNMXGHTcdHAFIzRJX+9WyIkx/NjFFzC8c67Pg+bWSnmJ/SUFEy1HzbPJc92kK/qiT/5Qg6Jayd8bA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR21MB1279 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Eran Ben Elisha HV VHCA is a layer which provides PF to VF communication channel based on HyperV PCI config channel. It implements Mellanox's Inter VHCA control communication protocol. The protocol contains control block in order to pass messages between the PF and VF drivers, and data blocks in order to pass actual data. The infrastructure is agent based. Each agent will be responsible of contiguous buffer blocks in the VHCA config space. This infrastructure will bind agents to their blocks, and those agents can only access read/write the buffer blocks assigned to them. Each agent will provide three callbacks (control, invalidate, cleanup). Control will be invoked when block-0 is invalidated with a command that concerns this agent. Invalidate callback will be invoked if one of the blocks assigned to this agent was invalidated. Cleanup will be invoked before the agent is being freed in order to clean all of its open resources or deferred works. Block-0 serves as the control block. All execution commands from the PF will be written by the PF over this block. VF will ack on those by writing on block-0 as well. Its format is described by struct mlx5_hv_vhca_control_block layout. Signed-off-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed Signed-off-by: Haiyang Zhang --- drivers/net/ethernet/mellanox/mlx5/core/Makefile | 2 +- .../net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c | 253 +++++++++++++++++++++ .../net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h | 102 +++++++++ drivers/net/ethernet/mellanox/mlx5/core/main.c | 7 + include/linux/mlx5/driver.h | 2 + 5 files changed, 365 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile index fd32a5b..8d443fc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile +++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile @@ -45,7 +45,7 @@ mlx5_core-$(CONFIG_MLX5_ESWITCH) += eswitch.o eswitch_offloads.o eswitch_offlo mlx5_core-$(CONFIG_MLX5_MPFS) += lib/mpfs.o mlx5_core-$(CONFIG_VXLAN) += lib/vxlan.o mlx5_core-$(CONFIG_PTP_1588_CLOCK) += lib/clock.o -mlx5_core-$(CONFIG_PCI_HYPERV_INTERFACE) += lib/hv.o +mlx5_core-$(CONFIG_PCI_HYPERV_INTERFACE) += lib/hv.o lib/hv_vhca.o # # Ipoib netdev diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c new file mode 100644 index 0000000..84d1d75 --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +// Copyright (c) 2018 Mellanox Technologies + +#include +#include "mlx5_core.h" +#include "lib/hv.h" +#include "lib/hv_vhca.h" + +struct mlx5_hv_vhca { + struct mlx5_core_dev *dev; + struct workqueue_struct *work_queue; + struct mlx5_hv_vhca_agent *agents[MLX5_HV_VHCA_AGENT_MAX]; + struct mutex agents_lock; /* Protect agents array */ +}; + +struct mlx5_hv_vhca_work { + struct work_struct invalidate_work; + struct mlx5_hv_vhca *hv_vhca; + u64 block_mask; +}; + +struct mlx5_hv_vhca_data_block { + u16 sequence; + u16 offset; + u8 reserved[4]; + u64 data[15]; +}; + +struct mlx5_hv_vhca_agent { + enum mlx5_hv_vhca_agent_type type; + struct mlx5_hv_vhca *hv_vhca; + void *priv; + u16 seq; + void (*control)(struct mlx5_hv_vhca_agent *agent, + struct mlx5_hv_vhca_control_block *block); + void (*invalidate)(struct mlx5_hv_vhca_agent *agent, + u64 block_mask); + void (*cleanup)(struct mlx5_hv_vhca_agent *agent); +}; + +struct mlx5_hv_vhca *mlx5_hv_vhca_create(struct mlx5_core_dev *dev) +{ + struct mlx5_hv_vhca *hv_vhca = NULL; + + hv_vhca = kzalloc(sizeof(*hv_vhca), GFP_KERNEL); + if (!hv_vhca) + return ERR_PTR(-ENOMEM); + + hv_vhca->work_queue = create_singlethread_workqueue("mlx5_hv_vhca"); + if (!hv_vhca->work_queue) { + kfree(hv_vhca); + return ERR_PTR(-ENOMEM); + } + + hv_vhca->dev = dev; + mutex_init(&hv_vhca->agents_lock); + + return hv_vhca; +} + +void mlx5_hv_vhca_destroy(struct mlx5_hv_vhca *hv_vhca) +{ + if (IS_ERR_OR_NULL(hv_vhca)) + return; + + destroy_workqueue(hv_vhca->work_queue); + kfree(hv_vhca); +} + +static void mlx5_hv_vhca_invalidate_work(struct work_struct *work) +{ + struct mlx5_hv_vhca_work *hwork; + struct mlx5_hv_vhca *hv_vhca; + int i; + + hwork = container_of(work, struct mlx5_hv_vhca_work, invalidate_work); + hv_vhca = hwork->hv_vhca; + + mutex_lock(&hv_vhca->agents_lock); + for (i = 0; i < MLX5_HV_VHCA_AGENT_MAX; i++) { + struct mlx5_hv_vhca_agent *agent = hv_vhca->agents[i]; + + if (!agent || !agent->invalidate) + continue; + + if (!(BIT(agent->type) & hwork->block_mask)) + continue; + + agent->invalidate(agent, hwork->block_mask); + } + mutex_unlock(&hv_vhca->agents_lock); + + kfree(hwork); +} + +void mlx5_hv_vhca_invalidate(void *context, u64 block_mask) +{ + struct mlx5_hv_vhca *hv_vhca = (struct mlx5_hv_vhca *)context; + struct mlx5_hv_vhca_work *work; + + work = kzalloc(sizeof(*work), GFP_ATOMIC); + if (!work) + return; + + INIT_WORK(&work->invalidate_work, mlx5_hv_vhca_invalidate_work); + work->hv_vhca = hv_vhca; + work->block_mask = block_mask; + + queue_work(hv_vhca->work_queue, &work->invalidate_work); +} + +int mlx5_hv_vhca_init(struct mlx5_hv_vhca *hv_vhca) +{ + if (IS_ERR_OR_NULL(hv_vhca)) + return IS_ERR_OR_NULL(hv_vhca); + + return mlx5_hv_register_invalidate(hv_vhca->dev, hv_vhca, + mlx5_hv_vhca_invalidate); +} + +void mlx5_hv_vhca_cleanup(struct mlx5_hv_vhca *hv_vhca) +{ + int i; + + if (IS_ERR_OR_NULL(hv_vhca)) + return; + + mutex_lock(&hv_vhca->agents_lock); + for (i = 0; i < MLX5_HV_VHCA_AGENT_MAX; i++) + WARN_ON(hv_vhca->agents[i]); + + mutex_unlock(&hv_vhca->agents_lock); + + mlx5_hv_unregister_invalidate(hv_vhca->dev); +} + +struct mlx5_hv_vhca_agent * +mlx5_hv_vhca_agent_create(struct mlx5_hv_vhca *hv_vhca, + enum mlx5_hv_vhca_agent_type type, + void (*control)(struct mlx5_hv_vhca_agent*, + struct mlx5_hv_vhca_control_block *block), + void (*invalidate)(struct mlx5_hv_vhca_agent*, + u64 block_mask), + void (*cleaup)(struct mlx5_hv_vhca_agent *agent), + void *priv) +{ + struct mlx5_hv_vhca_agent *agent; + + if (IS_ERR_OR_NULL(hv_vhca)) + return ERR_PTR(-ENOMEM); + + if (type >= MLX5_HV_VHCA_AGENT_MAX) + return ERR_PTR(-EINVAL); + + mutex_lock(&hv_vhca->agents_lock); + if (hv_vhca->agents[type]) { + mutex_unlock(&hv_vhca->agents_lock); + return ERR_PTR(-EINVAL); + } + mutex_unlock(&hv_vhca->agents_lock); + + agent = kzalloc(sizeof(*agent), GFP_KERNEL); + if (!agent) + return ERR_PTR(-ENOMEM); + + agent->type = type; + agent->hv_vhca = hv_vhca; + agent->priv = priv; + agent->control = control; + agent->invalidate = invalidate; + agent->cleanup = cleaup; + + mutex_lock(&hv_vhca->agents_lock); + hv_vhca->agents[type] = agent; + mutex_unlock(&hv_vhca->agents_lock); + + return agent; +} + +void mlx5_hv_vhca_agent_destroy(struct mlx5_hv_vhca_agent *agent) +{ + struct mlx5_hv_vhca *hv_vhca = agent->hv_vhca; + + mutex_lock(&hv_vhca->agents_lock); + + if (WARN_ON(agent != hv_vhca->agents[agent->type])) { + mutex_unlock(&hv_vhca->agents_lock); + return; + } + + hv_vhca->agents[agent->type] = NULL; + mutex_unlock(&hv_vhca->agents_lock); + + if (agent->cleanup) + agent->cleanup(agent); + + kfree(agent); +} + +static int mlx5_hv_vhca_data_block_prepare(struct mlx5_hv_vhca_agent *agent, + struct mlx5_hv_vhca_data_block *data_block, + void *src, int len, int *offset) +{ + int bytes = min_t(int, (int)sizeof(data_block->data), len); + + data_block->sequence = agent->seq; + data_block->offset = (*offset)++; + memcpy(data_block->data, src, bytes); + + return bytes; +} + +static void mlx5_hv_vhca_agent_seq_update(struct mlx5_hv_vhca_agent *agent) +{ + agent->seq++; +} + +int mlx5_hv_vhca_agent_write(struct mlx5_hv_vhca_agent *agent, + void *buf, int len) +{ + int offset = agent->type * HV_CONFIG_BLOCK_SIZE_MAX; + int block_offset = 0; + int total = 0; + int err; + + while (len) { + struct mlx5_hv_vhca_data_block data_block = {0}; + int bytes; + + bytes = mlx5_hv_vhca_data_block_prepare(agent, &data_block, + buf + total, + len, &block_offset); + if (!bytes) + return -ENOMEM; + + err = mlx5_hv_write_config(agent->hv_vhca->dev, &data_block, + sizeof(data_block), offset); + if (err) + return err; + + total += bytes; + len -= bytes; + } + + mlx5_hv_vhca_agent_seq_update(agent); + + return 0; +} + +void *mlx5_hv_vhca_agent_priv(struct mlx5_hv_vhca_agent *agent) +{ + return agent->priv; +} diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h new file mode 100644 index 0000000..cdf1303 --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ +/* Copyright (c) 2019 Mellanox Technologies. */ + +#ifndef __LIB_HV_VHCA_H__ +#define __LIB_HV_VHCA_H__ + +#include "en.h" +#include "lib/hv.h" + +struct mlx5_hv_vhca_agent; +struct mlx5_hv_vhca; +struct mlx5_hv_vhca_control_block; + +enum mlx5_hv_vhca_agent_type { + MLX5_HV_VHCA_AGENT_MAX = 32, +}; + +#if IS_ENABLED(CONFIG_PCI_HYPERV_INTERFACE) + +struct mlx5_hv_vhca_control_block { + u32 capabilities; + u32 control; + u16 command; + u16 command_ack; + u16 version; + u16 rings; + u32 reserved1[28]; +}; + +struct mlx5_hv_vhca *mlx5_hv_vhca_create(struct mlx5_core_dev *dev); +void mlx5_hv_vhca_destroy(struct mlx5_hv_vhca *hv_vhca); +int mlx5_hv_vhca_init(struct mlx5_hv_vhca *hv_vhca); +void mlx5_hv_vhca_cleanup(struct mlx5_hv_vhca *hv_vhca); +void mlx5_hv_vhca_invalidate(void *context, u64 block_mask); + +struct mlx5_hv_vhca_agent * +mlx5_hv_vhca_agent_create(struct mlx5_hv_vhca *hv_vhca, + enum mlx5_hv_vhca_agent_type type, + void (*control)(struct mlx5_hv_vhca_agent*, + struct mlx5_hv_vhca_control_block *block), + void (*invalidate)(struct mlx5_hv_vhca_agent*, + u64 block_mask), + void (*cleanup)(struct mlx5_hv_vhca_agent *agent), + void *context); + +void mlx5_hv_vhca_agent_destroy(struct mlx5_hv_vhca_agent *agent); +int mlx5_hv_vhca_agent_write(struct mlx5_hv_vhca_agent *agent, + void *buf, int len); +void *mlx5_hv_vhca_agent_priv(struct mlx5_hv_vhca_agent *agent); + +#else + +static inline struct mlx5_hv_vhca * +mlx5_hv_vhca_create(struct mlx5_core_dev *dev) +{ + return NULL; +} + +static inline void mlx5_hv_vhca_destroy(struct mlx5_hv_vhca *hv_vhca) +{ +} + +static inline int mlx5_hv_vhca_init(struct mlx5_hv_vhca *hv_vhca) +{ + return 0; +} + +static inline void mlx5_hv_vhca_cleanup(struct mlx5_hv_vhca *hv_vhca) +{ +} + +static inline void mlx5_hv_vhca_invalidate(void *context, + u64 block_mask) +{ +} + +static inline struct mlx5_hv_vhca_agent * +mlx5_hv_vhca_agent_create(struct mlx5_hv_vhca *hv_vhca, + enum mlx5_hv_vhca_agent_type type, + void (*control)(struct mlx5_hv_vhca_agent*, + struct mlx5_hv_vhca_control_block *block), + void (*invalidate)(struct mlx5_hv_vhca_agent*, + u64 block_mask), + void (*cleanup)(struct mlx5_hv_vhca_agent *agent), + void *context) +{ + return NULL; +} + +static inline void mlx5_hv_vhca_agent_destroy(struct mlx5_hv_vhca_agent *agent) +{ +} + +static inline int +mlx5_hv_vhca_write_agent(struct mlx5_hv_vhca_agent *agent, + void *buf, int len) +{ + return 0; +} +#endif + +#endif /* __LIB_HV_VHCA_H__ */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 0b70b1d..61388ca 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -69,6 +69,7 @@ #include "lib/pci_vsc.h" #include "diag/fw_tracer.h" #include "ecpf.h" +#include "lib/hv_vhca.h" MODULE_AUTHOR("Eli Cohen "); MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) core driver"); @@ -870,6 +871,7 @@ static int mlx5_init_once(struct mlx5_core_dev *dev) } dev->tracer = mlx5_fw_tracer_create(dev); + dev->hv_vhca = mlx5_hv_vhca_create(dev); return 0; @@ -900,6 +902,7 @@ static int mlx5_init_once(struct mlx5_core_dev *dev) static void mlx5_cleanup_once(struct mlx5_core_dev *dev) { + mlx5_hv_vhca_destroy(dev->hv_vhca); mlx5_fw_tracer_destroy(dev->tracer); mlx5_fpga_cleanup(dev); mlx5_eswitch_cleanup(dev->priv.eswitch); @@ -1067,6 +1070,8 @@ static int mlx5_load(struct mlx5_core_dev *dev) goto err_fw_tracer; } + mlx5_hv_vhca_init(dev->hv_vhca); + err = mlx5_fpga_device_start(dev); if (err) { mlx5_core_err(dev, "fpga device start failed %d\n", err); @@ -1122,6 +1127,7 @@ static int mlx5_load(struct mlx5_core_dev *dev) err_ipsec_start: mlx5_fpga_device_stop(dev); err_fpga_start: + mlx5_hv_vhca_cleanup(dev->hv_vhca); mlx5_fw_tracer_cleanup(dev->tracer); err_fw_tracer: mlx5_eq_table_destroy(dev); @@ -1142,6 +1148,7 @@ static void mlx5_unload(struct mlx5_core_dev *dev) mlx5_accel_ipsec_cleanup(dev); mlx5_accel_tls_cleanup(dev); mlx5_fpga_device_stop(dev); + mlx5_hv_vhca_cleanup(dev->hv_vhca); mlx5_fw_tracer_cleanup(dev->tracer); mlx5_eq_table_destroy(dev); mlx5_irq_table_destroy(dev); diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index df23f17..13b4cf2 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -659,6 +659,7 @@ struct mlx5_clock { struct mlx5_fw_tracer; struct mlx5_vxlan; struct mlx5_geneve; +struct mlx5_hv_vhca; struct mlx5_core_dev { struct device *device; @@ -706,6 +707,7 @@ struct mlx5_core_dev { struct mlx5_ib_clock_info *clock_info; struct mlx5_fw_tracer *tracer; u32 vsc_addr; + struct mlx5_hv_vhca *hv_vhca; }; struct mlx5_db { From patchwork Thu Aug 22 05:05:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haiyang Zhang X-Patchwork-Id: 11108427 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D26EC14DE for ; Thu, 22 Aug 2019 05:06:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9C4D3233A2 for ; Thu, 22 Aug 2019 05:06:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=microsoft.com header.i=@microsoft.com header.b="MxGlUfVV" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728883AbfHVFGU (ORCPT ); Thu, 22 Aug 2019 01:06:20 -0400 Received: from mail-eopbgr810109.outbound.protection.outlook.com ([40.107.81.109]:28619 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731340AbfHVFGC (ORCPT ); Thu, 22 Aug 2019 01:06:02 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gtYVXxm9F/8hKOWCnWZ9Jb6RW+r5sMPGkVr6yeL6LzQYaBM56CqcYF9J4gDTdRSkxMuUXyAlzP23gWqsiUVLY0lMgJVPnO+4enj4aIv0GRq2SkJyoRPdg9LsEadNSbLt1nDxzf1RZHijHkzeuoPZkEU/9IMAzDkD93AKeA6+m7h2QD2emBl8F7oI8sTmRtIKDcMtxUn8fEAWxyBZxEYRxua9CycIt/dQvvFxaDwrp4pu/IdJmC5nkLRZaJ26qkmXYWKG1LlO4ZJtXwTpnooZygY83TEL3LfqShHSoWvTpOs7LdKHxmZL1920HHRuLyLsvJDMWy3uWlqQPPWStxl2vA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=lsMtAx6Hrphtl0vQqpAve2mvPzW2E6YA1QY4cXYvV6o=; b=BY4KkexD51kcs2wpsYyHIj2cCS7hv31Anz4ESVbxfA7MzmTjwfMoT26OlJsjp6l01LDTJmBE0TzB3hJHhkutyqXMM/EdAHYQ1yTQHKfYS8meZapORb29jiY75cVsB9X3lCcfLguH7fh3n7NzxUPe+ILioA0fsORQtJ6Vis5kfODqNzREHF4a9oCQ2UaHB5D2hNNmgAabbZozsEBOR84WV9nKtfzNP9uMPZcNxM4fwIZfDYMMdkb73pe2NPmqx/+fYH6bDcM7BnruiEHVpUFIZvPWRgwg2nrqIr6V/+KHEmAwbVXXbyMQ8J5lLVGbDO3dr1Mt6rVoADsdl0gIzLVHCg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=lsMtAx6Hrphtl0vQqpAve2mvPzW2E6YA1QY4cXYvV6o=; b=MxGlUfVVURykT2YRjKgVvV9v3qJCq24QfQLj0S0/mNpDrlt6QfdNRvggDc5eua2hYFjXVc1djBps6EGfvhKoloE64GzcpY1/KN1wfmxkIpKYb8nmGSslua8RY9PSSk4xriKNRk51eX/58eRLFyf1t8UQ3D4ow0d1q4yuda8yoSU= Received: from MN2PR21MB1248.namprd21.prod.outlook.com (20.179.20.225) by MN2PR21MB1279.namprd21.prod.outlook.com (20.179.21.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2220.4; Thu, 22 Aug 2019 05:05:56 +0000 Received: from MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e]) by MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e%3]) with mapi id 15.20.2199.011; Thu, 22 Aug 2019 05:05:56 +0000 From: Haiyang Zhang To: "sashal@kernel.org" , "davem@davemloft.net" , "saeedm@mellanox.com" , "leon@kernel.org" , "eranbe@mellanox.com" , "lorenzo.pieralisi@arm.com" , "bhelgaas@google.com" , "linux-pci@vger.kernel.org" , "linux-hyperv@vger.kernel.org" , "netdev@vger.kernel.org" CC: Haiyang Zhang , KY Srinivasan , Stephen Hemminger , "linux-kernel@vger.kernel.org" Subject: [PATCH net-next,v4, 5/6] net/mlx5: Add HV VHCA control agent Thread-Topic: [PATCH net-next,v4, 5/6] net/mlx5: Add HV VHCA control agent Thread-Index: AQHVWKdHoKK4wQPn+UiFd8cQCSAi9g== Date: Thu, 22 Aug 2019 05:05:56 +0000 Message-ID: <1566450236-36757-6-git-send-email-haiyangz@microsoft.com> References: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> In-Reply-To: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: MWHPR14CA0039.namprd14.prod.outlook.com (2603:10b6:300:12b::25) To MN2PR21MB1248.namprd21.prod.outlook.com (2603:10b6:208:3b::33) authentication-results: spf=none (sender IP is ) smtp.mailfrom=lkmlhyz@microsoft.com; x-ms-exchange-messagesentrepresentingtype: 2 x-mailer: git-send-email 1.8.3.1 x-originating-ip: [13.77.154.182] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 12ddebf6-6e1a-4d67-a87d-08d726be6a38 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(5600158)(711020)(4605104)(1401327)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020);SRVR:MN2PR21MB1279; x-ms-traffictypediagnostic: MN2PR21MB1279:|MN2PR21MB1279: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:4303; x-forefront-prvs: 01371B902F x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(4636009)(39860400002)(396003)(136003)(366004)(376002)(346002)(189003)(199004)(71200400001)(71190400001)(186003)(446003)(66066001)(2616005)(4326008)(36756003)(6392003)(6436002)(256004)(53936002)(7846003)(7416002)(6512007)(26005)(6486002)(14444005)(11346002)(316002)(2906002)(2201001)(110136005)(22452003)(54906003)(10090500001)(476003)(25786009)(386003)(7736002)(64756008)(81156014)(66946007)(66446008)(8936002)(10290500003)(478600001)(66476007)(2501003)(102836004)(4720700003)(6116002)(3846002)(6506007)(305945005)(5660300002)(486006)(99286004)(66556008)(81166006)(14454004)(50226002)(8676002)(52116002)(76176011)(142933001)(921003)(1121003);DIR:OUT;SFP:1102;SCL:1;SRVR:MN2PR21MB1279;H:MN2PR21MB1248.namprd21.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: RWYtcLajFVR+FfwU+qaLgOAM/j/FI3LBuZLAmtFLBEQv1z3OGa5veVBqV7jcVNDt4+tbHIoNOkEagOyBUgkZj+OefnPxw/LT6MQplU+nbcxnQOrFXfuPOQhqq9T25oN/y2MO1rUCYlnxH+9G18hZCjAUmZvzd12Z2jDCVv+1uIhK3CB02y4mmgXfEIvAkP8AQ2MnaztQXZwZfQQtcitQjXZrq3hdxTNgNNBl3UNqjduqpO+xmZzBTDJaK0N3Y4GH0EOoSt4J4WyVZganQuRva2W1NnvaizasE2ADtLgvJr9EZPNF2TAo1Rm1eNpkAhyf6Ug4W/FtQnGXQiEZvqQTEaaUOinGDgonW/MEOv9ImrgqG0+r1g+P4eBh/BQCrHnBXC+nbzsQ6x4t6mThJUiKERt7KBjNLAymE9euuYCq9F0= MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: 12ddebf6-6e1a-4d67-a87d-08d726be6a38 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Aug 2019 05:05:56.6053 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 4Dt65JueP6/mt5DbJ/PVzrimGY1P6hnb6/czhXMv98RHNa+uzVPNOa3MEFvnvOQjbFfBdGC9t7KkP3O5LtOcwg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR21MB1279 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Eran Ben Elisha Control agent is responsible over of the control block (ID 0). It should update the PF via this block about every capability change. In addition, upon block 0 invalidate, it should activate all other supported agents with data requests from the PF. Upon agent create/destroy, the invalidate callback of the control agent is being called in order to update the PF driver about this change. The control agent is an integral part of HV VHCA and will be created and destroy as part of the HV VHCA init/cleanup flow. Signed-off-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed Signed-off-by: Haiyang Zhang --- .../net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c | 122 ++++++++++++++++++++- .../net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h | 1 + 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c index 84d1d75..4047629 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c @@ -109,22 +109,131 @@ void mlx5_hv_vhca_invalidate(void *context, u64 block_mask) queue_work(hv_vhca->work_queue, &work->invalidate_work); } +#define AGENT_MASK(type) (type ? BIT(type - 1) : 0 /* control */) + +static void mlx5_hv_vhca_agents_control(struct mlx5_hv_vhca *hv_vhca, + struct mlx5_hv_vhca_control_block *block) +{ + int i; + + for (i = 0; i < MLX5_HV_VHCA_AGENT_MAX; i++) { + struct mlx5_hv_vhca_agent *agent = hv_vhca->agents[i]; + + if (!agent || !agent->control) + continue; + + if (!(AGENT_MASK(agent->type) & block->control)) + continue; + + agent->control(agent, block); + } +} + +static void mlx5_hv_vhca_capabilities(struct mlx5_hv_vhca *hv_vhca, + u32 *capabilities) +{ + int i; + + for (i = 0; i < MLX5_HV_VHCA_AGENT_MAX; i++) { + struct mlx5_hv_vhca_agent *agent = hv_vhca->agents[i]; + + if (agent) + *capabilities |= AGENT_MASK(agent->type); + } +} + +static void +mlx5_hv_vhca_control_agent_invalidate(struct mlx5_hv_vhca_agent *agent, + u64 block_mask) +{ + struct mlx5_hv_vhca *hv_vhca = agent->hv_vhca; + struct mlx5_core_dev *dev = hv_vhca->dev; + struct mlx5_hv_vhca_control_block *block; + u32 capabilities = 0; + int err; + + block = kzalloc(sizeof(*block), GFP_KERNEL); + if (!block) + return; + + err = mlx5_hv_read_config(dev, block, sizeof(*block), 0); + if (err) + goto free_block; + + mlx5_hv_vhca_capabilities(hv_vhca, &capabilities); + + /* In case no capabilities, send empty block in return */ + if (!capabilities) { + memset(block, 0, sizeof(*block)); + goto write; + } + + if (block->capabilities != capabilities) + block->capabilities = capabilities; + + if (block->control & ~capabilities) + goto free_block; + + mlx5_hv_vhca_agents_control(hv_vhca, block); + block->command_ack = block->command; + +write: + mlx5_hv_write_config(dev, block, sizeof(*block), 0); + +free_block: + kfree(block); +} + +static struct mlx5_hv_vhca_agent * +mlx5_hv_vhca_control_agent_create(struct mlx5_hv_vhca *hv_vhca) +{ + return mlx5_hv_vhca_agent_create(hv_vhca, MLX5_HV_VHCA_AGENT_CONTROL, + NULL, + mlx5_hv_vhca_control_agent_invalidate, + NULL, NULL); +} + +static void mlx5_hv_vhca_control_agent_destroy(struct mlx5_hv_vhca_agent *agent) +{ + mlx5_hv_vhca_agent_destroy(agent); +} + int mlx5_hv_vhca_init(struct mlx5_hv_vhca *hv_vhca) { + struct mlx5_hv_vhca_agent *agent; + int err; + if (IS_ERR_OR_NULL(hv_vhca)) return IS_ERR_OR_NULL(hv_vhca); - return mlx5_hv_register_invalidate(hv_vhca->dev, hv_vhca, - mlx5_hv_vhca_invalidate); + err = mlx5_hv_register_invalidate(hv_vhca->dev, hv_vhca, + mlx5_hv_vhca_invalidate); + if (err) + return err; + + agent = mlx5_hv_vhca_control_agent_create(hv_vhca); + if (IS_ERR_OR_NULL(agent)) { + mlx5_hv_unregister_invalidate(hv_vhca->dev); + return IS_ERR_OR_NULL(agent); + } + + hv_vhca->agents[MLX5_HV_VHCA_AGENT_CONTROL] = agent; + + return 0; } void mlx5_hv_vhca_cleanup(struct mlx5_hv_vhca *hv_vhca) { + struct mlx5_hv_vhca_agent *agent; int i; if (IS_ERR_OR_NULL(hv_vhca)) return; + agent = hv_vhca->agents[MLX5_HV_VHCA_AGENT_CONTROL]; + if (agent) + mlx5_hv_vhca_control_agent_destroy(agent); + mutex_lock(&hv_vhca->agents_lock); for (i = 0; i < MLX5_HV_VHCA_AGENT_MAX; i++) WARN_ON(hv_vhca->agents[i]); @@ -134,6 +243,11 @@ void mlx5_hv_vhca_cleanup(struct mlx5_hv_vhca *hv_vhca) mlx5_hv_unregister_invalidate(hv_vhca->dev); } +static void mlx5_hv_vhca_agents_update(struct mlx5_hv_vhca *hv_vhca) +{ + mlx5_hv_vhca_invalidate(hv_vhca, BIT(MLX5_HV_VHCA_AGENT_CONTROL)); +} + struct mlx5_hv_vhca_agent * mlx5_hv_vhca_agent_create(struct mlx5_hv_vhca *hv_vhca, enum mlx5_hv_vhca_agent_type type, @@ -174,6 +288,8 @@ struct mlx5_hv_vhca_agent * hv_vhca->agents[type] = agent; mutex_unlock(&hv_vhca->agents_lock); + mlx5_hv_vhca_agents_update(hv_vhca); + return agent; } @@ -195,6 +311,8 @@ void mlx5_hv_vhca_agent_destroy(struct mlx5_hv_vhca_agent *agent) agent->cleanup(agent); kfree(agent); + + mlx5_hv_vhca_agents_update(hv_vhca); } static int mlx5_hv_vhca_data_block_prepare(struct mlx5_hv_vhca_agent *agent, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h index cdf1303..984e7ad 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h @@ -12,6 +12,7 @@ struct mlx5_hv_vhca_control_block; enum mlx5_hv_vhca_agent_type { + MLX5_HV_VHCA_AGENT_CONTROL = 0, MLX5_HV_VHCA_AGENT_MAX = 32, }; From patchwork Thu Aug 22 05:06:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haiyang Zhang X-Patchwork-Id: 11108423 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A41F1399 for ; Thu, 22 Aug 2019 05:06:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BE0F42339F for ; Thu, 22 Aug 2019 05:06:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=microsoft.com header.i=@microsoft.com header.b="aStOkcKJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731372AbfHVFGF (ORCPT ); Thu, 22 Aug 2019 01:06:05 -0400 Received: from mail-eopbgr810109.outbound.protection.outlook.com ([40.107.81.109]:28619 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731353AbfHVFGF (ORCPT ); Thu, 22 Aug 2019 01:06:05 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FcUIIeD48e6+HPY7XPtY7Yzd6DIWnYzevzC36NJkwi+6R3n7piHss/XHs0BBvz7G5me/sEAgi7xp7Y8mLMl+E+d9kv2HnQD+Dl5+yBm9AhzhCLfBiob2Gbk8jaulTlaVYbmB8nDYQpSevUfaiZKL3zk0VoZlQFJHbt9U2zywg32PudgetZMQdWxpZtYt4HJIdJouHVq9yI+L3BhM4yhJKxQ411H4rPQq2MPmOAyAuV51FjXHUE1aYwCLTW/y0x7/6SUd9ryPURIWJfwSJfBIn88KnicAiNqg3iGQ24SMjSdDw5H1pUVBf9HQXuh3kuiZSxdjrcsylc9j76MVFFHVjw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qJut3ge3rzBZu7s0lmJW6718rfv48Bvu2R3RCzYzVOg=; b=gLZ5MzwVytLuStk6Hrznl3SCzxLIm1p3sUUttzXzSkn4/CIhLSZELJ9VRRKrK01vbQEdxxdAVExp2Qmm6B23NX5zEXtWhIsDQCpta4eZxRue1nxYgqDVN3Oc8C6P1W04mKHMiU0GlGTeU7gPacV1rC4xXj4aYijk+tEB7ZYzMkjZHnlLD1YtGoYoCVsz5+cFdEZzOnA8F/85yzHYIvHEb6epIvGLUFcbvQP5gPAmHlvZflGYVqAPFQ4AeippJyunD82I9y/wvtozhLH4LBiDGE5L4rJYnMBU1je8H4KML0IyAYkb8njD97TwqF0FA90i7/TNPPDZQO8nRYdzX8Lf3A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qJut3ge3rzBZu7s0lmJW6718rfv48Bvu2R3RCzYzVOg=; b=aStOkcKJMQkCvnppwOOPByCDH2dDRSmfMs+wgWUEpnZtx9D/kX+LwlyoT202YjonrbyDZK/9eCTbm79QE64ae3Cb0bgHZgWeNwe1OZ57kqzL54faf+AQkxFqQNVtZXenVQxolSHlnem9aF3rQtnRcqIx9optFme8Rk8ciasQiUU= Received: from MN2PR21MB1248.namprd21.prod.outlook.com (20.179.20.225) by MN2PR21MB1279.namprd21.prod.outlook.com (20.179.21.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2220.4; Thu, 22 Aug 2019 05:06:01 +0000 Received: from MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e]) by MN2PR21MB1248.namprd21.prod.outlook.com ([fe80::147a:ea1f:326d:832e%3]) with mapi id 15.20.2199.011; Thu, 22 Aug 2019 05:06:01 +0000 From: Haiyang Zhang To: "sashal@kernel.org" , "davem@davemloft.net" , "saeedm@mellanox.com" , "leon@kernel.org" , "eranbe@mellanox.com" , "lorenzo.pieralisi@arm.com" , "bhelgaas@google.com" , "linux-pci@vger.kernel.org" , "linux-hyperv@vger.kernel.org" , "netdev@vger.kernel.org" CC: Haiyang Zhang , KY Srinivasan , Stephen Hemminger , "linux-kernel@vger.kernel.org" Subject: [PATCH net-next,v4, 6/6] net/mlx5e: Add mlx5e HV VHCA stats agent Thread-Topic: [PATCH net-next,v4, 6/6] net/mlx5e: Add mlx5e HV VHCA stats agent Thread-Index: AQHVWKdKh2+NWrz/8EWbrTfJz7rlOw== Date: Thu, 22 Aug 2019 05:06:00 +0000 Message-ID: <1566450236-36757-7-git-send-email-haiyangz@microsoft.com> References: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> In-Reply-To: <1566450236-36757-1-git-send-email-haiyangz@microsoft.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: MWHPR14CA0039.namprd14.prod.outlook.com (2603:10b6:300:12b::25) To MN2PR21MB1248.namprd21.prod.outlook.com (2603:10b6:208:3b::33) authentication-results: spf=none (sender IP is ) smtp.mailfrom=lkmlhyz@microsoft.com; x-ms-exchange-messagesentrepresentingtype: 2 x-mailer: git-send-email 1.8.3.1 x-originating-ip: [13.77.154.182] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 279aa970-e71e-4799-f9c0-08d726be6cc5 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(5600158)(711020)(4605104)(1401327)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020);SRVR:MN2PR21MB1279; x-ms-traffictypediagnostic: MN2PR21MB1279:|MN2PR21MB1279: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:3826; x-forefront-prvs: 01371B902F x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(4636009)(39860400002)(396003)(136003)(366004)(376002)(346002)(189003)(199004)(71200400001)(71190400001)(186003)(446003)(66066001)(2616005)(4326008)(36756003)(6392003)(6436002)(256004)(53936002)(7846003)(7416002)(6512007)(26005)(6486002)(14444005)(11346002)(316002)(2906002)(2201001)(110136005)(22452003)(54906003)(10090500001)(476003)(25786009)(386003)(7736002)(64756008)(81156014)(66946007)(66446008)(8936002)(10290500003)(478600001)(66476007)(2501003)(102836004)(4720700003)(6116002)(3846002)(6506007)(305945005)(5660300002)(486006)(99286004)(66556008)(81166006)(14454004)(50226002)(8676002)(52116002)(76176011)(42413003)(142933001)(32563001)(921003)(1121003);DIR:OUT;SFP:1102;SCL:1;SRVR:MN2PR21MB1279;H:MN2PR21MB1248.namprd21.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: 7dNJRHgMJTw1jIrVBYD5fYdt71/BGTpQuP30kUufSu47PzKvabR58vYn8q0Fp4f/bRwdxHF1DrhtZt2yaL6/91JYnCZGLqDwo7ngPUefzsLSqGhPm6xFpQIBBa8ZM/k/+sobICyAZ0Xf/GroiOPlFZ/s3012p9kOWVfzyVopPWqYCQz4liuCtqCT220OZuMCdOGShlQGv19JFRy63ESZjtdq+CfiW10iwilapU+uGlptcz0JgLKQgYg6dpr8dfwHOKKRAjxKg/1a9nL52Kq7evhuoS2NEGfZ3TlVJQGcflXuwSh+B6btfqLsmPWuSNmdt/h854Z2yeXb0PmEnW4DQUa6XPZ/WyYfqOWurVo1JVF60cn2CJm2ke8iTWFEd4JutuNRS+03w2Ec9wjy9iLG/dXzd9GNzZr011lHdFKjH1w= MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: 279aa970-e71e-4799-f9c0-08d726be6cc5 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Aug 2019 05:06:00.8069 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: Szn7Ag5mSeUQVuSxTLZDSh25UrgFuj7FuMjDdeSd9rtrfeTXsHCGgpxDyLe8SjH/ZiYTCcr5pHlCE4iKfm3qew== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR21MB1279 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Eran Ben Elisha HV VHCA stats agent is responsible on running a preiodic rx/tx packets/bytes stats update. Currently the supported format is version MLX5_HV_VHCA_STATS_VERSION. Block ID 1 is dedicated for statistics data transfer from the VF to the PF. The reporter fetch the statistics data from all opened channels, fill it in a buffer and send it to mlx5_hv_vhca_write_agent. As the stats layer should include some metadata per block (sequence and offset), the HV VHCA layer shall modify the buffer before actually send it over block 1. Signed-off-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed Signed-off-by: Haiyang Zhang --- drivers/net/ethernet/mellanox/mlx5/core/Makefile | 1 + drivers/net/ethernet/mellanox/mlx5/core/en.h | 13 ++ .../ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c | 162 +++++++++++++++++++++ .../ethernet/mellanox/mlx5/core/en/hv_vhca_stats.h | 25 ++++ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 + .../net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h | 1 + 6 files changed, 205 insertions(+) create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.h diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile index 8d443fc..f4de9cc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile +++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile @@ -36,6 +36,7 @@ mlx5_core-$(CONFIG_MLX5_CORE_EN_DCB) += en_dcbnl.o en/port_buffer.o mlx5_core-$(CONFIG_MLX5_ESWITCH) += en_rep.o en_tc.o en/tc_tun.o lib/port_tun.o lag_mp.o \ lib/geneve.o en/tc_tun_vxlan.o en/tc_tun_gre.o \ en/tc_tun_geneve.o diag/en_tc_tracepoint.o +mlx5_core-$(CONFIG_PCI_HYPERV_INTERFACE) += en/hv_vhca_stats.o # # Core extra diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index 7316571..4467927 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -54,6 +54,7 @@ #include "mlx5_core.h" #include "en_stats.h" #include "en/fs.h" +#include "lib/hv_vhca.h" extern const struct net_device_ops mlx5e_netdev_ops; struct page_pool; @@ -782,6 +783,15 @@ struct mlx5e_modify_sq_param { int rl_index; }; +#if IS_ENABLED(CONFIG_PCI_HYPERV_INTERFACE) +struct mlx5e_hv_vhca_stats_agent { + struct mlx5_hv_vhca_agent *agent; + struct delayed_work work; + u16 delay; + void *buf; +}; +#endif + struct mlx5e_xsk { /* UMEMs are stored separately from channels, because we don't want to * lose them when channels are recreated. The kernel also stores UMEMs, @@ -853,6 +863,9 @@ struct mlx5e_priv { struct devlink_health_reporter *tx_reporter; struct devlink_health_reporter *rx_reporter; struct mlx5e_xsk xsk; +#if IS_ENABLED(CONFIG_PCI_HYPERV_INTERFACE) + struct mlx5e_hv_vhca_stats_agent stats_agent; +#endif }; struct mlx5e_profile { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c new file mode 100644 index 0000000..c37b4ac --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +// Copyright (c) 2018 Mellanox Technologies + +#include "en.h" +#include "en/hv_vhca_stats.h" +#include "lib/hv_vhca.h" +#include "lib/hv.h" + +struct mlx5e_hv_vhca_per_ring_stats { + u64 rx_packets; + u64 rx_bytes; + u64 tx_packets; + u64 tx_bytes; +}; + +static void +mlx5e_hv_vhca_fill_ring_stats(struct mlx5e_priv *priv, int ch, + struct mlx5e_hv_vhca_per_ring_stats *data) +{ + struct mlx5e_channel_stats *stats; + int tc; + + stats = &priv->channel_stats[ch]; + data->rx_packets = stats->rq.packets; + data->rx_bytes = stats->rq.bytes; + + for (tc = 0; tc < priv->max_opened_tc; tc++) { + data->tx_packets += stats->sq[tc].packets; + data->tx_bytes += stats->sq[tc].bytes; + } +} + +static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, u64 *data, + int buf_len) +{ + int ch, i = 0; + + for (ch = 0; ch < priv->max_nch; ch++) { + u64 *buf = data + i; + + if (WARN_ON_ONCE(buf + + sizeof(struct mlx5e_hv_vhca_per_ring_stats) > + data + buf_len)) + return; + + mlx5e_hv_vhca_fill_ring_stats(priv, ch, + (struct mlx5e_hv_vhca_per_ring_stats *)buf); + i += sizeof(struct mlx5e_hv_vhca_per_ring_stats) / sizeof(u64); + } +} + +static int mlx5e_hv_vhca_stats_buf_size(struct mlx5e_priv *priv) +{ + return (sizeof(struct mlx5e_hv_vhca_per_ring_stats) * + priv->max_nch); +} + +static void mlx5e_hv_vhca_stats_work(struct work_struct *work) +{ + struct mlx5e_hv_vhca_stats_agent *sagent; + struct mlx5_hv_vhca_agent *agent; + struct delayed_work *dwork; + struct mlx5e_priv *priv; + int buf_len, rc; + void *buf; + + dwork = to_delayed_work(work); + sagent = container_of(dwork, struct mlx5e_hv_vhca_stats_agent, work); + priv = container_of(sagent, struct mlx5e_priv, stats_agent); + buf_len = mlx5e_hv_vhca_stats_buf_size(priv); + agent = sagent->agent; + buf = sagent->buf; + + memset(buf, 0, buf_len); + mlx5e_hv_vhca_fill_stats(priv, buf, buf_len); + + rc = mlx5_hv_vhca_agent_write(agent, buf, buf_len); + if (rc) { + mlx5_core_err(priv->mdev, + "%s: Failed to write stats, err = %d\n", + __func__, rc); + return; + } + + if (sagent->delay) + queue_delayed_work(priv->wq, &sagent->work, sagent->delay); +} + +enum { + MLX5_HV_VHCA_STATS_VERSION = 1, + MLX5_HV_VHCA_STATS_UPDATE_ONCE = 0xFFFF, +}; + +static void mlx5e_hv_vhca_stats_control(struct mlx5_hv_vhca_agent *agent, + struct mlx5_hv_vhca_control_block *block) +{ + struct mlx5e_hv_vhca_stats_agent *sagent; + struct mlx5e_priv *priv; + + priv = mlx5_hv_vhca_agent_priv(agent); + sagent = &priv->stats_agent; + + block->version = MLX5_HV_VHCA_STATS_VERSION; + block->rings = priv->max_nch; + + if (!block->command) { + cancel_delayed_work_sync(&priv->stats_agent.work); + return; + } + + sagent->delay = block->command == MLX5_HV_VHCA_STATS_UPDATE_ONCE ? 0 : + msecs_to_jiffies(block->command * 100); + + queue_delayed_work(priv->wq, &sagent->work, sagent->delay); +} + +static void mlx5e_hv_vhca_stats_cleanup(struct mlx5_hv_vhca_agent *agent) +{ + struct mlx5e_priv *priv = mlx5_hv_vhca_agent_priv(agent); + + cancel_delayed_work_sync(&priv->stats_agent.work); +} + +int mlx5e_hv_vhca_stats_create(struct mlx5e_priv *priv) +{ + int buf_len = mlx5e_hv_vhca_stats_buf_size(priv); + struct mlx5_hv_vhca_agent *agent; + + priv->stats_agent.buf = kvzalloc(buf_len, GFP_KERNEL); + if (!priv->stats_agent.buf) + return -ENOMEM; + + agent = mlx5_hv_vhca_agent_create(priv->mdev->hv_vhca, + MLX5_HV_VHCA_AGENT_STATS, + mlx5e_hv_vhca_stats_control, NULL, + mlx5e_hv_vhca_stats_cleanup, + priv); + + if (IS_ERR_OR_NULL(agent)) { + if (IS_ERR(agent)) + netdev_warn(priv->netdev, + "Failed to create hv vhca stats agent, err = %ld\n", + PTR_ERR(agent)); + + kfree(priv->stats_agent.buf); + return IS_ERR_OR_NULL(agent); + } + + priv->stats_agent.agent = agent; + INIT_DELAYED_WORK(&priv->stats_agent.work, mlx5e_hv_vhca_stats_work); + + return 0; +} + +void mlx5e_hv_vhca_stats_destroy(struct mlx5e_priv *priv) +{ + if (IS_ERR_OR_NULL(priv->stats_agent.agent)) + return; + + mlx5_hv_vhca_agent_destroy(priv->stats_agent.agent); + kfree(priv->stats_agent.buf); +} diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.h new file mode 100644 index 0000000..664463f --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ +/* Copyright (c) 2019 Mellanox Technologies. */ + +#ifndef __MLX5_EN_STATS_VHCA_H__ +#define __MLX5_EN_STATS_VHCA_H__ +#include "en.h" + +#if IS_ENABLED(CONFIG_PCI_HYPERV_INTERFACE) + +int mlx5e_hv_vhca_stats_create(struct mlx5e_priv *priv); +void mlx5e_hv_vhca_stats_destroy(struct mlx5e_priv *priv); + +#else + +static inline int mlx5e_hv_vhca_stats_create(struct mlx5e_priv *priv) +{ + return 0; +} + +static inline void mlx5e_hv_vhca_stats_destroy(struct mlx5e_priv *priv) +{ +} +#endif + +#endif /* __MLX5_EN_STATS_VHCA_H__ */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 7fdea64..fa4bf2d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -62,6 +62,7 @@ #include "en/xsk/setup.h" #include "en/xsk/rx.h" #include "en/xsk/tx.h" +#include "en/hv_vhca_stats.h" bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev) @@ -5109,6 +5110,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv) if (mlx5e_monitor_counter_supported(priv)) mlx5e_monitor_counter_init(priv); + mlx5e_hv_vhca_stats_create(priv); if (netdev->reg_state != NETREG_REGISTERED) return; #ifdef CONFIG_MLX5_CORE_EN_DCB @@ -5141,6 +5143,7 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv) queue_work(priv->wq, &priv->set_rx_mode_work); + mlx5e_hv_vhca_stats_destroy(priv); if (mlx5e_monitor_counter_supported(priv)) mlx5e_monitor_counter_cleanup(priv); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h index 984e7ad..4bad6a5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h @@ -13,6 +13,7 @@ enum mlx5_hv_vhca_agent_type { MLX5_HV_VHCA_AGENT_CONTROL = 0, + MLX5_HV_VHCA_AGENT_STATS = 1, MLX5_HV_VHCA_AGENT_MAX = 32, };