Xen-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
To: Oleksii Moisieiev <Oleksii_Moisieiev@epam.com>
Cc: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Anthony PERARD" <anthony.perard@vates.tech>,
	"Bertrand Marquis" <bertrand.marquis@arm.com>,
	"Jan Beulich" <jbeulich@suse.com>,
	"Juergen Gross" <jgross@suse.com>,
	"Julien Grall" <julien@xen.org>,
	"Michal Orzel" <michal.orzel@amd.com>,
	"Roger Pau Monné" <roger@xenproject.org>,
	"Stefano Stabellini" <sstabellini@kernel.org>,
	"Grygorii Strashko" <grygorii_strashko@epam.com>
Subject: Re: [PATCH v14 4/6] xen/arm: scmi: introduce SCI SCMI SMC multi-agent driver
Date: Thu, 29 Oct 2026 18:55:38 +0000	[thread overview]
Message-ID: <87v76knxp3.fsf@epam.com> (raw)
In-Reply-To: <8d8985e3-fd09-4664-abaa-c3c0f4ca33d6@epam.com> (Oleksii Moisieiev's message of "Mon, 26 Oct 2026 15:39:40 +0000")

Hi Oleksii,

Oleksii Moisieiev <Oleksii_Moisieiev@epam.com> writes:

> Hi Volodymyr,
>
> Thank you for the review. I agree with the most of your comments, just
> few more questions left:
>
> On 23/10/2026 04:56, Volodymyr Babchuk wrote:
>> Hi Oleksii,
>>
>> Oleksii Moisieiev <Oleksii_Moisieiev@epam.com> writes:
>>
>>> This patch introduces SCI driver to support for ARM EL3 Trusted Firmware-A
>>> (TF-A) which provides SCMI interface with multi-agent support, as shown
> [snip]
>>> diff --git a/xen/arch/arm/firmware/scmi-shmem.c b/xen/arch/arm/firmware/scmi-shmem.c
>>> new file mode 100644
>>> index 0000000000..e36745a85e
>>> --- /dev/null
>>> +++ b/xen/arch/arm/firmware/scmi-shmem.c
>>> @@ -0,0 +1,118 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>> +/*
>>> + * SMC/HVC shmem transport implementation used by
>>> + * SCI SCMI multi-agent driver.
>>> + *
>>> + * Oleksii Moisieiev <oleksii_moisieiev@epam.com>
>>> + * Copyright (c) 2025 EPAM Systems
>>> + */
>>> +
>>> +#include <xen/err.h>
>>> +#include <xen/io.h>
>>> +#include <asm/io.h>
>>> +
>>> +#include "scmi-proto.h"
>>> +#include "scmi-shmem.h"
>>> +
>>> +static inline int
>>> +shmem_channel_status(const volatile struct scmi_shared_mem __iomem *shmem)
>>> +{
>>> +    return (readl(&shmem->channel_status) &
>>> +            SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE) ? 0 : -EBUSY;
>>> +}
>>> +
>>> +int shmem_put_message(volatile struct scmi_shared_mem __iomem *shmem,
>>> +                      scmi_msg_header_t *hdr, void *data, unsigned int len)
>>> +{
>>> +    int ret;
>>> +
>>> +    if ( (len + offsetof(struct scmi_shared_mem, msg_payload)) >
>>> +         SCMI_SHMEM_MAPPED_SIZE )
>>> +    {
>>> +        printk(XENLOG_ERR "scmi: Wrong size of smc message. Data is invalid\n");
>> "of the SMC message". Also, looks like it is over 80 characters.
> agreed with both. thank you.
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    ret = shmem_channel_status(shmem);
>>> +    if ( ret )
>>> +        return ret;
>>> +
>>> +    writel_relaxed(0x0, &shmem->channel_status);
>>> +    /* Writing 0x0 right now, but "shmem"_FLAG_INTR_ENABLED can be set */
>>> +    writel_relaxed(0x0, &shmem->flags);
>>> +    writel_relaxed(sizeof(shmem->msg_header) + len, &shmem->length);
>>> +    writel(pack_scmi_header(hdr), &shmem->msg_header);
>> Why do you mix writel() and writel_relaxed() here?
>
> The main idea that I'm filling up SCMI header information following
> Device memory ordering and execute __iowmb before store in the last
> writel call.

Yes, but difference between writel_relaxed() and writel() is that
writel() has memory barrier for Normal Memory accesses. Writes to Device
Memory are guaranteed to arrive in the proper order.

>
>
>>> +
>>> +    if ( len > 0 && data )
>>> +        memcpy_toio(shmem->msg_payload, data, len);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +int shmem_get_response(const volatile struct scmi_shared_mem __iomem *shmem,
>>> +                       scmi_msg_header_t *hdr, void *data, unsigned int len)
>>> +{
>>> +    int recv_len;
>>> +    int ret;
>>> +    /*
>>> +     * First word of msg_payload carries the returned status; exclude it from
>>> +     * recv_len so only the protocol payload is copied back to the caller.
>>> +     */
>>> +    int pad = sizeof(hdr->status);
>>> +
>>> +    if ( len >= SCMI_SHMEM_MAPPED_SIZE -
>>> +         offsetof(struct scmi_shared_mem, msg_payload) )
>>> +    {
>>> +        printk(XENLOG_ERR
>>> +               "scmi: Wrong size of input smc message. Data may be invalid\n");
>> "of the input SMC message"
> +1
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    ret = shmem_channel_status(shmem);
>>> +    if ( ret )
>>> +        return ret;
>>> +
>>> +    recv_len = readl(&shmem->length) - sizeof(shmem->msg_header);
>>> +
>>> +    if ( recv_len < 0 )
>>> +    {
>>> +        printk(XENLOG_ERR
>>> +               "scmi: Wrong size of smc message. Data may be invalid\n");
>> "of the SMC message"
>>
>> Also, I am wondering if you really need to print this error messages in
>> the first place.
>>
> These generic messages were very helpful in determining the exact error.
> For example, this function returns -EINVAL both if
>
>   len >= SCMI_SHMEM_MAPPED_SIZE -  offsetof(struct scmi_shared_mem, msg_payload)  and if recv_len < 0
>
> However, if you think they are excessive, I can remove the prints and return different error codes instead.

Well, I have no strong opinion here. So you can leave them if you
wish. Just make sure that they have proper spelling.

>
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    unpack_scmi_header(readl(&shmem->msg_header), hdr);
>>> +
>>> +    hdr->status = readl(&shmem->msg_payload);
>>> +    recv_len = recv_len > pad ? recv_len - pad : 0;
>>> +
>>> +    ret = scmi_to_xen_errno(hdr->status);
>>> +    if ( ret )
>>> +    {
>>> +        printk(XENLOG_DEBUG "scmi: Error received: %d\n", ret);
>>> +        return ret;
>>> +    }
>>> +
>>> +    if ( recv_len > len )
>>> +    {
>>> +        printk(XENLOG_ERR
>>> +               "scmi: Not enough buffer for message %d, expecting %d\n",
>>> +               recv_len, len);
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    if ( recv_len > 0 )
>>> +        memcpy_fromio(data, shmem->msg_payload + pad, recv_len);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +/*
>>> + * Local variables:
>>> + * mode: C
>>> + * c-file-style: "BSD"
>>> + * c-basic-offset: 4
>>> + * tab-width: 4
>>> + * indent-tabs-mode: nil
>>> + * End:
>>> + */
>>> diff --git a/xen/arch/arm/firmware/scmi-shmem.h b/xen/arch/arm/firmware/scmi-shmem.h
>>> new file mode 100644
>>> index 0000000000..722263aa77
>>> --- /dev/null
>>> +++ b/xen/arch/arm/firmware/scmi-shmem.h
>>> @@ -0,0 +1,45 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>> +/*
>>> + * Arm System Control and Management Interface definitions
>>> + * Version 3.0 (DEN0056C)
>>> + * Shared Memory based Transport
>>> + *
>>> + * Copyright (c) 2024 EPAM Systems
>>> + */
>>> +
>>> +#ifndef ARM_FIRMWARE_SCMI_SHMEM_H_
>>> +#define ARM_FIRMWARE_SCMI_SHMEM_H_
>>> +
>>> +#include <xen/stdint.h>
>>> +
>>> +#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE  BIT(0, UL)
>>> +#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR BIT(1, UL)
>>> +
>>> +struct scmi_shared_mem {
>>> +    uint32_t reserved;
>>> +    uint32_t channel_status;
>>> +    uint32_t reserved1[2];
>>> +    uint32_t flags;
>>> +    uint32_t length;
>>> +    uint32_t msg_header;
>>> +    uint8_t msg_payload[];
>>> +};
>> Should it be __packed?
> The layout already matches the shared-memory format without padding:
> Every fixed member is a uint32_t or an array of uint8_t, and the
> mapping is page aligned.
>
> Therefore __packed would not change these offsets, but would reduce the
> structure's alignment guarantee. I would prefer to keep the natural
> alignment and add compile-time offset checks to document the transport
> layout. Does that address your concern?

Yes.

[...]


>>> diff --git a/xen/arch/arm/firmware/scmi-smc-multiagent.c b/xen/arch/arm/firmware/scmi-smc-multiagent.c
>>> new file mode 100644
>>> index 0000000000..6c46f6cd36
>>> --- /dev/null
>>> +++ b/xen/arch/arm/firmware/scmi-smc-multiagent.c
>>> @@ -0,0 +1,792 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>> +/*
>>> + * SCI SCMI multi-agent driver, using SMC/HVC shmem as transport.
>>> + *
>>> + * Oleksii Moisieiev <oleksii_moisieiev@epam.com>
>>> + * Copyright (c) 2025 EPAM Systems
>>> + */
>>> +
>>> +#include <xen/acpi.h>
>>> +
>>> +#include <xen/device_tree.h>
>>> +#include <xen/init.h>
>>> +#include <xen/iocap.h>
>>> +#include <xen/err.h>
>>> +#include <xen/libfdt/libfdt.h>
>>> +#include <xen/string.h>
>>> +#include <xen/param.h>
>>> +#include <xen/sched.h>
>>> +#include <xen/vmap.h>
>>> +
>>> +#include <asm/firmware/sci.h>
>>> +#include <asm/smccc.h>
>>> +
>>> +#include "scmi-proto.h"
>>> +#include "scmi-shmem.h"
>>> +
>>> +struct scmi_channel {
>>> +    uint32_t agent_id;
>> If all agent_ids large than UINT8_MAX are invalid, why do you need
>> uint32_t here?
>
> According to the DEN0056F document:
>
> https://support.arm.com/documentation/den0056/f/?lang=en
>
> agent_id is uint32_t  in SCMI messages.
>

Okay, so agent_id is 32-bit value. I can imagine a platform that have
agent IDs 0x100, 0x200, 0x300 and so on. I believe, in this case your
code will not work as intended, because you limit agent id to 8 bits in
domain structure.


[...]

>>> +static int collect_agent_id(struct scmi_channel *agent_channel)
>>> +{
>>> +    int ret;
>>> +    scmi_msg_header_t hdr;
>>> +    struct scmi_msg_base_discover_agent_p2a da_rx;
>>> +    struct scmi_msg_base_discover_agent_a2p da_tx;
>>> +
>>> +    ret = map_channel_memory(agent_channel);
>>> +    if ( ret )
>>> +        return ret;
>>> +
>>> +    hdr.id = SCMI_BASE_DISCOVER_AGENT;
>>> +    hdr.type = 0;
>>> +    hdr.protocol = SCMI_BASE_PROTOCOL;
>>> +
>>> +    da_tx.agent_id = agent_channel->agent_id;
>>> +
>>> +    ret = do_smc_xfer(agent_channel, &hdr, &da_tx, sizeof(da_tx), &da_rx,
>>> +                        sizeof(da_rx));
>>> +    if ( agent_channel->domain_id != DOMID_XEN )
>>> +        unmap_channel_memory(agent_channel);
>>> +    if ( ret )
>> On error, Xen's channel will be mapped still. Is this intended behaviour?
> It remains mapped when collect_agent_id() returns, but the existing
> caller cleans it up. scmi_probe() marks the management channel DOMID_XEN
> before discovery. If discovery fails, it jumps to error, calls
> unmap_channel_memory(channel), then free_channel_list(). Thus the current
> probe failure path does not leak the mapping.
>
>
> On successful discovery the management mapping is deliberately retained
> for subsequent permission and reset requests. Secondary discovery
> mappings are always removed by collect_agent_id(), whether the transfer
> succeeds or fails.

Ah, okay. Thank you for clarification.

[...]

--
WBR, Volodymyr

  reply	other threads:[~2026-10-29 18:56 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20  8:43 [PATCH v14 0/6] xen/arm: scmi: introduce SCI SCMI SMC multi-agent support Oleksii Moisieiev
2026-10-20  8:43 ` [PATCH v14 1/6] xen/domctl: chain SCI handling before IOMMU in assign_device domctl Oleksii Moisieiev
2026-10-20  8:43 ` [PATCH v14 4/6] xen/arm: scmi: introduce SCI SCMI SMC multi-agent driver Oleksii Moisieiev
2026-10-23  1:56   ` Volodymyr Babchuk
2026-10-26 15:39     ` Oleksii Moisieiev
2026-10-29 18:55       ` Volodymyr Babchuk [this message]
2026-10-20  8:43 ` [PATCH v14 2/6] xen: arm: smccc: add INVALID_PARAMETER error code Oleksii Moisieiev
2026-10-20  8:43 ` [PATCH v14 3/6] lib/arm: Add I/O memory copy helpers Oleksii Moisieiev
2026-10-20  8:43 ` [PATCH v14 6/6] docs: arm: add SCI SCMI SMC multi-agent driver docs Oleksii Moisieiev
2026-10-20  8:43 ` [PATCH v14 5/6] tools/xl/libxl: wire up SCMI SMC multi-agent configuration Oleksii Moisieiev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87v76knxp3.fsf@epam.com \
    --to=volodymyr_babchuk@epam.com \
    --cc=Oleksii_Moisieiev@epam.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=anthony.perard@vates.tech \
    --cc=bertrand.marquis@arm.com \
    --cc=grygorii_strashko@epam.com \
    --cc=jbeulich@suse.com \
    --cc=jgross@suse.com \
    --cc=julien@xen.org \
    --cc=michal.orzel@amd.com \
    --cc=roger@xenproject.org \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox