On 23/01/2026 03:51, Stefano Stabellini wrote:
> Not a full review, but I found three issues plus some spurious changes
>
>
> On Wed, 21 Jan 2026, Oleksii Moisieiev wrote:
>> diff --git a/docs/misc/xen-command-line.pandoc 
>> b/docs/misc/xen-command-line.pandoc
>> index 15f7a315a4..268df3010b 100644
>> --- a/docs/misc/xen-command-line.pandoc
>> +++ b/docs/misc/xen-command-line.pandoc
>> @@ -789,7 +789,7 @@ Specify the bit width of the DMA heap.
>>                   cpuid-faulting=<bool>, msr-relaxed=<bool>,
>>                   pf-fixup=<bool> ] (x86)
>>   
>> -    = List of [ sve=<integer> ] (Arm64)
>> +    = List of [ sve=<integer> ] (Arm)
>>   
>>   Controls for how dom0 is constructed on x86 systems.
> Spurious change
>
>
>> diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c
>> index e4407d6e3f..be0e6263ae 100644
>> --- a/tools/libs/light/libxl_arm.c
>> +++ b/tools/libs/light/libxl_arm.c
>> @@ -240,6 +240,10 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
>>       case LIBXL_ARM_SCI_TYPE_SCMI_SMC:
>>           config->arch.arm_sci_type = XEN_DOMCTL_CONFIG_ARM_SCI_SCMI_SMC;
>>           break;
>> +    case LIBXL_ARM_SCI_TYPE_SCMI_SMC_MULTIAGENT:
>> +        config->arch.arm_sci_type = XEN_DOMCTL_CONFIG_ARM_SCI_SCMI_SMC_MA;
>> +        config->arch.arm_sci_agent_id = 
>> d_config->b_info.arch_arm.arm_sci.agent_id;
>> +        break;
>>       default:
>>           LOG(ERROR, "Unknown ARM_SCI type %d",
>>               d_config->b_info.arch_arm.arm_sci.type);
>> diff --git a/tools/libs/light/libxl_types.idl 
>> b/tools/libs/light/libxl_types.idl
>> index 4a958f69f4..9bfbf09145 100644
>> --- a/tools/libs/light/libxl_types.idl
>> +++ b/tools/libs/light/libxl_types.idl
>> @@ -554,11 +554,13 @@ libxl_sve_type = Enumeration("sve_type", [
>>   
>>   libxl_arm_sci_type = Enumeration("arm_sci_type", [
>>       (0, "none"),
>> -    (1, "scmi_smc")
>> +    (1, "scmi_smc"),
>> +    (2, "scmi_smc_multiagent")
>>       ], init_val = "LIBXL_ARM_SCI_TYPE_NONE")
>>   
>>   libxl_arm_sci = Struct("arm_sci", [
>>       ("type", libxl_arm_sci_type),
>> +    ("agent_id", uint8)
>>       ])
>>   
>>   libxl_rdm_reserve = Struct("rdm_reserve", [
>> diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
>> index 1cc41f1bff..0c389d25f9 100644
>> --- a/tools/xl/xl_parse.c
>> +++ b/tools/xl/xl_parse.c
>> @@ -1306,6 +1306,18 @@ static int parse_arm_sci_config(XLU_Config *cfg, 
>> libxl_arm_sci *arm_sci,
>>               }
>>           }
>>   
>> +        if (MATCH_OPTION("agent_id", ptr, oparg)) {
>> +            unsigned long val = parse_ulong(oparg);
>> +
>> +            if (!val || val > 255) {
>> +                fprintf(stderr, "An invalid ARM_SCI agent_id specified 
>> (%lu). Valid range [1..255]\n",
>> +                        val);
>> +                ret = ERROR_INVAL;
>> +                goto out;
>> +            }
>> +            arm_sci->agent_id = val;
>> +        }
>> +
>>           ptr = strtok(NULL, ",");
>>       }
>>   
>> diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
>> index 4181c10538..ddadc89148 100644
>> --- a/xen/arch/arm/dom0less-build.c
>> +++ b/xen/arch/arm/dom0less-build.c
>> @@ -299,6 +299,17 @@ static int __init domu_dt_sci_parse(struct 
>> dt_device_node *node,
>>           d_cfg->arch.arm_sci_type = XEN_DOMCTL_CONFIG_ARM_SCI_NONE;
>>       else if ( !strcmp(sci_type, "scmi_smc") )
>>           d_cfg->arch.arm_sci_type = XEN_DOMCTL_CONFIG_ARM_SCI_SCMI_SMC;
>> +    else if ( !strcmp(sci_type, "scmi_smc_multiagent") )
>> +    {
>> +        uint32_t agent_id = 0;
>> +
>> +        if ( !dt_property_read_u32(node, "xen,sci-agent-id", &agent_id) ||
>> +             agent_id > UINT8_MAX )
>> +            return -EINVAL;
>> +
>> +        d_cfg->arch.arm_sci_type = XEN_DOMCTL_CONFIG_ARM_SCI_SCMI_SMC_MA;
>> +        d_cfg->arch.arm_sci_agent_id = agent_id;
>> +    }
>>       else
>>       {
>>           printk(XENLOG_ERR "xen,sci_type in not valid (%s) for domain %s\n",
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index 986a456f17..0796561306 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -86,6 +86,37 @@ int __init parse_arch_dom0_param(const char *s, const 
>> char *e)
>>       return -EINVAL;
>>   }
>>   
>> +/* SCMI agent ID for dom0 obtained from xen,sci container */
>> +#define SCMI_AGENT_ID_INVALID UINT8_MAX
>> +
>> +static uint8_t __init get_dom0_scmi_agent_id(void)
>> +{
>> +    const struct dt_device_node *config_node;
>> +    u32 val;
>> +    const struct dt_property *prop;
>> +
>> +    config_node = dt_find_compatible_node(NULL, NULL, "xen,sci");
>> +    if ( !config_node )
>> +        return SCMI_AGENT_ID_INVALID;
>> +
>> +    prop = dt_find_property(config_node, "xen,dom0-sci-agent-id", NULL);
>> +    if ( !prop )
>> +        return SCMI_AGENT_ID_INVALID;
>> +
>> +    if ( !dt_property_read_u32(config_node, "xen,dom0-sci-agent-id", &val) )
>> +        return SCMI_AGENT_ID_INVALID;
>> +
>> +    if ( val >= SCMI_AGENT_ID_INVALID )
>> +    {
>> +         printk(XENLOG_WARNING
>> +             "Invalid xen,dom0-sci-agent-id=%u, SCMI disabled for Dom0\n",
>> +             val);
>> +        return SCMI_AGENT_ID_INVALID;
>> +    }
>> +
>> +    return val;
>> +}
>> +
>>   /* Override macros from asm/page.h to make them work with mfn_t */
>>   #undef virt_to_mfn
>>   #define virt_to_mfn(va) _mfn(__virt_to_mfn(va))
>> @@ -509,7 +540,7 @@ static int __init write_properties(struct domain *d, 
>> struct kernel_info *kinfo,
>>                    dt_property_name_is_equal(prop, "linux,uefi-mmap-start") 
>> ||
>>                    dt_property_name_is_equal(prop, "linux,uefi-mmap-size") ||
>>                    dt_property_name_is_equal(prop, 
>> "linux,uefi-mmap-desc-size") ||
>> -                 dt_property_name_is_equal(prop, 
>> "linux,uefi-mmap-desc-ver"))
>> +                 dt_property_name_is_equal(prop, 
>> "linux,uefi-mmap-desc-ver") )
>>                   continue;
> Spurious change
>
>
>> +static int scmi_dt_assign_device(struct domain *d,
>> +                                 struct dt_phandle_args *ac_spec)
>> +{
>> +    struct scmi_channel *agent_channel;
>> +    uint32_t scmi_device_id = ac_spec->args[0];
>> +    int ret;
>> +
>> +    if ( !d->arch.sci_data )
>> +        return 0;
>> +
>> +    /* The access-controllers is specified for DT dev, but it's not a SCMI 
>> */
>> +    if ( ac_spec->np != scmi_data.dt_dev )
>> +        return 0;
> This comparison can erroneously fail when the pointers point to
> different copies of the same data
>
>
>> +    agent_channel = d->arch.sci_data;
>> +
>> +    spin_lock(&agent_channel->lock);
>> +
>> +    ret = scmi_assign_device(agent_channel->agent_id, scmi_device_id,
>> +                             SCMI_BASE_DEVICE_ACCESS_ALLOW);
>> +    if ( ret )
>> +    {
>> +        printk(XENLOG_ERR
>> +               "scmi: could not assign dev for %pd agent:%d dev_id:%u (%d)",
>> +               d, agent_channel->agent_id, scmi_device_id, ret);
>> +    }
>> +
>> +    spin_unlock(&agent_channel->lock);
>> +    return ret;
>> +}
>> +
>> +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 )
>> +        return ret;
>> +
>> +    printk(XENLOG_DEBUG "id=0x%x name=%s\n", da_rx.agent_id, da_rx.name);
>> +    agent_channel->agent_id = da_rx.agent_id;
>> +    return 0;
>> +}
>> +
>> +static __init int collect_agents(struct dt_device_node *scmi_node)
>> +{
>> +    const struct dt_device_node *config_node;
>> +    const __be32 *prop;
>> +    uint32_t len;
>> +    const __be32 *end;
>> +    uint32_t cells_per_entry = 3; /* Default to 3 cells if property is 
>> absent. */
>> +
>> +    config_node = dt_find_compatible_node(NULL, NULL, "xen,sci");
>> +    if ( !config_node )
>> +    {
>> +        printk(XENLOG_WARNING "scmi: xen,sci node not found, no agents to 
>> collect.\n");
>> +        return -ENOENT;
>> +    }
>> +
>> +    /* Check for the optional '#scmi-secondary-agents-cells' property. */
>> +    if ( dt_property_read_u32(config_node, "#scmi-secondary-agents-cells",
>> +                              &cells_per_entry) )
>> +    {
>> +        if ( cells_per_entry != 2 && cells_per_entry != 3 )
>> +        {
>> +            printk(XENLOG_ERR "scmi: Invalid #scmi-secondary-agents-cells 
>> value: %u\n",
>> +                   cells_per_entry);
>> +            return -EINVAL;
>> +        }
>> +    }
>> +
>> +    prop = dt_get_property(config_node, SCMI_SECONDARY_AGENTS, &len);
>> +    if ( !prop )
>> +    {
>> +        printk(XENLOG_ERR "scmi: No %s property found, no agents to 
>> collect.\n",
>> +               SCMI_SECONDARY_AGENTS);
>> +        return -EINVAL;
>> +    }
>> +
>> +    /* Validate that the property length is a multiple of the cell size. */
>> +    if ( len == 0 || len % (cells_per_entry * sizeof(uint32_t)) != 0 )
>> +    {
>> +        printk(XENLOG_ERR "scmi: Invalid length of %s property: %u for %u 
>> cells per entry\n",
>> +               SCMI_SECONDARY_AGENTS, len, cells_per_entry);
>> +        return -EINVAL;
>> +    }
>> +
>> +    end = (const __be32 *)((const u8 *)prop + len);
>> +
>> +    for ( ; prop < end; )
>> +    {
>> +        uint32_t agent_id;
>> +        uint32_t smc_id;
>> +        uint32_t shmem_phandle;
>> +        struct dt_device_node *node;
>> +        u64 addr, size;
>> +        int ret;
>> +        struct scmi_channel *agent_channel;
>> +
>> +        smc_id = be32_to_cpu(*prop++);
>> +        shmem_phandle = be32_to_cpu(*prop++);
>> +
>> +        if ( cells_per_entry == 3 )
>> +            agent_id = be32_to_cpu(*prop++);
>> +        else
>> +            agent_id = SCMI_BASE_AGENT_ID_OWN;
>> +
>> +        node = dt_find_node_by_phandle(shmem_phandle);
>> +        if ( !node )
>> +        {
>> +            printk(XENLOG_ERR "scmi: Could not find shmem node for agent 
>> %u\n",
>> +                   agent_id);
>> +            return -EINVAL;
>> +        }
>> +
>> +        ret = dt_device_get_address(node, 0, &addr, &size);
>> +        if ( ret )
>> +        {
>> +            printk(XENLOG_ERR
>> +                   "scmi: Could not read shmem address for agent %u: %d\n",
>> +                   agent_id, ret);
>> +            return ret;
>> +        }
>> +
>> +        if ( !IS_ALIGNED(size, SCMI_SHMEM_MAPPED_SIZE) )
>> +        {
>> +            printk(XENLOG_ERR "scmi: shmem memory is not aligned\n");
>> +            return -EINVAL;
>> +        }
>> +
>> +        agent_channel = smc_create_channel(agent_id, smc_id, addr);
>> +        if ( IS_ERR(agent_channel) )
>> +        {
>> +            printk(XENLOG_ERR "scmi: Could not create channel for agent %u: 
>> %ld\n",
>> +                   agent_id, PTR_ERR(agent_channel));
>> +            return PTR_ERR(agent_channel);
>> +        }
>> +
>> +        if ( cells_per_entry == 2 )
>> +        {
>> +            ret = collect_agent_id(agent_channel);
>> +            if ( ret )
>> +                return ret;
>> +        }
>> +
>> +        printk(XENLOG_DEBUG "scmi: Agent %u SMC %X addr %lx\n", 
>> agent_channel->agent_id,
>> +               smc_id, (unsigned long)addr);
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int scmi_domain_init(struct domain *d,
>> +                            struct xen_domctl_createdomain *config)
>> +{
>> +    struct scmi_channel *channel;
>> +    int ret;
>> +
>> +    if ( !scmi_data.initialized )
>> +        return 0;
>> +
>> +    /*
>> +     * SCMI support is configured via:
>> +     * - For dom0: xen,dom0-sci-agent-id property under the xen,sci 
>> container
>> +     * - For dom0less: xen,sci-agent-id in the domain node
>> +     * The config->arch.arm_sci_type and config->arch.arm_sci_agent_id
>> +     * are already set by domain_build.c or dom0less-build.c
>> +     */
>> +
>> +    if ( config->arch.arm_sci_type == XEN_DOMCTL_CONFIG_ARM_SCI_NONE )
>> +        return 0;
>> +
>> +    channel = acquire_scmi_channel(d, config->arch.arm_sci_agent_id);
>> +    if ( IS_ERR(channel) )
>> +    {
>> +        printk(XENLOG_ERR
>> +               "scmi: Failed to acquire SCMI channel for agent_id %u: 
>> %ld\n",
>> +               config->arch.arm_sci_agent_id, PTR_ERR(channel));
>> +        return PTR_ERR(channel);
>> +    }
>> +
>> +    printk(XENLOG_INFO
>> +           "scmi: Acquire channel id = 0x%x, domain_id = %d paddr = 
>> 0x%lx\n",
>> +           channel->agent_id, channel->domain_id, channel->paddr);
>> +
>> +    /*
>> +     * Dom0 (if present) needs to have an access to the guest memory range
>> +     * to satisfy iomem_access_permitted() check in 
>> XEN_DOMCTL_iomem_permission
>> +     * domctl.
>> +     */
>> +    if ( hardware_domain && !is_hardware_domain(d) )
>> +    {
>> +        ret = iomem_permit_access(hardware_domain, 
>> paddr_to_pfn(channel->paddr),
>> +                                  paddr_to_pfn(channel->paddr + PAGE_SIZE - 
>> 1));
>> +        if ( ret )
>> +            goto error;
>> +    }
>> +
>> +    d->arch.sci_data = channel;
>> +    d->arch.sci_enabled = true;
>> +
>> +    return 0;
>> +
>> +error:
>> +    relinquish_scmi_channel(channel);
>> +    return ret;
>> +}
>> +
>> +int scmi_domain_sanitise_config(struct xen_domctl_createdomain *config)
>> +{
>> +    if ( config->arch.arm_sci_type != XEN_DOMCTL_CONFIG_ARM_SCI_NONE &&
>> +         config->arch.arm_sci_type != XEN_DOMCTL_CONFIG_ARM_SCI_SCMI_SMC_MA 
>> )
>> +    {
>> +        dprintk(XENLOG_INFO, "scmi: Unsupported ARM_SCI type\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int scmi_relinquish_resources(struct domain *d)
>> +{
>> +    int ret;
>> +    struct scmi_channel *channel, *agent_channel;
>> +    scmi_msg_header_t hdr;
>> +    struct scmi_msg_base_reset_agent_cfg_a2p tx;
>> +
>> +    if ( !d->arch.sci_data )
>> +        return 0;
>> +
>> +    agent_channel = d->arch.sci_data;
>> +
>> +    spin_lock(&agent_channel->lock);
>> +    tx.agent_id = agent_channel->agent_id;
>> +    spin_unlock(&agent_channel->lock);
>> +
>> +    channel = get_channel_by_id(scmi_data.hyp_channel_agent_id);
>> +    if ( !channel )
>> +    {
>> +        printk(XENLOG_ERR
>> +               "scmi: Unable to get Hypervisor scmi channel for domain 
>> %d\n",
>> +               d->domain_id);
>> +        return -EINVAL;
>> +    }
>> +
>> +    hdr.id = SCMI_BASE_RESET_AGENT_CONFIGURATION;
>> +    hdr.type = 0;
>> +    hdr.protocol = SCMI_BASE_PROTOCOL;
>> +
>> +    tx.flags = 0;
> is this correct?
>
>
>> +    ret = do_smc_xfer(channel, &hdr, &tx, sizeof(tx), NULL, 0);
>> +    if ( ret == -EOPNOTSUPP )
>> +        return 0;
>> +
>> +    return ret;
>> +}
>> +
>> +static void scmi_domain_destroy(struct domain *d)
>> +{
>> +    struct scmi_channel *channel;
>> +
>> +    if ( !d->arch.sci_data )
>> +        return;
>> +
>> +    channel = d->arch.sci_data;
>> +    spin_lock(&channel->lock);
>> +
>> +    relinquish_scmi_channel(channel);
>> +    printk(XENLOG_DEBUG "scmi: Free domain %d\n", d->domain_id);
>> +
>> +    d->arch.sci_data = NULL;
>> +    d->arch.sci_enabled = false;
>> +
>> +    spin_unlock(&channel->lock);
>> +}
>> +
>> +static bool scmi_handle_call(struct cpu_user_regs *regs)
>> +{
>> +    uint32_t fid = (uint32_t)get_user_reg(regs, 0);
>> +    struct scmi_channel *agent_channel;
>> +    struct domain *d = current->domain;
>> +    struct arm_smccc_res resp;
>> +    bool res = false;
>> +
>> +    if ( !sci_domain_is_enabled(d) )
>> +        return false;
>> +
>> +    agent_channel = d->arch.sci_data;
>> +    spin_lock(&agent_channel->lock);
>> +
>> +    if ( agent_channel->func_id != fid )
>> +    {
>> +        res = false;
>> +        goto unlock;
>> +    }
>> +
>> +    arm_smccc_1_1_smc(fid,
>> +                      get_user_reg(regs, 1),
>> +                      get_user_reg(regs, 2),
>> +                      get_user_reg(regs, 3),
>> +                      get_user_reg(regs, 4),
>> +                      get_user_reg(regs, 5),
>> +                      get_user_reg(regs, 6),
>> +                      get_user_reg(regs, 7),
>> +                      &resp);
>> +
>> +    set_user_reg(regs, 0, resp.a0);
>> +    set_user_reg(regs, 1, resp.a1);
>> +    set_user_reg(regs, 2, resp.a2);
>> +    set_user_reg(regs, 3, resp.a3);
>> +    res = true;
>> +unlock:
>> +    spin_unlock(&agent_channel->lock);
>> +
>> +    return res;
>> +}
>> +
>> +static const struct sci_mediator_ops scmi_ops = {
>> +    .domain_init = scmi_domain_init,
>> +    .domain_destroy = scmi_domain_destroy,
>> +    .relinquish_resources = scmi_relinquish_resources,
>> +    .handle_call = scmi_handle_call,
>> +    .dom0_dt_handle_node = scmi_dt_handle_node,
>> +    .domain_sanitise_config = scmi_domain_sanitise_config,
>> +    .assign_dt_device = scmi_dt_assign_device,
>> +};
>> +
>> +static int __init scmi_check_smccc_ver(void)
>> +{
>> +    if ( smccc_ver < ARM_SMCCC_VERSION_1_1 )
>> +    {
>> +        printk(XENLOG_WARNING
>> +               "scmi: No SMCCC 1.1 support, SCMI calls forwarding 
>> disabled\n");
>> +        return -ENOSYS;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int __init scmi_dt_hyp_channel_read(struct dt_device_node *scmi_node,
>> +                                           struct scmi_data *scmi_data,
>> +                                           u64 *addr)
>> +{
>> +    int ret;
>> +    u64 size;
>> +
>> +    if ( !dt_property_read_u32(scmi_node, "arm,smc-id", 
>> &scmi_data->func_id) )
>> +    {
>> +        printk(XENLOG_ERR "scmi: unable to read smc-id from DT\n");
>> +        return -ENOENT;
>> +    }
>> +
>> +    ret = scmi_dt_read_hyp_channel_addr(scmi_node, addr, &size);
>> +    if ( IS_ERR_VALUE(ret) )
>> +        return -ENOENT;
>> +
>> +    if ( !IS_ALIGNED(size, SCMI_SHMEM_MAPPED_SIZE) )
>> +    {
>> +        printk(XENLOG_ERR "scmi: shmem memory is not aligned\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static __init int scmi_probe(struct dt_device_node *scmi_node, const void 
>> *data)
>> +{
>> +    u64 addr;
>> +    int ret;
>> +    struct scmi_channel *channel;
>> +    unsigned int n_agents;
>> +    scmi_msg_header_t hdr;
>> +    struct scmi_msg_base_attributes_p2a rx;
>> +
>> +    ASSERT(scmi_node != NULL);
>> +
>> +    /*
>> +     * Only bind to the SCMI node provided by Xen under the xen,sci 
>> container
>> +     * (e.g. /chosen/xen/xen_scmi_config/scmi). This avoids binding to 
>> firmware
>> +     * SCMI nodes that belong to the host OSPM and keeps the mediator 
>> scoped to
>> +     * Xen-provided configuration only.
>> +     */
>> +    if ( !scmi_is_under_xen_sci(scmi_node) )
>> +        return -ENODEV;
>> +
>> +    INIT_LIST_HEAD(&scmi_data.channel_list);
>> +    spin_lock_init(&scmi_data.channel_list_lock);
>> +
>> +    if ( !acpi_disabled )
>> +    {
>> +        printk(XENLOG_WARNING "scmi: is not supported when using ACPI\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    ret = scmi_check_smccc_ver();
>> +    if ( ret )
>> +        return ret;
>> +
>> +    ret = scmi_dt_hyp_channel_read(scmi_node, &scmi_data, &addr);
>> +    if ( ret )
>> +        return ret;
>> +
>> +    scmi_data.dt_dev = scmi_node;
>> +
>> +    channel = smc_create_channel(SCMI_BASE_AGENT_ID_OWN, scmi_data.func_id, 
>> addr);
>> +    if ( IS_ERR(channel) )
>> +        goto out;
>> +
>> +    /* Mark as Xen management channel before collecting agent ID */
>> +    channel->domain_id = DOMID_XEN;
>> +
>> +    /* Request agent id for Xen management channel  */
>> +    ret = collect_agent_id(channel);
>> +    if ( ret )
>> +        goto error;
>> +
>> +    /* Save the agent id for Xen management channel */
>> +    scmi_data.hyp_channel_agent_id = channel->agent_id;
>> +
>> +    hdr.id = SCMI_BASE_PROTOCOL_ATTIBUTES;
>> +    hdr.type = 0;
>> +    hdr.protocol = SCMI_BASE_PROTOCOL;
>> +
>> +    ret = do_smc_xfer(channel, &hdr, NULL, 0, &rx, sizeof(rx));
>> +    if ( ret )
>> +        goto error;
>> +
>> +    n_agents = SCMI_FIELD_GET(SCMI_BASE_ATTR_NUM_AGENT, rx.attributes);
>> +    printk(XENLOG_DEBUG "scmi: Got agent count %d\n", n_agents);
>> +    ret = collect_agents(scmi_node);
>> +    if ( ret )
>> +        goto error;
>> +
>> +    ret = sci_register(&scmi_ops);
>> +    if ( ret )
>> +    {
>> +        printk(XENLOG_ERR "SCMI: mediator already registered (ret = %d)\n",
>> +               ret);
>> +        return ret;
>> +    }
>> +
>> +    scmi_data.initialized = true;
>> +    goto out;
>> +
>> +error:
>> +    unmap_channel_memory(channel);
> This might cause the ASSERT at the beginning of unmap_channel_memory to
> trigger
>
>
Great finding... First `goto error` could be called after 
`collect_agent_id`.
So in case if we receive -ENOMEM from `ioremap_nocache` inside 
`map_channel_memory`
ASSERT will fire.

I'm planning to refactor this as follows:

     static void unmap_channel_memory(struct scmi_channel *channel)
     {
         ASSERT(channel);

         if ( !channel->shmem )
             return;
         ...
      }

This will cause function to skip iounmap if shmem is NULL;
What do you think?
>> +    free_channel_list();
>> +out:
>> +    return ret;
>> +}
>> +
>> +static const struct dt_device_match scmi_smc_match[] __initconst = {
>> +    DT_MATCH_COMPATIBLE("arm,scmi-smc"),
>> +    { /* sentinel */ },
>> +};
>> +
>> +DT_DEVICE_START(scmi_smc_ma, "SCMI SMC MEDIATOR", DEVICE_FIRMWARE)
>> +        .dt_match = scmi_smc_match,
>> +        .init = scmi_probe,
>> +DT_DEVICE_END
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * tab-width: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
>> index d30a288592..8f0f68544e 100644
>> --- a/xen/include/public/arch-arm.h
>> +++ b/xen/include/public/arch-arm.h
>> @@ -329,6 +329,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
>>   
>>   #define XEN_DOMCTL_CONFIG_ARM_SCI_NONE      0
>>   #define XEN_DOMCTL_CONFIG_ARM_SCI_SCMI_SMC  1
>> +#define XEN_DOMCTL_CONFIG_ARM_SCI_SCMI_SMC_MA  2
>>   
>>   struct xen_arch_domainconfig {
>>       /* IN/OUT */
>> @@ -355,6 +356,8 @@ struct xen_arch_domainconfig {
>>       uint32_t clock_frequency;
>>       /* IN */
>>       uint8_t arm_sci_type;
>> +    /* IN */
>> +    uint8_t arm_sci_agent_id;
>>   };
>>   #endif /* __XEN__ || __XEN_TOOLS__ */
>>   
>> -- 
>> 2.34.1
>>

Reply via email to