From patchwork Sat Aug 29 17:09:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 248707 Delivered-To: patch@linaro.org Received: by 2002:a92:5b9c:0:0:0:0:0 with SMTP id c28csp2036442ilg; Sat, 29 Aug 2020 10:09:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxnaFwwwhHtmqkZI8wx9BhmfE93Uq+IWf/mo3nvi8GuhVGMN2SAj7kvSmylsR+Sw+50Bd2m X-Received: by 2002:aa7:d54d:: with SMTP id u13mr4289869edr.356.1598720975799; Sat, 29 Aug 2020 10:09:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598720975; cv=none; d=google.com; s=arc-20160816; b=USnSOWgeWz0K1YqJ0bDGpQ5ZqZk4bg0wP9E1LfRwAOJDKTpmuTsHh6f+KgaXw0w6uD 3g2uBl9mE9bFgOcu/zfzMtMFi/rxuvW2Ca78XRGdxcTPg98AM7Twxjx4WOK8q0Pthr+y KbdS6CF7bsWTdBPFg49FStbLNwcKw99BlPMIKa+iyYo9jWwOhNNnYOSlGBs6Q0xG/5eb GtsmAK1GxqPnKR1VDlZaDKuFvBKDkgdhuHvI1Cg2RG5udUii4u7KawydTsH22zcqOKUH pysPYzQpQhHq4x/TsgOrch5Kj8kJxv6lfIyDvKzR6DulVeynzVcJsg+bn/WbquMlj1Ot D8QQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=JnjgGBobw9318wqJATlW8zd2EE7CLSaQdeqCyP74834=; b=mwxZK2PENd608FzCOPvIS+6l7ttzx1G6OOt5DROsFuly4UH0CeRh22pJUGoiVX0OLm XOmAwxYeXrOT3fmwdM1kFeetdbl0hGJKzKrnwdWFkdi2LwocCjBJPSs6H/pa4t6xe/BL 6wbaplqq8vXqzhVo/Fw/xbYu4UGcw+gMX4cRyfmuTwHLZk+o+dVIIVuOrSSnSxd/AZ+d 3rrISXkrmkb85KzdmwRC9gR89LpWr8x/aZhvQtULtlyxsZFxkCkYkK2X2K+ObdcJ7s/O Y8Lw/54/h+q2m11sBSIutNw/3OMovmG89jAHLfZLb6GQVma8pCAw1URsAsvrymTl/Iq3 hszg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d22si1952640edz.234.2020.08.29.10.09.35; Sat, 29 Aug 2020 10:09:35 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728410AbgH2RJe (ORCPT + 6 others); Sat, 29 Aug 2020 13:09:34 -0400 Received: from foss.arm.com ([217.140.110.172]:45032 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728412AbgH2RJe (ORCPT ); Sat, 29 Aug 2020 13:09:34 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 238DB1063; Sat, 29 Aug 2020 10:09:33 -0700 (PDT) Received: from usa.arm.com (e103737-lin.cambridge.arm.com [10.1.197.49]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 248373F71F; Sat, 29 Aug 2020 10:09:32 -0700 (PDT) From: Sudeep Holla To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Cc: Sudeep Holla , kernel-team@android.com, Will Deacon , tsoni@quicinc.com, pratikp@quicinc.com Subject: [PATCH 1/9] dt-bindings: Arm: Add Firmware Framework for Armv8-A (FF-A) binding Date: Sat, 29 Aug 2020 18:09:15 +0100 Message-Id: <20200829170923.29949-2-sudeep.holla@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com> References: <20200829170923.29949-1-sudeep.holla@arm.com> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Will Deacon Add devicetree bindings for a FF-A-compliant hypervisor, its partitions and their memory regions. The naming is ludicrous but also not by fault. Signed-off-by: Will Deacon (sudeep.holla: Dropped PSA from name and elsewhere as it seem to have disappeared mysteriously just before the final release) Signed-off-by: Sudeep Holla --- .../devicetree/bindings/arm/arm,ffa.yaml | 102 ++++++++++++++++++ .../reserved-memory/arm,ffa-memory.yaml | 71 ++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/arm,ffa.yaml create mode 100644 Documentation/devicetree/bindings/reserved-memory/arm,ffa-memory.yaml -- 2.17.1 diff --git a/Documentation/devicetree/bindings/arm/arm,ffa.yaml b/Documentation/devicetree/bindings/arm/arm,ffa.yaml new file mode 100644 index 000000000000..668a5995fcab --- /dev/null +++ b/Documentation/devicetree/bindings/arm/arm,ffa.yaml @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/arm,ffa.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arm Firmware Framework for Arm v8-A + +maintainers: + - Will Deacon + +description: | + Firmware frameworks implementing partition setup according to the FF-A + specification defined by ARM document number ARM DEN 0077A ("Arm Firmware + Framework for Arm v8-A") [0] must provide a "manifest and image" for each + partition to the "partition manager" so that the partition execution contexts + can be initialised. + + In the case of a virtual FFA instance, the manifest and image details can be + passed to the hypervisor (e.g. Linux KVM) using this binding. + + [0] https://developer.arm.com/docs/den0077/latest + +properties: + $nodename: + const: ffa_hyp + + compatible: + oneOf: + - const: arm,ffa-1.0-hypervisor + + memory-region: + $ref: '/schemas/types.yaml#/definitions/phandle' + description: | + A phandle to the reserved memory region [1] to be used by the hypervisor. + The reserved memory region must be compatible with + "arm,ffa-1.0-hypervisor-memory-region". + + [1] Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt + +patternProperties: + "^ffa_partition[0-9]+$": + type: object + description: One or more child nodes, each describing an FFA partition. + properties: + $nodename: + const: ffa_partition + + compatible: + oneOf: + - const: arm,ffa-1.0-partition + + uuid: + $ref: '/schemas/types.yaml#definitions/string' + description: | + The 128-bit UUID [2] of the service implemented by this partition. + + [2] https://tools.ietf.org/html/rfc4122 + + nr-exec-ctxs: + $ref: '/schemas/types.yaml#/definitions/uint32' + description: | + The number of virtual CPUs to instantiate for this partition. + + exec-state: + description: The execution state in which to execute the partition. + oneOf: + - const: "AArch64" + - const: "AArch32" + + entry-point: + $ref: '/schemas/types.yaml#/definitions/uint32-matrix' + description: | + The entry address of the partition specified as an Intermediate + Physical Address (IPA) encoded according to the '#address-cells' + property. + + memory-region: + $ref: '/schemas/types.yaml#/definitions/phandle-array' + description: | + A list of phandles to FFA reserved memory regions [3] for this + partition. + + [3] Documentation/devicetree/bindings/reserved-memory/arm,ffa-memory.yaml + +additionalProperties: false + +examples: + - | + ffa_hyp { + compatible = "arm,ffa-1.0-hypervisor"; + memory-region = <&ffa_hyp_reserved>; + + ffa_partition0 { + compatible = "arm,ffa-1.0-partition"; + uuid = "12345678-9abc-def0-1234-56789abcdef0"; + nr-exec-ctxs = <2>; + exec-state = "AArch64"; + entry-point = <0x80000>; + memory-region = <&ffa_reserved0 &ffa_reserved1>; + }; + }; diff --git a/Documentation/devicetree/bindings/reserved-memory/arm,ffa-memory.yaml b/Documentation/devicetree/bindings/reserved-memory/arm,ffa-memory.yaml new file mode 100644 index 000000000000..5335e07abcfc --- /dev/null +++ b/Documentation/devicetree/bindings/reserved-memory/arm,ffa-memory.yaml @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reserved-memory/arm,ffa-memory.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Memory Region for Arm Firmware Framework for Arm v8-A + +maintainers: + - Will Deacon + +description: | + This binding allows a FF-A implementation to describe the normal memory + regions of a partition [1] to a hypervisor according to [2]. + + The physical address range reserved for the partition can be specified as a + static allocation using the 'reg' property or as a dynamic allocation using + the 'size' property. If both properties are omitted, then the hypervisor can + allocate physical memory for the partition however it sees fit. + + [1] Documentation/devicetree/bindings/arm/arm,ffa.yaml + [2] Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt + +properties: + $nodename: + pattern: "^ffa_mem(@[0-9a-f]+)?$" + + compatible: + oneOf: + - const: arm,ffa-1.0-partition-memory-region + + ipa-range: + $ref: '/schemas/types.yaml#/definitions/uint32-matrix' + description: | + The Intermediate Physical Address (IPA) range (encoded in the same way as + a 'reg' property) at which to map the physical memory. If the IPA range is + larger than the physical memory region then the region is mapped starting + at the base of the IPA range. + + read-only: + type: boolean + description: | + (static allocation only) The memory region has been pre-populated + by the firmware framework and must be mapped without write permission + at stage 2. + + non-executable: + type: boolean + description: | + The memory region must be mapped without execute permission at stage 2. + + +required: + - compatible + +# The "reserved-memory" binding defines additional properties. +additionalProperties: true + +examples: + - | + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + + ffa_reserved0: ffa_mem@100000000 { + compatible = "arm,ffa-1.0-partition-memory-region"; + reg = <0x1 0x0 0x0 0x04000000>; // 64M @ 1GB + ipa-range = <0x0 0x0 0x0 0x04000000>; // 64M @ 0x0 + read-only; + }; + }; From patchwork Sat Aug 29 17:09:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 248708 Delivered-To: patch@linaro.org Received: by 2002:a92:5b9c:0:0:0:0:0 with SMTP id c28csp2036449ilg; Sat, 29 Aug 2020 10:09:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxkGvYs0BhicosdVL0rEriVPluCBmI8cJNX0nx2VZMrxmzd8q+5Y8Z8ZkI2qpuB739EFeWZ X-Received: by 2002:aa7:dd11:: with SMTP id i17mr4059419edv.170.1598720976563; Sat, 29 Aug 2020 10:09:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598720976; cv=none; d=google.com; s=arc-20160816; b=DrrCeh8e6s7t87WxJvfYpAdW2lVc9CaQNXYNghDPZjCCubVbg26RWrbuSKuZmBNKio XJa7iTprtTpkVXtYVreHrMaBI91urY5rEIeJPPNhgQcMQy/LFYWPOeHeNE4k6vmTnhO6 4+jmc2jH6TNw+NCLQzy1nvOTQOALXazPiS9BTWBzrJDLBYxhlT91fKUOLx1WRPwzCs+A BEGsJGhZ5YwGXzOTw9uaUk+WYuDB/fE3A5DB00TtZo3LfnlbZQhxcB4OfpxNrSKYF0y8 7teXhuURARC6N58CJwC6eG9vvYEqQWxYRNSVtcfwrT7yPR/Gt9IKzbqwyVX4OVNueyo4 ZI+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=SCAwU78C+CrukEtYgxn77tLE6Dzyck96+x616GNUj5o=; b=PlGevA1G2gC407kvW0nqflZgEedal6p0AxZYvCqeorAu73V3ZA2+nJN47fxWBrGiPT 8D9nZid4yG4YJd5sMo/dRZfu95UcK7v9b4dPEmg8D9Es2gFNLFXqwY+6u9z6d5fEkJJz MOAxW0RWyjuleOxKYgFEd2BljfRW6o3M5mKYxzA1w1z2C1KYOy9ag8snzP2KLED6/PDK PQ7rB2C3EtheY/OiaFHEmaSl4sfLNNElqID1NwPvZXgODPFXlUiQyRaCh+pZg2o6wM24 M6wLiyMS81E24BWiPcukQdvtMlZObDLzC3xZOGS8iwCQbfFn8jkHigM8+pjtX8G+6M7z Vmwg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d22si1952640edz.234.2020.08.29.10.09.36; Sat, 29 Aug 2020 10:09:36 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728470AbgH2RJf (ORCPT + 6 others); Sat, 29 Aug 2020 13:09:35 -0400 Received: from foss.arm.com ([217.140.110.172]:45040 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728412AbgH2RJf (ORCPT ); Sat, 29 Aug 2020 13:09:35 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 56C2E113E; Sat, 29 Aug 2020 10:09:34 -0700 (PDT) Received: from usa.arm.com (e103737-lin.cambridge.arm.com [10.1.197.49]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 57A6D3F71F; Sat, 29 Aug 2020 10:09:33 -0700 (PDT) From: Sudeep Holla To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Cc: Sudeep Holla , kernel-team@android.com, Will Deacon , tsoni@quicinc.com, pratikp@quicinc.com Subject: [PATCH 2/9] dt-bindings: Arm: Extend FF-A binding to support in-kernel usage of partitions Date: Sat, 29 Aug 2020 18:09:16 +0100 Message-Id: <20200829170923.29949-3-sudeep.holla@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com> References: <20200829170923.29949-1-sudeep.holla@arm.com> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Since the FF-A v1.0 specification doesn't list the UUID of all the partitions in the discovery API, we need to specify the UUID of the partitions that need to be accessed by drivers within the kernel. This extends the binding to provide the list of partitions that kernel drivers may need to access and are not part of the partitions managed by the hypervisor. Signed-off-by: Sudeep Holla --- .../devicetree/bindings/arm/arm,ffa.yaml | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) Hi, I am sure this is incomplete, but I couldn't figure out how to make all the child properties optional if it is not managed by hypervisor. Moreover, if we don't like the idea of adding UUID of all the partitions that in-kernel drivers may need to communicate to, one alternative I can think of is to allow the creation of FFA device from the FFA driver itself. Regards, Sudeep -- 2.17.1 diff --git a/Documentation/devicetree/bindings/arm/arm,ffa.yaml b/Documentation/devicetree/bindings/arm/arm,ffa.yaml index 668a5995fcab..d5c6d71c99de 100644 --- a/Documentation/devicetree/bindings/arm/arm,ffa.yaml +++ b/Documentation/devicetree/bindings/arm/arm,ffa.yaml @@ -23,11 +23,12 @@ description: | properties: $nodename: - const: ffa_hyp + pattern: "^(ffa|ffa_hyp)$" compatible: oneOf: - const: arm,ffa-1.0-hypervisor + - const: arm,ffa-1.0 memory-region: $ref: '/schemas/types.yaml#/definitions/phandle' @@ -83,10 +84,26 @@ description: | [3] Documentation/devicetree/bindings/reserved-memory/arm,ffa-memory.yaml +required: + - compatible + +allOf: + - if: + properties: + compatible: + contains: + const: arm,ffa-1.0-hypervisor + then: + required: + - memory-region + additionalProperties: false examples: - - | + - |+ + + // Case 1: Partitions managed by hypervisor + ffa_hyp { compatible = "arm,ffa-1.0-hypervisor"; memory-region = <&ffa_hyp_reserved>; @@ -100,3 +117,16 @@ additionalProperties: false memory-region = <&ffa_reserved0 &ffa_reserved1>; }; }; + + - |+ + + // Case 2: Partitions needing in-kernel usage + + ffa { + compatible = "arm,ffa-1.0"; + + ffa_partition1 { + compatible = "arm,ffa-1.0-partition"; + uuid = "589fc454-4502-4e66-9347-97b61e27cf73"; + }; + }; From patchwork Sat Aug 29 17:09:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 248709 Delivered-To: patch@linaro.org Received: by 2002:a92:5b9c:0:0:0:0:0 with SMTP id c28csp2036475ilg; Sat, 29 Aug 2020 10:09:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzS9w5b8+NeROssuQd4bsKraFATueA8YSPCMpS9VY1tCVNlbUF2/0ABCNnCl4NaJFqJTobR X-Received: by 2002:a05:6402:31a3:: with SMTP id dj3mr4296081edb.73.1598720979655; Sat, 29 Aug 2020 10:09:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598720979; cv=none; d=google.com; s=arc-20160816; b=qTEjV0nkrU2kAffY/7Oj42xbqr6ZCPeWMKB+4P7/vIsSRvxihqanaMlK6mUfRVtY7F 3GZURZ3NdM/I8zlP4DOXClgCPc7YFfHVMvKNjsm4Ivx/X7Yjk3tjbLE+ggVfz3hd2lk3 o9Sje7B6uTcjmrNXh8NrV5HDRus/+41J1Eaw9Th/Cf0ev24YuOUrlMg6MU7SJfMkGPVd xmaSYduoibvjMoUxlK2j++b0wZPINS1p6PVCUnEL24ecGfB5CRbUSD0Rr9o/s24ztxUN Og8jfwToeDX8GDrVruzCl/V2CSQfFu/WUH1UMU/qWvSqofxHzYn9unBOpKdOCs17bwbQ fTpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=aG5R0CLQP1PqeBkhhy1w2EQ3Ly1dgUxIRshmur6StxQ=; b=sbQLvp8KN0ol6jMkOGXh68wbufFTUMoUuc4iDK5yboOp/6Em76qCqE3qi51EqIt9lZ oNBArEEWrK4mRLlAEeh4L94ut/0YIW+FiN5a8U3LzOthldScNOb2+emOa5e7DET5VHDT GAWJurPB9LV8d7vLO4o/MG92HdCIxgn1nv/uqFxzlL3RJjzsIAGZREE8yFoePW0bSo/Y k8kKZAuGZI3JPezD/iC3knn6KdlOt7y+BmYJgD6hXC3PFFDMUGxXCQCp4tKV4dTmcPR6 8vumvB/apdbhkDuynQxHTDuqRpab6d1yCqmGUCpMoTNOx9+0jXBxsGrvuHce0hCecup8 m67Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d22si1952640edz.234.2020.08.29.10.09.39; Sat, 29 Aug 2020 10:09:39 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728412AbgH2RJh (ORCPT + 6 others); Sat, 29 Aug 2020 13:09:37 -0400 Received: from foss.arm.com ([217.140.110.172]:45052 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728452AbgH2RJg (ORCPT ); Sat, 29 Aug 2020 13:09:36 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 89A6811D4; Sat, 29 Aug 2020 10:09:35 -0700 (PDT) Received: from usa.arm.com (e103737-lin.cambridge.arm.com [10.1.197.49]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8A89F3F71F; Sat, 29 Aug 2020 10:09:34 -0700 (PDT) From: Sudeep Holla To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Cc: Sudeep Holla , kernel-team@android.com, Will Deacon , tsoni@quicinc.com, pratikp@quicinc.com Subject: [PATCH 3/9] arm64: smccc: Add support for SMCCCv1.2 input/output registers Date: Sat, 29 Aug 2020 18:09:17 +0100 Message-Id: <20200829170923.29949-4-sudeep.holla@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com> References: <20200829170923.29949-1-sudeep.holla@arm.com> MIME-Version: 1.0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org SMCCC v1.2 allows x8-x17 to be used as parameter registers and x4—x17 to be used as result registers in SMC64/HVC64. Arm Firmware Framework for Armv8-A specification makes use of x0-x7 as parameter and result registers. Current SMCCC interface in the kernel just use x0-x7 as parameter and x0-x3 as result registers. Let us add new interface to support x0-x7 as parameter and result registers. This can be extended to include x8-x17 when there are users for the same. Signed-off-by: Sudeep Holla --- arch/arm64/kernel/asm-offsets.c | 4 +++ arch/arm64/kernel/smccc-call.S | 22 +++++++++++++++ include/linux/arm-smccc.h | 50 +++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) -- 2.17.1 diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 7d32fc959b1a..32bcc25337ce 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -122,6 +122,10 @@ int main(void) DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id)); DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state)); + DEFINE(ARM_SMCCC_V1_2_RES_X0_OFFS, offsetof(struct arm_smccc_v1_2_res, a0)); + DEFINE(ARM_SMCCC_V1_2_RES_X2_OFFS, offsetof(struct arm_smccc_v1_2_res, a2)); + DEFINE(ARM_SMCCC_V1_2_RES_X4_OFFS, offsetof(struct arm_smccc_v1_2_res, a4)); + DEFINE(ARM_SMCCC_V1_2_RES_X6_OFFS, offsetof(struct arm_smccc_v1_2_res, a6)); BLANK(); DEFINE(HIBERN_PBE_ORIG, offsetof(struct pbe, orig_address)); DEFINE(HIBERN_PBE_ADDR, offsetof(struct pbe, address)); diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S index 1f93809528a4..70e3749b44cf 100644 --- a/arch/arm64/kernel/smccc-call.S +++ b/arch/arm64/kernel/smccc-call.S @@ -45,3 +45,25 @@ SYM_FUNC_START(__arm_smccc_hvc) SMCCC hvc SYM_FUNC_END(__arm_smccc_hvc) EXPORT_SYMBOL(__arm_smccc_hvc) + + .macro SMCCC_v1_2 instr + .cfi_startproc + \instr #0 + ldr x8, [sp] + stp x0, x1, [x8, #ARM_SMCCC_V1_2_RES_X0_OFFS] + stp x2, x3, [x8, #ARM_SMCCC_V1_2_RES_X2_OFFS] + stp x4, x5, [x8, #ARM_SMCCC_V1_2_RES_X4_OFFS] + stp x6, x7, [x8, #ARM_SMCCC_V1_2_RES_X6_OFFS] + ret + .cfi_endproc +.endm + +SYM_FUNC_START(arm_smccc_v1_2_hvc) + SMCCC_v1_2 hvc +SYM_FUNC_END(arm_smccc_v1_2_hvc) +EXPORT_SYMBOL(arm_smccc_v1_2_hvc) + +SYM_FUNC_START(arm_smccc_v1_2_smc) + SMCCC_v1_2 smc +SYM_FUNC_END(arm_smccc_v1_2_smc) +EXPORT_SYMBOL(arm_smccc_v1_2_smc) diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index 15c706fb0a37..b64552076b7e 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -152,6 +152,56 @@ struct arm_smccc_res { unsigned long a3; }; +#ifdef CONFIG_ARM64 +/* TODO Need to implement for ARM too */ +/** + * struct arm_smccc_v1_2_res - Result from SMC/HVC call + * @a0-a3 result values from registers 0 to 3 + */ +struct arm_smccc_v1_2_res { + unsigned long a0; + unsigned long a1; + unsigned long a2; + unsigned long a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long a7; +}; + +/** + * arm_smccc_v1_2_hvc() - make HVC calls + * @a0-a7: arguments passed in registers 0 to 7 + * @res: result values from registers 0 to 7 + * + * This function is used to make SMC calls following SMC Calling Convention + * v1.2 or above. The content of the supplied param are copied to registers + * 0 to 7 prior to the SMC instruction. The return values are updated with + * the content from register 0 to 7 on return from the SMC instruction. + */ +asmlinkage +void arm_smccc_v1_2_hvc(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + unsigned long a6, unsigned long a7, + struct arm_smccc_v1_2_res *res); + +/** + * arm_smccc_v1_2_smc() - make SMC calls + * @a0-a7: arguments passed in registers 0 to 7 + * @res: result values from registers 0 to 7 + * + * This function is used to make SMC calls following SMC Calling Convention + * v1.2 or above. The content of the supplied param are copied to registers + * 0 to 7 prior to the SMC instruction. The return values are updated with + * the content from register 0 to 7 on return from the SMC instruction. + */ +asmlinkage +void arm_smccc_v1_2_smc(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + unsigned long a6, unsigned long a7, + struct arm_smccc_v1_2_res *res); +#endif + /** * struct arm_smccc_quirk - Contains quirk information * @id: quirk identification From patchwork Sat Aug 29 17:09:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 248710 Delivered-To: patch@linaro.org Received: by 2002:a92:5b9c:0:0:0:0:0 with SMTP id c28csp2036495ilg; Sat, 29 Aug 2020 10:09:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzCTHnEBcxgvIyDHZxgXVYEgOxvZAFgaCWASb0fF0wMpuSIoqQkJPCHjxCQwX0guInHCgWi X-Received: by 2002:a17:906:b154:: with SMTP id bt20mr4588555ejb.272.1598720981074; Sat, 29 Aug 2020 10:09:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598720981; cv=none; d=google.com; s=arc-20160816; b=MXerQzEmbAi1AkuWNoyxz4Be1Iy6TPEOqWGqMCN9sQmkIcBWU2/LhQPnIKl2HOvMP1 uGxAvsQ5NTkP8AJ9KkUFspH6ulqSCNKrZFGCo8aK0giWgWFhwLlHFja4eL62TY4wGdpx ei1HYBMFdod368gtQzYzp0wR9rveTL8F+Pi61E/v6BbeIDmK3gNXnpdpSZEgQUD1oTOy YP+YDI5WTRZs/fGtt74b832DuOt7JatSFeRipHWFR44ectIf7pU6Y3Tobm6IRbJBdixx 9F0SUUCHIpOV9YdumFrz6J1R/qlortEAUc7tYN6Rhixh53hoJFFW+PNWOA/7Q0rXDa3u z+Lg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=ehYUy6Pl7rY9/D/wDTfln1hEHsokMRc4S0J5jKUED9I=; b=Gzi2JeCzdI2Cto0asr/wC/pQeFCdB3lH6rre4B/fQvPsRgxwBqOXFOQuRmgCxOgxcQ g1dBEK4Lq6PIQKVr+WifSS7I6eoVh6MOefRQM/36bD4o2xvUBbANbXJ92zN+ieKNsCKA N1dC4VK2rwZxLUOGp2jn2WFrdrjyylD8zIzyXaWxjI9BwY+PPkclwmPIf122do/llwXN 0NSOl95Bju//qKcIKX1tuRnMvecClALspIhkhdbtF1tzZvVygBB6PCfpY9OYWX4NJYYS EB9vvjWxqn1l/0os6SH43ry06p4+2q2LVlr8SWJ78XoEDgzUpCVg8GynJNU6KurA09ru CAYA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d22si1952640edz.234.2020.08.29.10.09.40; Sat, 29 Aug 2020 10:09:41 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728439AbgH2RJi (ORCPT + 6 others); Sat, 29 Aug 2020 13:09:38 -0400 Received: from foss.arm.com ([217.140.110.172]:45064 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728471AbgH2RJh (ORCPT ); Sat, 29 Aug 2020 13:09:37 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C623712FC; Sat, 29 Aug 2020 10:09:36 -0700 (PDT) Received: from usa.arm.com (e103737-lin.cambridge.arm.com [10.1.197.49]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id BD77E3F71F; Sat, 29 Aug 2020 10:09:35 -0700 (PDT) From: Sudeep Holla To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Cc: Sudeep Holla , kernel-team@android.com, Will Deacon , tsoni@quicinc.com, pratikp@quicinc.com Subject: [PATCH 4/9] firmware: smccc: export both smccc functions Date: Sat, 29 Aug 2020 18:09:18 +0100 Message-Id: <20200829170923.29949-5-sudeep.holla@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com> References: <20200829170923.29949-1-sudeep.holla@arm.com> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org We need to export both arm_smccc_1_1_get_conduit and arm_smccc_get_version to allow Arm FFA modules make use of them. Let us export them in preparation to add support for Arm FFA modules. Signed-off-by: Sudeep Holla --- drivers/firmware/smccc/smccc.c | 2 ++ 1 file changed, 2 insertions(+) -- 2.17.1 diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c index 4e80921ee212..00c88b809c0c 100644 --- a/drivers/firmware/smccc/smccc.c +++ b/drivers/firmware/smccc/smccc.c @@ -24,8 +24,10 @@ enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void) return smccc_conduit; } +EXPORT_SYMBOL_GPL(arm_smccc_1_1_get_conduit); u32 arm_smccc_get_version(void) { return smccc_version; } +EXPORT_SYMBOL_GPL(arm_smccc_get_version); From patchwork Sat Aug 29 17:09:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 248711 Delivered-To: patch@linaro.org Received: by 2002:a92:5b9c:0:0:0:0:0 with SMTP id c28csp2036513ilg; Sat, 29 Aug 2020 10:09:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzxNjIj2SZIa89BBPy+K4kVEYgs22JbrxFlFcWuThRigVdUcX0To/mMKYqv+kxe866dCYUe X-Received: by 2002:aa7:d85a:: with SMTP id f26mr4185855eds.363.1598720982947; Sat, 29 Aug 2020 10:09:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598720982; cv=none; d=google.com; s=arc-20160816; b=vtUMaT30FPuh+bak2JnyrMmkJ6puNy9HCFmkIGqRob3HfyDOt8NB2sRpJtP3UuakFu qgDDxPJ8awztaP6EOnO4z0HrXy1XM2wZNI53/eMHxXH7CLuXNfLNrxiLvVPrTHndhDvn 0VhAO/3IJlzy4KKNPP98AxcdqxnJRuB8KmNSvCbo5cMGutkdCfERI5jKDf3LRGNnb/BF dp/x4JILXSMQwr2jNzVK2f+TXslUWPVZlw2lnDp/dih8tSmqfrU65nfzcXLS+5yEWA52 LGCOMnDNP2PUrLnheyBi9xjO1OjvVPJCawgzMCPWlFtOO57+TOXNOK65hpvVzUjrnjT5 zoiA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=8pgxkTPCc4fcclVwiFK3UjmA3GR/+BzKd7x/O15WjIE=; b=VohnlFp87GY0BhrvgClAgykvcNt5Duv92VV8yzimFnKcWCFp6naCZfWSj+FfWwf8/q kCvGL8J4VJzaB3ByrfndH8p5jWHThwn5hObXmcAtwyP3PiGHJTaPq2dyTTpLrg2k0CJ/ lD55BB4OrCIyxVHL/fIyFMpkFUnB2l6Xe6CQ20QkWRIlOlJqXON4QeS14FFO6v6u50Zb /LToCHYgLtmg/egJrLx42pB0eoydD4xJzEZy0cKAoUuTUs8IAPiJnbT+6R3lBHIjfIEf Y0OugeVIgIYYOaIo2Or5q64vwxaOYs8Otl2DZt5py6C8GcyubbZ9VD7XOvFuRhH19Yg+ wxgg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d22si1952640edz.234.2020.08.29.10.09.42; Sat, 29 Aug 2020 10:09:42 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728478AbgH2RJl (ORCPT + 6 others); Sat, 29 Aug 2020 13:09:41 -0400 Received: from foss.arm.com ([217.140.110.172]:45080 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728472AbgH2RJj (ORCPT ); Sat, 29 Aug 2020 13:09:39 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0525D1396; Sat, 29 Aug 2020 10:09:38 -0700 (PDT) Received: from usa.arm.com (e103737-lin.cambridge.arm.com [10.1.197.49]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 05FDD3F71F; Sat, 29 Aug 2020 10:09:36 -0700 (PDT) From: Sudeep Holla To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Cc: Sudeep Holla , kernel-team@android.com, Will Deacon , tsoni@quicinc.com, pratikp@quicinc.com Subject: [PATCH 5/9] firmware: arm_ffa: Add initial FFA bus support for device enumeration Date: Sat, 29 Aug 2020 18:09:19 +0100 Message-Id: <20200829170923.29949-6-sudeep.holla@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com> References: <20200829170923.29949-1-sudeep.holla@arm.com> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The Arm FF for Armv8-A specification has concept of endpoints or partitions. In the Normal world, a partition could be a VM when the Virtualization extension is enabled or the kernel itself. In order to handle multiple partitions, we can create a FFA device for each partition on a dedicated FFA bus. Similarly, different drivers requiring FFA transport can be registered on the same bus. We can match the device and drivers using UUID. This is mostly for the in-kernel users with FFA drivers. However, to support usage of FFA transport from user-space, there is also a provision to create character device interface for the same. Signed-off-by: Sudeep Holla --- drivers/firmware/Kconfig | 1 + drivers/firmware/Makefile | 1 + drivers/firmware/arm_ffa/Kconfig | 16 +++ drivers/firmware/arm_ffa/Makefile | 3 + drivers/firmware/arm_ffa/bus.c | 193 ++++++++++++++++++++++++++++++ include/linux/arm_ffa.h | 81 +++++++++++++ 6 files changed, 295 insertions(+) create mode 100644 drivers/firmware/arm_ffa/Kconfig create mode 100644 drivers/firmware/arm_ffa/Makefile create mode 100644 drivers/firmware/arm_ffa/bus.c create mode 100644 include/linux/arm_ffa.h -- 2.17.1 diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index fbd785dd0513..8660014e9ec7 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -296,6 +296,7 @@ config TURRIS_MOX_RWTM other manufacturing data and also utilize the Entropy Bit Generator for hardware random number generation. +source "drivers/firmware/arm_ffa/Kconfig" source "drivers/firmware/broadcom/Kconfig" source "drivers/firmware/google/Kconfig" source "drivers/firmware/efi/Kconfig" diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 99510be9f5ed..cd990d411f89 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o obj-$(CONFIG_TURRIS_MOX_RWTM) += turris-mox-rwtm.o +obj-y += arm_ffa/ obj-$(CONFIG_ARM_SCMI_PROTOCOL) += arm_scmi/ obj-y += broadcom/ obj-y += meson/ diff --git a/drivers/firmware/arm_ffa/Kconfig b/drivers/firmware/arm_ffa/Kconfig new file mode 100644 index 000000000000..261a3660650a --- /dev/null +++ b/drivers/firmware/arm_ffa/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only +config ARM_FFA_TRANSPORT + tristate "Arm Firmware Framework for Armv8-A" + depends on OF + depends on ARM64 + default n + help + This Firmware Framework(FF) for Arm A-profile processors describes + interfaces that standardize communication between the various + software images which includes communication between images in + the Secure world and Normal world. It also leverages the + virtualization extension to isolate software images provided + by an ecosystem of vendors from each other. + + This driver provides interface for all the client drivers making + use of the features offered by ARM FF-A. diff --git a/drivers/firmware/arm_ffa/Makefile b/drivers/firmware/arm_ffa/Makefile new file mode 100644 index 000000000000..fadb325ee888 --- /dev/null +++ b/drivers/firmware/arm_ffa/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_ARM_FFA_TRANSPORT) = ffa-bus.o +ffa-bus-y = bus.o diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c new file mode 100644 index 000000000000..b5789bd4dfcd --- /dev/null +++ b/drivers/firmware/arm_ffa/bus.c @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 ARM Ltd. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "arm_ffa" +#define FFA_MAX_CDEVS 32 + +static DEFINE_IDA(ffa_dev_id); +static dev_t ffa_devt; + +static int ffa_device_match(struct device *dev, struct device_driver *drv) +{ + const struct ffa_device_id *id_table; + struct ffa_device *ffa_dev; + + id_table = to_ffa_driver(drv)->id_table; + ffa_dev = to_ffa_dev(dev); + + while (!uuid_is_null(&id_table->uuid)) { + if (uuid_equal(&ffa_dev->uuid, &id_table->uuid)) + return 1; + id_table++; + } + + return 0; +} + +static int ffa_device_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + uuid_t *dev_id = &to_ffa_dev(dev)->uuid; + + return add_uevent_var(env, "MODALIAS=arm_ffa:%pUb", dev_id); +} + +struct bus_type ffa_bus_type = { + .name = "arm_ffa", + .match = ffa_device_match, + .uevent = ffa_device_uevent, +}; +EXPORT_SYMBOL_GPL(ffa_bus_type); + +int ffa_driver_register(struct ffa_driver *driver, struct module *owner, + const char *mod_name) +{ + int ret; + + driver->driver.bus = &ffa_bus_type; + driver->driver.name = driver->name; + driver->driver.owner = owner; + driver->driver.mod_name = mod_name; + + ret = driver_register(&driver->driver); + if (!ret) + pr_debug("registered new ffa driver %s\n", driver->name); + + return ret; +} +EXPORT_SYMBOL_GPL(ffa_driver_register); + +void ffa_driver_unregister(struct ffa_driver *driver) +{ + driver_unregister(&driver->driver); +} +EXPORT_SYMBOL_GPL(ffa_driver_unregister); + +static void ffa_release_device(struct device *dev) +{ + struct ffa_device *ffa_dev = to_ffa_dev(dev); + + kfree(ffa_dev); +} + +static int __ffa_devices_unregister(struct device *dev, void *data) +{ + ffa_release_device(dev); + + return 0; +} + +static void ffa_devices_unregister(void) +{ + bus_for_each_dev(&ffa_bus_type, NULL, NULL, + __ffa_devices_unregister); +} + +static char * +ffa_devnode(struct device *dev, umode_t *mode, kuid_t *uid, kgid_t *gid) +{ + return kasprintf(GFP_KERNEL, DEVICE_NAME "/%s", dev_name(dev)); +} + +static struct device_type ffa_dev_type = { + .devnode = ffa_devnode, +}; + +int ffa_device_register(struct ffa_device *ffa_dev) +{ + int ret; + struct cdev *cdev; + struct device *dev; + + if (!ffa_dev) + return -EINVAL; + + dev = &ffa_dev->dev; + cdev = &ffa_dev->cdev; + + dev->bus = &ffa_bus_type; + dev->type = &ffa_dev_type; + dev->release = ffa_release_device; + + device_initialize(dev); + + if (cdev->ops) { + ret = ida_simple_get(&ffa_dev_id, 0, FFA_MAX_CDEVS, GFP_KERNEL); + if (ret < 0) { + put_device(dev); + return ret; + } + + dev->devt = MKDEV(MAJOR(ffa_devt), ret); + + cdev->owner = cdev->ops->owner; + } + + ret = cdev_device_add(cdev, dev); + if (ret) { + dev_err(dev, "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n", + dev_name(dev), MAJOR(dev->devt), MINOR(dev->devt), + ret); + put_device(dev); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ffa_device_register); + +void ffa_device_unregister(struct ffa_device *ffa_dev) +{ + if (!ffa_dev) + return; + + cdev_device_del(&ffa_dev->cdev, &ffa_dev->dev); + + put_device(&ffa_dev->dev); +} +EXPORT_SYMBOL_GPL(ffa_device_unregister); + +static int __init arm_ffa_bus_init(void) +{ + int ret; + + ret = alloc_chrdev_region(&ffa_devt, 0, FFA_MAX_CDEVS, DEVICE_NAME); + if (ret) { + pr_err("failed to allocate char dev region\n"); + return ret; + } + + ret = bus_register(&ffa_bus_type); + if (ret) { + pr_err("ffa bus register failed (%d)\n", ret); + unregister_chrdev_region(ffa_devt, FFA_MAX_CDEVS); + } + + return ret; +} +subsys_initcall(arm_ffa_bus_init); + +static void __exit arm_ffa_bus_exit(void) +{ + ffa_devices_unregister(); + bus_unregister(&ffa_bus_type); + unregister_chrdev_region(ffa_devt, FFA_MAX_CDEVS); +} + +module_exit(arm_ffa_bus_exit); + +MODULE_ALIAS("arm-ffa-bus"); +MODULE_AUTHOR("Sudeep Holla "); +MODULE_DESCRIPTION("Arm FF-A bus driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h new file mode 100644 index 000000000000..2fe16176149f --- /dev/null +++ b/include/linux/arm_ffa.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 ARM Ltd. + */ + +#ifndef _LINUX_ARM_FFA_H +#define _LINUX_ARM_FFA_H + +#include +#include +#include +#include +#include + +struct ffa_device { + u32 vm_id; + uuid_t uuid; + struct device dev; + struct cdev cdev; +}; + +#define to_ffa_dev(d) container_of(d, struct ffa_device, dev) + +struct ffa_device_id { + uuid_t uuid; +}; + +struct ffa_driver { + const char *name; + int (*probe)(struct ffa_device *sdev); + void (*remove)(struct ffa_device *sdev); + const struct ffa_device_id *id_table; + + struct device_driver driver; +}; + +#define to_ffa_driver(d) container_of(d, struct ffa_driver, driver) + +#if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT) +int ffa_device_register(struct ffa_device *ffa_dev); +void ffa_device_unregister(struct ffa_device *ffa_dev); +int ffa_driver_register(struct ffa_driver *driver, struct module *owner, + const char *mod_name); +void ffa_driver_unregister(struct ffa_driver *driver); + +#else +static inline int ffa_device_register(struct ffa_device *ffa_dev) +{ + return -EINVAL; +} + +static inline void ffa_device_unregister(struct ffa_device *dev) {} + +static inline int +ffa_driver_register(struct ffa_driver *driver, struct module *owner, + const char *mod_name) +{ + return -EINVAL; +} + +static inline void ffa_driver_unregister(struct ffa_driver *driver) {} + +#endif /* CONFIG_ARM_FFA_TRANSPORT */ + +#define ffa_register(driver) \ + ffa_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) +#define ffa_unregister(driver) \ + ffa_driver_unregister(driver) + +/** + * module_ffa_driver() - Helper macro for registering a psa_ffa driver + * @__ffa_driver: ffa_driver structure + * + * Helper macro for psa_ffa drivers to set up proper module init / exit + * functions. Replaces module_init() and module_exit() and keeps people from + * printing pointless things to the kernel log when their driver is loaded. + */ +#define module_ffa_driver(__ffa_driver) \ + module_driver(__ffa_driver, ffa_register, ffa_unregister) + +#endif /* _LINUX_ARM_FFA_H */ From patchwork Sat Aug 29 17:09:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 248713 Delivered-To: patch@linaro.org Received: by 2002:a92:5b9c:0:0:0:0:0 with SMTP id c28csp2036515ilg; Sat, 29 Aug 2020 10:09:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy0fGJFueJIr3mgsRTKsOICvqhved/YSlzYoaZ/wJy7Y4C7/6ICUZ+JTtdP42+D1gqY6pE6 X-Received: by 2002:a17:906:3ac4:: with SMTP id z4mr4113399ejd.65.1598720983340; Sat, 29 Aug 2020 10:09:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598720983; cv=none; d=google.com; s=arc-20160816; b=s50h8wF3N9a63Z1baVOEiJWfN/qce0AXu8/zt3GtPsEQgW6LL2aTrU8X4ry2thTMwT XKoJ5ge5xlZ8itGJX8m8nBJMqC6hq5CjMHoQpZkLZtwRjyemR7jKr+xERhgVuOPIvmLr Zvcl40S9B1kQa8huDnm1G8egtxnWEbgFZcG/Wuja2/Id+5OHbWBNuTI69ShKf1XPh19T Yla86tHka4myvWJXu6OUbSW4sAvJkr/eovX17BG9p0mbWMfETV5x2tswC5jpjuRv3yR/ /38/M/6ffA4usKbOAUx1ZA4FfOXJCo4ijmGz77UaWfLP/FNgqtPcZutUBA7KeD7QpU0S qqvQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=QuWeDsYk0B5s9ftFU4jsVMLgDVtijdqXpbxF8lsgyQw=; b=r78X2zTD5s2y2719Fl/+iUmRTHOOoI/OoiD9UvCVYh6uUgeZiC1W3HSRn9txw7Mma/ Pgklso8N1TdJCezlWJEIJ5ghYwALnMjFHKqpKAYz+3e6zdqwLmsyHrE8VnNHD68t0YJQ b7dIZcSzwi+nb1JZ4+cnX0cmhisNqgiqGr96rQzSXfHShekJihdkZlheiOFUpCkb/RCh 9tD2mQKY6vjI4n1g/dWAyJaoL1PFbKXL94fpWj3Qb82qkosx8OvbrXl0EcZjLk5ylAkR S3q3mAY2bpF00b7QfcikcRmKGhYQjHVWFz+s8qD0XbJHOoKo+ACC8uvdIcAQvsrUeXVs wW2Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d22si1952640edz.234.2020.08.29.10.09.43; Sat, 29 Aug 2020 10:09:43 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728472AbgH2RJm (ORCPT + 6 others); Sat, 29 Aug 2020 13:09:42 -0400 Received: from foss.arm.com ([217.140.110.172]:45064 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728452AbgH2RJk (ORCPT ); Sat, 29 Aug 2020 13:09:40 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 38C0B142F; Sat, 29 Aug 2020 10:09:39 -0700 (PDT) Received: from usa.arm.com (e103737-lin.cambridge.arm.com [10.1.197.49]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 393263F71F; Sat, 29 Aug 2020 10:09:38 -0700 (PDT) From: Sudeep Holla To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Cc: Sudeep Holla , kernel-team@android.com, Will Deacon , tsoni@quicinc.com, pratikp@quicinc.com Subject: [PATCH 6/9] firmware: arm_ffa: Add initial Arm FFA driver support Date: Sat, 29 Aug 2020 18:09:20 +0100 Message-Id: <20200829170923.29949-7-sudeep.holla@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com> References: <20200829170923.29949-1-sudeep.holla@arm.com> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This just add a basic driver that sets up the transport(e.g. SMCCC), checks the FFA version implemented, get the partition ID for self and sets up the Tx/Rx buffers for communication. Signed-off-by: Sudeep Holla --- drivers/firmware/arm_ffa/Makefile | 3 +- drivers/firmware/arm_ffa/common.h | 23 +++ drivers/firmware/arm_ffa/driver.c | 288 ++++++++++++++++++++++++++++++ 3 files changed, 313 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/arm_ffa/common.h create mode 100644 drivers/firmware/arm_ffa/driver.c -- 2.17.1 diff --git a/drivers/firmware/arm_ffa/Makefile b/drivers/firmware/arm_ffa/Makefile index fadb325ee888..1a9bd2bf8752 100644 --- a/drivers/firmware/arm_ffa/Makefile +++ b/drivers/firmware/arm_ffa/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_ARM_FFA_TRANSPORT) = ffa-bus.o +obj-$(CONFIG_ARM_FFA_TRANSPORT) = ffa-bus.o ffa-driver.o ffa-bus-y = bus.o +ffa-driver-y = driver.o diff --git a/drivers/firmware/arm_ffa/common.h b/drivers/firmware/arm_ffa/common.h new file mode 100644 index 000000000000..720c8425dfd6 --- /dev/null +++ b/drivers/firmware/arm_ffa/common.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 ARM Ltd. + */ + +#ifndef _FFA_COMMON_H +#define _FFA_COMMON_H + +#include +#include + +typedef struct arm_smccc_v1_2_res ffa_res_t; + +typedef ffa_res_t +(ffa_fn)(unsigned long, unsigned long, unsigned long, unsigned long, + unsigned long, unsigned long, unsigned long, unsigned long); + +static inline int __init ffa_transport_init(ffa_fn **invoke_ffa_fn) +{ + return -EOPNOTSUPP; +} + +#endif /* _FFA_COMMON_H */ diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c new file mode 100644 index 000000000000..3670ba400f89 --- /dev/null +++ b/drivers/firmware/arm_ffa/driver.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Arm Firmware Framework for ARMv8-A(FFA) interface driver + * + * The Arm FFA specification[1] describes a software architecture to + * leverages the virtualization extension to isolate software images + * provided by an ecosystem of vendors from each other and describes + * interfaces that standardize communication between the various software + * images including communication between images in the Secure world and + * Normal world. Any Hypervisor could use the FFA interfaces to enable + * communication between VMs it manages. + * + * The Hypervisor a.k.a Partition managers in FFA terminology can assign + * system resources(Memory regions, Devices, CPU cycles) to the partitions + * and manage isolation amongst them. + * + * [1] https://developer.arm.com/docs/den0077/latest + * + * Copyright (C) 2020 Arm Ltd. + */ + +#define DRIVER_NAME "ARM FF-A" +#define pr_fmt(fmt) DRIVER_NAME ": " fmt + +#include +#include +#include +#include +#include + +#include "common.h" + +#define FFA_SMC(calling_convention, func_num) \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, (calling_convention), \ + ARM_SMCCC_OWNER_STANDARD, (func_num)) + +#define FFA_SMC_32(func_num) FFA_SMC(ARM_SMCCC_SMC_32, (func_num)) +#define FFA_SMC_64(func_num) FFA_SMC(ARM_SMCCC_SMC_64, (func_num)) + +#define FFA_ERROR FFA_SMC_32(0x60) +#define FFA_SUCCESS FFA_SMC_32(0x61) +#define FFA_INTERRUPT FFA_SMC_32(0x62) +#define FFA_VERSION FFA_SMC_32(0x63) +#define FFA_FEATURES FFA_SMC_32(0x64) +#define FFA_RX_RELEASE FFA_SMC_32(0x65) +#define FFA_RXTX_MAP FFA_SMC_32(0x66) +#define FFA_RXTX_UNMAP FFA_SMC_32(0x67) +#define FFA_PARTITION_INFO_GET FFA_SMC_32(0x68) +#define FFA_ID_GET FFA_SMC_32(0x69) +#define FFA_MSG_POLL FFA_SMC_32(0x6A) +#define FFA_MSG_WAIT FFA_SMC_32(0x6B) +#define FFA_YIELD FFA_SMC_32(0x6C) +#define FFA_RUN FFA_SMC_32(0x6D) +#define FFA_MSG_SEND FFA_SMC_32(0x6E) +#define FFA_MSG_SEND_DIRECT_REQ FFA_SMC_32(0x6F) +#define FFA_FN64_MSG_SEND_DIRECT_REQ FFA_SMC_64(0x6F) +#define FFA_MSG_SEND_DIRECT_RESP FFA_SMC_32(0x70) +#define FFA_FN64_MSG_SEND_DIRECT_RESP FFA_SMC_64(0x70) +#define FFA_MEM_DONATE FFA_SMC_32(0x71) +#define FFA_FN64_MEM_DONATE FFA_SMC_32(0x71) +#define FFA_MEM_LEND FFA_SMC_32(0x72) +#define FFA_FN64_MEM_LEND FFA_SMC_32(0x72) +#define FFA_MEM_SHARE FFA_SMC_32(0x73) +#define FFA_FN64_MEM_SHARE FFA_SMC_64(0x73) +#define FFA_MEM_RETRIEVE_REQ FFA_SMC_32(0x74) +#define FFA_FN64_MEM_RETRIEVE_REQ FFA_SMC_64(0x74) +#define FFA_MEM_RETRIEVE_RESP FFA_SMC_32(0x75) +#define FFA_MEM_RELINQUISH FFA_SMC_32(0x76) +#define FFA_MEM_RECLAIM FFA_SMC_32(0x77) +#define FFA_MEM_OP_PAUSE FFA_SMC_32(0x78) +#define FFA_MEM_OP_RESUME FFA_SMC_32(0x79) +#define FFA_MEM_FRAG_RX FFA_SMC_32(0x7A) +#define FFA_MEM_FRAG_TX FFA_SMC_32(0x7B) +#define FFA_NORMAL_WORLD_RESUME FFA_SMC_32(0x7C) + +/* + * For some calls it is necessary to use SMC64 to pass or return 64-bit values. + * For such calls FFA_FN_NATIVE(name) will choose the appropriate + * (native-width) function ID. + */ +#ifdef CONFIG_64BIT +#define FFA_FN_NATIVE(name) FFA_FN64_##name +#else +#define FFA_FN_NATIVE(name) FFA_##name +#endif + +/* FFA error codes. */ +#define FFA_RET_SUCCESS (0) +#define FFA_RET_NOT_SUPPORTED (-1) +#define FFA_RET_INVALID_PARAMETERS (-2) +#define FFA_RET_NO_MEMORY (-3) +#define FFA_RET_BUSY (-4) +#define FFA_RET_INTERRUPTED (-5) +#define FFA_RET_DENIED (-6) +#define FFA_RET_RETRY (-7) +#define FFA_RET_ABORTED (-8) + +#define MAJOR_VERSION_MASK GENMASK(30, 16) +#define MINOR_VERSION_MASK GENMASK(15, 0) +#define MAJOR_VERSION(x) (u16)(FIELD_GET(MAJOR_VERSION_MASK, (x))) +#define MINOR_VERSION(x) (u16)(FIELD_GET(MINOR_VERSION_MASK, (x))) +#define PACK_VERSION_INFO(major, minor) \ + (FIELD_PREP(MAJOR_VERSION_MASK, (major)) | \ + FIELD_PREP(MINOR_VERSION_MASK, (minor))) +#define FFA_VERSION_1_0 PACK_VERSION_INFO(1, 0) +#define FFA_MIN_VERSION FFA_VERSION_1_0 +#define FFA_DRIVER_VERSION FFA_VERSION_1_0 + +#define SENDER_ID_MASK GENMASK(31, 16) +#define RECEIVER_ID_MASK GENMASK(15, 0) +#define SENDER_ID(x) (u16)(FIELD_GET(SENDER_ID_MASK, (x))) +#define RECEIVER_ID(x) (u16)(FIELD_GET(RECEIVER_ID_MASK, (x))) +#define PACK_TARGET_INFO(s, r) \ + (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r))) + +/** + * FF-A specification mentions explicitly about '4K pages'. This should + * not be confused with the kernel PAGE_SIZE, which is the translation + * granule kernel is configured and may be one among 4K, 16K and 64K. + */ +#define FFA_PAGE_SIZE SZ_4K +/* Keeping RX TX buffer size as 64K for now */ +#define RXTX_BUFFER_SIZE SZ_64K + +static ffa_fn *invoke_ffa_fn; + +static const int ffa_linux_errmap[] = { + /* better than switch case as long as return value is continuous */ + 0, /* FFA_RET_SUCCESS */ + -EOPNOTSUPP, /* FFA_RET_NOT_SUPPORTED */ + -EINVAL, /* FFA_RET_INVALID_PARAMETERS */ + -ENOMEM, /* FFA_RET_NO_MEMORY */ + -EBUSY, /* FFA_RET_BUSY */ + -EINTR, /* FFA_RET_INTERRUPTED */ + -EACCES, /* FFA_RET_DENIED */ + -EAGAIN, /* FFA_RET_RETRY */ + -ECANCELED, /* FFA_RET_ABORTED */ +}; + +static inline int ffa_to_linux_errno(int errno) +{ + if (errno < FFA_RET_SUCCESS && errno >= FFA_RET_ABORTED) + return ffa_linux_errmap[-errno]; + return -EINVAL; +} + +struct ffa_drv_info { + u32 version; + u16 vm_id; + struct mutex rx_lock; /* lock to protect Rx buffer */ + struct mutex tx_lock; /* lock to protect Tx buffer */ + void *rx_buffer; + void *tx_buffer; +}; + +static struct ffa_drv_info *drv_info; + +static int ffa_version_check(u32 *version) +{ + ffa_res_t ver; + + ver = invoke_ffa_fn(FFA_VERSION, FFA_DRIVER_VERSION, 0, 0, 0, 0, 0, 0); + + if (ver.a0 == FFA_RET_NOT_SUPPORTED) { + pr_info("FFA_VERSION returned not supported\n"); + return -EOPNOTSUPP; + } + + if (ver.a0 < FFA_MIN_VERSION || ver.a0 > FFA_DRIVER_VERSION) { + pr_err("Incompatible version %d.%d found\n", + MAJOR_VERSION(ver.a0), MINOR_VERSION(ver.a0)); + return -EINVAL; + } + + *version = ver.a0; + pr_info("Version %d.%d found\n", MAJOR_VERSION(ver.a0), + MINOR_VERSION(ver.a0)); + return 0; +} + +static int ffa_rxtx_map(phys_addr_t tx_buf, phys_addr_t rx_buf, u32 pg_cnt) +{ + ffa_res_t ret; + + ret = invoke_ffa_fn(FFA_RXTX_MAP, tx_buf, rx_buf, pg_cnt, 0, 0, 0, 0); + + if (ret.a0 == FFA_ERROR) + return ffa_to_linux_errno((int)ret.a2); + + return 0; +} + +static int ffa_rxtx_unmap(u16 vm_id) +{ + ffa_res_t ret; + + ret = invoke_ffa_fn(FFA_RXTX_UNMAP, vm_id, 0, 0, 0, 0, 0, 0); + + if (ret.a0 == FFA_ERROR) + return ffa_to_linux_errno((int)ret.a2); + + return 0; +} + +#define VM_ID_MASK GENMASK(15, 0) +static int ffa_id_get(u16 *vm_id) +{ + ffa_res_t id; + + id = invoke_ffa_fn(FFA_ID_GET, 0, 0, 0, 0, 0, 0, 0); + + if (id.a0 == FFA_ERROR) + return ffa_to_linux_errno((int)id.a2); + + *vm_id = FIELD_GET(VM_ID_MASK, (id.a2)); + + return 0; +} + +static int __init ffa_init(void) +{ + int ret; + + ret = ffa_transport_init(&invoke_ffa_fn); + if (ret) + return ret; + + drv_info = kzalloc(sizeof(*drv_info), GFP_KERNEL); + if (!drv_info) + return -ENOMEM; + + ret = ffa_version_check(&drv_info->version); + if (ret) + goto free_drv_info; + + if (ffa_id_get(&drv_info->vm_id)) { + pr_err("failed to obtain VM id for self\n"); + ret = -ENODEV; + goto free_drv_info; + } + + drv_info->rx_buffer = alloc_pages_exact(RXTX_BUFFER_SIZE, GFP_KERNEL); + if (!drv_info->rx_buffer) { + ret = -ENOMEM; + goto free_pages; + } + + drv_info->tx_buffer = alloc_pages_exact(RXTX_BUFFER_SIZE, GFP_KERNEL); + if (!drv_info->tx_buffer) { + ret = -ENOMEM; + goto free_pages; + } + + ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer), + virt_to_phys(drv_info->rx_buffer), + RXTX_BUFFER_SIZE / FFA_PAGE_SIZE); + if (ret) { + pr_err("failed to register FFA RxTx buffers\n"); + goto free_pages; + } + + mutex_init(&drv_info->rx_lock); + mutex_init(&drv_info->tx_lock); + + return 0; +free_pages: + if (drv_info->tx_buffer) + free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE); + free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE); +free_drv_info: + kfree(drv_info); + return ret; +} +module_init(ffa_init); + +static void __exit ffa_exit(void) +{ + ffa_rxtx_unmap(drv_info->vm_id); + free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE); + free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE); + kfree(drv_info); +} +module_exit(ffa_exit); + +MODULE_ALIAS("arm-ffa"); +MODULE_AUTHOR("Sudeep Holla "); +MODULE_DESCRIPTION("Arm FF-A interface driver"); +MODULE_LICENSE("GPL v2"); From patchwork Sat Aug 29 17:09:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 248712 Delivered-To: patch@linaro.org Received: by 2002:a92:5b9c:0:0:0:0:0 with SMTP id c28csp2036519ilg; Sat, 29 Aug 2020 10:09:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwQD8ONdah7HlKSfGM9uwMYLNnVVj66+uFyp782aiZ/4rKDoTW/PVSrGi5Ky/eSrtUjjvT9 X-Received: by 2002:a50:baa2:: with SMTP id x31mr4217144ede.330.1598720983701; Sat, 29 Aug 2020 10:09:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598720983; cv=none; d=google.com; s=arc-20160816; b=fFn08uzaKt94rYEVjWCgGfhebhZHIh6a0J3cj64Wm09WldESvB7jn7vul8rj9EHlrZ +Il0Xq9V2qxiFvTGQY0aS6GW4jZMNDBnjottjAWYxe+T8HeMsaAHWA8y3Pd1J8gOnS34 4hfcZlE8ru4MPZun32s0R92z/LmnqfRELBRuZcOp/wTqV4BQlQ0ZVs83wLmu3gEtfbwd DaJ7f+PTZHjpc2yvrJw1ElSiptZZPe8wn95fIqNwjPcAYrLuiYWH7CdA39uQozvCe4Zg o92ZSkCL/fRdv9vMeHWkPaDQfZCgopNNN7J9iFRirVEqaoOOOJDtTUzA2M67vaM6NR3B y1BA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=YS45i5rS1zi9yAF6f/keE5LumxRlaU7YQuvk4gcY80o=; b=VkLxGFl45jR80512CWUg6F7yuZ3Sbkcmtx1PjiDzftcot+7RXwJ583AmvcJVmk0lwm EuWYxJ3pi/5SFQxObKAjvISX3lHlJNalyazxMdVopQTM0UqwN6CBeiXUxd9DlivnvnpC Rp1JMfZfMjaCXxf+ARHr3fM3dhtSoSPwDuKjlMQAwdcffQVAejbBG8xFWBAksawWxn8s hxCcHdqCOg7G1jFshDq9Sm7Vn8Bx4GZ/1eH40x7mAFH+6lSbDiyvdJ4IMxIyn1NFcd09 UU4dFQKbWtSn8Qy2X84gW43nxXgJzgoqPPaD2b+NEgpzZndHIXbRkUiAGwcwEm2oU26w 3wVQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d22si1952640edz.234.2020.08.29.10.09.43; Sat, 29 Aug 2020 10:09:43 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728452AbgH2RJm (ORCPT + 6 others); Sat, 29 Aug 2020 13:09:42 -0400 Received: from foss.arm.com ([217.140.110.172]:45100 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728471AbgH2RJl (ORCPT ); Sat, 29 Aug 2020 13:09:41 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6C0A7101E; Sat, 29 Aug 2020 10:09:40 -0700 (PDT) Received: from usa.arm.com (e103737-lin.cambridge.arm.com [10.1.197.49]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 6CCBA3F71F; Sat, 29 Aug 2020 10:09:39 -0700 (PDT) From: Sudeep Holla To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Cc: Sudeep Holla , kernel-team@android.com, Will Deacon , tsoni@quicinc.com, pratikp@quicinc.com Subject: [PATCH 7/9] firmware: arm_ffa: Add support for SMCCC as transport to FFA driver Date: Sat, 29 Aug 2020 18:09:21 +0100 Message-Id: <20200829170923.29949-8-sudeep.holla@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com> References: <20200829170923.29949-1-sudeep.holla@arm.com> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org There are requests to keep the transport separate in order to allow other possible transports like virtio. So let us keep the SMCCC transport specifi routines abstracted. It is kept simple for now. Once we add another transport, we can develop better abstraction. Signed-off-by: Sudeep Holla --- drivers/firmware/arm_ffa/Kconfig | 5 +++ drivers/firmware/arm_ffa/Makefile | 1 + drivers/firmware/arm_ffa/common.h | 4 +++ drivers/firmware/arm_ffa/smccc.c | 54 +++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 drivers/firmware/arm_ffa/smccc.c -- 2.17.1 diff --git a/drivers/firmware/arm_ffa/Kconfig b/drivers/firmware/arm_ffa/Kconfig index 261a3660650a..5e3ae5cf82e8 100644 --- a/drivers/firmware/arm_ffa/Kconfig +++ b/drivers/firmware/arm_ffa/Kconfig @@ -14,3 +14,8 @@ config ARM_FFA_TRANSPORT This driver provides interface for all the client drivers making use of the features offered by ARM FF-A. + +config ARM_FFA_SMCCC + bool + default ARM_FFA_TRANSPORT + depends on ARM64 && HAVE_ARM_SMCCC_DISCOVERY diff --git a/drivers/firmware/arm_ffa/Makefile b/drivers/firmware/arm_ffa/Makefile index 1a9bd2bf8752..1aaac512384c 100644 --- a/drivers/firmware/arm_ffa/Makefile +++ b/drivers/firmware/arm_ffa/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_ARM_FFA_TRANSPORT) = ffa-bus.o ffa-driver.o ffa-bus-y = bus.o ffa-driver-y = driver.o +ffa-driver-$(CONFIG_ARM_FFA_SMCCC) += smccc.o diff --git a/drivers/firmware/arm_ffa/common.h b/drivers/firmware/arm_ffa/common.h index 720c8425dfd6..10ac3f363f52 100644 --- a/drivers/firmware/arm_ffa/common.h +++ b/drivers/firmware/arm_ffa/common.h @@ -15,9 +15,13 @@ typedef ffa_res_t (ffa_fn)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); +#ifdef CONFIG_ARM_FFA_SMCCC +int __init ffa_transport_init(ffa_fn **invoke_ffa_fn); +#else static inline int __init ffa_transport_init(ffa_fn **invoke_ffa_fn) { return -EOPNOTSUPP; } +#endif #endif /* _FFA_COMMON_H */ diff --git a/drivers/firmware/arm_ffa/smccc.c b/drivers/firmware/arm_ffa/smccc.c new file mode 100644 index 000000000000..b93d281d2399 --- /dev/null +++ b/drivers/firmware/arm_ffa/smccc.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 ARM Ltd. + */ + +#include + +#include "common.h" + +static struct arm_smccc_v1_2_res +__arm_ffa_fn_smc(unsigned long function_id, unsigned long arg0, + unsigned long arg1, unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5, unsigned long arg6) +{ + struct arm_smccc_v1_2_res res; + + arm_smccc_v1_2_smc(function_id, arg0, arg1, arg2, arg3, arg4, arg5, + arg6, &res); + + return res; +} + +static struct arm_smccc_v1_2_res +__arm_ffa_fn_hvc(unsigned long function_id, unsigned long arg0, + unsigned long arg1, unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5, unsigned long arg6) +{ + struct arm_smccc_v1_2_res res; + + arm_smccc_v1_2_hvc(function_id, arg0, arg1, arg2, arg3, arg4, arg5, + arg6, &res); + return res; +} + +int __init ffa_transport_init(ffa_fn **invoke_ffa_fn) +{ + enum arm_smccc_conduit conduit; + + if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2) + return -EOPNOTSUPP; + + conduit = arm_smccc_1_1_get_conduit(); + if (conduit == SMCCC_CONDUIT_NONE) { + pr_err("%s: invalid SMCCC conduit\n", __func__); + return -EOPNOTSUPP; + } + + if (conduit == SMCCC_CONDUIT_SMC) + *invoke_ffa_fn = __arm_ffa_fn_smc; + else + *invoke_ffa_fn = __arm_ffa_fn_hvc; + + return 0; +} From patchwork Sat Aug 29 17:09:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 248714 Delivered-To: patch@linaro.org Received: by 2002:a92:5b9c:0:0:0:0:0 with SMTP id c28csp2036529ilg; Sat, 29 Aug 2020 10:09:45 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw0FLmf8VraUvzgPzwVndqvt91q7jfJHQyqSLY40dmpRnBCMDjMWFov8YCM4oWqvaruuxTu X-Received: by 2002:aa7:d85a:: with SMTP id f26mr4185991eds.363.1598720984952; Sat, 29 Aug 2020 10:09:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598720984; cv=none; d=google.com; s=arc-20160816; b=aGdgqNwumg/LJwV6SQT/oxIjuS3U87NuJUV8JsQozDtjgx9bzvvLXOBtInUHPOKU1g dym4iHYLBmcgRICNi/ZJgEASR06UTjXLIN2G7eW1+MEDaOBVTp71LVKKKviWVHr3OsiK GiDrPyvG4JGWMmM9WDT8Dt17YvZo2BSZkanKtu4CWQKcY6Hi20w0c/CBO6ND6SDHYZBT aMfZ39DkNaKdyhU7Smkfh6Cx5MTjyQ1iiQ5mw5vNN3JspJXYL3d4LvxZ4mG+h8kEsH5p n/PBKuAEHhjf0dQwL6F0lcqRTV9QZUUkBm8uFuWKN7cHewIyFqFXK9c1DAOU1xuSw8NO Wpiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=8AcEMPMv1gqBeCennpUZ0imT/WCd7VCt+ziKf2tSH4Q=; b=QhW/Nnjz+XJXVlSKyQuo8LpUQzra6AgaCFEOm8K0db6vTg9CuNGeMJ8+bjGHwDubPK 24XXQViydQKmrmqMbiZSVis/wOD4co/PSGd2nQNAya9SSDQSnPWzjk6yXcynozDdW4rJ Pm0+fjdy6ylP9qoWQL98so66/EupI4PcroywbzRWCxRemgVR/dtVHYZ5wILpFXNWYXM+ WBcUe3lhvHtAjZ1ZyFrIkM8em00T0rOyYmkg0P4JeIFhXqQHA/wXf+AqtboZwiTF7i9+ IWo3wuS9Cgsa1/x2zd+/Da7ywBshtZ8A5mSRXmXFG89nDaP//neFQGWyQKBtYqFNmTd2 KZvQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d22si1952640edz.234.2020.08.29.10.09.44; Sat, 29 Aug 2020 10:09:44 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728480AbgH2RJn (ORCPT + 6 others); Sat, 29 Aug 2020 13:09:43 -0400 Received: from foss.arm.com ([217.140.110.172]:45080 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728479AbgH2RJm (ORCPT ); Sat, 29 Aug 2020 13:09:42 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A25F71063; Sat, 29 Aug 2020 10:09:41 -0700 (PDT) Received: from usa.arm.com (e103737-lin.cambridge.arm.com [10.1.197.49]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id A04FE3F71F; Sat, 29 Aug 2020 10:09:40 -0700 (PDT) From: Sudeep Holla To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Cc: Sudeep Holla , kernel-team@android.com, Will Deacon , tsoni@quicinc.com, pratikp@quicinc.com Subject: [PATCH 8/9] firmware: arm_ffa: Setup and register all the KVM managed partitions Date: Sat, 29 Aug 2020 18:09:22 +0100 Message-Id: <20200829170923.29949-9-sudeep.holla@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com> References: <20200829170923.29949-1-sudeep.holla@arm.com> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Parse the FFA nodes from the device-tree and register all the partitions managed by the KVM hypervisor. All the partitions including the host(self) are registered as the character device with a set of file operations. Most of the interface will concentrated in the ioctl. For now, we have a tiny set of initial ioctls implemented. Signed-off-by: Sudeep Holla --- drivers/firmware/arm_ffa/bus.c | 2 + drivers/firmware/arm_ffa/driver.c | 378 +++++++++++++++++++++++++++++- include/linux/arm_ffa.h | 3 + include/uapi/linux/arm_ffa.h | 56 +++++ 4 files changed, 438 insertions(+), 1 deletion(-) create mode 100644 include/uapi/linux/arm_ffa.h -- 2.17.1 diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c index b5789bd4dfcd..4af354e16750 100644 --- a/drivers/firmware/arm_ffa/bus.c +++ b/drivers/firmware/arm_ffa/bus.c @@ -78,6 +78,7 @@ static void ffa_release_device(struct device *dev) { struct ffa_device *ffa_dev = to_ffa_dev(dev); + mutex_destroy(&ffa_dev->mutex); kfree(ffa_dev); } @@ -115,6 +116,7 @@ int ffa_device_register(struct ffa_device *ffa_dev) dev = &ffa_dev->dev; cdev = &ffa_dev->cdev; + mutex_init(&ffa_dev->mutex); dev->bus = &ffa_bus_type; dev->type = &ffa_dev_type; diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c index 3670ba400f89..96113e594db6 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -22,11 +22,17 @@ #define DRIVER_NAME "ARM FF-A" #define pr_fmt(fmt) DRIVER_NAME ": " fmt +#include #include +#include +#include #include #include +#include #include -#include +#include +#include +#include #include "common.h" @@ -122,6 +128,13 @@ /* Keeping RX TX buffer size as 64K for now */ #define RXTX_BUFFER_SIZE SZ_64K +#define list_to_ffa_dev(n) container_of(n, struct ffa_device, node) + +/* List of all FFA devices active in system */ +static LIST_HEAD(ffa_devs_list); +/* Protection for the entire list */ +static DEFINE_MUTEX(ffa_devs_list_mutex); + static ffa_fn *invoke_ffa_fn; static const int ffa_linux_errmap[] = { @@ -178,6 +191,20 @@ static int ffa_version_check(u32 *version) return 0; } +static int ffa_rx_release(void) +{ + ffa_res_t ret; + + ret = invoke_ffa_fn(FFA_RX_RELEASE, 0, 0, 0, 0, 0, 0, 0); + + if (ret.a0 == FFA_ERROR) + return ffa_to_linux_errno((int)ret.a2); + + /* check for ret.a0 == FFA_RX_RELEASE ? */ + + return 0; +} + static int ffa_rxtx_map(phys_addr_t tx_buf, phys_addr_t rx_buf, u32 pg_cnt) { ffa_res_t ret; @@ -202,6 +229,50 @@ static int ffa_rxtx_unmap(u16 vm_id) return 0; } +static int ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3, + struct ffa_partition_info **buffer) +{ + int count; + ffa_res_t partition_info; + + mutex_lock(&drv_info->rx_lock); + partition_info = invoke_ffa_fn(FFA_PARTITION_INFO_GET, uuid0, uuid1, + uuid2, uuid3, 0, 0, 0); + + if (partition_info.a0 == FFA_ERROR) + return ffa_to_linux_errno((int)partition_info.a2); + + count = partition_info.a2; + + if (buffer) + memcpy(*buffer, drv_info->rx_buffer, sizeof(*buffer) * count); + + ffa_rx_release(); + + mutex_unlock(&drv_info->rx_lock); + + return count; +} + +static int ffa_partition_probe(const char *uuid_str, + struct ffa_partition_info *buffer) +{ + int count; + uuid_t uuid; + u32 uuid0_4[4] = { 0 }; + + if (uuid_parse(uuid_str, &uuid)) { + pr_err("invalid uuid (%s)\n", uuid_str); + return -ENODEV; + } + + export_uuid((u8 *)uuid0_4, &uuid); + count = ffa_partition_info_get(uuid0_4[0], uuid0_4[1], uuid0_4[2], + uuid0_4[3], &buffer); + + return count; +} + #define VM_ID_MASK GENMASK(15, 0) static int ffa_id_get(u16 *vm_id) { @@ -217,6 +288,296 @@ static int ffa_id_get(u16 *vm_id) return 0; } +static int ffa_msg_send(u16 src_id, u16 dst_id, void *buf, u32 len) +{ + ffa_res_t ret; + u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id); + + mutex_lock(&drv_info->tx_lock); + + memcpy(drv_info->tx_buffer, buf, len); + + ret = invoke_ffa_fn(FFA_MSG_SEND, src_dst_ids, 0, len, 0, 0, 0, 0); + + mutex_unlock(&drv_info->tx_lock); + + if (ret.a0 == FFA_ERROR) + return ffa_to_linux_errno((int)ret.a2); + + return 0; +} + +static int ffa_msg_send_direct_req(u16 src_id, u16 dst_id, + struct ffa_send_direct_data *data) +{ + u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id); + ffa_res_t ret; + + ret = invoke_ffa_fn(FFA_FN_NATIVE(MSG_SEND_DIRECT_REQ), src_dst_ids, 0, + data->data0, data->data1, data->data2, + data->data3, data->data4); + + while (ret.a0 == FFA_INTERRUPT) + ret = invoke_ffa_fn(FFA_RUN, ret.a1, 0, 0, 0, 0, 0, 0); + if (ret.a0 == FFA_ERROR) + return ffa_to_linux_errno((int)ret.a2); + + if (ret.a0 == FFA_FN_NATIVE(MSG_SEND_DIRECT_RESP)) { + data->data0 = ret.a3; + data->data1 = ret.a4; + data->data2 = ret.a5; + data->data3 = ret.a6; + data->data4 = ret.a7; + } + + return 0; +} + +static struct ffa_device *ffa_device_get_from_minor(int minor) +{ + struct list_head *p; + struct ffa_device *ffa_dev = NULL; + + mutex_lock(&ffa_devs_list_mutex); + + list_for_each(p, &ffa_devs_list) { + struct device *dev; + struct ffa_device *tmp_dev; + + tmp_dev = list_to_ffa_dev(p); + dev = &tmp_dev->dev; + + if (minor == MINOR(dev->devt)) { + ffa_dev = tmp_dev; + break; + } + } + + mutex_unlock(&ffa_devs_list_mutex); + + return ffa_dev; +} + +static void ffa_device_get(struct ffa_device *ffa_dev) +{ + mutex_lock(&ffa_dev->mutex); + ffa_dev->num_users++; + mutex_unlock(&ffa_dev->mutex); +} + +static void ffa_device_put(struct ffa_device *ffa_dev) +{ + mutex_lock(&ffa_dev->mutex); + ffa_dev->num_users--; + mutex_unlock(&ffa_dev->mutex); +} + +static int ffa_open(struct inode *inode, struct file *filp) +{ + struct ffa_device *ffa_dev; + + ffa_dev = ffa_device_get_from_minor(iminor(inode)); + if (!ffa_dev) + return -EINVAL; + + ffa_device_get(ffa_dev); + + filp->private_data = ffa_dev; + + return 0; +} + +static int ffa_release(struct inode *inode, struct file *filp) +{ + struct ffa_device *ffa_dev = filp->private_data; + + ffa_device_put(ffa_dev); + + filp->private_data = NULL; + + return 0; +} + +static long ffa_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) +{ + long r = -EINVAL; + void __user *argp = (void __user *)arg; + struct ffa_device *ffa_dev = filp->private_data; + + switch (ioctl) { + case FFA_GET_API_VERSION: + if (arg) + goto out; + r = drv_info->version; + break; + case FFA_GET_PARTITION_ID: + if (arg) + goto out; + r = ffa_dev->vm_id; + break; + case FFA_GET_PARTITION_INFO: { + struct ffa_partition_info pbuf; + struct ffa_part_info __user *pinfo = argp; + struct ffa_part_info info; + unsigned int count; + + r = -EFAULT; + if (copy_from_user(&info, pinfo, sizeof(info))) + break; + count = ffa_partition_probe(info.uuid_str, &pbuf); + if (count > 1) { + r = -E2BIG; + break; + } + r = -EFAULT; + if (copy_to_user(pinfo, &info, sizeof(info))) + break; + r = 0; + break; + } + case FFA_SEND_RECEIVE_SYNC: { + struct ffa_send_recv_sync __user *udata = argp; + struct ffa_send_recv_sync kdata; + + r = -EFAULT; + if (copy_from_user(&kdata, udata, sizeof(kdata))) + break; + r = ffa_msg_send_direct_req(ffa_dev->vm_id, kdata.endpoint_id, + &kdata.data); + if (r) + break; + if (copy_to_user(udata, &kdata, sizeof(kdata))) + break; + break; + } + case FFA_SEND_RECEIVE_ASYNC: { + struct ffa_send_recv_async __user *udata = argp; + struct ffa_send_recv_async kdata; + void *buf; + + r = -EFAULT; + if (copy_from_user(&kdata, udata, sizeof(kdata))) + break; + + if (kdata.length < 0 || kdata.length > RXTX_BUFFER_SIZE) { + r = -EINVAL; + break; + } + + buf = kzalloc(kdata.length, GFP_KERNEL); + if (!buf) { + r = -ENOMEM; + break; + } + + if (copy_from_user(buf, udata->buffer, kdata.length)) { + kfree(buf); + break; + } + + r = ffa_msg_send(ffa_dev->vm_id, kdata.endpoint_id, buf, + kdata.length); + if (r) { + kfree(buf); + break; + } + + break; + } + default: + r = -EINVAL; + } +out: + return r; +} + +static const struct file_operations ffa_fops = { + .owner = THIS_MODULE, + .open = ffa_open, + .release = ffa_release, + .unlocked_ioctl = ffa_ioctl, + .llseek = noop_llseek, +}; + +static int ffa_device_alloc_register(const char *name, u16 vm_id, uuid_t *uuid) +{ + int ret; + struct ffa_device *ffa_dev; + + ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL); + if (!ffa_dev) + return -ENOMEM; + + ffa_dev->vm_id = vm_id; + if (uuid) + memcpy(uuid, &ffa_dev->uuid, sizeof(*uuid)); + + dev_set_name(&ffa_dev->dev, name); + dev_set_drvdata(&ffa_dev->dev, drv_info); + cdev_init(&ffa_dev->cdev, &ffa_fops); + + ret = ffa_device_register(ffa_dev); + if (ret) + return ret; + + mutex_lock(&ffa_devs_list_mutex); + list_add_tail(&ffa_dev->node, &ffa_devs_list); + mutex_unlock(&ffa_devs_list_mutex); + + return 0; +} + +static int ffa_setup_partitions(void) +{ + int ret; + struct ffa_partition_info pbuf; + struct device_node *child, *parent; + const char *p_uuid, *pfx = "Ignoring FFA partition"; + const char *compatible = "arm,ffa-1.0-hypervisor"; + uuid_t uuid = UUID_INIT(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + + parent = of_find_compatible_node(NULL, NULL, compatible); + if (!parent) + return 0; + + for_each_child_of_node(parent, child) { + if (!of_device_is_compatible(child, "arm,ffa-1.0-partition")) { + of_node_put(child); + continue; + } + + if (of_property_read_string(child, "uuid", &p_uuid)) { + pr_err("%s: failed to parse \"uuid\" property\n", pfx); + of_node_put(child); + continue; + } + + of_node_put(child); + + if (uuid_parse(p_uuid, &uuid)) { + pr_err("%s: invalid \"uuid\" property (%s)\n", + pfx, p_uuid); + continue; + } + + ret = ffa_partition_probe(p_uuid, &pbuf); + if (ret != 1) { + pr_err("%s: %s partition info probe failed\n", + pfx, p_uuid); + return -EINVAL; + } + + ret = ffa_device_alloc_register(p_uuid, pbuf.id, &uuid); + if (ret) { + pr_err("%s: failed to register %s\n", pfx, p_uuid); + continue; + } + } + + of_node_put(parent); + return 0; +} + static int __init ffa_init(void) { int ret; @@ -262,6 +623,14 @@ static int __init ffa_init(void) mutex_init(&drv_info->rx_lock); mutex_init(&drv_info->tx_lock); + /* This will be default device both in theguests and host */ + ret = ffa_device_alloc_register("self", drv_info->vm_id, NULL); + if (ret) + return ret; + + /* Set up all the partitions that KVM hypervisor maintains */ + ffa_setup_partitions(); + return 0; free_pages: if (drv_info->tx_buffer) @@ -275,6 +644,13 @@ module_init(ffa_init); static void __exit ffa_exit(void) { + struct list_head *p; + + mutex_lock(&ffa_devs_list_mutex); + list_for_each(p, &ffa_devs_list) + ffa_device_unregister(list_to_ffa_dev(p)); + mutex_unlock(&ffa_devs_list_mutex); + ffa_rxtx_unmap(drv_info->vm_id); free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE); free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE); diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h index 2fe16176149f..6824e0633c77 100644 --- a/include/linux/arm_ffa.h +++ b/include/linux/arm_ffa.h @@ -17,6 +17,9 @@ struct ffa_device { uuid_t uuid; struct device dev; struct cdev cdev; + size_t num_users; + struct mutex mutex; /* protects num_users */ + struct list_head node; }; #define to_ffa_dev(d) container_of(d, struct ffa_device, dev) diff --git a/include/uapi/linux/arm_ffa.h b/include/uapi/linux/arm_ffa.h new file mode 100644 index 000000000000..88ddddb4742f --- /dev/null +++ b/include/uapi/linux/arm_ffa.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (C) 2020 Arm Ltd. + */ + +#ifndef _UAPI_LINUX_ARM_FFA_H +#define _UAPI_LINUX_ARM_FFA_H + +#include +#include + +#define FFA_BASE 0xFF + +struct ffa_partition_info { + __u16 id; + __u16 exec_ctxt; +/* partition supports receipt of direct requests */ +#define FFA_PARTITION_DIRECT_RECV BIT(0) +/* partition can send direct requests. */ +#define FFA_PARTITION_DIRECT_SEND BIT(1) +/* partition can send and receive indirect messages. */ +#define FFA_PARTITION_INDIRECT_MSG BIT(2) + __u32 properties; +}; + +struct ffa_part_info { + char uuid_str[36]; + struct ffa_partition_info info; +}; + +struct ffa_send_direct_data { + unsigned long data0; + unsigned long data1; + unsigned long data2; + unsigned long data3; + unsigned long data4; +}; + +struct ffa_send_recv_sync { + __u16 endpoint_id; + struct ffa_send_direct_data data; +}; + +struct ffa_send_recv_async { + __u16 endpoint_id; + int length; + char buffer[]; +}; + +#define FFA_GET_API_VERSION _IO(FFA_BASE, 0x00) +#define FFA_GET_PARTITION_ID _IO(FFA_BASE, 0x01) +#define FFA_GET_PARTITION_INFO _IOWR(FFA_BASE, 0x02, struct ffa_part_info) +#define FFA_SEND_RECEIVE_SYNC _IOWR(FFA_BASE, 0x03, struct ffa_send_recv_sync) +#define FFA_SEND_RECEIVE_ASYNC _IOW(FFA_BASE, 0x04, struct ffa_send_recv_async) + +#endif /*_UAPI_LINUX_ARM_FFA_H*/ From patchwork Sat Aug 29 17:09:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 248715 Delivered-To: patch@linaro.org Received: by 2002:a92:5b9c:0:0:0:0:0 with SMTP id c28csp2036550ilg; Sat, 29 Aug 2020 10:09:47 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzRsDcq71xlst1MkW2k+jEXuIOnkpqhYa7XBAuaPDFhNPAFND0rkCXToc//qcfNqIqBzx2Y X-Received: by 2002:a05:6402:1d2a:: with SMTP id dh10mr4246084edb.278.1598720987121; Sat, 29 Aug 2020 10:09:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598720987; cv=none; d=google.com; s=arc-20160816; b=urw/5sHfVtoPubrCE4jnMU1gJB6lWVStemEKIWo7NiubXrCFJAJ5afrPn0HGbvXdu0 pVRpTwhELO7tdw8JP6Ce8XxtOvamxLrMitlMFiIgOr0yqV/COZwhm10hSSc0Zj9Z7SiN FZeEPxPYRJldDr+SUgfxAviHqIauuSfWgh7yZj2Q54+PsObB+46Mk7JFg4prl/PCu36n KpjIFIMP9kk7Z+z3A0eKFUvUXKDIBqTDGj1Tc0wHOJl1aCv20yL/G2g2kpe1ej2dwyCw LUvjsWABXavL6eqGePzMdYNoFry6YM2TH9bct3M6tdPbUUbItu/dUUicSSiTJ9cf92l/ Vs1A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=2E2zFirpVLMd8OxHaDvN7Vzj/F1tDvGYa6CbEW7qoYM=; b=j7psik+yBxjCKOfdlhJGbOw+iC6oGtRCd3z37uUR47vo0yMGbquuNKmlyIdlNue118 zT1Ee6X2OQfDH8a2gDTpAloPWBYCVD5I62wbV5BQWnhCktY/v693SxpFyzf1XVRn35a0 Sy0Hz2BVgo0UIvJBdeqg1QjxZVf6cOJ3I11j+/IhBOKuJn1Y9gFvM63+e69pmMgft4zp JQVnckSItZHRcLNuJtsBTDuxkndlOHWGmZvZYll5J3MpqwbDJ5asWjZVBXyDGocSzKzn K/AURt4dmNnR/p+HghlT+Vp8B8IYJFOTtOrm1Vt3CDaN4Grqgpw5kliNz5538lVmCNgg oqjQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d22si1952640edz.234.2020.08.29.10.09.46; Sat, 29 Aug 2020 10:09:47 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728479AbgH2RJo (ORCPT + 6 others); Sat, 29 Aug 2020 13:09:44 -0400 Received: from foss.arm.com ([217.140.110.172]:45064 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728471AbgH2RJn (ORCPT ); Sat, 29 Aug 2020 13:09:43 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D8D78113E; Sat, 29 Aug 2020 10:09:42 -0700 (PDT) Received: from usa.arm.com (e103737-lin.cambridge.arm.com [10.1.197.49]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id D67EC3F71F; Sat, 29 Aug 2020 10:09:41 -0700 (PDT) From: Sudeep Holla To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Cc: Sudeep Holla , kernel-team@android.com, Will Deacon , tsoni@quicinc.com, pratikp@quicinc.com Subject: [PATCH 9/9] firmware: arm_ffa: Setup in-kernel users of FFA partitions Date: Sat, 29 Aug 2020 18:09:23 +0100 Message-Id: <20200829170923.29949-10-sudeep.holla@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com> References: <20200829170923.29949-1-sudeep.holla@arm.com> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org In order to also enable in-kernel users of FFA interface along with the access to user-space applications, let us add simple set of operations for such devices. The in-kernel users are registered without the character device interface. Signed-off-by: Sudeep Holla --- drivers/firmware/arm_ffa/driver.c | 119 ++++++++++++++++++++++++++---- include/linux/arm_ffa.h | 12 +++ 2 files changed, 117 insertions(+), 14 deletions(-) -- 2.17.1 diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c index 96113e594db6..811558ef2a1d 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -372,6 +372,97 @@ static void ffa_device_put(struct ffa_device *ffa_dev) mutex_unlock(&ffa_dev->mutex); } +static int ffa_dev_open(struct ffa_device *ffa_dev) +{ + ffa_device_get(ffa_dev); + + return 0; +} + +static int ffa_dev_close(struct ffa_device *ffa_dev) +{ + ffa_device_put(ffa_dev); + + return 0; +} + +static long +ffa_dev_ioctl(struct ffa_device *ffa_dev, unsigned int ioctl, void *arg) +{ + long r = -EINVAL; + + switch (ioctl) { + case FFA_GET_API_VERSION: + r = drv_info->version; + break; + case FFA_GET_PARTITION_ID: + r = ffa_dev->vm_id; + break; + case FFA_GET_PARTITION_INFO: { + struct ffa_part_info *pinfo = arg; + + if (ffa_partition_probe(pinfo->uuid_str, &pinfo->info) != 1) + r = -E2BIG; + break; + } + case FFA_SEND_RECEIVE_SYNC: { + struct ffa_send_recv_sync *kdata = arg; + + r = ffa_msg_send_direct_req(ffa_dev->vm_id, kdata->endpoint_id, + &kdata->data); + break; + } + case FFA_SEND_RECEIVE_ASYNC: { + struct ffa_send_recv_async *kdata = arg; + + if (kdata->length < 0 || kdata->length > RXTX_BUFFER_SIZE) { + r = -EINVAL; + break; + } + + r = ffa_msg_send(ffa_dev->vm_id, kdata->endpoint_id, + kdata->buffer, kdata->length); + break; + } + default: + r = -EINVAL; + } + + return r; +} + +struct ffa_dev_ops ffa_ops = { + .open = ffa_dev_open, + .close = ffa_dev_close, + .ioctl = ffa_dev_ioctl, +}; + +struct ffa_dev_ops *ffa_dev_ops_get(struct ffa_device *dev) +{ + struct list_head *p; + struct ffa_dev_ops *ops = NULL; + + if (uuid_is_null(&dev->uuid)) + return NULL; + + mutex_lock(&ffa_devs_list_mutex); + + list_for_each(p, &ffa_devs_list) { + struct ffa_device *tmp_dev; + + tmp_dev = list_to_ffa_dev(p); + + if (uuid_equal(&tmp_dev->uuid, &dev->uuid)) { + ops = &ffa_ops; + break; + } + } + + mutex_unlock(&ffa_devs_list_mutex); + + return ops; +} + static int ffa_open(struct inode *inode, struct file *filp) { struct ffa_device *ffa_dev; @@ -380,7 +471,7 @@ static int ffa_open(struct inode *inode, struct file *filp) if (!ffa_dev) return -EINVAL; - ffa_device_get(ffa_dev); + ffa_dev_open(ffa_dev); filp->private_data = ffa_dev; @@ -391,7 +482,7 @@ static int ffa_release(struct inode *inode, struct file *filp) { struct ffa_device *ffa_dev = filp->private_data; - ffa_device_put(ffa_dev); + ffa_dev_close(ffa_dev); filp->private_data = NULL; @@ -406,14 +497,10 @@ static long ffa_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) switch (ioctl) { case FFA_GET_API_VERSION: - if (arg) - goto out; - r = drv_info->version; - break; case FFA_GET_PARTITION_ID: if (arg) goto out; - r = ffa_dev->vm_id; + r = ffa_dev_ioctl(ffa_dev, FFA_GET_PARTITION_ID, NULL); break; case FFA_GET_PARTITION_INFO: { struct ffa_partition_info pbuf; @@ -499,7 +586,8 @@ static const struct file_operations ffa_fops = { .llseek = noop_llseek, }; -static int ffa_device_alloc_register(const char *name, u16 vm_id, uuid_t *uuid) +static int ffa_device_alloc_register(const char *name, u16 vm_id, + uuid_t *uuid, bool cdev_if) { int ret; struct ffa_device *ffa_dev; @@ -514,7 +602,7 @@ static int ffa_device_alloc_register(const char *name, u16 vm_id, uuid_t *uuid) dev_set_name(&ffa_dev->dev, name); dev_set_drvdata(&ffa_dev->dev, drv_info); - cdev_init(&ffa_dev->cdev, &ffa_fops); + cdev_init(&ffa_dev->cdev, cdev_if ? &ffa_fops : NULL); ret = ffa_device_register(ffa_dev); if (ret) @@ -527,13 +615,13 @@ static int ffa_device_alloc_register(const char *name, u16 vm_id, uuid_t *uuid) return 0; } -static int ffa_setup_partitions(void) +static int ffa_setup_partitions(bool hyp) { int ret; struct ffa_partition_info pbuf; struct device_node *child, *parent; const char *p_uuid, *pfx = "Ignoring FFA partition"; - const char *compatible = "arm,ffa-1.0-hypervisor"; + const char *compatible = hyp ? "arm,ffa-1.0-hypervisor" : "arm,ffa-1.0"; uuid_t uuid = UUID_INIT(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); parent = of_find_compatible_node(NULL, NULL, compatible); @@ -567,7 +655,7 @@ static int ffa_setup_partitions(void) return -EINVAL; } - ret = ffa_device_alloc_register(p_uuid, pbuf.id, &uuid); + ret = ffa_device_alloc_register(p_uuid, pbuf.id, &uuid, hyp); if (ret) { pr_err("%s: failed to register %s\n", pfx, p_uuid); continue; @@ -624,12 +712,15 @@ static int __init ffa_init(void) mutex_init(&drv_info->tx_lock); /* This will be default device both in theguests and host */ - ret = ffa_device_alloc_register("self", drv_info->vm_id, NULL); + ret = ffa_device_alloc_register("self", drv_info->vm_id, NULL, true); if (ret) return ret; /* Set up all the partitions that KVM hypervisor maintains */ - ffa_setup_partitions(); + ffa_setup_partitions(true); + + /* Set up all the partitions which have in-kernel drivers */ + ffa_setup_partitions(false); return 0; free_pages: diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h index 6824e0633c77..1df7399d207d 100644 --- a/include/linux/arm_ffa.h +++ b/include/linux/arm_ffa.h @@ -11,6 +11,7 @@ #include #include #include +#include struct ffa_device { u32 vm_id; @@ -39,12 +40,19 @@ struct ffa_driver { #define to_ffa_driver(d) container_of(d, struct ffa_driver, driver) +struct ffa_dev_ops { + int (*open)(struct ffa_device *dev); + int (*close)(struct ffa_device *dev); + long (*ioctl)(struct ffa_device *dev, unsigned int ioctl, void *arg); +}; + #if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT) int ffa_device_register(struct ffa_device *ffa_dev); void ffa_device_unregister(struct ffa_device *ffa_dev); int ffa_driver_register(struct ffa_driver *driver, struct module *owner, const char *mod_name); void ffa_driver_unregister(struct ffa_driver *driver); +struct ffa_dev_ops *ffa_dev_ops_get(struct ffa_device *dev); #else static inline int ffa_device_register(struct ffa_device *ffa_dev) @@ -63,6 +71,10 @@ ffa_driver_register(struct ffa_driver *driver, struct module *owner, static inline void ffa_driver_unregister(struct ffa_driver *driver) {} +struct ffa_dev_ops *ffa_dev_ops_get(struct ffa_device *dev) +{ + return NULL; +} #endif /* CONFIG_ARM_FFA_TRANSPORT */ #define ffa_register(driver) \