From patchwork Tue Oct 11 00:08:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614289 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 7F915C43217 for ; Tue, 11 Oct 2022 00:10:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230307AbiJKAKE (ORCPT ); Mon, 10 Oct 2022 20:10:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53602 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230214AbiJKAJ4 (ORCPT ); Mon, 10 Oct 2022 20:09:56 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2BF2D10FE7; Mon, 10 Oct 2022 17:09:41 -0700 (PDT) Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29B02wMb003601; Tue, 11 Oct 2022 00:09:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=/7XgmW5ZeZvpEDn454JVrvGghfAFwyCZe3fb56CjADM=; b=Wlu80ogkUtlpRvTPu9eyDODbcC1syhDUmd2snoYeORXzezU4ls8AhSRbzYY9eI1w2Ee8 GtDF+WAYZ9hMbMTQ93bxprj/2ryBhXTsBQLLBZfSmXjWgmU+YEAyNIUUFNgabgA8u8wp YtNHF2Ee2yFLqDCjQ4c9TUvjp2RQyoDUlgX9l0tACMNKurnylMcpF0Mod14+fHht9CT6 akvX42/nEv0lPbfqIo0BjmjNAxqEK7yrjq8ZF7xqLXoX2aKj91Fz886BVYzQ/oXrY8sc uAhy/yvIgNi3FodblknQYOTJhlQGygmriNOc128yu7/va+VKKQAUaaqiH8fBqYr90JII tA== Received: from nasanppmta01.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3k4rxa0hmd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:24 +0000 Received: from nasanex01b.na.qualcomm.com (corens_vlan604_snip.qualcomm.com [10.53.140.1]) by NASANPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 29B09NuU012957 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:23 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:22 -0700 From: Elliot Berman To: Bjorn Andersson , Jonathan Corbet CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Marc Zyngier , Rob Herring , Krzysztof Kozlowski , Will Deacon , "Catalin Marinas" , Arnd Bergmann , "Greg Kroah-Hartman" , , , , Subject: [PATCH v5 01/13] docs: gunyah: Introduce Gunyah Hypervisor Date: Mon, 10 Oct 2022 17:08:28 -0700 Message-ID: <20221011000840.289033-2-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: piJmfRK8HYu-D2XDGUT22zlXsoDi70Hf X-Proofpoint-GUID: piJmfRK8HYu-D2XDGUT22zlXsoDi70Hf X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 suspectscore=0 spamscore=0 mlxscore=0 clxscore=1015 adultscore=0 impostorscore=0 bulkscore=0 priorityscore=1501 mlxlogscore=999 malwarescore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210100143 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Gunyah is an open-source Type-1 hypervisor developed by Qualcomm. It does not depend on any lower-privileged OS/kernel code for its core functionality. This increases its security and can support a smaller trusted computing based when compared to Type-2 hypervisors. Add documentation describing the Gunyah hypervisor and the main components of the Gunyah hypervisor which are of interest to Linux virtualization development. Signed-off-by: Elliot Berman --- Documentation/virt/gunyah/index.rst | 114 ++++++++++++++++++++ Documentation/virt/gunyah/message-queue.rst | 54 ++++++++++ Documentation/virt/index.rst | 1 + MAINTAINERS | 7 ++ 4 files changed, 176 insertions(+) create mode 100644 Documentation/virt/gunyah/index.rst create mode 100644 Documentation/virt/gunyah/message-queue.rst diff --git a/Documentation/virt/gunyah/index.rst b/Documentation/virt/gunyah/index.rst new file mode 100644 index 000000000000..fbadbdd24da7 --- /dev/null +++ b/Documentation/virt/gunyah/index.rst @@ -0,0 +1,114 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================= +Gunyah Hypervisor +================= + +.. toctree:: + :maxdepth: 1 + + message-queue + +Gunyah is a Type-1 hypervisor which is independent of any OS kernel, and runs in +a higher CPU privilege level. It does not depend on any lower-privileged operating system +for its core functionality. This increases its security and can support a much smaller +trusted computing base than a Type-2 hypervisor. + +Gunyah is an open source hypervisor. The source repo is available at +https://github.com/quic/gunyah-hypervisor. + +Gunyah provides these following features. + +- Scheduling: + + A scheduler for virtual CPUs (vCPUs) on physical CPUs and enables time-sharing + of the CPUs. Gunyah supports two models of scheduling: + + 1. "Behind the back" scheduling in which Gunyah hypervisor schedules vCPUS on its own. + 2. "Proxy" scheduling in which a delegated VM can donate part of one of its vCPU slice + to another VM's vCPU via a hypercall. + +- Memory Management: + + APIs handling memory, abstracted as objects, limiting direct use of physical + addresses. Memory ownership and usage tracking of all memory under its control. + Memory partitioning between VMs is a fundamental security feature. + +- Interrupt Virtualization: + + Uses CPU hardware interrupt virtualization capabilities. Interrupts are handled + in the hypervisor and routed to the assigned VM. + +- Inter-VM Communication: + + There are several different mechanisms provided for communicating between VMs. + +- Virtual platform: + + Architectural devices such as interrupt controllers and CPU timers are directly provided + by the hypervisor as well as core virtual platform devices and system APIs such as ARM PSCI. + +- Device Virtualization: + + Para-virtualization of devices is supported using inter-VM communication. + +Architectures supported +======================= +AArch64 with a GIC + +Resources and Capabilities +========================== + +Some services or resources provided by the Gunyah hypervisor are described to a virtual machine by +capability IDs. For instance, inter-VM communication is performed with doorbells and message queues. +Gunyah allows access to manipulate that doorbell via the capability ID. These devices are described +in Linux as a struct gunyah_resource. + +High level management of these resources is performed by the resource manager VM. RM informs a +guest VM about resources it can access through either the device tree or via guest-initiated RPC. + +For each virtual machine, Gunyah maintains a table of resources which can be accessed by that VM. +An entry in this table is called a "capability" and VMs can only access resources via this +capability table. Hence, virtual Gunyah devices are referenced by a "capability IDs" and not a +"resource IDs". A VM can have multiple capability IDs mapping to the same resource. If 2 VMs have +access to the same resource, they may not be using the same capability ID to access that resource +since the tables are independent per VM. + +Resource Manager +================ + +The resource manager (RM) is a privileged application VM supporting the Gunyah Hypervisor. +It provides policy enforcement aspects of the virtualization system. The resource manager can +be treated as an extension of the Hypervisor but is separated to its own partition to ensure +that the hypervisor layer itself remains small and secure and to maintain a separation of policy +and mechanism in the platform. On arm64, RM runs at NS-EL1 similar to other virtual machines. + +Communication with the resource manager from each guest VM happens with message-queue.rst. Details +about the specific messages can be found in drivers/virt/gunyah/rsc_mgr.c + +:: + + +-------+ +--------+ +--------+ + | RM | | VM_A | | VM_B | + +-.-.-.-+ +---.----+ +---.----+ + | | | | + +-.-.-----------.------------.----+ + | | \==========/ | | + | \========================/ | + | Gunyah | + +---------------------------------+ + +The source for the resource manager is available at https://github.com/quic/gunyah-resource-manager. + +The resource manager provides the following features: + +- VM lifecycle management: allocating a VM, starting VMs, destruction of VMs +- VM access control policy, including memory sharing and lending +- Interrupt routing configuration +- Forwarding of system-level events (e.g. VM shutdown) to owner VM + +When booting a virtual machine which uses a devicetree, resource manager overlays a +/hypervisor node. This node can let Linux know it is running as a Gunyah guest VM, +how to communicate with resource manager, and basic description and capabilities of +this VM. See Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml for a description +of this node. diff --git a/Documentation/virt/gunyah/message-queue.rst b/Documentation/virt/gunyah/message-queue.rst new file mode 100644 index 000000000000..d7dc2f0f5d45 --- /dev/null +++ b/Documentation/virt/gunyah/message-queue.rst @@ -0,0 +1,54 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Message Queues +============== +Message queue is a simple low-capacity IPC channel between two VMs. It is +intended for sending small control and configuration messages. Each message +queue object is unidirectional, so a full-duplex IPC channel requires a pair of +objects. + +Messages can be up to 1024 bytes in length. Longer messages require a further +protocol on top of the message queue messages themselves. For instance, communication +with the resource manager adds a header field for sending longer messages via multiple +message fragments. + +The diagram below shows how message queue works. A typical configuration involves +2 message queues. Message queue 1 allows VM_A to send messages to VM_B. Message +queue 2 allows VM_B to send messages to VM_A. + +1. VM_A sends a message of up to 1024 bytes in length. It raises a hypercall + with the message to inform the hypervisor to add the message to + message queue 1's queue. + +2. Gunyah raises the corresponding interrupt for VM_B when any of these happens: + a. gh_msgq_send has PUSH flag. Queue is immediately flushed. This is the typical case. + b. Explicility with gh_msgq_push command from VM_A. + c. Message queue has reached a threshold depth. + +3. VM_B calls gh_msgq_recv and Gunyah copies message to requested buffer. + +For VM_B to send a message to VM_A, the process is identical, except that hypercalls +reference message queue 2's capability ID. + +:: + + +---------------+ +-----------------+ +---------------+ + | VM_A | |Gunyah hypervisor| | VM_B | + | | | | | | + | | | | | | + | | Tx | | | | + | |-------->| | Rx vIRQ | | + |gh_msgq_send() | Tx vIRQ |Message queue 1 |-------->|gh_msgq_recv() | + | |<------- | | | | + | | | | | | + | Message Queue | | | | Message Queue | + | driver | | | | driver | + | | | | | | + | | | | | | + | | | | Tx | | + | | Rx vIRQ | |<--------| | + |gh_msgq_recv() |<--------|Message queue 2 | Tx vIRQ |gh_msgq_send() | + | | | |-------->| | + | | | | | | + | | | | | | + +---------------+ +-----------------+ +---------------+ diff --git a/Documentation/virt/index.rst b/Documentation/virt/index.rst index 2f1cffa87b1b..418d540f5484 100644 --- a/Documentation/virt/index.rst +++ b/Documentation/virt/index.rst @@ -15,6 +15,7 @@ Linux Virtualization Support acrn/index coco/sev-guest hyperv/index + gunyah/index .. only:: html and subproject diff --git a/MAINTAINERS b/MAINTAINERS index 72b9654f764c..91d00b00d91c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8879,6 +8879,13 @@ L: linux-efi@vger.kernel.org S: Maintained F: block/partitions/efi.* +GUNYAH HYPERVISOR DRIVER +M: Elliot Berman +M: Murali Nalajala +L: linux-arm-msm@vger.kernel.org +S: Supported +F: Documentation/virt/gunyah/ + HABANALABS PCI DRIVER M: Oded Gabbay S: Supported From patchwork Tue Oct 11 00:08:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614290 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 41684C43219 for ; Tue, 11 Oct 2022 00:10:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230259AbiJKAKA (ORCPT ); Mon, 10 Oct 2022 20:10:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230201AbiJKAJs (ORCPT ); Mon, 10 Oct 2022 20:09:48 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC20A6330; Mon, 10 Oct 2022 17:09:39 -0700 (PDT) Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29B04nOX021273; Tue, 11 Oct 2022 00:09:25 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=aqnQgx63miVwivntYqrT//nA4Iku+Hti2EEJs7oBSOQ=; b=Z7QMvFuiLbIQPthx1RRVjrrGe0ajc/TpiYVWSt+dkFTTlu9FMl8Aw6+Af7rZmbCuCV/+ 0Y5xSlVuY2gHoO4sUI8BbERxRjHs9wn9Jd8NLXJMDLC282ENB5M3PRib6RplE0UO6KwV mXEksOrWolV2OEamLtM2xiqKoDWrQTiF2NLTredw/WExNn7qMU0YHWUVwxZSgkWyP38N r7HIKDVcpBhs/PhKPOJixYjsGnP87pDre8OAbuH1xLzYSrBxJ+KLsNX0MJhrNcN1yvuW 6iZNL1FQ3OGEtfxNHVU/QvN4AzqS4scIRVpmzfhUzMK4ibzOPNDT5aKpyKedHohvIDgu Aw== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3k4rxe0hjq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:25 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 29B09OBn021532 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:24 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:23 -0700 From: Elliot Berman To: Bjorn Andersson , Rob Herring , Krzysztof Kozlowski CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Marc Zyngier , Jonathan Corbet , Will Deacon , Catalin Marinas , Arnd Bergmann , Greg Kroah-Hartman , , , , Subject: [PATCH v5 02/13] dt-bindings: Add binding for gunyah hypervisor Date: Mon, 10 Oct 2022 17:08:29 -0700 Message-ID: <20221011000840.289033-3-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: ac6btpWz-18PEzqAMWCJ8reXLFeJTfNj X-Proofpoint-ORIG-GUID: ac6btpWz-18PEzqAMWCJ8reXLFeJTfNj X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 malwarescore=0 priorityscore=1501 impostorscore=0 clxscore=1015 phishscore=0 spamscore=0 adultscore=0 suspectscore=0 mlxlogscore=999 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210100143 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org When Linux is booted as a guest under the Gunyah hypervisor, the Gunyah Resource Manager applies a devicetree overlay describing the virtual platform configuration of the guest VM, such as the message queue capability IDs for communicating with the Resource Manager. This information is not otherwise discoverable by a VM: the Gunyah hypervisor core does not provide a direct interface to discover capability IDs nor a way to communicate with RM without having already known the corresponding message queue capability ID. Add the DT bindings that Gunyah adheres for the hypervisor node and message queues. Signed-off-by: Elliot Berman --- .../bindings/firmware/gunyah-hypervisor.yaml | 87 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 88 insertions(+) create mode 100644 Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml diff --git a/Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml b/Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml new file mode 100644 index 000000000000..f0a14101e2fd --- /dev/null +++ b/Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/firmware/gunyah-hypervisor.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Gunyah Hypervisor + +maintainers: + - Murali Nalajala + - Elliot Berman + +description: |+ + On systems which support devicetree, Gunyah generates and overlays a deviceetree overlay which + describes the basic configuration of the hypervisor. Virtual machines use this information to determine + the capability IDs of the message queues used to communicate with the Gunyah Resource Manager. + See also: https://github.com/quic/gunyah-resource-manager/blob/develop/src/vm_creation/dto_construct.c + +properties: + compatible: + items: + - const: gunyah-hypervisor-1.0 + - const: gunyah-hypervisor + + "#address-cells": + description: Number of cells needed to represent 64-bit capability IDs. + const: 2 + + "#size-cells": + description: must be 0, because capability IDs are not memory address + ranges and do not have a size. + const: 0 + +patternProperties: + "^gunyah-resource-mgr(@.*)?": + type: object + description: + Resource Manager node which is required to communicate to Resource + Manager VM using Gunyah Message Queues. + + properties: + compatible: + items: + - const: gunyah-resource-manager-1-0 + - const: gunyah-resource-manager + + reg: + items: + - description: Gunyah capability ID of the TX message queue + - description: Gunyah capability ID of the RX message queue + + interrupts: + items: + - description: Interrupt for the TX message queue + - description: Interrupt for the RX message queue + + additionalProperties: false + + required: + - compatible + - reg + - interrupts + +additionalProperties: false + +required: + - compatible + - "#address-cells" + - "#size-cells" + +examples: + - | + #include + + hypervisor { + #address-cells = <2>; + #size-cells = <0>; + compatible = "gunyah-hypervisor-1.0", "gunyah-hypervisor"; + + gunyah-resource-mgr@0 { + compatible = "gunyah-resource-manager-1-0", "gunyah-resource-manager"; + interrupts = , /* TX full IRQ */ + ; /* RX empty IRQ */ + reg = <0x00000000 0x00000000>, <0x00000000 0x00000001>; + /* TX, RX cap ids */ + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 91d00b00d91c..ef6de7599d98 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8884,6 +8884,7 @@ M: Elliot Berman M: Murali Nalajala L: linux-arm-msm@vger.kernel.org S: Supported +F: Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml F: Documentation/virt/gunyah/ HABANALABS PCI DRIVER From patchwork Tue Oct 11 00:08:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614292 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 13483C433F5 for ; Tue, 11 Oct 2022 00:09:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229973AbiJKAJ1 (ORCPT ); Mon, 10 Oct 2022 20:09:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50732 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229921AbiJKAJZ (ORCPT ); Mon, 10 Oct 2022 20:09:25 -0400 Received: from alexa-out-sd-02.qualcomm.com (alexa-out-sd-02.qualcomm.com [199.106.114.39]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3C5B7B29F; Mon, 10 Oct 2022 17:09:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1665446964; x=1696982964; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MrhwlQAfhZGplfbn4CVVzacAfeIm/Sjcv9oTY6XARX4=; b=gAD36LpA+Cq+ePYmwywbdYnk7JiKlZjkRXs3dIYoYSjx8vjBMbuxLusQ /XxoDMdH0EWl9Av3MYGEiVxV+rTumkt9uQi7M6+3dliDdIca0COUfRKVf ROmdWqlH8n+OAOnHocH5Rim0c7bmGme3dVMhjbUQAgaqYoxnuZsxn1PBs o=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 10 Oct 2022 17:09:24 -0700 X-QCInternal: smtphost Received: from nasanex01b.na.qualcomm.com ([10.46.141.250]) by ironmsg04-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Oct 2022 17:09:24 -0700 Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:23 -0700 From: Elliot Berman To: Bjorn Andersson , Arnd Bergmann CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Marc Zyngier , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , "Will Deacon" , Catalin Marinas , "Greg Kroah-Hartman" , , , , Subject: [PATCH v5 03/13] gunyah: Common types and error codes for Gunyah hypercalls Date: Mon, 10 Oct 2022 17:08:30 -0700 Message-ID: <20221011000840.289033-4-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add architecture-independent standard error codes, types, and macros for Gunyah hypercalls. Signed-off-by: Elliot Berman --- MAINTAINERS | 1 + include/asm-generic/gunyah.h | 74 ++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 include/asm-generic/gunyah.h diff --git a/MAINTAINERS b/MAINTAINERS index ef6de7599d98..4fe8cec61551 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8886,6 +8886,7 @@ L: linux-arm-msm@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml F: Documentation/virt/gunyah/ +F: include/asm-generic/gunyah.h HABANALABS PCI DRIVER M: Oded Gabbay diff --git a/include/asm-generic/gunyah.h b/include/asm-generic/gunyah.h new file mode 100644 index 000000000000..64a02dd3b5ad --- /dev/null +++ b/include/asm-generic/gunyah.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _ASM_GUNYAH_H +#define _ASM_GUNYAH_H + +#include +#include + +/* Common Gunyah macros */ +#define GH_CAPID_INVAL U64_MAX +#define GH_VMID_ROOT_VM 0xff + +#define GH_ERROR_OK 0 + +#define GH_ERROR_UNIMPLEMENTED -1 +#define GH_ERROR_RETRY -2 + +#define GH_ERROR_ARG_INVAL 1 +#define GH_ERROR_ARG_SIZE 2 +#define GH_ERROR_ARG_ALIGN 3 + +#define GH_ERROR_NOMEM 10 + +#define GH_ERROR_ADDR_OVFL 20 +#define GH_ERROR_ADDR_UNFL 21 +#define GH_ERROR_ADDR_INVAL 22 + +#define GH_ERROR_DENIED 30 +#define GH_ERROR_BUSY 31 +#define GH_ERROR_IDLE 32 + +#define GH_ERROR_IRQ_BOUND 40 +#define GH_ERROR_IRQ_UNBOUND 41 + +#define GH_ERROR_CSPACE_CAP_NULL 50 +#define GH_ERROR_CSPACE_CAP_REVOKED 51 +#define GH_ERROR_CSPACE_WRONG_OBJ_TYPE 52 +#define GH_ERROR_CSPACE_INSUF_RIGHTS 53 +#define GH_ERROR_CSPACE_FULL 54 + +#define GH_ERROR_MSGQUEUE_EMPTY 60 +#define GH_ERROR_MSGQUEUE_FULL 61 + +static inline int gh_remap_error(int gh_error) +{ + switch (gh_error) { + case GH_ERROR_OK: + return 0; + case GH_ERROR_NOMEM: + return -ENOMEM; + case GH_ERROR_DENIED: + case GH_ERROR_CSPACE_CAP_NULL: + case GH_ERROR_CSPACE_CAP_REVOKED: + case GH_ERROR_CSPACE_WRONG_OBJ_TYPE: + case GH_ERROR_CSPACE_INSUF_RIGHTS: + case GH_ERROR_CSPACE_FULL: + return -EACCES; + case GH_ERROR_BUSY: + case GH_ERROR_IDLE: + return -EBUSY; + case GH_ERROR_IRQ_BOUND: + case GH_ERROR_IRQ_UNBOUND: + case GH_ERROR_MSGQUEUE_FULL: + case GH_ERROR_MSGQUEUE_EMPTY: + return -EPERM; + default: + return -EINVAL; + } +} + +#endif From patchwork Tue Oct 11 00:08:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614886 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 8278EC433F5 for ; Tue, 11 Oct 2022 00:10:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230240AbiJKAJ7 (ORCPT ); Mon, 10 Oct 2022 20:09:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230198AbiJKAJs (ORCPT ); Mon, 10 Oct 2022 20:09:48 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F0BD60D9; Mon, 10 Oct 2022 17:09:39 -0700 (PDT) Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29B06gDP004946; Tue, 11 Oct 2022 00:09:26 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=NdBMegGfQRT3NVnpSimV4eMtuPXioAvn9GAQ6vw5iwE=; b=FgnoofQqOf5m8TIpkVMQ0CXQnA5cXmrZzVDzFhs7jEXJ/iYqAWV/Ri7yMikybVQi84dz 8zp7h8DNabNDMC2FS6Jn+CVw9oi7T2ZoKH+rCV6k+9zL/QiufEWGFKS1pIfeM4djd/lX rVYaoNZO/htpqrFX2WH2FZ34kImVqqbOM4ooH619dM3JTuGoQtnMG2+MKN0FJ9CfgGhl cnAaf1Jewv7OZ9ALghAwuXkXMM5enP+hn3fAp5JCXeUYKOPmxxvmSJPNG2h98+Uh5iwj tCtBsFRXIkdCFS8iI5JEl9iue4VzphCZUH7/3smNFMvNzyx2hnK0phB1XOGO3x5OhDNx lQ== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3k4rxc8j55-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:26 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 29B09PFc026368 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:25 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:24 -0700 From: Elliot Berman To: Bjorn Andersson , Mark Rutland , Lorenzo Pieralisi , "Sudeep Holla" CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Marc Zyngier , "Rob Herring" , Krzysztof Kozlowski , Jonathan Corbet , "Will Deacon" , Catalin Marinas , "Arnd Bergmann" , Greg Kroah-Hartman , , , , Subject: [PATCH v5 04/13] arm64: smccc: Include alternative-macros.h Date: Mon, 10 Oct 2022 17:08:31 -0700 Message-ID: <20221011000840.289033-5-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: eEPdW6E04Yjqaw7hXiQ57iwYILOeDMaz X-Proofpoint-GUID: eEPdW6E04Yjqaw7hXiQ57iwYILOeDMaz X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 mlxlogscore=693 priorityscore=1501 bulkscore=0 lowpriorityscore=0 spamscore=0 mlxscore=0 suspectscore=0 adultscore=0 clxscore=1015 malwarescore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210100143 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Fix build error when CONFIG_ARM64_SVE is selected and asm/alternative-macros.h wasn't implicitly included by another header. Fixes: cfa7ff959a78 ("arm64: smccc: Support SMCCC v1.3 SVE register saving hint") Signed-off-by: Elliot Berman --- include/linux/arm-smccc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index 220c8c60e021..6a627cdbbdec 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -383,6 +383,7 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, /* nVHE hypervisor doesn't have a current thread so needs separate checks */ #if defined(CONFIG_ARM64_SVE) && !defined(__KVM_NVHE_HYPERVISOR__) +#include #define SMCCC_SVE_CHECK ALTERNATIVE("nop \n", "bl __arm_smccc_sve_check \n", \ ARM64_SVE) From patchwork Tue Oct 11 00:08:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614885 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 0F5A0C4332F for ; Tue, 11 Oct 2022 00:10:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230294AbiJKAKD (ORCPT ); Mon, 10 Oct 2022 20:10:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53652 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230217AbiJKAJ4 (ORCPT ); Mon, 10 Oct 2022 20:09:56 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C38511150; Mon, 10 Oct 2022 17:09:41 -0700 (PDT) Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29ANh7kS022576; Tue, 11 Oct 2022 00:09:27 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=dv+S1bIwCI+xZZH1fha0WqbTjqAwk+RIiLm0/0GFec0=; b=h5kAXaF4JengJ24o8fQxFbtfPQXXy8/LpgTjTxbIPa6zh75UuEg9OPPSS1sjon1SlfmY RqlVzsx6Rnvss8D/KkWnn4r9i1d/bgLAcK8naU7qr9WXbDeY+UP5om1594HC+GIYJ/wk 2qwYaznm2SkV2xsF0qeJI3o99GVLoCco1rOqc3BYiuhOAOJv55+vji6Iv0DQ/N/MR/5A jiDBesqUMpnFqW7X9OTjQ6O6Wwb6K9P4ue5uB4/bgrrHXXHqgM9JafaNb6d1GnagWiKI FOTowlUlEtNaJkbNZcjK6gStpa4CmU1hv285rV255KJaCYCpLOHVKHcaSgw3+U8Rce59 RA== Received: from nasanppmta05.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3k4rxa0hme-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:26 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 29B09PYL005297 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:25 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:25 -0700 From: Elliot Berman To: Bjorn Andersson , Mark Rutland , Lorenzo Pieralisi , "Sudeep Holla" , Arnd Bergmann CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Marc Zyngier , "Rob Herring" , Krzysztof Kozlowski , Jonathan Corbet , "Will Deacon" , Catalin Marinas , "Greg Kroah-Hartman" , , , , Subject: [PATCH v5 05/13] virt: gunyah: Add hypercalls to identify Gunyah Date: Mon, 10 Oct 2022 17:08:32 -0700 Message-ID: <20221011000840.289033-6-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: PIs96nz9PYWwG-qn5X55WYkyaQwBT2Wg X-Proofpoint-GUID: PIs96nz9PYWwG-qn5X55WYkyaQwBT2Wg X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 suspectscore=0 spamscore=0 mlxscore=0 clxscore=1015 adultscore=0 impostorscore=0 bulkscore=0 priorityscore=1501 mlxlogscore=999 malwarescore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210100143 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add hypercalls to identify when Linux is running a virtual machine under Gunyah. There are two calls to help identify Gunyah: 1. gh_hypercall_get_uid() returns a UID when running under a Gunyah hypervisor. 2. gh_hypercall_hyp_identify() returns build information and a set of feature flags that are supported by Gunyah. Signed-off-by: Elliot Berman --- MAINTAINERS | 2 + arch/arm64/Kbuild | 1 + arch/arm64/gunyah/Makefile | 2 + arch/arm64/gunyah/hypercall.c | 71 +++++++++++++++++++++++++++++++++++ drivers/virt/Kconfig | 1 + drivers/virt/gunyah/Kconfig | 13 +++++++ include/asm-generic/gunyah.h | 36 ++++++++++++++++++ 7 files changed, 126 insertions(+) create mode 100644 arch/arm64/gunyah/Makefile create mode 100644 arch/arm64/gunyah/hypercall.c create mode 100644 drivers/virt/gunyah/Kconfig diff --git a/MAINTAINERS b/MAINTAINERS index 4fe8cec61551..ed2bc98c3818 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8886,6 +8886,8 @@ L: linux-arm-msm@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml F: Documentation/virt/gunyah/ +F: arch/arm64/gunyah/ +F: drivers/virt/gunyah/ F: include/asm-generic/gunyah.h HABANALABS PCI DRIVER diff --git a/arch/arm64/Kbuild b/arch/arm64/Kbuild index 5bfbf7d79c99..e4847ba0e3c9 100644 --- a/arch/arm64/Kbuild +++ b/arch/arm64/Kbuild @@ -3,6 +3,7 @@ obj-y += kernel/ mm/ net/ obj-$(CONFIG_KVM) += kvm/ obj-$(CONFIG_XEN) += xen/ obj-$(subst m,y,$(CONFIG_HYPERV)) += hyperv/ +obj-$(CONFIG_GUNYAH) += gunyah/ obj-$(CONFIG_CRYPTO) += crypto/ # for cleaning diff --git a/arch/arm64/gunyah/Makefile b/arch/arm64/gunyah/Makefile new file mode 100644 index 000000000000..f71a9533c266 --- /dev/null +++ b/arch/arm64/gunyah/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_GUNYAH) += gunyah_hypercall.o +gunyah_hypercall-y += hypercall.o diff --git a/arch/arm64/gunyah/hypercall.c b/arch/arm64/gunyah/hypercall.c new file mode 100644 index 000000000000..5b08c9d80de0 --- /dev/null +++ b/arch/arm64/gunyah/hypercall.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include + +#define GH_CALL_TYPE_PLATFORM_CALL 0 +#define GH_CALL_TYPE_HYPERCALL 2 +#define GH_CALL_TYPE_SERVICE 3 +#define GH_CALL_TYPE_SHIFT 14 +#define GH_CALL_FUNCTION_NUM_MASK 0x3fff + +#define GH_SERVICE(fn) ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + (GH_CALL_TYPE_SERVICE << GH_CALL_TYPE_SHIFT) \ + | ((fn) & GH_CALL_FUNCTION_NUM_MASK)) + +#define GH_HYPERCALL_CALL_UID GH_SERVICE(0x3f01) + +#define GH_HYPERCALL(fn) ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + (GH_CALL_TYPE_HYPERCALL << GH_CALL_TYPE_SHIFT) \ + | ((fn) & GH_CALL_FUNCTION_NUM_MASK)) + +#define GH_HYPERCALL_HYP_IDENTIFY GH_HYPERCALL(0x0000) + +/** + * gh_hypercall_get_uid() - Returns a UID when running under a Gunyah hypervisor. + * @uid: An array of 4 u32's (u32 uid[4];) + * + * The UID will be either QC_HYP_UID or GUNYAH_UID defined in include/asm-generic/gunyah.h. + * QC_HYP_UID is returned on platforms using Qualcomm's version of Gunyah. + * GUNYAH_UID is returned on platforms using open source version of Gunyah. + * If the uid is not one of the above two UIDs, then it is assumed that the hypervisor or firmware + * is not Gunyah. + */ +void gh_hypercall_get_uid(u32 *uid) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_hvc(GH_HYPERCALL_CALL_UID, &res); + + uid[0] = res.a0; + uid[1] = res.a1; + uid[2] = res.a2; + uid[3] = res.a3; +} +EXPORT_SYMBOL_GPL(gh_hypercall_get_uid); + +/** + * gh_hypercall_hyp_identify() - Returns build information and feature flags supported by Gunyah. + * @hyp_identify: filled by the hypercall with the API info and feature flags. + */ +void gh_hypercall_hyp_identify(struct gh_hypercall_hyp_identify_resp *hyp_identity) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_hvc(GH_HYPERCALL_HYP_IDENTIFY, &res); + + hyp_identity->api_info = res.a0; + hyp_identity->flags[0] = res.a1; + hyp_identity->flags[1] = res.a2; + hyp_identity->flags[2] = res.a3; +} +EXPORT_SYMBOL_GPL(gh_hypercall_hyp_identify); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Gunyah Hypervisor Hypercalls"); diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig index 87ef258cec64..259dc2be6cad 100644 --- a/drivers/virt/Kconfig +++ b/drivers/virt/Kconfig @@ -52,4 +52,5 @@ source "drivers/virt/coco/efi_secret/Kconfig" source "drivers/virt/coco/sev-guest/Kconfig" +source "drivers/virt/gunyah/Kconfig" endif diff --git a/drivers/virt/gunyah/Kconfig b/drivers/virt/gunyah/Kconfig new file mode 100644 index 000000000000..7ac917e0aa3f --- /dev/null +++ b/drivers/virt/gunyah/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config GUNYAH + tristate "Gunyah Virtualization drivers" + depends on ARM64 + select AUXILIARY_BUS + help + The Gunyah drivers are the helper interfaces that runs in a guest VM + such as basic inter-VM IPC and signaling mechanisms, and higher level + services such as memory/device sharing, IRQ sharing, and so on. + + Say Y/M here to enable the drivers needed to interact in a Gunyah + virtual environment. diff --git a/include/asm-generic/gunyah.h b/include/asm-generic/gunyah.h index 64a02dd3b5ad..86eb59e203ef 100644 --- a/include/asm-generic/gunyah.h +++ b/include/asm-generic/gunyah.h @@ -71,4 +71,40 @@ static inline int gh_remap_error(int gh_error) } } +#define QC_HYP_UID0 0x19bd54bd +#define QC_HYP_UID1 0x0b37571b +#define QC_HYP_UID2 0x946f609b +#define QC_HYP_UID3 0x54539de6 + +#define GUNYAH_UID0 0x673d5f14 +#define GUNYAH_UID1 0x9265ce36 +#define GUNYAH_UID2 0xa4535fdb +#define GUNYAH_UID3 0xc1d58fcd + +#define gh_uid_matches(prefix, uid) \ + ((uid)[0] == prefix ## _UID0 && (uid)[1] == prefix ## _UID1 && \ + (uid)[2] == prefix ## _UID2 && (uid)[3] == prefix ## _UID3) + +#define GH_API_INFO_API_VERSION(x) (((x) >> 0) & 0x3fff) +#define GH_API_INFO_BIG_ENDIAN(x) (((x) >> 14) & 1) +#define GH_API_INFO_IS_64BIT(x) (((x) >> 15) & 1) +#define GH_API_INFO_VARIANT(x) (((x) >> 56) & 0xff) + +#define GH_IDENTIFY_PARTITION_CSPACE(flags) (((flags)[0] >> 0) & 1) +#define GH_IDENTIFY_DOORBELL(flags) (((flags)[0] >> 1) & 1) +#define GH_IDENTIFY_MSGQUEUE(flags) (((flags)[0] >> 2) & 1) +#define GH_IDENTIFY_VIC(flags) (((flags)[0] >> 3) & 1) +#define GH_IDENTIFY_VPM(flags) (((flags)[0] >> 4) & 1) +#define GH_IDENTIFY_VCPU(flags) (((flags)[0] >> 5) & 1) +#define GH_IDENTIFY_MEMEXTENT(flags) (((flags)[0] >> 6) & 1) +#define GH_IDENTIFY_TRACE_CTRL(flags) (((flags)[0] >> 7) & 1) + +struct gh_hypercall_hyp_identify_resp { + u64 api_info; + u64 flags[3]; +}; + +void gh_hypercall_get_uid(u32 *uid); +void gh_hypercall_hyp_identify(struct gh_hypercall_hyp_identify_resp *hyp_identity); + #endif From patchwork Tue Oct 11 00:08:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614884 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 E7219C4332F for ; Tue, 11 Oct 2022 00:10:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230316AbiJKAKG (ORCPT ); Mon, 10 Oct 2022 20:10:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52050 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230114AbiJKAJ5 (ORCPT ); Mon, 10 Oct 2022 20:09:57 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27D67BC3D; Mon, 10 Oct 2022 17:09:41 -0700 (PDT) Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29B025sh015760; Tue, 11 Oct 2022 00:09:27 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=rrQpMl+TyNIKRY9rHebJbBrgYsWLOpC0fYbbUnfUSjM=; b=SRdkBJvq/+1gZIYcwhBj1VjkqSPjVxfAUmxvvYTyZ7+7UFPFk0Hspv5aGAiqeGol2AgX IWWtnV2ob5IlLN17w4OEmwPsYoGFLq5b5aJO+ZuwinniGeKGKCZZZiQ7vsyXKnx8o0Kk 3Pry/7TaSYodEj/TCeDFUhX/szTt4b2A2wISaHnlAWlqaESmZZY4seUUZHqxjR1ZyV1g 33A7f0vHeMMc0ek5UycIlxnJHDO1EtbEVwqR39LPfr3NRJAks6D/3GJyupIbCN4izsj/ 6pz5EDnIZVXq3BSiXQ5i0ud0RO49ES57/zbxq3LcJKdrQIBcAucnCH5Rs4J3a9usv3dL pg== Received: from nasanppmta02.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3k4rx4rj19-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:27 +0000 Received: from nasanex01b.na.qualcomm.com (corens_vlan604_snip.qualcomm.com [10.53.140.1]) by NASANPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 29B09QWf020393 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:26 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:25 -0700 From: Elliot Berman To: Bjorn Andersson CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Marc Zyngier , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , "Will Deacon" , Catalin Marinas , "Arnd Bergmann" , Greg Kroah-Hartman , , , , Subject: [PATCH v5 06/13] virt: gunyah: Identify hypervisor version Date: Mon, 10 Oct 2022 17:08:33 -0700 Message-ID: <20221011000840.289033-7-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: gDO8b4OFU1rMRXR7GpCZ0nF559N1AFSP X-Proofpoint-ORIG-GUID: gDO8b4OFU1rMRXR7GpCZ0nF559N1AFSP X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 priorityscore=1501 suspectscore=0 spamscore=0 mlxlogscore=999 impostorscore=0 phishscore=0 adultscore=0 clxscore=1015 malwarescore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210100143 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Export the version of Gunyah which is reported via the hyp_identify hypercall. Increments of the major API version indicate possibly backwards incompatible changes. Export the hypervisor identity so that Gunyah drivers can act according to the major API version. Signed-off-by: Elliot Berman --- MAINTAINERS | 1 + drivers/virt/Makefile | 1 + drivers/virt/gunyah/Makefile | 2 ++ drivers/virt/gunyah/gunyah.c | 41 ++++++++++++++++++++++++++++++++++++ include/asm-generic/gunyah.h | 3 +++ 5 files changed, 48 insertions(+) create mode 100644 drivers/virt/gunyah/Makefile create mode 100644 drivers/virt/gunyah/gunyah.c diff --git a/MAINTAINERS b/MAINTAINERS index ed2bc98c3818..c5458aeec023 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8884,6 +8884,7 @@ M: Elliot Berman M: Murali Nalajala L: linux-arm-msm@vger.kernel.org S: Supported +F: Documentation/ABI/testing/sysfs-hypervisor-gunyah F: Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml F: Documentation/virt/gunyah/ F: arch/arm64/gunyah/ diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile index 093674e05c40..10b87f934730 100644 --- a/drivers/virt/Makefile +++ b/drivers/virt/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_NITRO_ENCLAVES) += nitro_enclaves/ obj-$(CONFIG_ACRN_HSM) += acrn/ obj-$(CONFIG_EFI_SECRET) += coco/efi_secret/ obj-$(CONFIG_SEV_GUEST) += coco/sev-guest/ +obj-$(CONFIG_GUNYAH) += gunyah/ diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile new file mode 100644 index 000000000000..dc081e2dc02b --- /dev/null +++ b/drivers/virt/gunyah/Makefile @@ -0,0 +1,2 @@ +gunyah-y += gunyah.o +obj-$(CONFIG_GUNYAH) += gunyah.o diff --git a/drivers/virt/gunyah/gunyah.c b/drivers/virt/gunyah/gunyah.c new file mode 100644 index 000000000000..2893a56f3dfc --- /dev/null +++ b/drivers/virt/gunyah/gunyah.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#define pr_fmt(fmt) "gunyah: " fmt + +#include +#include +#include +#include + +struct gh_hypercall_hyp_identify_resp gunyah_api; +EXPORT_SYMBOL(gunyah_api); + +static int __init gunyah_init(void) +{ + u32 uid[4]; + + gh_hypercall_get_uid(uid); + + if (!(gh_uid_matches(GUNYAH, uid) || gh_uid_matches(QC_HYP, uid))) + return 0; + + gh_hypercall_hyp_identify(&gunyah_api); + + pr_info("Running under Gunyah hypervisor %llx/v%lld\n", + GH_API_INFO_VARIANT(gunyah_api.api_info), + GH_API_INFO_API_VERSION(gunyah_api.api_info)); + + return 0; +} +arch_initcall(gunyah_init); + +static void __exit gunyah_exit(void) +{ +} +module_exit(gunyah_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Gunyah Hypervisor Driver"); diff --git a/include/asm-generic/gunyah.h b/include/asm-generic/gunyah.h index 86eb59e203ef..8f9d4c649ba8 100644 --- a/include/asm-generic/gunyah.h +++ b/include/asm-generic/gunyah.h @@ -85,6 +85,8 @@ static inline int gh_remap_error(int gh_error) ((uid)[0] == prefix ## _UID0 && (uid)[1] == prefix ## _UID1 && \ (uid)[2] == prefix ## _UID2 && (uid)[3] == prefix ## _UID3) +#define GUNYAH_API_V1 1 + #define GH_API_INFO_API_VERSION(x) (((x) >> 0) & 0x3fff) #define GH_API_INFO_BIG_ENDIAN(x) (((x) >> 14) & 1) #define GH_API_INFO_IS_64BIT(x) (((x) >> 15) & 1) @@ -103,6 +105,7 @@ struct gh_hypercall_hyp_identify_resp { u64 api_info; u64 flags[3]; }; +extern struct gh_hypercall_hyp_identify_resp gunyah_api; void gh_hypercall_get_uid(u32 *uid); void gh_hypercall_hyp_identify(struct gh_hypercall_hyp_identify_resp *hyp_identity); From patchwork Tue Oct 11 00:08:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614288 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 F043FC4321E for ; Tue, 11 Oct 2022 00:10:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230201AbiJKAKH (ORCPT ); Mon, 10 Oct 2022 20:10:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51136 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230219AbiJKAJ5 (ORCPT ); Mon, 10 Oct 2022 20:09:57 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E8623101EF; Mon, 10 Oct 2022 17:09:41 -0700 (PDT) Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29AMlA35010964; Tue, 11 Oct 2022 00:09:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=GvXA7z5IQZxKRT0LbI1ydxR1t3A4IO5H0ORgws0t6KQ=; b=i+4j7o/thKelhAN7GTEAP2/l+/C0Jq3TWJNzmpRemuedBn60yx11HkRObdxFK1CQ+jzJ pUC2c1MKhfbRTcW/BqNzkY/KdoYYkFbZNOzkOL6AsmMMsrpb/v/cORIHXMCBQv1uztoW cBuWMiN8uFL0ftmZ4eKkHCHkS7+9aKHI01nx6Xx6gm38Q0B2FYbjwjNnuWyH/W+wQFwT rrnGA+vS5bLwt4ktuQmbj3faIfCgUprhyM8rlgPfjt0e22OG9ScijMQDD09V2qz0p3i1 aaBOPdN3mWr+Uqo8thjwKSvkOG/EKljnAR/PmgpWqK5s8JUdH2qX2ChOeW2LMdBAPipg RA== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3k4rxa0hmf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:28 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 29B09R7G021551 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:27 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:26 -0700 From: Elliot Berman To: Bjorn Andersson , Jassi Brar CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , , "Mark Rutland" , Lorenzo Pieralisi , Sudeep Holla , "Marc Zyngier" , Rob Herring , "Krzysztof Kozlowski" , Jonathan Corbet , Will Deacon , Catalin Marinas , Arnd Bergmann , Greg Kroah-Hartman , , , , Subject: [PATCH v5 07/13] mailbox: Allow direct registration to a channel Date: Mon, 10 Oct 2022 17:08:34 -0700 Message-ID: <20221011000840.289033-8-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: izFwKd_SI0RX35Tx5pIiyhWDcmz4oHcC X-Proofpoint-GUID: izFwKd_SI0RX35Tx5pIiyhWDcmz4oHcC X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 suspectscore=0 spamscore=0 mlxscore=0 clxscore=1015 adultscore=0 impostorscore=0 bulkscore=0 priorityscore=1501 mlxlogscore=999 malwarescore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210100143 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Support virtual mailbox controllers and clients which are not platform devices or come from the devicetree by allowing them to match client to channel via some other mechanism. Signed-off-by: Elliot Berman --- drivers/mailbox/mailbox.c | 96 ++++++++++++++++++++++++---------- include/linux/mailbox_client.h | 1 + 2 files changed, 69 insertions(+), 28 deletions(-) diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index 4229b9b5da98..adf36c05fa43 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -317,6 +317,71 @@ int mbox_flush(struct mbox_chan *chan, unsigned long timeout) } EXPORT_SYMBOL_GPL(mbox_flush); +static int __mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl) +{ + struct device *dev = cl->dev; + unsigned long flags; + int ret; + + if (chan->cl || !try_module_get(chan->mbox->dev->driver->owner)) { + dev_dbg(dev, "%s: mailbox not free\n", __func__); + return -EBUSY; + } + + spin_lock_irqsave(&chan->lock, flags); + chan->msg_free = 0; + chan->msg_count = 0; + chan->active_req = NULL; + chan->cl = cl; + init_completion(&chan->tx_complete); + + if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone) + chan->txdone_method = TXDONE_BY_ACK; + + spin_unlock_irqrestore(&chan->lock, flags); + + if (chan->mbox->ops->startup) { + ret = chan->mbox->ops->startup(chan); + + if (ret) { + dev_err(dev, "Unable to startup the chan (%d)\n", ret); + mbox_free_channel(chan); + return ret; + } + } + + return 0; +} + +/** + * mbox_bind_client - Request a mailbox channel. + * @chan: The mailbox channel to bind the client to. + * @cl: Identity of the client requesting the channel. + * + * The Client specifies its requirements and capabilities while asking for + * a mailbox channel. It can't be called from atomic context. + * The channel is exclusively allocated and can't be used by another + * client before the owner calls mbox_free_channel. + * After assignment, any packet received on this channel will be + * handed over to the client via the 'rx_callback'. + * The framework holds reference to the client, so the mbox_client + * structure shouldn't be modified until the mbox_free_channel returns. + * + * Return: 0 if the channel was assigned to the client successfully. + * <0 for request failure. + */ +int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl) +{ + int ret; + + mutex_lock(&con_mutex); + ret = __mbox_bind_client(chan, cl); + mutex_unlock(&con_mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(mbox_bind_client); + /** * mbox_request_channel - Request a mailbox channel. * @cl: Identity of the client requesting the channel. @@ -340,7 +405,6 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) struct mbox_controller *mbox; struct of_phandle_args spec; struct mbox_chan *chan; - unsigned long flags; int ret; if (!dev || !dev->of_node) { @@ -372,33 +436,9 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) return chan; } - if (chan->cl || !try_module_get(mbox->dev->driver->owner)) { - dev_dbg(dev, "%s: mailbox not free\n", __func__); - mutex_unlock(&con_mutex); - return ERR_PTR(-EBUSY); - } - - spin_lock_irqsave(&chan->lock, flags); - chan->msg_free = 0; - chan->msg_count = 0; - chan->active_req = NULL; - chan->cl = cl; - init_completion(&chan->tx_complete); - - if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone) - chan->txdone_method = TXDONE_BY_ACK; - - spin_unlock_irqrestore(&chan->lock, flags); - - if (chan->mbox->ops->startup) { - ret = chan->mbox->ops->startup(chan); - - if (ret) { - dev_err(dev, "Unable to startup the chan (%d)\n", ret); - mbox_free_channel(chan); - chan = ERR_PTR(ret); - } - } + ret = __mbox_bind_client(chan, cl); + if (ret) + chan = ERR_PTR(ret); mutex_unlock(&con_mutex); return chan; diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h index 65229a45590f..734694912ef7 100644 --- a/include/linux/mailbox_client.h +++ b/include/linux/mailbox_client.h @@ -37,6 +37,7 @@ struct mbox_client { void (*tx_done)(struct mbox_client *cl, void *mssg, int r); }; +int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl); struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl, const char *name); struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index); From patchwork Tue Oct 11 00:08:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614887 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 AB2E0C4332F for ; Tue, 11 Oct 2022 00:09:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230136AbiJKAJf (ORCPT ); Mon, 10 Oct 2022 20:09:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50788 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230084AbiJKAJa (ORCPT ); Mon, 10 Oct 2022 20:09:30 -0400 Received: from alexa-out-sd-02.qualcomm.com (alexa-out-sd-02.qualcomm.com [199.106.114.39]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 620FD7FE6C; Mon, 10 Oct 2022 17:09:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1665446969; x=1696982969; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Nfzd46oSkcPBuDNBj/hlLZBnD+einRNj+ZW3TWK43hg=; b=BGwfQFJYqrUnMpoTiHyWieJTETnTJU97PVnJf/4sOfPDz4IxlQw0wN2Q 56blJIPdWxkmgUlYtPOQ80UlBevXZITkuRkAFOZeKXBHPmDN9g2EKol8s UR/BLC/SVsyzgG/VKwwmnA26g/fMOvjoRrJYb7JmhPtKCj1Sj/yUw6jIn 4=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 10 Oct 2022 17:09:29 -0700 X-QCInternal: smtphost Received: from nasanex01b.na.qualcomm.com ([10.46.141.250]) by ironmsg04-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Oct 2022 17:09:27 -0700 Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:26 -0700 From: Elliot Berman To: Bjorn Andersson CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Marc Zyngier , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , "Will Deacon" , Catalin Marinas , "Arnd Bergmann" , Greg Kroah-Hartman , , , , Subject: [PATCH v5 08/13] virt: gunyah: msgq: Add hypercalls to send and receive messages Date: Mon, 10 Oct 2022 17:08:35 -0700 Message-ID: <20221011000840.289033-9-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add hypercalls to send and receive messages on a Gunyah message queue. Signed-off-by: Elliot Berman --- arch/arm64/gunyah/hypercall.c | 33 +++++++++++++++++++++++++++++++++ include/asm-generic/gunyah.h | 5 +++++ 2 files changed, 38 insertions(+) diff --git a/arch/arm64/gunyah/hypercall.c b/arch/arm64/gunyah/hypercall.c index 5b08c9d80de0..042cca31879e 100644 --- a/arch/arm64/gunyah/hypercall.c +++ b/arch/arm64/gunyah/hypercall.c @@ -26,6 +26,8 @@ | ((fn) & GH_CALL_FUNCTION_NUM_MASK)) #define GH_HYPERCALL_HYP_IDENTIFY GH_HYPERCALL(0x0000) +#define GH_HYPERCALL_MSGQ_SEND GH_HYPERCALL(0x001B) +#define GH_HYPERCALL_MSGQ_RECV GH_HYPERCALL(0x001C) /** * gh_hypercall_get_uid() - Returns a UID when running under a Gunyah hypervisor. @@ -67,5 +69,36 @@ void gh_hypercall_hyp_identify(struct gh_hypercall_hyp_identify_resp *hyp_identi } EXPORT_SYMBOL_GPL(gh_hypercall_hyp_identify); +int gh_hypercall_msgq_send(u64 capid, size_t size, uintptr_t buff, int tx_flags, bool *ready) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_hvc(GH_HYPERCALL_MSGQ_SEND, capid, size, buff, tx_flags, 0, &res); + + if (res.a0) + return res.a0; + + *ready = res.a1; + + return res.a0; +} +EXPORT_SYMBOL_GPL(gh_hypercall_msgq_send); + +int gh_hypercall_msgq_recv(u64 capid, uintptr_t buff, size_t size, size_t *recv_size, bool *ready) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_hvc(GH_HYPERCALL_MSGQ_RECV, capid, buff, size, 0, &res); + + if (res.a0) + return res.a0; + + *recv_size = res.a1; + *ready = res.a2; + + return res.a0; +} +EXPORT_SYMBOL_GPL(gh_hypercall_msgq_recv); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Gunyah Hypervisor Hypercalls"); diff --git a/include/asm-generic/gunyah.h b/include/asm-generic/gunyah.h index 8f9d4c649ba8..34c41c8393d0 100644 --- a/include/asm-generic/gunyah.h +++ b/include/asm-generic/gunyah.h @@ -110,4 +110,9 @@ extern struct gh_hypercall_hyp_identify_resp gunyah_api; void gh_hypercall_get_uid(u32 *uid); void gh_hypercall_hyp_identify(struct gh_hypercall_hyp_identify_resp *hyp_identity); +#define GH_HYPERCALL_MSGQ_TX_FLAGS_PUSH BIT(0) + +int gh_hypercall_msgq_send(u64 capid, size_t size, uintptr_t buff, int tx_flags, bool *ready); +int gh_hypercall_msgq_recv(u64 capid, uintptr_t buff, size_t size, size_t *recv_size, bool *ready); + #endif From patchwork Tue Oct 11 00:08:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614291 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 1625DC43219 for ; Tue, 11 Oct 2022 00:09:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230138AbiJKAJh (ORCPT ); Mon, 10 Oct 2022 20:09:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50790 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230102AbiJKAJa (ORCPT ); Mon, 10 Oct 2022 20:09:30 -0400 Received: from alexa-out-sd-02.qualcomm.com (alexa-out-sd-02.qualcomm.com [199.106.114.39]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 979EF7B29F; Mon, 10 Oct 2022 17:09:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1665446969; x=1696982969; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oBW+7/9X+jHDTSDThdcuAyLo5eseMZTZ2Va/4ZjFfOo=; b=dTrsBctHRNNtnWhpQNi90AOJpAS1aGNCbourc/C4JjmtCCQyKkF1nLDi puNMxBeARcC5XcqlzzeTvbGoZQAzekaPlYaxGF4DwihXTV5X0jcBmK11z nqgsj4RN5SzFRtYVyWlnYhPuXuwCkl7IMmXQkUtirlitXh/krzc1ypPKp 4=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 10 Oct 2022 17:09:29 -0700 X-QCInternal: smtphost Received: from nasanex01b.na.qualcomm.com ([10.46.141.250]) by ironmsg04-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Oct 2022 17:09:29 -0700 Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:27 -0700 From: Elliot Berman To: Bjorn Andersson , Jassi Brar CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , , "Mark Rutland" , Lorenzo Pieralisi , Sudeep Holla , "Marc Zyngier" , Rob Herring , "Krzysztof Kozlowski" , Jonathan Corbet , Will Deacon , Catalin Marinas , Arnd Bergmann , Greg Kroah-Hartman , , , , Subject: [PATCH v5 09/13] mailbox: Add Gunyah message queue mailbox Date: Mon, 10 Oct 2022 17:08:36 -0700 Message-ID: <20221011000840.289033-10-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Gunyah message queues are a unidirectional inter-VM pipe for messages up to 1024 bytes. This driver supports pairing a receiver message queue and a transmitter message queue to expose a single mailbox channel. Signed-off-by: Elliot Berman --- MAINTAINERS | 2 + drivers/mailbox/Kconfig | 10 ++ drivers/mailbox/Makefile | 2 + drivers/mailbox/gunyah-msgq.c | 254 ++++++++++++++++++++++++++++++++++ drivers/virt/gunyah/Kconfig | 2 + include/linux/gunyah.h | 67 +++++++++ 6 files changed, 337 insertions(+) create mode 100644 drivers/mailbox/gunyah-msgq.c create mode 100644 include/linux/gunyah.h diff --git a/MAINTAINERS b/MAINTAINERS index c5458aeec023..599804836d05 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8888,8 +8888,10 @@ F: Documentation/ABI/testing/sysfs-hypervisor-gunyah F: Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml F: Documentation/virt/gunyah/ F: arch/arm64/gunyah/ +F: drivers/mailbox/gunyah-msgq.c F: drivers/virt/gunyah/ F: include/asm-generic/gunyah.h +F: include/linux/gunyah.h HABANALABS PCI DRIVER M: Oded Gabbay diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index 05d6fae800e3..baf9451c5f04 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -41,6 +41,16 @@ config IMX_MBOX help Mailbox implementation for i.MX Messaging Unit (MU). +config GUNYAH_MESSAGE_QUEUES + tristate "Gunyah Message Queue Mailbox" + depends on GUNYAH + help + Mailbox implementation for Gunyah Message Queues. Gunyah message queues + are an IPC mechanism to pass short messages between virtual machines + running under the Gunyah hypervisor. + + Say Y here if you run Linux as a Gunyah virtual machine. + config PLATFORM_MHU tristate "Platform MHU Mailbox" depends on OF diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index fc9376117111..5f929bb55e9a 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -55,6 +55,8 @@ obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o obj-$(CONFIG_ZYNQMP_IPI_MBOX) += zynqmp-ipi-mailbox.o +obj-$(CONFIG_GUNYAH) += gunyah-msgq.o + obj-$(CONFIG_SUN6I_MSGBOX) += sun6i-msgbox.o obj-$(CONFIG_SPRD_MBOX) += sprd-mailbox.o diff --git a/drivers/mailbox/gunyah-msgq.c b/drivers/mailbox/gunyah-msgq.c new file mode 100644 index 000000000000..f0cd96920c64 --- /dev/null +++ b/drivers/mailbox/gunyah-msgq.c @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define mbox_chan_to_msgq(chan) (container_of(chan->mbox, struct gunyah_msgq, mbox)) + +static inline bool gh_msgq_has_tx(struct gunyah_msgq *msgq) +{ + return msgq->tx_ghrsc.type == GUNYAH_RESOURCE_TYPE_MSGQ_TX; +} + +static inline bool gh_msgq_has_rx(struct gunyah_msgq *msgq) +{ + return msgq->rx_ghrsc.type == GUNYAH_RESOURCE_TYPE_MSGQ_RX; +} + +static ssize_t __gh_msgq_recv(struct gunyah_msgq *msgq, void *buff, size_t size, bool *ready) +{ + unsigned long gh_err; + size_t recv_size; + ssize_t ret; + + gh_err = gh_hypercall_msgq_recv(msgq->rx_ghrsc.capid, (uintptr_t)buff, size, + &recv_size, ready); + switch (gh_err) { + case GH_ERROR_OK: + ret = recv_size; + break; + case GH_ERROR_MSGQUEUE_EMPTY: + ret = -EAGAIN; + *ready = false; + break; + default: + ret = gh_remap_error(gh_err); + break; + } + + return ret; +} + +static irqreturn_t gh_msgq_rx_irq_handler(int irq, void *data) +{ + struct gunyah_msgq *msgq = data; + struct gunyah_msgq_rx_data rx_data; + ssize_t ret; + bool more; + + do { + ret = __gh_msgq_recv(msgq, &rx_data.data, sizeof(rx_data.data), &more); + + if (ret >= 0) { + rx_data.length = ret; + mbox_chan_received_data(gunyah_msgq_chan(msgq), &rx_data); + } else if (ret != -EAGAIN) + pr_warn("Failed to receive data from msgq for %s: %ld\n", + msgq->mbox.dev ? dev_name(msgq->mbox.dev) : "", ret); + } while (ret >= 0); + + return IRQ_HANDLED; +} + +static irqreturn_t gh_msgq_tx_irq_handler(int irq, void *data) +{ + struct gunyah_msgq *msgq = data; + + mbox_chan_txdone(gunyah_msgq_chan(msgq), 0); + + return IRQ_HANDLED; +} + +static void gh_msgq_txdone_tasklet(unsigned long data) +{ + struct gunyah_msgq *msgq = (struct gunyah_msgq *)data; + + mbox_chan_txdone(gunyah_msgq_chan(msgq), msgq->last_status); +} + +static int __gh_msgq_send(struct gunyah_msgq *msgq, void *buff, size_t size, u64 tx_flags) +{ + unsigned long gh_err; + ssize_t ret; + bool ready; + + gh_err = gh_hypercall_msgq_send(msgq->tx_ghrsc.capid, size, (uintptr_t)buff, tx_flags, + &ready); + switch (gh_err) { + case GH_ERROR_OK: + ret = !ready; + break; + case GH_ERROR_MSGQUEUE_FULL: + ret = -EAGAIN; + break; + default: + /* Not sure how to propagate these out to client. If we get here, nobody is going + * to trigger a retry + */ + ret = gh_remap_error(gh_err); + break; + } + + return ret; +} + +static int gh_msgq_send_data(struct mbox_chan *chan, void *data) +{ + struct gunyah_msgq *msgq = mbox_chan_to_msgq(chan); + struct gunyah_msgq_tx_data *msgq_data = data; + u64 tx_flags = 0; + int ret; + + if (msgq_data->push) + tx_flags |= GH_HYPERCALL_MSGQ_TX_FLAGS_PUSH; + + ret = __gh_msgq_send(msgq, msgq_data->data, msgq_data->length, tx_flags); + + /** + * EAGAIN: message didn't send. + * ret = 1: message sent, but now the message queue is full and we can't send any more msgs. + * Either way, don't report that this message is done. + */ + if (ret == -EAGAIN || ret == 1) + return ret; + + /** + * Mailbox framework requires that tx done happens asynchronously to sending the message + * IOW, a notification that the message was sent happens after sending the message. + * To work around this, defer the txdone to a tasklet. + */ + msgq->last_status = ret; + tasklet_schedule(&msgq->txdone_tasklet); + + return 0; +} + +struct mbox_chan_ops gunyah_msgq_ops = { + .send_data = gh_msgq_send_data, +}; + +/** + * gunyah_msgq_init() - Initialize a Gunyah message queue with an mbox_client + * @parent: optional, device parent used for the mailbox controller + * @msgq: Pointer to the gunyah_msgq to initialize + * @cl: A mailbox client to bind to the mailbox channel that the message queue creates + * @tx_ghrsc: optional, the transmission side of the message queue + * @rx_ghrsc: optional, the receiving side of the message queue + * + * At least one of tx_ghrsc and rx_ghrsc should be not NULL. Most message queue use cases come with + * a pair of message queues to facilitiate bidirectional communication. When tx_ghrsc is set, + * the client can send messages with mbox_send_message(gunyah_msgq_chan(msgq), msg). When rx_ghrsc + * is set, the mbox_client should register an .rx_callback() and the message queue driver will + * push all available messages upon receiving the RX ready interrupt. The messages should be + * consumed or copied by the client right away as the gunyah_msgq_rx_data will be replaced/destroyed + * after the callback. + * + * Returns - 0 on success, negative otherwise + */ +int gunyah_msgq_init(struct device *parent, struct gunyah_msgq *msgq, struct mbox_client *cl, + struct gunyah_resource *tx_ghrsc, struct gunyah_resource *rx_ghrsc) +{ + int ret; + + /* Must have at least a tx_ghrsc or rx_ghrsc and that they are the right device types */ + if ((!tx_ghrsc && !rx_ghrsc) || + (tx_ghrsc && tx_ghrsc->type != GUNYAH_RESOURCE_TYPE_MSGQ_TX) || + (rx_ghrsc && rx_ghrsc->type != GUNYAH_RESOURCE_TYPE_MSGQ_RX)) + return -EINVAL; + + msgq->tx_ghrsc = *tx_ghrsc; + msgq->rx_ghrsc = *rx_ghrsc; + + msgq->mbox.dev = parent; + msgq->mbox.ops = &gunyah_msgq_ops; + msgq->mbox.chans = kcalloc(1, sizeof(*msgq->mbox.chans), GFP_KERNEL); + msgq->mbox.num_chans = 1; + msgq->mbox.txdone_irq = true; + + if (gh_msgq_has_tx(msgq)) { + ret = request_irq(msgq->tx_ghrsc.irq, gh_msgq_tx_irq_handler, 0, "gh_msgq_tx", + msgq); + if (ret) + goto err_chans; + } + + if (gh_msgq_has_rx(msgq)) { + ret = request_threaded_irq(msgq->rx_ghrsc.irq, NULL, gh_msgq_rx_irq_handler, + IRQF_ONESHOT, "gh_msgq_rx", msgq); + if (ret) + goto err_tx_irq; + } + + tasklet_init(&msgq->txdone_tasklet, gh_msgq_txdone_tasklet, (unsigned long)msgq); + + ret = mbox_controller_register(&msgq->mbox); + if (ret) + goto err_rx_irq; + + ret = mbox_bind_client(gunyah_msgq_chan(msgq), cl); + if (ret) + goto err_mbox; + + return 0; +err_mbox: + mbox_controller_unregister(&msgq->mbox); +err_rx_irq: + if (gh_msgq_has_rx(msgq)) + free_irq(msgq->rx_ghrsc.irq, msgq); +err_tx_irq: + if (gh_msgq_has_tx(msgq)) + free_irq(msgq->tx_ghrsc.irq, msgq); +err_chans: + kfree(msgq->mbox.chans); + return ret; +} +EXPORT_SYMBOL_GPL(gunyah_msgq_init); + +void gunyah_msgq_remove(struct gunyah_msgq *msgq) +{ + if (gh_msgq_has_tx(msgq)) + free_irq(msgq->tx_ghrsc.irq, msgq); + + kfree(msgq->mbox.chans); +} +EXPORT_SYMBOL_GPL(gunyah_msgq_remove); + + +static int __init gh_msgq_init(void) +{ + if (GH_API_INFO_API_VERSION(gunyah_api.api_info) != GUNYAH_API_V1) { + pr_warn("Unrecognized gunyah version: %llu. Currently supported: %d\n", + GH_API_INFO_API_VERSION(gunyah_api.api_info), GUNYAH_API_V1); + return -ENODEV; + } + + return 0; +} +module_init(gh_msgq_init); + +static void __exit gh_msgq_exit(void) +{ +} +module_exit(gh_msgq_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Gunyah Message Queue Driver"); diff --git a/drivers/virt/gunyah/Kconfig b/drivers/virt/gunyah/Kconfig index 7ac917e0aa3f..f4c822a82f1a 100644 --- a/drivers/virt/gunyah/Kconfig +++ b/drivers/virt/gunyah/Kconfig @@ -4,6 +4,8 @@ config GUNYAH tristate "Gunyah Virtualization drivers" depends on ARM64 select AUXILIARY_BUS + select MAILBOX + select GUNYAH_MESSAGE_QUEUES help The Gunyah drivers are the helper interfaces that runs in a guest VM such as basic inter-VM IPC and signaling mechanisms, and higher level diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h new file mode 100644 index 000000000000..0e9709555c79 --- /dev/null +++ b/include/linux/gunyah.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _GUNYAH_H +#define _GUNYAH_H + +#include +#include +#include + +#include + +/* Follows resource manager's resource types for VM_GET_HYP_RESOURCES */ +enum gunyah_resource_type { + GUNYAH_RESOURCE_TYPE_BELL_TX = 0, + GUNYAH_RESOURCE_TYPE_BELL_RX = 1, + GUNYAH_RESOURCE_TYPE_MSGQ_TX = 2, + GUNYAH_RESOURCE_TYPE_MSGQ_RX = 3, + GUNYAH_RESOURCE_TYPE_VCPU = 4, +}; + +struct gunyah_resource { + enum gunyah_resource_type type; + u64 capid; + int irq; +}; + +/** + * Gunyah Message Queues + */ + +#define GH_MSGQ_MAX_MSG_SIZE 240 + +struct gunyah_msgq_tx_data { + size_t length; + bool push; + char data[]; +}; + +struct gunyah_msgq_rx_data { + size_t length; + char data[GH_MSGQ_MAX_MSG_SIZE]; +}; + +struct gunyah_msgq { + struct gunyah_resource tx_ghrsc; + struct gunyah_resource rx_ghrsc; + + /* msgq private */ + int last_status; + struct mbox_controller mbox; + struct tasklet_struct txdone_tasklet; +}; + + +int gunyah_msgq_init(struct device *parent, struct gunyah_msgq *msgq, struct mbox_client *cl, + struct gunyah_resource *tx_ghrsc, struct gunyah_resource *rx_ghrsc); +void gunyah_msgq_remove(struct gunyah_msgq *msgq); + +static inline struct mbox_chan *gunyah_msgq_chan(struct gunyah_msgq *msgq) +{ + return &msgq->mbox.chans[0]; +} + +#endif From patchwork Tue Oct 11 00:08:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614287 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 270A5C4167B for ; Tue, 11 Oct 2022 00:10:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230355AbiJKAKz (ORCPT ); Mon, 10 Oct 2022 20:10:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54664 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230280AbiJKAKB (ORCPT ); Mon, 10 Oct 2022 20:10:01 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DFBB619015; Mon, 10 Oct 2022 17:09:45 -0700 (PDT) Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29B033Fb025718; Tue, 11 Oct 2022 00:09:30 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=9UruJwBTRuTgk4nsswhdIgDZqSZtS2kkT2j0uxsJc8g=; b=K94788DGfumgCoaDnfQ+kSgTNo5/8aGIjbv4wvH/yQ5qDwlvDzWNcRKjngAShSH+9V+L OhYUmCBCX2KC3NeUjUvagdrttjozu/cTQ8H/ok5iIoNNLoUWU/hGX2O5hR4/AJo7gsSJ swWB7seRaHsbr3RmHZ7p8DHARbugymihLSHsjcPSR4BhuCxbwnNS1G1vh48xmlwvcd7H rarXlk9y2NcNaTAvioB59J45py2DxzRiMncACxz77q0t5rHAEEfymWQNcEUpWBTD/Ymm TnkeX/nQyfiS3tSp2QsVioUydq8ICLVmH4HU+7KsZdLAN3Je3YBZrkW9y1ou3AKalI8k VA== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3k4rxc8j5a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:30 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 29B09TvJ021574 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:29 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:28 -0700 From: Elliot Berman To: Bjorn Andersson CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Marc Zyngier , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , "Will Deacon" , Catalin Marinas , "Arnd Bergmann" , Greg Kroah-Hartman , , , , Subject: [PATCH v5 10/13] gunyah: rsc_mgr: Add resource manager RPC core Date: Mon, 10 Oct 2022 17:08:37 -0700 Message-ID: <20221011000840.289033-11-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: V4QFwKfwLhz1DcKFVRP3ltNM4D7z4t6w X-Proofpoint-GUID: V4QFwKfwLhz1DcKFVRP3ltNM4D7z4t6w X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 mlxlogscore=999 priorityscore=1501 bulkscore=0 lowpriorityscore=0 spamscore=0 mlxscore=0 suspectscore=0 adultscore=0 clxscore=1015 malwarescore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210100143 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org The resource manager is a special virtual machine which is always running on a Gunyah system. It provides APIs for creating and destroying VMs, secure memory management, sharing/lending of memory between VMs, and setup of inter-VM communication. Calls to the resource manager are made via message queues. This patch implements the basic probing and RPC mechanism to make those API calls. Request/response calls can be made with gh_rm_call. Drivers can also register to notifications pushed by RM via gh_rm_register_notifier Specific API calls that resource manager supports will be implemented in subsequent patches. Signed-off-by: Elliot Berman --- MAINTAINERS | 2 +- drivers/virt/gunyah/Kconfig | 20 +- drivers/virt/gunyah/Makefile | 3 + drivers/virt/gunyah/rsc_mgr.c | 601 +++++++++++++++++++++++++++++++++ drivers/virt/gunyah/rsc_mgr.h | 34 ++ include/linux/gunyah_rsc_mgr.h | 26 ++ 6 files changed, 682 insertions(+), 4 deletions(-) create mode 100644 drivers/virt/gunyah/rsc_mgr.c create mode 100644 drivers/virt/gunyah/rsc_mgr.h create mode 100644 include/linux/gunyah_rsc_mgr.h diff --git a/MAINTAINERS b/MAINTAINERS index 599804836d05..8a3d79b56698 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8891,7 +8891,7 @@ F: arch/arm64/gunyah/ F: drivers/mailbox/gunyah-msgq.c F: drivers/virt/gunyah/ F: include/asm-generic/gunyah.h -F: include/linux/gunyah.h +F: include/linux/gunyah*.h HABANALABS PCI DRIVER M: Oded Gabbay diff --git a/drivers/virt/gunyah/Kconfig b/drivers/virt/gunyah/Kconfig index f4c822a82f1a..78deed3c4562 100644 --- a/drivers/virt/gunyah/Kconfig +++ b/drivers/virt/gunyah/Kconfig @@ -3,9 +3,6 @@ config GUNYAH tristate "Gunyah Virtualization drivers" depends on ARM64 - select AUXILIARY_BUS - select MAILBOX - select GUNYAH_MESSAGE_QUEUES help The Gunyah drivers are the helper interfaces that runs in a guest VM such as basic inter-VM IPC and signaling mechanisms, and higher level @@ -13,3 +10,20 @@ config GUNYAH Say Y/M here to enable the drivers needed to interact in a Gunyah virtual environment. + +if GUNYAH + +config GUNYAH_RESORUCE_MANAGER + tristate "Gunyah Resource Manager" + select MAILBOX + select GUNYAH_MESSAGE_QUEUES + default y + help + The resource manager (RM) is a privileged application VM supporting + the Gunyah Hypervisor. Enable this driver to support communicating + with Gunyah RM. This is typically required for a VM running under + Gunyah wanting to have Gunyah-awareness. + + Say Y/M here if unsure. + +endif diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile index dc081e2dc02b..2cae8ea5bc7d 100644 --- a/drivers/virt/gunyah/Makefile +++ b/drivers/virt/gunyah/Makefile @@ -1,2 +1,5 @@ gunyah-y += gunyah.o obj-$(CONFIG_GUNYAH) += gunyah.o + +gunyah_rsc_mgr-y += rsc_mgr.o +obj-$(CONFIG_GUNYAH_RESORUCE_MANAGER) += gunyah_rsc_mgr.o diff --git a/drivers/virt/gunyah/rsc_mgr.c b/drivers/virt/gunyah/rsc_mgr.c new file mode 100644 index 000000000000..0e2f04984ada --- /dev/null +++ b/drivers/virt/gunyah/rsc_mgr.c @@ -0,0 +1,601 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#define pr_fmt(fmt) "gh_rsc_mgr: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rsc_mgr.h" + +/* Resource Manager Header */ +struct gh_rm_rpc_hdr { + u8 version:4, + hdr_words:4; + u8 type:2, + fragments:6; + u16 seq; + u32 msg_id; +} __packed; + +/* Standard reply header */ +struct gh_rm_rpc_reply_hdr { + struct gh_rm_rpc_hdr rpc_hdr; + u32 err_code; +} __packed; + +/* RPC Header versions */ +#define GH_RM_RPC_HDR_VERSION_ONE 0x1 + +/* RPC Header words */ +#define GH_RM_RPC_HDR_WORDS 0x2 + +/* RPC Message types */ +#define GH_RM_RPC_TYPE_CONT 0x0 +#define GH_RM_RPC_TYPE_REQ 0x1 +#define GH_RM_RPC_TYPE_RPLY 0x2 +#define GH_RM_RPC_TYPE_NOTIF 0x3 + +#define GH_RM_MAX_NUM_FRAGMENTS 62 + +#define GH_RM_MAX_MSG_SIZE (GH_MSGQ_MAX_MSG_SIZE - sizeof(struct gh_rm_rpc_hdr)) + +/** + * struct gh_rm_connection - Represents a complete message from resource manager + * @payload: Combined payload of all the fragments (i.e. msg headers stripped off). + * @size: Size of the payload. + * @ret: Linux return code, set in case there was an error processing the connection. + * @msg_id: Message ID from the header. + * @type: GH_RM_RPC_TYPE_RPLY or GH_RM_RPC_TYPE_NOTIF. + * @num_fragments: total number of fragments expected to be received for this connection. + * @fragments_recieved: fragments received so far. + * @rm_error: For request/reply sequences with standard replies. + * @seq: Sequence ID for the main message. + */ +struct gh_rm_connection { + void *payload; + size_t size; + int ret; + u32 msg_id; + u8 type; + + u8 num_fragments; + u8 fragments_received; + + /* only for req/reply sequence */ + u32 rm_error; + u16 seq; + struct completion seq_done; +}; + +struct gh_rm_notif_complete { + struct gh_rm_connection *conn; + struct work_struct work; +}; + +struct gh_rsc_mgr { + struct gunyah_msgq msgq; + struct mbox_client msgq_client; + struct gh_rm_connection *active_rx_connection; + int last_tx_ret; + + struct idr call_idr; + struct mutex call_idr_lock; + + struct mutex send_lock; + + struct work_struct recv_work; +}; + +static struct gh_rsc_mgr *__rsc_mgr; +SRCU_NOTIFIER_HEAD_STATIC(gh_rm_notifier); + +static struct gh_rm_connection *gh_rm_alloc_connection(u32 msg_id, u8 type) +{ + struct gh_rm_connection *connection; + + connection = kzalloc(sizeof(*connection), GFP_KERNEL); + if (!connection) + return NULL; + + connection->type = type; + connection->msg_id = msg_id; + + return connection; +} + +/** + * gh_rm_init_connection_payload() - Fills the first message for a connection. + */ +static int gh_rm_init_connection_payload(struct gh_rm_connection *connection, void *msg, + size_t hdr_size, size_t payload_size) +{ + struct gh_rm_rpc_hdr *hdr = msg; + size_t max_buf_size; + + connection->num_fragments = hdr->fragments; + connection->fragments_received = 0; + connection->type = hdr->type; + + /* There's not going to be any payload, no need to allocate buffer. */ + if (!payload_size && !connection->num_fragments) + return 0; + + /* + * maximum payload size is GH_MSGQ_MAX_MSG_SIZE - hdr_size + * and can received (hdr->fragments + 1) of those + */ + max_buf_size = (GH_MSGQ_MAX_MSG_SIZE - hdr_size) * (hdr->fragments + 1); + + connection->payload = kzalloc(max_buf_size, GFP_KERNEL); + if (!connection->payload) + return -ENOMEM; + + memcpy(connection->payload, msg + hdr_size, payload_size); + connection->size = payload_size; + return 0; +} + +static void gh_rm_notif_work(struct work_struct *work) +{ + struct gh_rm_notif_complete *notif = container_of(work, struct gh_rm_notif_complete, work); + struct gh_rm_connection *connection = notif->conn; + u32 notif_id = connection->msg_id; + struct gh_rm_notification notification = { + .buff = connection->payload, + .size = connection->size, + }; + + srcu_notifier_call_chain(&gh_rm_notifier, notif_id, ¬ification); + + kfree(connection->payload); + kfree(connection); + kfree(notif); +} + +static struct gh_rm_connection *gh_rm_process_notif(struct gh_rsc_mgr *rsc_mgr, + void *msg, size_t msg_size) +{ + struct gh_rm_rpc_hdr *hdr = msg; + struct gh_rm_connection *connection; + + connection = gh_rm_alloc_connection(hdr->msg_id, hdr->type); + if (!connection) { + pr_err("Failed to alloc connection for notification, dropping.\n"); + return NULL; + } + + if (gh_rm_init_connection_payload(connection, msg, sizeof(*hdr), msg_size - sizeof(*hdr))) { + pr_err("Failed to alloc connection buffer for notification, dropping.\n"); + kfree(connection); + return NULL; + } + + return connection; +} + +static struct gh_rm_connection *gh_rm_process_rply(struct gh_rsc_mgr *rsc_mgr, + void *msg, size_t msg_size) +{ + struct gh_rm_rpc_reply_hdr *reply_hdr = msg; + struct gh_rm_rpc_hdr *hdr = msg; + struct gh_rm_connection *connection; + + if (mutex_lock_interruptible(&rsc_mgr->call_idr_lock)) + return ERR_PTR(-ERESTARTSYS); + + connection = idr_find(&rsc_mgr->call_idr, hdr->seq); + mutex_unlock(&rsc_mgr->call_idr_lock); + + if (!connection) { + pr_err("Failed to find connection for sequence %u\n", hdr->seq); + return NULL; + } + if (connection->msg_id != hdr->msg_id) { + pr_err("Reply for sequence %u expected msg_id: %x but got %x\n", hdr->seq, + connection->msg_id, hdr->msg_id); + /* + * Don't complete connection and error the client, maybe resource manager will + * send us the expected reply sequence soon. + */ + return NULL; + } + + if (gh_rm_init_connection_payload(connection, msg, sizeof(*reply_hdr), + msg_size - sizeof(*reply_hdr))) { + pr_err("Failed to alloc connection buffer for sequence %d\n", hdr->seq); + /* Send connection complete and error the client. */ + connection->ret = -ENOMEM; + complete(&connection->seq_done); + return NULL; + } + + connection->rm_error = reply_hdr->err_code; + return connection; +} + +static void gh_rm_process_cont(struct gh_rm_connection *connection, void *msg, size_t msg_size) +{ + struct gh_rm_rpc_hdr *hdr = msg; + size_t payload_size = msg_size - sizeof(*hdr); + + /* + * hdr->fragments and hdr->msg_id preserves the value from first reply or notif message. + * For sake of sanity, check if it's still intact. + */ + if (connection->msg_id != hdr->msg_id) + pr_warn("Appending mismatched continuation with id %d to connection with id %d\n", + hdr->msg_id, connection->msg_id); + if (connection->num_fragments != hdr->fragments) + pr_warn("Number of fragments mismatch for seq: %d\n", hdr->seq); + + memcpy(connection->payload + connection->size, msg + sizeof(*hdr), payload_size); + connection->size += payload_size; + connection->fragments_received++; +} + +static bool gh_rm_complete_connection(struct gh_rm_connection *connection) +{ + struct gh_rm_notif_complete *notif_work; + + if (!connection) + return false; + + if (connection->fragments_received != connection->num_fragments) + return false; + + switch (connection->type) { + case GH_RM_RPC_TYPE_RPLY: + complete(&connection->seq_done); + break; + case GH_RM_RPC_TYPE_NOTIF: + notif_work = kzalloc(sizeof(*notif_work), GFP_KERNEL); + if (notif_work == NULL) + break; + + notif_work->conn = connection; + INIT_WORK(¬if_work->work, gh_rm_notif_work); + + schedule_work(¬if_work->work); + break; + default: + pr_err("Invalid message type (%d) received\n", connection->type); + break; + } + + return true; +} + +static void gh_rm_abort_connection(struct gh_rm_connection *connection) +{ + switch (connection->type) { + case GH_RM_RPC_TYPE_RPLY: + connection->ret = -EIO; + complete(&connection->seq_done); + break; + case GH_RM_RPC_TYPE_NOTIF: + fallthrough; + default: + kfree(connection->payload); + kfree(connection); + } +} + +static void gh_rm_msgq_rx_data(struct mbox_client *cl, void *mssg) +{ + struct gh_rsc_mgr *rsc_mgr = container_of(cl, struct gh_rsc_mgr, msgq_client); + struct gunyah_msgq_rx_data *rx_data = mssg; + void *msg = rx_data->data; + size_t msg_size = rx_data->length; + struct gh_rm_rpc_hdr *hdr; + + if (msg_size <= sizeof(struct gh_rm_rpc_hdr)) { + pr_err("Invalid message size received: %ld is too small\n", msg_size); + return; + } + + hdr = msg; + switch (hdr->type) { + case GH_RM_RPC_TYPE_NOTIF: + if (rsc_mgr->active_rx_connection) { + /* Not possible per protocol. Do something better than BUG_ON */ + pr_warn("Received start of new notification without finishing existing message series.\n"); + gh_rm_abort_connection(rsc_mgr->active_rx_connection); + } + rsc_mgr->active_rx_connection = gh_rm_process_notif(rsc_mgr, msg, msg_size); + break; + case GH_RM_RPC_TYPE_RPLY: + if (rsc_mgr->active_rx_connection) { + /* Not possible per protocol. Do something better than BUG_ON */ + pr_warn("Received start of new reply without finishing existing message series.\n"); + gh_rm_abort_connection(rsc_mgr->active_rx_connection); + } + rsc_mgr->active_rx_connection = gh_rm_process_rply(rsc_mgr, msg, msg_size); + break; + case GH_RM_RPC_TYPE_CONT: + if (!rsc_mgr->active_rx_connection) { + pr_warn("Received a continuation message without receiving initial message\n"); + break; + } + gh_rm_process_cont(rsc_mgr->active_rx_connection, msg, msg_size); + break; + default: + pr_err("Invalid message type (%d) received\n", hdr->type); + return; + } + + if (gh_rm_complete_connection(rsc_mgr->active_rx_connection)) + rsc_mgr->active_rx_connection = NULL; +} + +static void gh_rm_msgq_tx_done(struct mbox_client *cl, void *mssg, int r) +{ + struct gh_rsc_mgr *rsc_mgr = container_of(cl, struct gh_rsc_mgr, msgq_client); + + kfree(mssg); + rsc_mgr->last_tx_ret = r; +} + +static int gh_rm_send_request(struct gh_rsc_mgr *rsc_mgr, u32 message_id, + const void *req_buff, size_t req_buff_size, + struct gh_rm_connection *connection) +{ + size_t buff_size_remaining = req_buff_size; + const void *req_buff_curr = req_buff; + struct gh_rm_rpc_hdr *hdr; + u32 cont_fragments = req_buff_size / GH_RM_MAX_MSG_SIZE; + size_t payload_size; + struct gunyah_msgq_tx_data *msg; + int i, ret; + + if (WARN(cont_fragments > GH_RM_MAX_NUM_FRAGMENTS, + "Limit exceeded for the number of fragments: %u\n", cont_fragments)) + return -E2BIG; + + ret = mutex_lock_interruptible(&rsc_mgr->send_lock); + if (ret) + return ret; + + /* Consider also the 'request' packet for the loop count */ + for (i = 0; i <= cont_fragments; i++) { + if (buff_size_remaining > GH_RM_MAX_MSG_SIZE) { + payload_size = GH_RM_MAX_MSG_SIZE; + buff_size_remaining -= payload_size; + } else { + payload_size = buff_size_remaining; + } + + msg = kzalloc(sizeof(*msg) + GH_MSGQ_MAX_MSG_SIZE, GFP_KERNEL); + if (!msg) { + ret = -ENOMEM; + goto out; + } + + /* Fill header */ + hdr = (struct gh_rm_rpc_hdr *)msg->data; + hdr->version = GH_RM_RPC_HDR_VERSION_ONE; + hdr->hdr_words = GH_RM_RPC_HDR_WORDS; + hdr->type = i == 0 ? GH_RM_RPC_TYPE_REQ : GH_RM_RPC_TYPE_CONT; + hdr->fragments = cont_fragments; + hdr->seq = connection->seq; + hdr->msg_id = message_id; + + /* Copy payload */ + memcpy(msg->data + sizeof(*hdr), req_buff_curr, payload_size); + req_buff_curr += payload_size; + + /* Force the last fragment to immediately alert the receiver */ + msg->push = i == cont_fragments; + msg->length = sizeof(*hdr) + payload_size; + + ret = mbox_send_message(gunyah_msgq_chan(&rsc_mgr->msgq), msg); + if (ret < 0) { + kfree(msg); + break; + } + + if (rsc_mgr->last_tx_ret) { + ret = rsc_mgr->last_tx_ret; + break; + } + } + +out: + mutex_unlock(&rsc_mgr->send_lock); + return ret < 0 ? ret : 0; +} + +/** + * gh_rm_call: Achieve request-response type communication with RPC + * @message_id: The RM RPC message-id + * @req_buff: Request buffer that contains the payload + * @req_buff_size: Total size of the payload + * @resp_buf: Pointer to a response buffer + * @resp_buff_size: Size of the response buffer + * @reply_err_code: Returns Gunyah standard error code for the response + * + * Make a request to the RM-VM and wait for reply back. For a successful + * response, the function returns the payload. The size of the payload is set in resp_buff_size. + * The resp_buf should be freed by the caller. + * + * Context: Process context. Will sleep waiting for reply. + * Return: >0 is standard reply error from RM. <0 on internal error. + */ +int gh_rm_call(u32 message_id, void *req_buff, size_t req_buff_size, + void **resp_buf, size_t *resp_buff_size) +{ + struct gh_rm_connection *connection; + int ret; + struct gh_rsc_mgr *rsc_mgr = __rsc_mgr; + + /* messaged_id 0 is reserved */ + if (!message_id) + return -EINVAL; + + if (!rsc_mgr) + return -EPROBE_DEFER; + + connection = gh_rm_alloc_connection(message_id, GH_RM_RPC_TYPE_RPLY); + if (!connection) + return -ENOMEM; + + init_completion(&connection->seq_done); + + /* Allocate a new seq number for this connection */ + if (mutex_lock_interruptible(&rsc_mgr->call_idr_lock)) { + kfree(connection); + return -ERESTARTSYS; + } + connection->seq = idr_alloc_cyclic(&rsc_mgr->call_idr, connection, 0, U16_MAX, GFP_KERNEL); + mutex_unlock(&rsc_mgr->call_idr_lock); + + /* Send the request to the Resource Manager */ + ret = gh_rm_send_request(rsc_mgr, message_id, req_buff, req_buff_size, connection); + if (ret < 0) + goto out; + + /* Wait for response */ + ret = wait_for_completion_interruptible(&connection->seq_done); + if (ret) + goto out; + + if (connection->ret) { + ret = connection->ret; + kfree(connection->payload); + goto out; + } + + if (connection->rm_error) { + ret = connection->rm_error; + kfree(connection->payload); + goto out; + } + + *resp_buf = connection->payload; + *resp_buff_size = connection->size; + +out: + mutex_lock(&rsc_mgr->call_idr_lock); + idr_remove(&rsc_mgr->call_idr, connection->seq); + mutex_unlock(&rsc_mgr->call_idr_lock); + + kfree(connection); + return ret; +} + +int gh_rm_register_notifier(struct notifier_block *nb) +{ + return srcu_notifier_chain_register(&gh_rm_notifier, nb); +} +EXPORT_SYMBOL_GPL(gh_rm_register_notifier); + +int gh_rm_unregister_notifier(struct notifier_block *nb) +{ + return srcu_notifier_chain_unregister(&gh_rm_notifier, nb); +} +EXPORT_SYMBOL_GPL(gh_rm_unregister_notifier); + +static int gh_msgq_platform_probe_direction(struct platform_device *pdev, + u8 gh_type, int idx, struct gunyah_resource *ghrsc) +{ + int ret; + struct device_node *node = pdev->dev.of_node; + + ghrsc->type = gh_type; + + ghrsc->irq = platform_get_irq(pdev, idx); + if (ghrsc->irq < 0) { + dev_err(&pdev->dev, "Failed to get irq%d: %d\n", idx, ghrsc->irq); + return ghrsc->irq; + } + + ret = of_property_read_u64_index(node, "reg", idx, &ghrsc->capid); + if (ret) { + dev_err(&pdev->dev, "Failed to get capid%d: %d\n", idx, ret); + return ret; + } + + return 0; +} + +static int gh_rm_drv_probe(struct platform_device *pdev) +{ + struct gh_rsc_mgr *rsc_mgr; + struct gunyah_resource tx_ghrsc, rx_ghrsc; + int ret; + + rsc_mgr = devm_kzalloc(&pdev->dev, sizeof(*rsc_mgr), GFP_KERNEL); + if (!rsc_mgr) + return -ENOMEM; + platform_set_drvdata(pdev, rsc_mgr); + + mutex_init(&rsc_mgr->call_idr_lock); + idr_init(&rsc_mgr->call_idr); + mutex_init(&rsc_mgr->send_lock); + + ret = gh_msgq_platform_probe_direction(pdev, GUNYAH_RESOURCE_TYPE_MSGQ_TX, 0, &tx_ghrsc); + if (ret) + return ret; + + ret = gh_msgq_platform_probe_direction(pdev, GUNYAH_RESOURCE_TYPE_MSGQ_RX, 1, &rx_ghrsc); + if (ret) + return ret; + + rsc_mgr->msgq_client.dev = &pdev->dev; + rsc_mgr->msgq_client.tx_block = true; + rsc_mgr->msgq_client.rx_callback = gh_rm_msgq_rx_data; + rsc_mgr->msgq_client.tx_done = gh_rm_msgq_tx_done; + + ret = gunyah_msgq_init(&pdev->dev, &rsc_mgr->msgq, &rsc_mgr->msgq_client, + &tx_ghrsc, &rx_ghrsc); + if (ret) + return ret; + + __rsc_mgr = rsc_mgr; + + return 0; +} + +static int gh_rm_drv_remove(struct platform_device *pdev) +{ + struct gh_rsc_mgr *rsc_mgr = platform_get_drvdata(pdev); + + __rsc_mgr = NULL; + + mbox_free_channel(gunyah_msgq_chan(&rsc_mgr->msgq)); + gunyah_msgq_remove(&rsc_mgr->msgq); + + return 0; +} + +static const struct of_device_id gh_rm_of_match[] = { + { .compatible = "gunyah-resource-manager" }, + { } +}; +MODULE_DEVICE_TABLE(of, gh_rm_of_match); + +static struct platform_driver gh_rm_driver = { + .probe = gh_rm_drv_probe, + .remove = gh_rm_drv_remove, + .driver = { + .name = "gh_rsc_mgr", + .of_match_table = gh_rm_of_match, + }, +}; +module_platform_driver(gh_rsc_mgr_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Gunyah Resource Manager Driver"); diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h new file mode 100644 index 000000000000..e4f2499267bf --- /dev/null +++ b/drivers/virt/gunyah/rsc_mgr.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ +#ifndef __GH_RSC_MGR_PRIV_H +#define __GH_RSC_MGR_PRIV_H + +#include + +/* RM Error codes */ +#define GH_RM_ERROR_OK 0x0 +#define GH_RM_ERROR_UNIMPLEMENTED 0xFFFFFFFF +#define GH_RM_ERROR_NOMEM 0x1 +#define GH_RM_ERROR_NORESOURCE 0x2 +#define GH_RM_ERROR_DENIED 0x3 +#define GH_RM_ERROR_INVALID 0x4 +#define GH_RM_ERROR_BUSY 0x5 +#define GH_RM_ERROR_ARGUMENT_INVALID 0x6 +#define GH_RM_ERROR_HANDLE_INVALID 0x7 +#define GH_RM_ERROR_VALIDATE_FAILED 0x8 +#define GH_RM_ERROR_MAP_FAILED 0x9 +#define GH_RM_ERROR_MEM_INVALID 0xA +#define GH_RM_ERROR_MEM_INUSE 0xB +#define GH_RM_ERROR_MEM_RELEASED 0xC +#define GH_RM_ERROR_VMID_INVALID 0xD +#define GH_RM_ERROR_LOOKUP_FAILED 0xE +#define GH_RM_ERROR_IRQ_INVALID 0xF +#define GH_RM_ERROR_IRQ_INUSE 0x10 +#define GH_RM_ERROR_IRQ_RELEASED 0x11 + +int gh_rm_call(u32 message_id, void *req_buff, size_t req_buff_size, + void **resp_buf, size_t *resp_buff_size); + +#endif diff --git a/include/linux/gunyah_rsc_mgr.h b/include/linux/gunyah_rsc_mgr.h new file mode 100644 index 000000000000..b3b37225b7fb --- /dev/null +++ b/include/linux/gunyah_rsc_mgr.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _GUNYAH_RSC_MGR_H +#define _GUNYAH_RSC_MGR_H + +#include +#include +#include + +#define GH_VMID_INVAL U16_MAX + +/* Gunyah recognizes VMID0 as an alias to the current VM's ID */ +#define GH_VMID_SELF 0 + +struct gh_rm_notification { + const void *buff; + const size_t size; +}; + +int gh_rm_register_notifier(struct notifier_block *nb); +int gh_rm_unregister_notifier(struct notifier_block *nb); + +#endif From patchwork Tue Oct 11 00:08:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614286 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 330CBC433F5 for ; Tue, 11 Oct 2022 00:11:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230417AbiJKALS (ORCPT ); Mon, 10 Oct 2022 20:11:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56064 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230329AbiJKAKM (ORCPT ); Mon, 10 Oct 2022 20:10:12 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 57AE619C14; Mon, 10 Oct 2022 17:09:46 -0700 (PDT) Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29B09VPY002497; Tue, 11 Oct 2022 00:09:31 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=P0lLr7aK19S1+yv1vs1G44smdfqvt8pl/Cr2VkW0RfU=; b=DClDY29Ioy5txiSp2hGc7O2ox4pA6CMjYNmOWNl3VdB/yNX+Pv1UBzz63PmfTd2yYonn c8vKlRhyl0Xo+fUMdKcWTL7y0ogBcSzYyrdKkww9m/AosfODgV30OCFpE/mPzHylNe+B umb/mGDmcvuYLCXeLUXHTEHZ5liR8rHGr/aGzofTKzumFpbsFLX+zQSY+oNShcWZnvTa GO//EZdJTGYygaa0bVxs6B4RTSvXZY/YkoBjiE/fSSjPHrvlY43sBHSITDoSPZY1k7nx vjSweNK+01lAZoFYTsJhFpOZTLY0HrCWJapsrXF7V0o4yXoEyZB2dxgHCRXjc1xgZFsV UA== Received: from nasanppmta05.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3k4rxe0hjv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:31 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 29B09TtE005738 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:30 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:29 -0700 From: Elliot Berman To: Bjorn Andersson CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Marc Zyngier , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , "Will Deacon" , Catalin Marinas , "Arnd Bergmann" , Greg Kroah-Hartman , , , , Subject: [PATCH v5 11/13] gunyah: rsc_mgr: Add RPC for console services Date: Mon, 10 Oct 2022 17:08:38 -0700 Message-ID: <20221011000840.289033-12-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: IAq9Zjr57Rk16Rc58SZ8yf8zm0ROe5u- X-Proofpoint-ORIG-GUID: IAq9Zjr57Rk16Rc58SZ8yf8zm0ROe5u- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 malwarescore=0 priorityscore=1501 impostorscore=0 clxscore=1015 phishscore=0 spamscore=0 adultscore=0 suspectscore=0 mlxlogscore=766 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210100143 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Gunyah resource manager defines a simple API for virtual machine log sharing with the console service. A VM's own log can be opened by using GH_VMID_SELF. Another VM's log can be accessed via its VMID. Once opened, characters can be written to the log with a write command. Characters are received with resource manager notifications (using ID GH_RM_NOTIF_VM_CONSOLE_CHARS). These high level rpc calls are kept in drivers/virt/gunyah/rsc_mgr_rpc.c. Future RPC calls, e.g. to launch a VM will also be maintained in this file. Signed-off-by: Elliot Berman --- drivers/virt/gunyah/Makefile | 2 +- drivers/virt/gunyah/rsc_mgr.h | 22 ++++++ drivers/virt/gunyah/rsc_mgr_rpc.c | 126 ++++++++++++++++++++++++++++++ include/linux/gunyah_rsc_mgr.h | 18 +++++ 4 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 drivers/virt/gunyah/rsc_mgr_rpc.c diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile index 2cae8ea5bc7d..5eb6ad3c45ba 100644 --- a/drivers/virt/gunyah/Makefile +++ b/drivers/virt/gunyah/Makefile @@ -1,5 +1,5 @@ gunyah-y += gunyah.o obj-$(CONFIG_GUNYAH) += gunyah.o -gunyah_rsc_mgr-y += rsc_mgr.o +gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o obj-$(CONFIG_GUNYAH_RESORUCE_MANAGER) += gunyah_rsc_mgr.o diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h index e4f2499267bf..4620ac648bcf 100644 --- a/drivers/virt/gunyah/rsc_mgr.h +++ b/drivers/virt/gunyah/rsc_mgr.h @@ -28,6 +28,28 @@ #define GH_RM_ERROR_IRQ_INUSE 0x10 #define GH_RM_ERROR_IRQ_RELEASED 0x11 +/* Message IDs: VM Management */ +#define GH_RM_RPC_VM_GET_VMID 0x56000024 + +/* Message IDs: VM Services */ +#define GH_RM_RPC_VM_CONSOLE_OPEN_ID 0x56000081 +#define GH_RM_RPC_VM_CONSOLE_CLOSE_ID 0x56000082 +#define GH_RM_RPC_VM_CONSOLE_WRITE_ID 0x56000083 +#define GH_RM_RPC_VM_CONSOLE_FLUSH_ID 0x56000084 + +/* Call: CONSOLE_OPEN, CONSOLE_CLOSE, CONSOLE_FLUSH */ +struct gh_vm_common_vmid_req { + u16 vmid; + u16 reserved0; +} __packed; + +/* Call: CONSOLE_WRITE */ +struct gh_vm_console_write_req { + u16 vmid; + u16 num_bytes; + u8 data[0]; +} __packed; + int gh_rm_call(u32 message_id, void *req_buff, size_t req_buff_size, void **resp_buf, size_t *resp_buff_size); diff --git a/drivers/virt/gunyah/rsc_mgr_rpc.c b/drivers/virt/gunyah/rsc_mgr_rpc.c new file mode 100644 index 000000000000..89d3a295f072 --- /dev/null +++ b/drivers/virt/gunyah/rsc_mgr_rpc.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#define pr_fmt(fmt) "gh_rsc_mgr: " fmt + +#include +#include +#include +#include + +#include "rsc_mgr.h" + +/* Several RM calls take only a VMID as a parameter and give only standard response back. + * Deduplicate boilerplate code by using this common call. + */ +static int gh_rm_common_vmid_call(u32 message_id, u16 vmid) +{ + void *resp = NULL; + struct gh_vm_common_vmid_req req_payload = { + .vmid = vmid, + }; + size_t resp_size; + int ret; + + ret = gh_rm_call(message_id, &req_payload, sizeof(req_payload), &resp, &resp_size); + if (!ret) + kfree(resp); + + WARN_ON(!ret && resp_size); + + return ret; +} + +/** + * gh_rm_get_vmid() - Retrieve VMID of this virtual machine + * @vmid: Filled with the VMID of this VM + */ +int gh_rm_get_vmid(u16 *vmid) +{ + void *resp; + size_t resp_size; + int ret; + int payload = 0; + + ret = gh_rm_call(GH_RM_RPC_VM_GET_VMID, &payload, sizeof(payload), &resp, &resp_size); + if (ret) + return ret; + + if (resp_size != sizeof(*vmid)) + return -EIO; + *vmid = *(u16 *)resp; + kfree(resp); + + return ret; +} + +/** + * gh_rm_console_open() - Open a console with a VM + * @vmid: VMID of the other VM whose console to open. If VMID is GH_VMID_SELF, the + * console associated with this VM is opened. + */ +int gh_rm_console_open(u16 vmid) +{ + return gh_rm_common_vmid_call(GH_RM_RPC_VM_CONSOLE_OPEN_ID, vmid); +} +EXPORT_SYMBOL_GPL(gh_rm_console_open); + +/** + * gh_rm_console_close() - Close a console with a VM + * @vmid: The vmid of the vm whose console to close. + */ +int gh_rm_console_close(u16 vmid) +{ + return gh_rm_common_vmid_call(GH_RM_RPC_VM_CONSOLE_CLOSE_ID, vmid); +} +EXPORT_SYMBOL_GPL(gh_rm_console_close); + +/** + * gh_rm_console_write() - Write to a VM's console + * @vmid: The vmid of the vm whose console to write to. + * @buf: Buffer to write to the VM's console + * @size: Size of the buffer + */ +int gh_rm_console_write(u16 vmid, const char *buf, size_t size) +{ + void *resp; + struct gh_vm_console_write_req *req_payload; + size_t resp_size; + int ret = 0; + size_t req_payload_size = sizeof(*req_payload) + size; + + if (size < 1 || size > (U32_MAX - sizeof(*req_payload))) + return -EINVAL; + + req_payload = kzalloc(req_payload_size, GFP_KERNEL); + + if (!req_payload) + return -ENOMEM; + + req_payload->vmid = vmid; + req_payload->num_bytes = size; + memcpy(req_payload->data, buf, size); + + ret = gh_rm_call(GH_RM_RPC_VM_CONSOLE_WRITE_ID, + req_payload, req_payload_size, + &resp, &resp_size); + + kfree(req_payload); + if (!ret) + kfree(resp); + + return ret; +} +EXPORT_SYMBOL_GPL(gh_rm_console_write); + +/** + * gh_rm_console_flush() - Flush a console with a VM + * @vmid: The vmid of the vm whose console to flush + */ +int gh_rm_console_flush(u16 vmid) +{ + return gh_rm_common_vmid_call(GH_RM_RPC_VM_CONSOLE_FLUSH_ID, vmid); +} +EXPORT_SYMBOL_GPL(gh_rm_console_flush); diff --git a/include/linux/gunyah_rsc_mgr.h b/include/linux/gunyah_rsc_mgr.h index b3b37225b7fb..2a1a51299247 100644 --- a/include/linux/gunyah_rsc_mgr.h +++ b/include/linux/gunyah_rsc_mgr.h @@ -23,4 +23,22 @@ struct gh_rm_notification { int gh_rm_register_notifier(struct notifier_block *nb); int gh_rm_unregister_notifier(struct notifier_block *nb); +/* Notification type Message IDs */ +#define GH_RM_NOTIF_VM_CONSOLE_CHARS 0x56100080 + +struct gh_rm_notif_vm_console_chars { + u16 vmid; + u16 num_bytes; + u8 bytes[]; +} __packed; + +/* RPC Calls */ +int gh_rm_get_vmid(u16 *vmid); +int gh_rm_console_open(u16 vmid); +int gh_rm_console_close(u16 vmid); +// Number of characters that can fit in a single RM message. +#define GH_RM_CONSOLE_WRITE_CHARS 228 +int gh_rm_console_write(u16 vmid, const char *buf, size_t size); +int gh_rm_console_flush(u16 vmid); + #endif From patchwork Tue Oct 11 00:08:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614883 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 81A6DC43219 for ; Tue, 11 Oct 2022 00:10:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230267AbiJKAKx (ORCPT ); Mon, 10 Oct 2022 20:10:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230210AbiJKAKA (ORCPT ); Mon, 10 Oct 2022 20:10:00 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AFCF31834A; Mon, 10 Oct 2022 17:09:44 -0700 (PDT) Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29B02acQ031330; Tue, 11 Oct 2022 00:09:31 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=4du6J6uH6CXmzBBodOef6TTxa3ya1AMlco9t1wxgDvM=; b=BigI5qEQUYsVICn+ExowI4gObT5WrJD7PG5ADB7l1DdIHlqehT/3t8hAAhqyLfKJb+Jy dH7EKSq99/PJztgZ650xgTPaYqZtzKYbHJtSPqJrQ+Kv+2G+CIOzXuq0WIKvvdTIXsbW LG9ZZ+yV8Nft+hWv5DLRk6ACwaZJDeV5FeMFopgatd33Tpwjg2Gb+K/HlyPXrCUK9Mbw PDYdsNQ+pUqXyFTHwZJF9mLpP1ZDjyVeEIuzETiAFAXalvTdvT7NazaRhk4IxKLG4EK+ iaVNaeF98wiAua3ETBOb1uO86dK7gf8zHssW2tmW8kThqNaApl/7jxLcghegf/Lk9E5I qg== Received: from nasanppmta05.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3k4rx5rhkj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:31 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 29B09Ue0005744 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:30 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:29 -0700 From: Elliot Berman To: Bjorn Andersson , Greg Kroah-Hartman CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Marc Zyngier , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , "Will Deacon" , Catalin Marinas , "Arnd Bergmann" , , , , Subject: [PATCH v5 12/13] gunyah: rsc_mgr: Add subdevices bus Date: Mon, 10 Oct 2022 17:08:39 -0700 Message-ID: <20221011000840.289033-13-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: YG76mkgYcD3kj6ZeEOm5xfD_rgR8_rpC X-Proofpoint-ORIG-GUID: YG76mkgYcD3kj6ZeEOm5xfD_rgR8_rpC X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 priorityscore=1501 spamscore=0 bulkscore=0 malwarescore=0 adultscore=0 suspectscore=0 mlxlogscore=999 impostorscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210100143 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Gunyah Resource Manager exposes an interface which should occupy a few devices on Linux: - a remote procedure call framework to talk to RM - a console device for VMs to interact with each other - a virtual machine manager to launch VMs, share memory with them, schedule runtime for those VMs, and handle certain faults. Create a virtual device bus for the console and VM Manager functions. Signed-off-by: Elliot Berman --- drivers/virt/gunyah/Makefile | 2 +- drivers/virt/gunyah/rsc_mgr.c | 45 ++++++++++++++++- drivers/virt/gunyah/rsc_mgr.h | 10 ++++ drivers/virt/gunyah/rsc_mgr_bus.c | 84 +++++++++++++++++++++++++++++++ include/linux/gunyah_rsc_mgr.h | 20 ++++++++ include/linux/mod_devicetable.h | 8 +++ scripts/mod/devicetable-offsets.c | 3 ++ scripts/mod/file2alias.c | 10 ++++ 8 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 drivers/virt/gunyah/rsc_mgr_bus.c diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile index 5eb6ad3c45ba..c376f403e712 100644 --- a/drivers/virt/gunyah/Makefile +++ b/drivers/virt/gunyah/Makefile @@ -1,5 +1,5 @@ gunyah-y += gunyah.o obj-$(CONFIG_GUNYAH) += gunyah.o -gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o +gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o rsc_mgr_bus.o obj-$(CONFIG_GUNYAH_RESORUCE_MANAGER) += gunyah_rsc_mgr.o diff --git a/drivers/virt/gunyah/rsc_mgr.c b/drivers/virt/gunyah/rsc_mgr.c index 0e2f04984ada..cdf96cb29c23 100644 --- a/drivers/virt/gunyah/rsc_mgr.c +++ b/drivers/virt/gunyah/rsc_mgr.c @@ -98,6 +98,8 @@ struct gh_rsc_mgr { struct mutex send_lock; struct work_struct recv_work; + + struct gh_rm_device console_dev, vm_mgr_dev; }; static struct gh_rsc_mgr *__rsc_mgr; @@ -566,13 +568,30 @@ static int gh_rm_drv_probe(struct platform_device *pdev) __rsc_mgr = rsc_mgr; + ret = gh_rm_device_add(&rsc_mgr->console_dev, &pdev->dev, GH_RM_DEVICE_CONSOLE); + if (ret) + goto err_msgq; + + ret = gh_rm_device_add(&rsc_mgr->vm_mgr_dev, &pdev->dev, GH_RM_DEVICE_VM_MGR); + if (ret) + goto err_console_remove; + return 0; + +err_console_remove: + gh_rm_device_delete(&rsc_mgr->console_dev); +err_msgq: + gunyah_msgq_remove(&rsc_mgr->msgq); + return ret; } static int gh_rm_drv_remove(struct platform_device *pdev) { struct gh_rsc_mgr *rsc_mgr = platform_get_drvdata(pdev); + gh_rm_device_delete(&rsc_mgr->vm_mgr_dev); + gh_rm_device_delete(&rsc_mgr->console_dev); + __rsc_mgr = NULL; mbox_free_channel(gunyah_msgq_chan(&rsc_mgr->msgq)); @@ -595,7 +614,31 @@ static struct platform_driver gh_rm_driver = { .of_match_table = gh_rm_of_match, }, }; -module_platform_driver(gh_rsc_mgr_driver); + +static int __init gh_rm_init(void) +{ + int ret; + + ret = gh_rm_bus_register(); + if (ret) { + pr_err("Failed to register gh_rm_bus: %d\n", ret); + return ret; + } + + ret = platform_driver_register(&gh_rm_driver); + if (ret) + gh_rm_bus_unregister(); + + return ret; +} +subsys_initcall(gh_rm_init); + +static void __exit gh_rm_exit(void) +{ + platform_driver_unregister(&gh_rm_driver); + gh_rm_bus_unregister(); +} +module_exit(gh_rm_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Gunyah Resource Manager Driver"); diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h index 4620ac648bcf..a511858a456d 100644 --- a/drivers/virt/gunyah/rsc_mgr.h +++ b/drivers/virt/gunyah/rsc_mgr.h @@ -53,4 +53,14 @@ struct gh_vm_console_write_req { int gh_rm_call(u32 message_id, void *req_buff, size_t req_buff_size, void **resp_buf, size_t *resp_buff_size); +struct gh_rm_device { + struct device dev; + const char *name; +}; + +int gh_rm_bus_register(void); +void gh_rm_bus_unregister(void); +int gh_rm_device_add(struct gh_rm_device *ghrm_dev, struct device *parent, const char *name); +void gh_rm_device_delete(struct gh_rm_device *ghrm_dev); + #endif diff --git a/drivers/virt/gunyah/rsc_mgr_bus.c b/drivers/virt/gunyah/rsc_mgr_bus.c new file mode 100644 index 000000000000..dfd466c775f4 --- /dev/null +++ b/drivers/virt/gunyah/rsc_mgr_bus.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#define pr_fmt(fmt) "gh_rsc_mgr: " fmt + +#include +#include +#include + +#include "rsc_mgr.h" + +#define to_gh_rm_device(dev) container_of(dev, struct gh_rm_device, dev) +#define to_gh_rm_driver(drv) container_of(drv, struct gh_rm_driver, drv) + +static int gh_rm_bus_match(struct device *dev, struct device_driver *drv) +{ + struct gh_rm_device *ghrm_dev = to_gh_rm_device(dev); + struct gh_rm_driver *ghrm_drv = to_gh_rm_driver(drv); + + // Multiple id_table entries not needed + return !strncmp(ghrm_dev->name, ghrm_drv->id_table->name, GUNYAH_RSC_MGR_NAME_SIZE); +} + +static int gh_rm_bus_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct gh_rm_device *ghrm_dev = to_gh_rm_device(dev); + + return add_uevent_var(env, "MODALIAS=%s%s", GUNYAH_RSC_MGR_PREFIX, ghrm_dev->name); +} + +static struct bus_type gh_rm_bus = { + .name = "gh_rsc_mgr", + .match = gh_rm_bus_match, + .uevent = gh_rm_bus_uevent, +}; + +int gh_rm_bus_register(void) +{ + return bus_register(&gh_rm_bus); +} + +void gh_rm_bus_unregister(void) +{ + bus_unregister(&gh_rm_bus); +} + +int gh_rm_device_add(struct gh_rm_device *ghrm_dev, struct device *parent, const char *name) +{ + ghrm_dev->dev.bus = &gh_rm_bus; + ghrm_dev->dev.parent = parent; + ghrm_dev->name = name; + + device_initialize(&ghrm_dev->dev); + + dev_set_name(&ghrm_dev->dev, "%s.%s", dev_name(parent), name); + return device_add(&ghrm_dev->dev); +} + +void gh_rm_device_delete(struct gh_rm_device *ghrm_dev) +{ + device_del(&ghrm_dev->dev); +} + +int __gh_rm_driver_register(struct gh_rm_driver *ghrm_drv, struct module *owner, + const char *modname) +{ + if (WARN_ON(!ghrm_drv->drv.probe) || WARN_ON(!ghrm_drv->id_table)) + return -EINVAL; + + ghrm_drv->drv.bus = &gh_rm_bus; + ghrm_drv->drv.owner = owner; + ghrm_drv->drv.mod_name = modname; + + return driver_register(&ghrm_drv->drv); +} +EXPORT_SYMBOL_GPL(__gh_rm_driver_register); + +void gh_rm_driver_unregister(struct gh_rm_driver *ghrm_drv) +{ + driver_unregister(&ghrm_drv->drv); +} +EXPORT_SYMBOL_GPL(gh_rm_driver_unregister); diff --git a/include/linux/gunyah_rsc_mgr.h b/include/linux/gunyah_rsc_mgr.h index 2a1a51299247..7aea3344d655 100644 --- a/include/linux/gunyah_rsc_mgr.h +++ b/include/linux/gunyah_rsc_mgr.h @@ -9,6 +9,8 @@ #include #include #include +#include +#include #define GH_VMID_INVAL U16_MAX @@ -41,4 +43,22 @@ int gh_rm_console_close(u16 vmid); int gh_rm_console_write(u16 vmid, const char *buf, size_t size); int gh_rm_console_flush(u16 vmid); +#define GH_RM_DEVICE_CONSOLE "console" +#define GH_RM_DEVICE_VM_MGR "vm_mgr" + +struct gh_rm_driver { + const struct gunyah_rsc_mgr_device_id *id_table; + struct device_driver drv; +}; + +int __gh_rm_driver_register(struct gh_rm_driver *ghrm_drv, struct module *owner, + const char *modname); +#define gh_rm_driver_register(ghrm_drv) \ + __gh_rm_driver_register(ghrm_drv, THIS_MODULE, KBUILD_MODNAME) + +void gh_rm_driver_unregister(struct gh_rm_driver *ghrm_drv); + +#define module_gh_rm_driver(ghrm_drv) \ + module_driver(ghrm_drv, gh_rm_driver_register, gh_rm_driver_unregister) + #endif diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 549590e9c644..c4dc0ee6ae00 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -911,4 +911,12 @@ struct ishtp_device_id { kernel_ulong_t driver_data; }; +#define GUNYAH_RSC_MGR_NAME_SIZE 32 +#define GUNYAH_RSC_MGR_PREFIX "gh_rsc_mgr:" + +struct gunyah_rsc_mgr_device_id { + const char name[GUNYAH_RSC_MGR_NAME_SIZE]; + kernel_ulong_t driver_data; +}; + #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index c0d3bcb99138..7b6944ed9336 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -262,5 +262,8 @@ int main(void) DEVID(ishtp_device_id); DEVID_FIELD(ishtp_device_id, guid); + DEVID(gunyah_rsc_mgr_device_id); + DEVID_FIELD(gunyah_rsc_mgr_device_id, name); + return 0; } diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 80d973144fde..a02b9e8e02a8 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1452,6 +1452,15 @@ static int do_dfl_entry(const char *filename, void *symval, char *alias) return 1; } +/* Looks like: gh_rsc_mgr:S */ +static int do_gunyah_rsc_mgr_entry(const char *filename, void *symval, char *alias) +{ + DEF_FIELD_ADDR(symval, gunyah_rsc_mgr_device_id, name); + sprintf(alias, GUNYAH_RSC_MGR_PREFIX "%s", *name); + + return 1; +} + /* Does namelen bytes of name exactly match the symbol? */ static bool sym_is(const char *name, unsigned namelen, const char *symbol) { @@ -1531,6 +1540,7 @@ static const struct devtable devtable[] = { {"ssam", SIZE_ssam_device_id, do_ssam_entry}, {"dfl", SIZE_dfl_device_id, do_dfl_entry}, {"ishtp", SIZE_ishtp_device_id, do_ishtp_entry}, + {"gh_rsc_mgr", SIZE_gunyah_rsc_mgr_device_id, do_gunyah_rsc_mgr_entry}, }; /* Create MODULE_ALIAS() statements. From patchwork Tue Oct 11 00:08:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 614882 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 41177C4167D for ; Tue, 11 Oct 2022 00:10:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230112AbiJKAK4 (ORCPT ); Mon, 10 Oct 2022 20:10:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53606 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230173AbiJKAKC (ORCPT ); Mon, 10 Oct 2022 20:10:02 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5788F193DF; Mon, 10 Oct 2022 17:09:46 -0700 (PDT) Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29AMp3ZQ020824; Tue, 11 Oct 2022 00:09:32 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=XFAz8+Jl6XNJGFSbiHb9TYEp8cP07MIlPe92gO674AY=; b=mYYR63Mu4Pkw9kPS5z4z8+CV3vrOB51Jz8qVJjA48DXbilezCNijtHC/ueI13oPm6o+o ZKnii5tRv0z5Gv/N/2LYcl4IrhLtfICiy+iEe5gZyjyBj8+zyLTCPtDj37RAc1myngZy cRf8cgQPgCyk5vqMAsCXwp/TBnt08ueihcRmsuPo9PeNxpclbs93zZl77dMTJ7tRj039 3KZu7buNjSncWs1hdEwm9Gg4ureqY3kutXMkFGiUJvD3Vy5GOET6ZoREP0xuOwTNUUoF bZHBDElGFdLAD4LtcpVEC4rV+3SicXjvNaKVaFh5ZtC5KPQOhUAPj+9JmJx3wOWxo17F lg== Received: from nasanppmta01.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3k4rxa0hmj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:32 +0000 Received: from nasanex01b.na.qualcomm.com (corens_vlan604_snip.qualcomm.com [10.53.140.1]) by NASANPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 29B09V46012990 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Oct 2022 00:09:31 GMT Received: from hu-eberman-lv.qualcomm.com (10.49.16.6) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Mon, 10 Oct 2022 17:09:30 -0700 From: Elliot Berman To: Bjorn Andersson , Greg Kroah-Hartman , Jiri Slaby CC: Elliot Berman , Murali Nalajala , Trilok Soni , "Srivatsa Vaddagiri" , Carl van Schaik , Prakruthi Deepak Heragu , Andy Gross , Dmitry Baryshkov , Jassi Brar , , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , Marc Zyngier , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , "Will Deacon" , Catalin Marinas , "Arnd Bergmann" , , , , Subject: [PATCH v5 13/13] tty: gunyah: Add tty console driver for RM Console Services Date: Mon, 10 Oct 2022 17:08:40 -0700 Message-ID: <20221011000840.289033-14-quic_eberman@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221011000840.289033-1-quic_eberman@quicinc.com> References: <20221011000840.289033-1-quic_eberman@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: 5aFaaY3klHeFhllOpVENG9ztcqJCdnva X-Proofpoint-GUID: 5aFaaY3klHeFhllOpVENG9ztcqJCdnva X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 suspectscore=0 spamscore=0 mlxscore=0 clxscore=1015 adultscore=0 impostorscore=0 bulkscore=0 priorityscore=1501 mlxlogscore=999 malwarescore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210100143 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Gunyah provides a console for each VM using the VM console resource manager APIs. This driver allows console data from other VMs to be accessed via a TTY device and exports a console device to dump Linux's own logs to our console. Signed-off-by: Elliot Berman --- MAINTAINERS | 1 + drivers/tty/Kconfig | 8 + drivers/tty/Makefile | 1 + drivers/tty/gunyah_console.c | 439 +++++++++++++++++++++++++++++++++++ 4 files changed, 449 insertions(+) create mode 100644 drivers/tty/gunyah_console.c diff --git a/MAINTAINERS b/MAINTAINERS index 8a3d79b56698..e85140fa0dfe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8889,6 +8889,7 @@ F: Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml F: Documentation/virt/gunyah/ F: arch/arm64/gunyah/ F: drivers/mailbox/gunyah-msgq.c +F: drivers/tty/gunyah_tty.c F: drivers/virt/gunyah/ F: include/asm-generic/gunyah.h F: include/linux/gunyah*.h diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index cc30ff93e2e4..ff86e977f9ac 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -380,6 +380,14 @@ config RPMSG_TTY To compile this driver as a module, choose M here: the module will be called rpmsg_tty. +config GUNYAH_CONSOLE + tristate "Gunyah Consoles" + depends on GUNYAH + help + This enables support for console output using Gunyah's Resource Manager RPC. + This is normally used when a secondary VM which does not have exclusive access + to a real or virtualized serial device and virtio-console is unavailable. + endif # TTY source "drivers/tty/serdev/Kconfig" diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 07aca5184a55..134b7321c630 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -27,5 +27,6 @@ obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o obj-$(CONFIG_VCC) += vcc.o obj-$(CONFIG_RPMSG_TTY) += rpmsg_tty.o +obj-$(CONFIG_GUNYAH_CONSOLE) += gunyah_console.o obj-y += ipwireless/ diff --git a/drivers/tty/gunyah_console.c b/drivers/tty/gunyah_console.c new file mode 100644 index 000000000000..71d9f22c2a43 --- /dev/null +++ b/drivers/tty/gunyah_console.c @@ -0,0 +1,439 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The Linux TTY code requires us to know ahead of time how many ports we might + * need. Each port here corresponds to a VM. 16 seems like a reasonable number + * of ports for systems that are running Gunyah and using the console interface. + */ +#define RM_CONS_TTY_ADAPATERS (16) + +struct rm_cons_port { + struct tty_port port; + u16 vmid; + unsigned int index; +}; + +struct rm_cons_drv_data { + struct tty_driver *tty_driver; + struct device *dev; + + spinlock_t ports_lock; + struct rm_cons_port *ports[RM_CONS_TTY_ADAPATERS]; + + struct notifier_block rm_cons_notif; + struct console console; + + /* below are for printk console. + * gh_rm_console_* calls will sleep and console_write can be called from + * atomic ctx. Two xmit buffers are used. The active buffer is tracked with + * co_xmit_idx. Writes go into the co_xmit_buf[co_xmit_idx] buffer. + * A work is scheduled to flush the bytes. The work will swap the active buffer + * and write out the other buffer. + */ + char *co_xmit_buf[2]; + int co_xmit_idx; + unsigned int co_xmit_count; + spinlock_t co_xmit_lock; + struct work_struct co_flush_work; +}; + +static int rm_cons_notif_handler(struct notifier_block *nb, unsigned long cmd, void *data) +{ + int count, i; + struct rm_cons_port *rm_port = NULL; + struct tty_port *tty_port = NULL; + struct rm_cons_drv_data *cons_data = + container_of(nb, struct rm_cons_drv_data, rm_cons_notif); + const struct gh_rm_notification *notif = data; + struct gh_rm_notif_vm_console_chars const * const msg = notif->buff; + + if (cmd != GH_RM_NOTIF_VM_CONSOLE_CHARS || + notif->size < sizeof(*msg)) + return NOTIFY_DONE; + + spin_lock(&cons_data->ports_lock); + for (i = 0; i < RM_CONS_TTY_ADAPATERS; i++) { + if (!cons_data->ports[i]) + continue; + if (cons_data->ports[i]->vmid == msg->vmid) { + rm_port = cons_data->ports[i]; + break; + } + } + if (rm_port) + tty_port = tty_port_get(&rm_port->port); + spin_unlock(&cons_data->ports_lock); + + if (!rm_port) + dev_warn(cons_data->dev, "Received unexpected console characters for VMID %u\n", + msg->vmid); + if (!tty_port) + return NOTIFY_DONE; + + count = tty_buffer_request_room(tty_port, msg->num_bytes); + tty_insert_flip_string(tty_port, msg->bytes, count); + tty_flip_buffer_push(tty_port); + + tty_port_put(tty_port); + return NOTIFY_OK; +} + +static int rm_cons_tty_open(struct tty_struct *tty, struct file *filp) +{ + struct rm_cons_port *rm_port = dev_get_drvdata(tty->dev); + + return tty_port_open(&rm_port->port, tty, filp); +} + +static void rm_cons_tty_close(struct tty_struct *tty, struct file *filp) +{ + struct rm_cons_port *rm_port = dev_get_drvdata(tty->dev); + + tty_port_close(&rm_port->port, tty, filp); +} + +static int rm_cons_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + struct rm_cons_port *rm_port = dev_get_drvdata(tty->dev); + int ret; + + if (!count) + return 0; + + ret = gh_rm_console_write(rm_port->vmid, buf, count); + if (ret) + return -EAGAIN; + return count; +} + +static void rm_cons_tty_flush_chars(struct tty_struct *tty) +{ + struct rm_cons_port *rm_port = dev_get_drvdata(tty->dev); + + gh_rm_console_flush(rm_port->vmid); +} + +static unsigned int rm_cons_mgr_tty_write_room(struct tty_struct *tty) +{ + return GH_RM_CONSOLE_WRITE_CHARS; +} + +static const struct tty_operations rm_cons_tty_ops = { + .open = rm_cons_tty_open, + .close = rm_cons_tty_close, + .write = rm_cons_tty_write, + .flush_chars = rm_cons_tty_flush_chars, + .write_room = rm_cons_mgr_tty_write_room, +}; + +static int rm_cons_port_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct rm_cons_port *rm_port = container_of(port, struct rm_cons_port, port); + + return gh_rm_console_open(rm_port->vmid); +} + +static void rm_cons_port_shutdown(struct tty_port *port) +{ + struct rm_cons_port *rm_port = container_of(port, struct rm_cons_port, port); + int ret; + + ret = gh_rm_console_close(rm_port->vmid); + if (ret) + dev_err(port->tty->dev, "Failed to close ttyGH%d: %d\n", rm_port->index, ret); +} + +static void rm_cons_port_destruct(struct tty_port *port) +{ + struct rm_cons_port *rm_port = container_of(port, struct rm_cons_port, port); + struct rm_cons_drv_data *cons_data = dev_get_drvdata(port->tty->dev); + + spin_lock(&cons_data->ports_lock); + cons_data->ports[rm_port->index] = NULL; + spin_unlock(&cons_data->ports_lock); + kfree(rm_port); +} + +static const struct tty_port_operations rm_cons_port_ops = { + .activate = rm_cons_port_activate, + .shutdown = rm_cons_port_shutdown, + .destruct = rm_cons_port_destruct, +}; + +static void rm_cons_console_flush_work(struct work_struct *ws) +{ + struct rm_cons_drv_data *cons_data = + container_of(ws, struct rm_cons_drv_data, co_flush_work); + struct console *co = &cons_data->console; + struct rm_cons_port *rm_port = co->data; + unsigned long flags; + size_t size; + int ret, old_buf = cons_data->co_xmit_idx; + + spin_lock_irqsave(&cons_data->co_xmit_lock, flags); + cons_data->co_xmit_idx = 1 - old_buf; + size = cons_data->co_xmit_count; + cons_data->co_xmit_count = 0; + spin_unlock_irqrestore(&cons_data->co_xmit_lock, flags); + + do { + ret = gh_rm_console_write(rm_port->vmid, cons_data->co_xmit_buf[old_buf], size); + } while (ret && ret != -ENOMEM); + + gh_rm_console_flush(rm_port->vmid); +} + +static void rm_cons_console_write(struct console *co, const char *buf, unsigned count) +{ + struct rm_cons_drv_data *cons_data = container_of(co, struct rm_cons_drv_data, console); + unsigned long flags; + + spin_lock_irqsave(&cons_data->co_xmit_lock, flags); + count = min(count, (unsigned)(PAGE_SIZE - cons_data->co_xmit_count)); + memcpy(&cons_data->co_xmit_buf[cons_data->co_xmit_idx][cons_data->co_xmit_count], buf, + count); + cons_data->co_xmit_count += count; + spin_unlock_irqrestore(&cons_data->co_xmit_lock, flags); + + schedule_work(&cons_data->co_flush_work); +} + +static struct tty_driver *rm_cons_console_device(struct console *co, int *index) +{ + struct rm_cons_drv_data *cons_data = container_of(co, struct rm_cons_drv_data, console); + struct rm_cons_port *rm_port = co->data; + + *index = rm_port->index; + return cons_data->tty_driver; +} + +static int rm_cons_console_setup(struct console *co, char *unused) +{ + struct rm_cons_drv_data *cons_data = container_of(co, struct rm_cons_drv_data, console); + struct rm_cons_port *rm_port = co->data; + int ret; + + if (!tty_port_get(&rm_port->port)) + return -ENODEV; + + cons_data->co_xmit_buf[0] = (unsigned char *)get_zeroed_page(GFP_KERNEL); + if (!cons_data->co_xmit_buf[0]) + goto err; + cons_data->co_xmit_buf[1] = (unsigned char *)get_zeroed_page(GFP_KERNEL); + if (!cons_data->co_xmit_buf[1]) + goto err; + + mutex_lock(&rm_port->port.mutex); + if (!tty_port_initialized(&rm_port->port)) { + ret = gh_rm_console_open(rm_port->vmid); + if (ret) { + dev_err(rm_port->port.tty->dev, "Failed to open %s%d: %d\n", + co->name, rm_port->index, ret); + goto err; + } + tty_port_set_initialized(&rm_port->port, true); + } + rm_port->port.console = true; + mutex_unlock(&rm_port->port.mutex); + + return 0; +err: + if (cons_data->co_xmit_buf[1]) + free_page((unsigned long)cons_data->co_xmit_buf[1]); + if (cons_data->co_xmit_buf[0]) + free_page((unsigned long)cons_data->co_xmit_buf[0]); + mutex_unlock(&rm_port->port.mutex); + tty_port_put(&rm_port->port); + return ret; +} + +static int rm_cons_console_exit(struct console *co) +{ + struct rm_cons_port *rm_port = co->data; + int ret; + + mutex_lock(&rm_port->port.mutex); + rm_port->port.console = false; + + if (!tty_port_active(&rm_port->port)) { + ret = gh_rm_console_close(rm_port->vmid); + if (ret) + dev_err(rm_port->port.tty->dev, "Failed to close %s%d: %d\n", + co->name, rm_port->index, ret); + tty_port_set_initialized(&rm_port->port, false); + } + + mutex_unlock(&rm_port->port.mutex); + tty_port_put(&rm_port->port); + + return 0; +} + +static struct rm_cons_port *rm_cons_port_create(struct rm_cons_drv_data *cons_data, u16 vmid) +{ + struct rm_cons_port *rm_port; + struct device *ttydev; + unsigned int index; + int ret; + + rm_port = kzalloc(sizeof(*rm_port), GFP_KERNEL); + if (!rm_port) + return ERR_PTR(-ENOMEM); + rm_port->vmid = vmid; + tty_port_init(&rm_port->port); + rm_port->port.ops = &rm_cons_port_ops; + + spin_lock(&cons_data->ports_lock); + for (index = 0; index < RM_CONS_TTY_ADAPATERS; index++) { + if (!cons_data->ports[index]) { + cons_data->ports[index] = rm_port; + rm_port->index = index; + break; + } + } + spin_unlock(&cons_data->ports_lock); + if (index >= RM_CONS_TTY_ADAPATERS) { + ret = -ENOSPC; + goto err_put_port; + } + + ttydev = tty_port_register_device_attr(&rm_port->port, cons_data->tty_driver, index, + cons_data->dev, rm_port, NULL); + if (IS_ERR(ttydev)) { + ret = PTR_ERR(ttydev); + goto err_put_port; + } + + return rm_port; +err_put_port: + tty_port_put(&rm_port->port); + return ERR_PTR(ret); +} + +static int rm_cons_console_probe(struct device *dev) +{ + struct rm_cons_drv_data *cons_data; + struct rm_cons_port *rm_port; + int ret; + u16 vmid; + + cons_data = devm_kzalloc(dev, sizeof(*cons_data), GFP_KERNEL); + if (!cons_data) + return -ENOMEM; + dev_set_drvdata(dev, cons_data); + cons_data->dev = dev; + + cons_data->tty_driver = tty_alloc_driver(RM_CONS_TTY_ADAPATERS, + TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | + TTY_DRIVER_RESET_TERMIOS); + if (IS_ERR(cons_data->tty_driver)) + return PTR_ERR(cons_data->tty_driver); + + cons_data->tty_driver->driver_name = KBUILD_MODNAME; + cons_data->tty_driver->name = "ttyGH"; + cons_data->tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; + cons_data->tty_driver->subtype = SYSTEM_TYPE_TTY; + cons_data->tty_driver->init_termios = tty_std_termios; + tty_set_operations(cons_data->tty_driver, &rm_cons_tty_ops); + + ret = tty_register_driver(cons_data->tty_driver); + if (ret) { + dev_err(dev, "Could not register tty driver: %d\n", ret); + goto err_put_tty; + } + + spin_lock_init(&cons_data->ports_lock); + + cons_data->rm_cons_notif.notifier_call = rm_cons_notif_handler; + ret = gh_rm_register_notifier(&cons_data->rm_cons_notif); + if (ret) { + dev_err(dev, "Could not register for resource manager notifications: %d\n", ret); + goto err_put_tty; + } + + spin_lock_init(&cons_data->co_xmit_lock); + INIT_WORK(&cons_data->co_flush_work, rm_cons_console_flush_work); + + rm_port = rm_cons_port_create(cons_data, GH_VMID_SELF); + if (IS_ERR(rm_port)) { + ret = PTR_ERR(rm_port); + dev_err(dev, "Could not create own console: %d\n", ret); + goto err_unreg_notif; + } + + rm_port->port.console = 1; + strncpy(cons_data->console.name, "ttyGH", sizeof(cons_data->console.name)); + cons_data->console.write = rm_cons_console_write; + cons_data->console.device = rm_cons_console_device; + cons_data->console.setup = rm_cons_console_setup; + cons_data->console.exit = rm_cons_console_exit; + cons_data->console.index = rm_port->index; + cons_data->console.data = rm_port; + register_console(&cons_data->console); + + ret = gh_rm_get_vmid(&vmid); + if (!ret) { + rm_port = rm_cons_port_create(cons_data, vmid); + if (IS_ERR(rm_port)) + dev_warn(dev, "Could not create loopback console: %ld\n", PTR_ERR(rm_port)); + } else { + dev_warn(dev, "Failed to get this VM's VMID: %d. Not creating loop-back console\n", + ret); + } + + return 0; +err_unreg_notif: + gh_rm_unregister_notifier(&cons_data->rm_cons_notif); +err_put_tty: + tty_driver_kref_put(cons_data->tty_driver); + return ret; +} + +static int rm_cons_console_remove(struct device *dev) +{ + struct rm_cons_drv_data *cons_data = dev_get_drvdata(dev); + + unregister_console(&cons_data->console); + if (cons_data->co_xmit_buf[1]) + free_page((unsigned long)cons_data->co_xmit_buf[1]); + if (cons_data->co_xmit_buf[0]) + free_page((unsigned long)cons_data->co_xmit_buf[0]); + gh_rm_unregister_notifier(&cons_data->rm_cons_notif); + tty_unregister_driver(cons_data->tty_driver); + tty_driver_kref_put(cons_data->tty_driver); + + return 0; +} + +static struct gunyah_rm_cons_device_id rm_cons_console_ids[] = { + { .name = GH_RM_DEVICE_CONSOLE }, + {} +}; +MODULE_DEVICE_TABLE(gunyah_rsc_mgr, rm_cons_console_ids); + +static struct gh_rm_driver rm_cons_console_drv = { + .drv = { + .name = KBUILD_MODNAME, + .probe = rm_cons_console_probe, + .remove = rm_cons_console_remove, + }, + .id_table = rm_cons_console_ids, +}; +module_gh_rm_driver(rm_cons_console_drv); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Gunyah Console");