From patchwork Thu Apr 7 04:30:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Parri X-Patchwork-Id: 12804434 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07931C433F5 for ; Thu, 7 Apr 2022 04:32:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240655AbiDGEeR (ORCPT ); Thu, 7 Apr 2022 00:34:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46840 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240505AbiDGEeJ (ORCPT ); Thu, 7 Apr 2022 00:34:09 -0400 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [IPv6:2a00:1450:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13EFA1E6E89; Wed, 6 Apr 2022 21:32:10 -0700 (PDT) Received: by mail-ej1-x629.google.com with SMTP id ot30so8231895ejb.12; Wed, 06 Apr 2022 21:32:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0ZT/IdIg9UVN/KaRkbp2Q3ZH8GXUNvhUw+iGlhxbQRk=; b=juqfs5ewbM4T3/5g+BA73v8c0k5OHlqFDrH68lFXcOxmcNCs5OmgZll2YSGf3z0vzE fHICTdF/I8eJCGuPfGF8e941WQrDX2CDBGC+a7375TZo7D0S2rPxAP2yhxUVFv2YNESw stW3mkW2IQ9jX9cDj3e6UuufUeJdsA5qIzUsXSj8ya13qvmjs1I/ybtOgRB/zDJsTC4Y Z9j2akF2PaOtFrdKHWlgRBCQ2xNaeQTy0hPMqOGp3B3IhUxuvXV8W1RKsjtGvgqJ0SWR jqXRrbKfQ1UFHlhDdX43D2Q02PhlxcUbGa3irnWD6nMKwoxgJupu+Bt1n0y0vmY+ZI/Z R/qQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0ZT/IdIg9UVN/KaRkbp2Q3ZH8GXUNvhUw+iGlhxbQRk=; b=Iq54N0uWm/QBTqwSGOM8MKuRo0Rbsqb0BAfV5SY/xgB/RVO6PrTeK7XrF7WDhULEjV L6+nSiMC0o88dsu4lGm21bR31Zo5YQXIMTZoIPZy5ivTuO+K1rbwfB5/M1tylHoPGOjd JlXUOl1JbM46CR6WC30LeLWkO2arBIAUj6HUVHyRSt0TViI1ELL0fAC9yXHiE0UlI7HC a9WGbsw0HnTKQ+wdZ1rUL1Ze4bE4H23GJpU0inDTJLy9OdKz8XtzcMgAsttLyPo18Dkb iWThDGgAIJfTBnLroJ6ikanV1KBEZMYjSWgbZKgw0yvZ9pS1GWFwMPQHJxh9/lya55oD 7JrQ== X-Gm-Message-State: AOAM5338d0fGtKWMwekbkYqrzpEOfyhMpWuUqPKN1FTfOK3cno15wccK nORmZJinhkYf2mp41mK6ElM= X-Google-Smtp-Source: ABdhPJxV10ybNQjOqtJCfnmVB3wxkUsdMt9kWR2ssh8IHswe4BN8WrQZqCzzWKXMXUOdn2t2eJYE2A== X-Received: by 2002:a17:907:1c82:b0:6e0:acef:d238 with SMTP id nb2-20020a1709071c8200b006e0acefd238mr11815589ejc.96.1649305928456; Wed, 06 Apr 2022 21:32:08 -0700 (PDT) Received: from anparri.mshome.net (host-87-11-75-174.retail.telecomitalia.it. [87.11.75.174]) by smtp.gmail.com with ESMTPSA id ke11-20020a17090798eb00b006e7fbf53398sm3531341ejc.129.2022.04.06.21.32.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Apr 2022 21:32:08 -0700 (PDT) From: "Andrea Parri (Microsoft)" To: KY Srinivasan , Haiyang Zhang , Stephen Hemminger , Wei Liu , Dexuan Cui , Michael Kelley , Wei Hu , Lorenzo Pieralisi , Rob Herring , Krzysztof Wilczynski , Bjorn Helgaas Cc: linux-hyperv@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, "Andrea Parri (Microsoft)" Subject: [PATCH 1/6] Drivers: hv: vmbus: Fix handling of messages with transaction ID of zero Date: Thu, 7 Apr 2022 06:30:23 +0200 Message-Id: <20220407043028.379534-2-parri.andrea@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220407043028.379534-1-parri.andrea@gmail.com> References: <20220407043028.379534-1-parri.andrea@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org vmbus_request_addr() returns 0 (zero) if the transaction ID passed to as argument is 0. This is unfortunate for two reasons: first, netvsc_send_completion() does not check for a NULL cmd_rqst (before dereferencing the corresponding NVSP message); second, 0 is a *valid* value of cmd_rqst in netvsc_send_tx_complete(), cf. the call of vmbus_sendpacket() in netvsc_send_pkt(). vmbus_request_addr() has included the code in question since its introduction with commit e8b7db38449ac ("Drivers: hv: vmbus: Add vmbus_requestor data structure for VMBus hardening"); such code was motivated by the early use of vmbus_requestor by hv_storvsc. Since hv_storvsc moved to a tag-based mechanism to generate and retrieve transaction IDs with commit bf5fd8cae3c8f ("scsi: storvsc: Use blk_mq_unique_tag() to generate requestIDs"), vmbus_request_addr() can be modified to return VMBUS_RQST_ERROR if the ID is 0. This change solves the issues in hv_netvsc (and makes the handling of messages with transaction ID of 0 consistent with the semantics "the ID is not contained in the requestor/invalid ID"). vmbus_next_request_id(), vmbus_request_addr() should still reserve the ID of 0 for Hyper-V, because Hyper-V will "ignore" (not respond to) VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED packets/requests with transaction ID of 0 from the guest. Fixes: bf5fd8cae3c8f ("scsi: storvsc: Use blk_mq_unique_tag() to generate requestIDs") Signed-off-by: Andrea Parri (Microsoft) Reviewed-by: Michael Kelley --- The above hv_netvsc issues precede bf5fd8cae3c8f; however, these changes should not be backported to earlier commits since such a back-port would 'break' hv_storvsc. drivers/hv/channel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index dc5c35210c16a..20fc8d50a0398 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -1245,7 +1245,9 @@ u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr) /* * Cannot return an ID of 0, which is reserved for an unsolicited - * message from Hyper-V. + * message from Hyper-V; Hyper-V does not acknowledge (respond to) + * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED requests with ID of + * 0 sent by the guest. */ return current_id + 1; } @@ -1270,7 +1272,7 @@ u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id) /* Hyper-V can send an unsolicited message with ID of 0 */ if (!trans_id) - return trans_id; + return VMBUS_RQST_ERROR; spin_lock_irqsave(&rqstor->req_lock, flags); From patchwork Thu Apr 7 04:30:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Parri X-Patchwork-Id: 12804437 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5C9BDC433FE for ; Thu, 7 Apr 2022 04:32:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240660AbiDGEeS (ORCPT ); Thu, 7 Apr 2022 00:34:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240656AbiDGEeP (ORCPT ); Thu, 7 Apr 2022 00:34:15 -0400 Received: from mail-ej1-x62f.google.com (mail-ej1-x62f.google.com [IPv6:2a00:1450:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7D7041E6E8F; Wed, 6 Apr 2022 21:32:13 -0700 (PDT) Received: by mail-ej1-x62f.google.com with SMTP id bq8so8276209ejb.10; Wed, 06 Apr 2022 21:32:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PLk82bq3hxGeZAsu9PKoYX7IPjIjTIMBZgaXITeK+Oo=; b=FgBomAD9uMBxBhvAxcGsyN8xGpx6a4yc7XbtSZF0jBwzC3SxUwv9d1sucKUMJQt14W p6RBZbhkhyBeQ6srNiXAw6b3PP6rAcp8GfwZSqRyogyhKhzcf+imd7HBVV+lN2Y5oed+ M6V2lB6gWpouN051rJsiURiw3SA8U8aSjGtvw4Dzgzcq3L9t+Pt4xYL+Gad40UwBDUyS iRZzFSGvGF822WBLdeORC7hVGAId5/eEdrB0VMw896z0IRdGONoyBn40b2RleNmahIcG SNMSJGIHB4N6t02/jRH84aTyKmwez0wxDSV9rOgWmjSE9FAu21uqugOtm/gYZnqAjHax oPQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PLk82bq3hxGeZAsu9PKoYX7IPjIjTIMBZgaXITeK+Oo=; b=knQR2a8PSM2neMWN8ThE/XZHLM67AADZWJEbZ1+InP7KuxB67EajM3r9QKp6rLdMJw 1n9dBBOv5s0nJMeLnNiFmwBt8UJbDTBDERUREVHwXCigyMs3J7wHGQFxGlN5/2d2TKXw UuKNaQYElQfyrr8OCi1Pkdt72w8+9QwOVD22HXPQKpAYpxMQ9PcuwPTi7obMtmA5HF7O JK9t+8WaXrc6VL3Jtn/IgfVM1xy3vHADB3RWuSsravNTiP1/XttBFm0o2wx+wFBrGR2e emxYaIKfMFhN0X6uePeZMkKOJTslgSh7Lr5++D41PB3cPegaD5wjjOCeM0m8+leXELPD evDg== X-Gm-Message-State: AOAM532DEtssh5WJh/9/M4xu5wplhqilkfQw5PgdJ3TOYzQSrluTm186 wnLyrRpVdKGOmT2fIaklC50= X-Google-Smtp-Source: ABdhPJxfGXZZDvMla7/zEF1udPgXurPdzhQgieX4EzxF2MqJtQrYqZdQ1q2bbCDdmAdv1RRKwdagNw== X-Received: by 2002:a17:907:6d2a:b0:6df:e513:5410 with SMTP id sa42-20020a1709076d2a00b006dfe5135410mr11302460ejc.544.1649305931920; Wed, 06 Apr 2022 21:32:11 -0700 (PDT) Received: from anparri.mshome.net (host-87-11-75-174.retail.telecomitalia.it. [87.11.75.174]) by smtp.gmail.com with ESMTPSA id ke11-20020a17090798eb00b006e7fbf53398sm3531341ejc.129.2022.04.06.21.32.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Apr 2022 21:32:11 -0700 (PDT) From: "Andrea Parri (Microsoft)" To: KY Srinivasan , Haiyang Zhang , Stephen Hemminger , Wei Liu , Dexuan Cui , Michael Kelley , Wei Hu , Lorenzo Pieralisi , Rob Herring , Krzysztof Wilczynski , Bjorn Helgaas Cc: linux-hyperv@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, "Andrea Parri (Microsoft)" Subject: [PATCH 2/6] PCI: hv: Use vmbus_requestor to generate transaction IDs for VMbus hardening Date: Thu, 7 Apr 2022 06:30:24 +0200 Message-Id: <20220407043028.379534-3-parri.andrea@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220407043028.379534-1-parri.andrea@gmail.com> References: <20220407043028.379534-1-parri.andrea@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Currently, pointers to guest memory are passed to Hyper-V as transaction IDs in hv_pci. In the face of errors or malicious behavior in Hyper-V, hv_pci should not expose or trust the transaction IDs returned by Hyper-V to be valid guest memory addresses. Instead, use small integers generated by vmbus_requestor as request (transaction) IDs. Suggested-by: Michael Kelley Signed-off-by: Andrea Parri (Microsoft) --- drivers/pci/controller/pci-hyperv.c | 39 +++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 88b3b56d05228..c1322ac37cda9 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -91,6 +91,13 @@ static enum pci_protocol_version_t pci_protocol_versions[] = { /* space for 32bit serial number as string */ #define SLOT_NAME_SIZE 11 +/* + * Size of requestor for VMbus; the value is based on the observation + * that having more than one request outstanding is 'rare', and so 64 + * should be generous in ensuring that we don't ever run out. + */ +#define HV_PCI_RQSTOR_SIZE 64 + /* * Message Types */ @@ -1407,7 +1414,7 @@ static void hv_int_desc_free(struct hv_pci_dev *hpdev, int_pkt->wslot.slot = hpdev->desc.win_slot.slot; int_pkt->int_desc = *int_desc; vmbus_sendpacket(hpdev->hbus->hdev->channel, int_pkt, sizeof(*int_pkt), - (unsigned long)&ctxt.pkt, VM_PKT_DATA_INBAND, 0); + 0, VM_PKT_DATA_INBAND, 0); kfree(int_desc); } @@ -2649,7 +2656,7 @@ static void hv_eject_device_work(struct work_struct *work) ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE; ejct_pkt->wslot.slot = hpdev->desc.win_slot.slot; vmbus_sendpacket(hbus->hdev->channel, ejct_pkt, - sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt, + sizeof(*ejct_pkt), 0, VM_PKT_DATA_INBAND, 0); /* For the get_pcichild() in hv_pci_eject_device() */ @@ -2696,8 +2703,9 @@ static void hv_pci_onchannelcallback(void *context) const int packet_size = 0x100; int ret; struct hv_pcibus_device *hbus = context; + struct vmbus_channel *chan = hbus->hdev->channel; u32 bytes_recvd; - u64 req_id; + u64 req_id, req_addr; struct vmpacket_descriptor *desc; unsigned char *buffer; int bufferlen = packet_size; @@ -2715,8 +2723,8 @@ static void hv_pci_onchannelcallback(void *context) return; while (1) { - ret = vmbus_recvpacket_raw(hbus->hdev->channel, buffer, - bufferlen, &bytes_recvd, &req_id); + ret = vmbus_recvpacket_raw(chan, buffer, bufferlen, + &bytes_recvd, &req_id); if (ret == -ENOBUFS) { kfree(buffer); @@ -2743,11 +2751,14 @@ static void hv_pci_onchannelcallback(void *context) switch (desc->type) { case VM_PKT_COMP: - /* - * The host is trusted, and thus it's safe to interpret - * this transaction ID as a pointer. - */ - comp_packet = (struct pci_packet *)req_id; + req_addr = chan->request_addr_callback(chan, req_id); + if (req_addr == VMBUS_RQST_ERROR) { + dev_warn_ratelimited(&hbus->hdev->device, + "Invalid transaction ID %llx\n", + req_id); + break; + } + comp_packet = (struct pci_packet *)req_addr; response = (struct pci_response *)buffer; comp_packet->completion_func(comp_packet->compl_ctxt, response, @@ -3428,6 +3439,10 @@ static int hv_pci_probe(struct hv_device *hdev, goto free_dom; } + hdev->channel->next_request_id_callback = vmbus_next_request_id; + hdev->channel->request_addr_callback = vmbus_request_addr; + hdev->channel->rqstor_size = HV_PCI_RQSTOR_SIZE; + ret = vmbus_open(hdev->channel, pci_ring_size, pci_ring_size, NULL, 0, hv_pci_onchannelcallback, hbus); if (ret) @@ -3758,6 +3773,10 @@ static int hv_pci_resume(struct hv_device *hdev) hbus->state = hv_pcibus_init; + hdev->channel->next_request_id_callback = vmbus_next_request_id; + hdev->channel->request_addr_callback = vmbus_request_addr; + hdev->channel->rqstor_size = HV_PCI_RQSTOR_SIZE; + ret = vmbus_open(hdev->channel, pci_ring_size, pci_ring_size, NULL, 0, hv_pci_onchannelcallback, hbus); if (ret) From patchwork Thu Apr 7 04:30:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Parri X-Patchwork-Id: 12804435 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56E24C433F5 for ; Thu, 7 Apr 2022 04:32:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240681AbiDGEeW (ORCPT ); Thu, 7 Apr 2022 00:34:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47266 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240668AbiDGEeP (ORCPT ); Thu, 7 Apr 2022 00:34:15 -0400 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [IPv6:2a00:1450:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D3CB81E7477; Wed, 6 Apr 2022 21:32:15 -0700 (PDT) Received: by mail-ej1-x629.google.com with SMTP id ot30so8232253ejb.12; Wed, 06 Apr 2022 21:32:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Iq7An3zFyBeCpeIq4u05/jP/2nSd8ol7Y0CCrrlrlJg=; b=D3Wqlt0qjBhc8coIHUt9hckX7eJc8xt11zAjZLmh77d+rvAwVScZtDf6iE79dBfX81 2LMlrOua9j0GzkPsDcS6P1aGZ7xjDAY9Il2/CeHWj/hMbLofgGRK8v2NlTvGvxQeoVef CK05QBMjdsV1dNhIOhfS/trcnsyS9r8Ssdw2uAStO/CVfuuGw6SEIeco+nPJU+5O41bG 5qWtfIdUXWV6ZH8OJjzII7sV6nBW6kd0Npvi2oplTctMr0Q8e9151LhEhTvGnFmSjKXV X3P3V1gIsFz9oexZUd5Rpdg/1292sHysUHj+sxDGvIAmwWKLL0gBnHs4lXz9/L767LFp D/Aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Iq7An3zFyBeCpeIq4u05/jP/2nSd8ol7Y0CCrrlrlJg=; b=d+YAT5XvP1+EdlXmUv+pNIcZsoerVbthFQBNouB2fYvniYgvgM6VFNQ6SuM5sGJ5tk T9ooZUBfklOdR0Civm0qQvvu24481igSGV0liDJhVZijgLtEzJ6prrQyIO+xwdUzRuw6 MZlRKfsKBZ3oCpGsxY3F8r6xSX+dIXIqhIBxyjcvpJeOlwK94z8YcR4rYD3OPTcl7qBA u0o8q+H+0EBWYjn8CCSw7U+VxhfWqIYaBFvn3mg/48Jd5ug11q8xa77Mfi2DzdJAEsyS WRiqXSAvYnpFHMt//Pm98kQ+XKK7G/lbYGrLS44LII73wayWbnRIEwVyjIJSoRL7P44+ LjeA== X-Gm-Message-State: AOAM530Aaux6vDgRK0jnjjQbgZQrrLyINhhFaRcle8yIths/bH8+2spj Vb1JhCsfdzje1chgNn0/qeM= X-Google-Smtp-Source: ABdhPJxsy/jIuf6iPkPoCW0oaCroTHFOQ9d0eGmRA8H/VZqearcPata1OQgad+gD9zAOk9zaaDfoug== X-Received: by 2002:a17:906:19c6:b0:6ce:98a4:5ee6 with SMTP id h6-20020a17090619c600b006ce98a45ee6mr11186596ejd.567.1649305934325; Wed, 06 Apr 2022 21:32:14 -0700 (PDT) Received: from anparri.mshome.net (host-87-11-75-174.retail.telecomitalia.it. [87.11.75.174]) by smtp.gmail.com with ESMTPSA id ke11-20020a17090798eb00b006e7fbf53398sm3531341ejc.129.2022.04.06.21.32.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Apr 2022 21:32:13 -0700 (PDT) From: "Andrea Parri (Microsoft)" To: KY Srinivasan , Haiyang Zhang , Stephen Hemminger , Wei Liu , Dexuan Cui , Michael Kelley , Wei Hu , Lorenzo Pieralisi , Rob Herring , Krzysztof Wilczynski , Bjorn Helgaas Cc: linux-hyperv@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, "Andrea Parri (Microsoft)" Subject: [PATCH 3/6] Drivers: hv: vmbus: Introduce vmbus_sendpacket_getid() Date: Thu, 7 Apr 2022 06:30:25 +0200 Message-Id: <20220407043028.379534-4-parri.andrea@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220407043028.379534-1-parri.andrea@gmail.com> References: <20220407043028.379534-1-parri.andrea@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org The function can be used to send a VMbus packet and retrieve the corresponding transaction ID. It will be used by hv_pci. No functional change. Suggested-by: Michael Kelley Signed-off-by: Andrea Parri (Microsoft) Reviewed-by: Michael Kelley --- drivers/hv/channel.c | 38 ++++++++++++++++++++++++++++++++------ drivers/hv/hyperv_vmbus.h | 2 +- drivers/hv/ring_buffer.c | 14 +++++++++++--- include/linux/hyperv.h | 7 +++++++ 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 20fc8d50a0398..585a8084848bf 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -1022,11 +1022,13 @@ void vmbus_close(struct vmbus_channel *channel) EXPORT_SYMBOL_GPL(vmbus_close); /** - * vmbus_sendpacket() - Send the specified buffer on the given channel + * vmbus_sendpacket_getid() - Send the specified buffer on the given channel * @channel: Pointer to vmbus_channel structure * @buffer: Pointer to the buffer you want to send the data from. * @bufferlen: Maximum size of what the buffer holds. * @requestid: Identifier of the request + * @trans_id: Identifier of the transaction associated to this request, if + * the send is successful; undefined, otherwise. * @type: Type of packet that is being sent e.g. negotiate, time * packet etc. * @flags: 0 or VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED @@ -1036,8 +1038,8 @@ EXPORT_SYMBOL_GPL(vmbus_close); * * Mainly used by Hyper-V drivers. */ -int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer, - u32 bufferlen, u64 requestid, +int vmbus_sendpacket_getid(struct vmbus_channel *channel, void *buffer, + u32 bufferlen, u64 requestid, u64 *trans_id, enum vmbus_packet_type type, u32 flags) { struct vmpacket_descriptor desc; @@ -1063,7 +1065,31 @@ int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer, bufferlist[2].iov_base = &aligned_data; bufferlist[2].iov_len = (packetlen_aligned - packetlen); - return hv_ringbuffer_write(channel, bufferlist, num_vecs, requestid); + return hv_ringbuffer_write(channel, bufferlist, num_vecs, requestid, trans_id); +} +EXPORT_SYMBOL(vmbus_sendpacket_getid); + +/** + * vmbus_sendpacket() - Send the specified buffer on the given channel + * @channel: Pointer to vmbus_channel structure + * @buffer: Pointer to the buffer you want to send the data from. + * @bufferlen: Maximum size of what the buffer holds. + * @requestid: Identifier of the request + * @type: Type of packet that is being sent e.g. negotiate, time + * packet etc. + * @flags: 0 or VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED + * + * Sends data in @buffer directly to Hyper-V via the vmbus. + * This will send the data unparsed to Hyper-V. + * + * Mainly used by Hyper-V drivers. + */ +int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer, + u32 bufferlen, u64 requestid, + enum vmbus_packet_type type, u32 flags) +{ + return vmbus_sendpacket_getid(channel, buffer, bufferlen, + requestid, NULL, type, flags); } EXPORT_SYMBOL(vmbus_sendpacket); @@ -1122,7 +1148,7 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, bufferlist[2].iov_base = &aligned_data; bufferlist[2].iov_len = (packetlen_aligned - packetlen); - return hv_ringbuffer_write(channel, bufferlist, 3, requestid); + return hv_ringbuffer_write(channel, bufferlist, 3, requestid, NULL); } EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer); @@ -1160,7 +1186,7 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel, bufferlist[2].iov_base = &aligned_data; bufferlist[2].iov_len = (packetlen_aligned - packetlen); - return hv_ringbuffer_write(channel, bufferlist, 3, requestid); + return hv_ringbuffer_write(channel, bufferlist, 3, requestid, NULL); } EXPORT_SYMBOL_GPL(vmbus_sendpacket_mpb_desc); diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 3a1f007b678a0..64c0b9cbe183b 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -181,7 +181,7 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); int hv_ringbuffer_write(struct vmbus_channel *channel, const struct kvec *kv_list, u32 kv_count, - u64 requestid); + u64 requestid, u64 *trans_id); int hv_ringbuffer_read(struct vmbus_channel *channel, void *buffer, u32 buflen, u32 *buffer_actual_len, diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 3d215d9dec433..e101b11f95e5d 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -283,7 +283,7 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info) /* Write to the ring buffer. */ int hv_ringbuffer_write(struct vmbus_channel *channel, const struct kvec *kv_list, u32 kv_count, - u64 requestid) + u64 requestid, u64 *trans_id) { int i; u32 bytes_avail_towrite; @@ -294,7 +294,7 @@ int hv_ringbuffer_write(struct vmbus_channel *channel, unsigned long flags; struct hv_ring_buffer_info *outring_info = &channel->outbound; struct vmpacket_descriptor *desc = kv_list[0].iov_base; - u64 rqst_id = VMBUS_NO_RQSTOR; + u64 __trans_id, rqst_id = VMBUS_NO_RQSTOR; if (channel->rescind) return -ENODEV; @@ -353,7 +353,15 @@ int hv_ringbuffer_write(struct vmbus_channel *channel, } } desc = hv_get_ring_buffer(outring_info) + old_write; - desc->trans_id = (rqst_id == VMBUS_NO_RQSTOR) ? requestid : rqst_id; + __trans_id = (rqst_id == VMBUS_NO_RQSTOR) ? requestid : rqst_id; + /* + * Ensure the compiler doesn't generate code that reads the value of + * the transaction ID from the ring buffer, which is shared with the + * Hyper-V host and subject to being changed at any time. + */ + WRITE_ONCE(desc->trans_id, __trans_id); + if (trans_id) + *trans_id = __trans_id; /* Set previous packet start */ prev_indices = hv_get_ring_bufferindices(outring_info); diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index fe2e0179ed51e..a7cb596d893b1 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1161,6 +1161,13 @@ extern int vmbus_open(struct vmbus_channel *channel, extern void vmbus_close(struct vmbus_channel *channel); +extern int vmbus_sendpacket_getid(struct vmbus_channel *channel, + void *buffer, + u32 bufferLen, + u64 requestid, + u64 *trans_id, + enum vmbus_packet_type type, + u32 flags); extern int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer, u32 bufferLen, From patchwork Thu Apr 7 04:30:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Parri X-Patchwork-Id: 12804436 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C3E7C4332F for ; Thu, 7 Apr 2022 04:32:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240669AbiDGEeX (ORCPT ); Thu, 7 Apr 2022 00:34:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47324 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240639AbiDGEeR (ORCPT ); Thu, 7 Apr 2022 00:34:17 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB28A1E6F80; Wed, 6 Apr 2022 21:32:17 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id r10so5000580eda.1; Wed, 06 Apr 2022 21:32:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XzsO0OH64I9oYEuJ3bY1ziODzwl46OGR5ery+8e6tc4=; b=Kqciknive9KvGUbs71Z+2JUtJqRbxHRIRvk+3wCe2zKZjAe2FuZN5Iw9V+bM4ShVas zrCB6gvQQzXb0V5n1G3OUBkHlbuTZ2y7v7/IfbgCC9yKDBDkBafTuz9SdYdFrc1fFxZq 5JDHnt+nXlL1JrgYi0qtmAiexcbooenX81b5mTWw+ZxLUwCOD3aXy/0OdZFYnuIdROf4 YOkCPhWIj45uea7nw5GwQV7RyelvZKYDKrYcT0VYzDYYj7isyL3QCtZWK4YKSLae5H2w E2hP7/cKNk6OtoTnAawWd8wiZ/V0hV6GJohSCq9tDuLJRpESMbP1T9/yMPfQ4oftGxff nVow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XzsO0OH64I9oYEuJ3bY1ziODzwl46OGR5ery+8e6tc4=; b=x1YSwQuxsfCFlDJ179K7zNzL/Eea2pTr9GGuierg7cczoJpwXrC81mbC7hpFEZvDxB 72Lo99D8N+3g5SC6WkxgI0NDCryYKAa2PYQ8P9HQJj0B/9HeXMMu/Ik9PlEwxJMZUBaT iyD80OSc/95MXsZyjdzJuOe+H/2TMSQhGZgMU8W5Aaaje34JNnH7LbbE+Zab+8MThNHu 713dPUvUKh7eVlxhpO2e7vlH/nsWXlEefZ+BWl8IVRH1YKrTvHvnHWB/O08lpXuF50lV KZJWMh6LWzLG2eZkFovajXtyvqOzIKb7TEoimgDL+DvSGzTUWGCJhQ7h4GlEMCYXyLHR D+AA== X-Gm-Message-State: AOAM530ZwPRKkHSLfR3sUAug23V9muHJkXlaoVZDxeW4UgUbPbyX+Ff+ R1qtBpMOGp+s4ggM0zL4h0s= X-Google-Smtp-Source: ABdhPJxvbHS6Z5yrJL4QnjMLuMR2ia6OQV2phjaGSlfbQ5cEiI6213i9pD6/nJTh40E7oiTIYXjsVQ== X-Received: by 2002:a05:6402:190d:b0:41b:a70d:1367 with SMTP id e13-20020a056402190d00b0041ba70d1367mr12116188edz.155.1649305936485; Wed, 06 Apr 2022 21:32:16 -0700 (PDT) Received: from anparri.mshome.net (host-87-11-75-174.retail.telecomitalia.it. [87.11.75.174]) by smtp.gmail.com with ESMTPSA id ke11-20020a17090798eb00b006e7fbf53398sm3531341ejc.129.2022.04.06.21.32.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Apr 2022 21:32:16 -0700 (PDT) From: "Andrea Parri (Microsoft)" To: KY Srinivasan , Haiyang Zhang , Stephen Hemminger , Wei Liu , Dexuan Cui , Michael Kelley , Wei Hu , Lorenzo Pieralisi , Rob Herring , Krzysztof Wilczynski , Bjorn Helgaas Cc: linux-hyperv@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, "Andrea Parri (Microsoft)" Subject: [PATCH 4/6] Drivers: hv: vmbus: Introduce vmbus_request_addr_match() Date: Thu, 7 Apr 2022 06:30:26 +0200 Message-Id: <20220407043028.379534-5-parri.andrea@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220407043028.379534-1-parri.andrea@gmail.com> References: <20220407043028.379534-1-parri.andrea@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org The function can be used to retrieve and clear/remove a transation ID from a channel requestor, provided the memory address corresponding to the ID equals a specified address. The function, and its 'lockless' variant __vmbus_request_addr_match(), will be used by hv_pci. Refactor vmbus_request_addr() to reuse the 'newly' introduced code. No functional change. Suggested-by: Michael Kelley Signed-off-by: Andrea Parri (Microsoft) --- drivers/hv/channel.c | 65 ++++++++++++++++++++++++++++++------------ include/linux/hyperv.h | 5 ++++ 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 585a8084848bf..49f10a603a091 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -1279,17 +1279,11 @@ u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr) } EXPORT_SYMBOL_GPL(vmbus_next_request_id); -/* - * vmbus_request_addr - Returns the memory address stored at @trans_id - * in @rqstor. Uses a spin lock to avoid race conditions. - * @channel: Pointer to the VMbus channel struct - * @trans_id: Request id sent back from Hyper-V. Becomes the requestor's - * next request id. - */ -u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id) +/* As in vmbus_request_addr_match() but without the requestor lock */ +u64 __vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, + u64 rqst_addr) { struct vmbus_requestor *rqstor = &channel->requestor; - unsigned long flags; u64 req_addr; /* Check rqstor has been initialized */ @@ -1300,25 +1294,60 @@ u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id) if (!trans_id) return VMBUS_RQST_ERROR; - spin_lock_irqsave(&rqstor->req_lock, flags); - /* Data corresponding to trans_id is stored at trans_id - 1 */ trans_id--; /* Invalid trans_id */ - if (trans_id >= rqstor->size || !test_bit(trans_id, rqstor->req_bitmap)) { - spin_unlock_irqrestore(&rqstor->req_lock, flags); + if (trans_id >= rqstor->size || !test_bit(trans_id, rqstor->req_bitmap)) return VMBUS_RQST_ERROR; - } req_addr = rqstor->req_arr[trans_id]; - rqstor->req_arr[trans_id] = rqstor->next_request_id; - rqstor->next_request_id = trans_id; + if (rqst_addr == VMBUS_RQST_ADDR_ANY || req_addr == rqst_addr) { + rqstor->req_arr[trans_id] = rqstor->next_request_id; + rqstor->next_request_id = trans_id; - /* The already held spin lock provides atomicity */ - bitmap_clear(rqstor->req_bitmap, trans_id, 1); + /* The already held spin lock provides atomicity */ + bitmap_clear(rqstor->req_bitmap, trans_id, 1); + } + + return req_addr; +} +EXPORT_SYMBOL_GPL(__vmbus_request_addr_match); + +/* + * vmbus_request_addr_match - Clears/removes @trans_id from the @channel's + * requestor, provided the memory address stored at @trans_id equals @rqst_addr + * (or provided @rqst_addr matches the sentinel value VMBUS_RQST_ADDR_ANY). + * + * Returns the memory address stored at @trans_id, or VMBUS_RQST_ERROR if + * @trans_id is not contained in the requestor. + * + * Acquires and releases the requestor spin lock. + */ +u64 vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, + u64 rqst_addr) +{ + struct vmbus_requestor *rqstor = &channel->requestor; + unsigned long flags; + u64 req_addr; + spin_lock_irqsave(&rqstor->req_lock, flags); + req_addr = __vmbus_request_addr_match(channel, trans_id, rqst_addr); spin_unlock_irqrestore(&rqstor->req_lock, flags); + return req_addr; } +EXPORT_SYMBOL_GPL(vmbus_request_addr_match); + +/* + * vmbus_request_addr - Returns the memory address stored at @trans_id + * in @rqstor. Uses a spin lock to avoid race conditions. + * @channel: Pointer to the VMbus channel struct + * @trans_id: Request id sent back from Hyper-V. Becomes the requestor's + * next request id. + */ +u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id) +{ + return vmbus_request_addr_match(channel, trans_id, VMBUS_RQST_ADDR_ANY); +} EXPORT_SYMBOL_GPL(vmbus_request_addr); diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index a7cb596d893b1..c77d78f34b96a 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -788,6 +788,7 @@ struct vmbus_requestor { #define VMBUS_NO_RQSTOR U64_MAX #define VMBUS_RQST_ERROR (U64_MAX - 1) +#define VMBUS_RQST_ADDR_ANY U64_MAX /* NetVSC-specific */ #define VMBUS_RQST_ID_NO_RESPONSE (U64_MAX - 2) /* StorVSC-specific */ @@ -1042,6 +1043,10 @@ struct vmbus_channel { }; u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr); +u64 __vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, + u64 rqst_addr); +u64 vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, + u64 rqst_addr); u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id); static inline bool is_hvsock_channel(const struct vmbus_channel *c) From patchwork Thu Apr 7 04:30:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Parri X-Patchwork-Id: 12804438 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D61ABC433EF for ; Thu, 7 Apr 2022 04:32:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240688AbiDGEeY (ORCPT ); Thu, 7 Apr 2022 00:34:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47246 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238977AbiDGEeS (ORCPT ); Thu, 7 Apr 2022 00:34:18 -0400 Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [IPv6:2a00:1450:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E9BFC1E816B; Wed, 6 Apr 2022 21:32:19 -0700 (PDT) Received: by mail-ej1-x62b.google.com with SMTP id n6so8233344ejc.13; Wed, 06 Apr 2022 21:32:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YeGL7lzBfsKJziEcGc06vjizc2vur51ZL5S8EuTAwZw=; b=F54Lu3n41OZgyScu9We50U8ODKJ+j4XTgJi5+ISj8520Kevyg8EhNJFxqlcTxWMwjM zQxrXX8xCqjlj9y84u8+DXqPK0mytpDmRZAP24zEM1D2nHAraSocombPlalItxS7kvgI +loq4sazD48S3UgrvloGuAB2y/J+AeupGJQItOMObywN/pdI5qmi/Mna92v84XCKzuDw PxxzBqa2z4QIFHjmRZYrGCdZfsfnRCoCrZzhr8pMFl3plkoBFnsx74rD1al8rEAOcOy0 PnACIX/pGkSKd60zprf7eCF6tmDYFbqvorPtQLLq47sqWbVek2eEVJNaiWIdIID6dKfE AqMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YeGL7lzBfsKJziEcGc06vjizc2vur51ZL5S8EuTAwZw=; b=0yhuuq3S0Qj4jBG3VlTZ+U8NVReV9PAe5fEHo+IY5euS62RsieuWX9jRZXrqwF8xqw +DVkBabJOTjadbpQqBdbKV/OA35gzDj1E/+5R8EYaTVXz8zEw7RLyr2MKOcB4rZnVNOe sTEPkYSbXtX8m510nj7/ou51X6ve4Esc5Xp7/FPQvFm6iItahffczxf0plvajo3kLAyh VdxgSLVhWLiho3u14eAeC+QmkIvzLLYXUxtf+Yq3RBcr40mODf5PPugPv2El0tqpsoyp 43PTocuYM9cexI07L1y3f9jNvVOr0AEC9h3f6v03YTse6KcIJFgH+AgCc0anZNX0KE6e OSMg== X-Gm-Message-State: AOAM5301mBt/14VaVnSIbAVtEjKCZS5SLzLK0d8h+rNfSJNKmcbje1LS 3WhFBXUfHgIopUs5rU7JuHI= X-Google-Smtp-Source: ABdhPJxzAw6z+Kr7CeDU3lk5MWo4uT91DzsFchXuq/QeynrICu0+t8Y62KmD4gcCStkUJ1T7V4cXBg== X-Received: by 2002:a17:907:a088:b0:6e4:dad7:1b1f with SMTP id hu8-20020a170907a08800b006e4dad71b1fmr11236607ejc.84.1649305938504; Wed, 06 Apr 2022 21:32:18 -0700 (PDT) Received: from anparri.mshome.net (host-87-11-75-174.retail.telecomitalia.it. [87.11.75.174]) by smtp.gmail.com with ESMTPSA id ke11-20020a17090798eb00b006e7fbf53398sm3531341ejc.129.2022.04.06.21.32.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Apr 2022 21:32:18 -0700 (PDT) From: "Andrea Parri (Microsoft)" To: KY Srinivasan , Haiyang Zhang , Stephen Hemminger , Wei Liu , Dexuan Cui , Michael Kelley , Wei Hu , Lorenzo Pieralisi , Rob Herring , Krzysztof Wilczynski , Bjorn Helgaas Cc: linux-hyperv@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, "Andrea Parri (Microsoft)" Subject: [PATCH 5/6] Drivers: hv: vmbus: Introduce {lock,unlock}_requestor() Date: Thu, 7 Apr 2022 06:30:27 +0200 Message-Id: <20220407043028.379534-6-parri.andrea@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220407043028.379534-1-parri.andrea@gmail.com> References: <20220407043028.379534-1-parri.andrea@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org To abtract the lock and unlock operations on the requestor spin lock. The helpers will come in handy in hv_pci. No functional change. Suggested-by: Michael Kelley Signed-off-by: Andrea Parri (Microsoft) Reviewed-by: Michael Kelley --- drivers/hv/channel.c | 11 +++++------ include/linux/hyperv.h | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 49f10a603a091..56f7e06c673e4 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -1252,12 +1252,12 @@ u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr) if (!channel->rqstor_size) return VMBUS_NO_RQSTOR; - spin_lock_irqsave(&rqstor->req_lock, flags); + lock_requestor(channel, flags); current_id = rqstor->next_request_id; /* Requestor array is full */ if (current_id >= rqstor->size) { - spin_unlock_irqrestore(&rqstor->req_lock, flags); + unlock_requestor(channel, flags); return VMBUS_RQST_ERROR; } @@ -1267,7 +1267,7 @@ u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr) /* The already held spin lock provides atomicity */ bitmap_set(rqstor->req_bitmap, current_id, 1); - spin_unlock_irqrestore(&rqstor->req_lock, flags); + unlock_requestor(channel, flags); /* * Cannot return an ID of 0, which is reserved for an unsolicited @@ -1327,13 +1327,12 @@ EXPORT_SYMBOL_GPL(__vmbus_request_addr_match); u64 vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, u64 rqst_addr) { - struct vmbus_requestor *rqstor = &channel->requestor; unsigned long flags; u64 req_addr; - spin_lock_irqsave(&rqstor->req_lock, flags); + lock_requestor(channel, flags); req_addr = __vmbus_request_addr_match(channel, trans_id, rqst_addr); - spin_unlock_irqrestore(&rqstor->req_lock, flags); + unlock_requestor(channel, flags); return req_addr; } diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index c77d78f34b96a..015e4ceb43029 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1042,6 +1042,21 @@ struct vmbus_channel { u32 max_pkt_size; }; +#define lock_requestor(channel, flags) \ +do { \ + struct vmbus_requestor *rqstor = &(channel)->requestor; \ + \ + spin_lock_irqsave(&rqstor->req_lock, flags); \ +} while (0) + +static __always_inline void unlock_requestor(struct vmbus_channel *channel, + unsigned long flags) +{ + struct vmbus_requestor *rqstor = &channel->requestor; + + spin_unlock_irqrestore(&rqstor->req_lock, flags); +} + u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr); u64 __vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, u64 rqst_addr); From patchwork Thu Apr 7 04:30:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Parri X-Patchwork-Id: 12804439 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92CA1C433F5 for ; Thu, 7 Apr 2022 04:32:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240505AbiDGEe1 (ORCPT ); Thu, 7 Apr 2022 00:34:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47626 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240674AbiDGEeU (ORCPT ); Thu, 7 Apr 2022 00:34:20 -0400 Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [IPv6:2a00:1450:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 452111E869E; Wed, 6 Apr 2022 21:32:22 -0700 (PDT) Received: by mail-ej1-x633.google.com with SMTP id bh17so8285066ejb.8; Wed, 06 Apr 2022 21:32:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fnlZDRRS7PR+XhZFKAMVuyrkTCKVrR39UF+kw4DUCS0=; b=BM9yF4lax9++9+ia/3A+nNKqN4zI6aKd9ErEK1F9b9SLYKIxtr/GuRoFFKh01k+5Gl 7FYHRR/KzDJ1DMWQgccwTYACFks3lG9azjO5G93lyabu9XFUF338NE+BtZRzEbJN8LG3 Bx0En7Cg1wBs4tXHuI+88Z7xY74SAzL2t2DSKMYVzMfnOeGqu49IEGF+jlvOn9l0ANhF d50+VqMjiUIZQuYIFujVSLXMX9olUig6tOoBtGBtgZQBu8v8Ft8pWPiRWRD6mF11N5cZ NDzgWg+Gagqm5NWS3ZyyuBfELYhxu53g37Hz834vXKEhgL7L2wVltekkBi7gaHfBp5Wv Kc9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fnlZDRRS7PR+XhZFKAMVuyrkTCKVrR39UF+kw4DUCS0=; b=CDbjziNummREBnzuEpBs5xm0EYJeyvUWiblHCQyXljvqQr087GyRnCoPo8Z8kJpV2C zGDnl0jyTMIfMRzTs3czKQQNDQ0W6L3ad+jvEAABuyloOQM61C7EK/BzChcM/4bYQCaB nsODnlrj+2VzPJfgPWmVNJTsyIBGCDOMiTbBhYr7N+DdkhUDzaxJ620A37ikRQ2C+sm/ L5iQGtzhhHwpbrD+lFTH5/0+rzkjbz+g9bwP+F7a9dpGwsNwaJXOuq43wmZ8asoTgeks L8tlxHHsXprtwyzi8CVQp0zux6Uzp6iz0uIX4F+pGb7fNq1kFLJTKrsEan6SdklbyfFa zfOw== X-Gm-Message-State: AOAM531ZiEZRR2UE84tfvKUBxp4CNsjTSO2KpvhtKS/a5FbGkp9POCt+ JKzKZZWD9kqMOvFMAEDKx0M= X-Google-Smtp-Source: ABdhPJzz9E6ugccX49b5so3/0qNL929ZI5Flwv/RHmpUhYr2mojndRYy9BSupaQ4p5pdfzbcYFNLEQ== X-Received: by 2002:a17:907:60c8:b0:6da:83f0:9eaa with SMTP id hv8-20020a17090760c800b006da83f09eaamr11172034ejc.605.1649305940725; Wed, 06 Apr 2022 21:32:20 -0700 (PDT) Received: from anparri.mshome.net (host-87-11-75-174.retail.telecomitalia.it. [87.11.75.174]) by smtp.gmail.com with ESMTPSA id ke11-20020a17090798eb00b006e7fbf53398sm3531341ejc.129.2022.04.06.21.32.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Apr 2022 21:32:20 -0700 (PDT) From: "Andrea Parri (Microsoft)" To: KY Srinivasan , Haiyang Zhang , Stephen Hemminger , Wei Liu , Dexuan Cui , Michael Kelley , Wei Hu , Lorenzo Pieralisi , Rob Herring , Krzysztof Wilczynski , Bjorn Helgaas Cc: linux-hyperv@vger.kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, "Andrea Parri (Microsoft)" Subject: [PATCH 6/6] PCI: hv: Fix synchronization between channel callback and hv_compose_msi_msg() Date: Thu, 7 Apr 2022 06:30:28 +0200 Message-Id: <20220407043028.379534-7-parri.andrea@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220407043028.379534-1-parri.andrea@gmail.com> References: <20220407043028.379534-1-parri.andrea@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Dexuan wrote: "[...] when we disable AccelNet, the host PCI VSP driver sends a PCI_EJECT message first, and the channel callback may set hpdev->state to hv_pcichild_ejecting on a different CPU. This can cause hv_compose_msi_msg() to exit from the loop and 'return', and the on-stack variable 'ctxt' is invalid. Now, if the response message from the host arrives, the channel callback will try to access the invalid 'ctxt' variable, and this may cause a crash." Schematically: Hyper-V sends PCI_EJECT msg hv_pci_onchannelcallback() state = hv_pcichild_ejecting hv_compose_msi_msg() alloc and init comp_pkt state == hv_pcichild_ejecting Hyper-V sends VM_PKT_COMP msg hv_pci_onchannelcallback() retrieve address of comp_pkt 'free' comp_pkt and return comp_pkt->completion_func() Dexuan also showed how the crash can be triggered after introducing suitable delays in the driver code, thus validating the 'assumption' that the host can still normally respond to the guest's compose_msi request after the host has started to eject the PCI device. Fix the synchronization by leveraging the requestor lock as follows: - Before 'return'-ing in hv_compose_msi_msg(), remove the ID (while holding the requestor lock) associated to the completion packet. - Retrieve the address *and call ->completion_func() within a same (requestor) critical section in hv_pci_onchannelcallback(). Fixes: de0aa7b2f97d3 ("PCI: hv: Fix 2 hang issues in hv_compose_msi_msg()") Reported-by: Wei Hu Reported-by: Dexuan Cui Suggested-by: Michael Kelley Signed-off-by: Andrea Parri (Microsoft) Reviewed-by: Michael Kelley --- The "Fixes:" tag is mainly a reference: a back-port would depend on the entire series (which, in turn, shouldn't be backported to commits preceding bf5fd8cae3c8f). drivers/pci/controller/pci-hyperv.c | 33 +++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index c1322ac37cda9..f1d794f8a5ef1 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -1695,7 +1695,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) struct pci_create_interrupt3 v3; } int_pkts; } __packed ctxt; - + u64 trans_id; u32 size; int ret; @@ -1757,10 +1757,10 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) goto free_int_desc; } - ret = vmbus_sendpacket(hpdev->hbus->hdev->channel, &ctxt.int_pkts, - size, (unsigned long)&ctxt.pci_pkt, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + ret = vmbus_sendpacket_getid(hpdev->hbus->hdev->channel, &ctxt.int_pkts, + size, (unsigned long)&ctxt.pci_pkt, + &trans_id, VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret) { dev_err(&hbus->hdev->device, "Sending request for interrupt failed: 0x%x", @@ -1839,6 +1839,15 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) enable_tasklet: tasklet_enable(&channel->callback_event); + /* + * The completion packet on the stack becomes invalid after 'return'; + * remove the ID from the VMbus requestor if the identifier is still + * mapped to/associated with the packet. (The identifier could have + * been 're-used', i.e., already removed and (re-)mapped.) + * + * Cf. hv_pci_onchannelcallback(). + */ + vmbus_request_addr_match(channel, trans_id, (unsigned long)&ctxt.pci_pkt); free_int_desc: kfree(int_desc); drop_reference: @@ -2717,6 +2726,7 @@ static void hv_pci_onchannelcallback(void *context) struct pci_dev_inval_block *inval; struct pci_dev_incoming *dev_message; struct hv_pci_dev *hpdev; + unsigned long flags; buffer = kmalloc(bufferlen, GFP_ATOMIC); if (!buffer) @@ -2751,8 +2761,11 @@ static void hv_pci_onchannelcallback(void *context) switch (desc->type) { case VM_PKT_COMP: - req_addr = chan->request_addr_callback(chan, req_id); + lock_requestor(chan, flags); + req_addr = __vmbus_request_addr_match(chan, req_id, + VMBUS_RQST_ADDR_ANY); if (req_addr == VMBUS_RQST_ERROR) { + unlock_requestor(chan, flags); dev_warn_ratelimited(&hbus->hdev->device, "Invalid transaction ID %llx\n", req_id); @@ -2760,9 +2773,17 @@ static void hv_pci_onchannelcallback(void *context) } comp_packet = (struct pci_packet *)req_addr; response = (struct pci_response *)buffer; + /* + * Call ->completion_func() within the critical section to make + * sure that the packet pointer is still valid during the call: + * here 'valid' means that there's a task still waiting for the + * completion, and that the packet data is still on the waiting + * task's stack. Cf. hv_compose_msi_msg(). + */ comp_packet->completion_func(comp_packet->compl_ctxt, response, bytes_recvd); + unlock_requestor(chan, flags); break; case VM_PKT_DATA_INBAND: