From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C3E8C6FA8E for ; Fri, 24 Feb 2023 22:40:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229569AbjBXWkK (ORCPT ); Fri, 24 Feb 2023 17:40:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48772 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229620AbjBXWkI (ORCPT ); Fri, 24 Feb 2023 17:40:08 -0500 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 755246F424; Fri, 24 Feb 2023 14:40:02 -0800 (PST) Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 31OFZaCr015746; Fri, 24 Feb 2023 22:39:40 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=message-id : date : mime-version : subject : to : cc : references : from : in-reply-to : content-type : content-transfer-encoding; s=qcppdkim1; bh=Aa6PSvz5BZk1EStzRiqlmzYuoCdHzQ0e/pseI0xLwrc=; b=eYS0+Gcy9rjHPabSaRz5Yc+Wf6gahJnBvN2zl467y/Xj89G7T/7Y/oTn1DGYJ0T8LZLt k/v92VdyEip+hZcSC1gRQBXbC889RJe2pAkfpUyZHM8dHO9q+nZqmLV4HnCvvRD7apJH I58ZKzCiALGhKTdr29kYZj4QkRHpQWLXmj6A7iJI8wj8ljl9eB5Wj/XoEipmXnrpJLNM u2+wdBBecuAxmeJEXXyzrukvrOelytFhyUNDw0gu6PD01oygIHPnWpJvkNDo1GcqJUtu yIJe0tiPSnao/pkCPK5mRr5N8MP/Ee99rfVeKOj/AF1If+DAdtt5wdJVqFM50WsRX8di Kw== Received: from nasanppmta01.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3nwybwp285-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Feb 2023 22:39:40 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 31OMdYjI010164 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Feb 2023 22:39:34 GMT Received: from [10.110.9.108] (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.41; Fri, 24 Feb 2023 14:39:33 -0800 Message-ID: <2fe3993a-b3b1-119d-e335-56979d6ecd99@quicinc.com> Date: Fri, 24 Feb 2023 14:39:32 -0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.6.1 Subject: Re: [PATCH v10 08/26] gunyah: rsc_mgr: Add resource manager RPC core Content-Language: en-US To: Alex Elder , Alex Elder , Srinivas Kandagatla , Prakruthi Deepak Heragu CC: Murali Nalajala , Trilok Soni , Srivatsa Vaddagiri , Carl van Schaik , Dmitry Baryshkov , Bjorn Andersson , "Konrad Dybcio" , Arnd Bergmann , "Greg Kroah-Hartman" , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Bagas Sanjaya , Catalin Marinas , Jassi Brar , , , , , References: <20230214211229.3239350-1-quic_eberman@quicinc.com> <20230214212327.3310128-1-quic_eberman@quicinc.com> <9c56e16e-ecd0-2ef4-14d8-476029458359@linaro.org> From: Elliot Berman In-Reply-To: <9c56e16e-ecd0-2ef4-14d8-476029458359@linaro.org> Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 8bit X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: CKgDjhI-4ZSijQj4g5jO2634-VPPGT9M X-Proofpoint-ORIG-GUID: CKgDjhI-4ZSijQj4g5jO2634-VPPGT9M X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.930,Hydra:6.0.562,FMLib:17.11.170.22 definitions=2023-02-24_16,2023-02-24_01,2023-02-09_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 mlxlogscore=999 malwarescore=0 impostorscore=0 bulkscore=0 spamscore=0 mlxscore=0 priorityscore=1501 adultscore=0 phishscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2302240182 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org On 2/23/2023 3:28 PM, Alex Elder wrote: > On 2/14/23 3:23 PM, Elliot Berman wrote: >> >> +} >> + >> +static int gh_rm_init_connection_payload(struct gh_rm_connection >> *connection, void *msg, >> +                    size_t hdr_size, size_t msg_size) > > The value of hdr_size is *always* sizeof(*hdr), so you can > do without passing it as an argument. > hdr_size is different when receiving reply (1 extra word) vs notification. >> +{ >> +    size_t max_buf_size, payload_size; >> +    struct gh_rm_rpc_hdr *hdr = msg; >> + > > It probably sounds dumb, but I'd reverse the values > compared below (and the operator). > >> +    if (hdr_size > msg_size) >> +        return -EINVAL; >> + >> +    payload_size = msg_size - hdr_size; >> + >> +    connection->num_fragments = FIELD_GET(RM_RPC_FRAGMENTS_MASK, >> hdr->type); >> +    connection->fragments_received = 0; >> + >> +    /* There's not going to be any payload, no need to allocate >> buffer. */ >> +    if (!payload_size && !connection->num_fragments) > > The payload size is the same across all messages in the > "connection" right?  As is the number of fragments? > It's not even possible/valid to have a zero payload size > and non-zero number of fragments.  I think the second > half of the above test can be dropped. > The RM RPC specification doesn't require that the first message have payload. (It makes sense to do it and it does, but that's implementation detail) >> +        return 0; >> + >> +    if (connection->num_fragments > GH_RM_MAX_NUM_FRAGMENTS) >> +        return -EINVAL; >> + >> +    max_buf_size = payload_size + (connection->num_fragments * >> GH_RM_MAX_MSG_SIZE); >> + >> +    connection->payload = kzalloc(max_buf_size, GFP_KERNEL); >> +    if (!connection->payload) >> +        return -ENOMEM; >> + >> +    memcpy(connection->payload, msg + hdr_size, payload_size); > > I think I suggested (hdr + 1) rather than (msg + size) elsewhere > and you took that suggestion.  I'd say do it one way or the other, > consistently, everywhere. > hdr_size != sizeof(*hdr) when we receive a reply message. >> +    connection->size = payload_size; >> +    return 0; >> +} >> + >> +static void gh_rm_notif_work(struct work_struct *work) >> +{ >> +    struct gh_rm_connection *connection = container_of(work, struct >> gh_rm_connection, >> +                                notification.work); >> +    struct gh_rm *rm = connection->notification.rm; >> + >> +    blocking_notifier_call_chain(&rm->nh, connection->msg_id, >> connection->payload); >> + >> +    put_gh_rm(rm); >> +    kfree(connection->payload); >> +    kfree(connection); >> +} >> + >> +static struct gh_rm_connection *gh_rm_process_notif(struct gh_rm *rm, >> void *msg, size_t msg_size) > > I think it might be better if you do some of what the caller > does here.  I.e., verify the current connection is null (and > abort if not and make it NULL), then assign it to the new > connection before you return success.  And return an errno. > Since you and Srini both suggest to do it, I'll cave. :-) >> +{ >> +    struct gh_rm_connection *connection; >> +    struct gh_rm_rpc_hdr *hdr = msg; >> +    int ret; >> + >> +    connection = gh_rm_alloc_connection(hdr->msg_id, RM_RPC_TYPE_NOTIF); >> +    if (IS_ERR(connection)) { >> +        dev_err(rm->dev, "Failed to alloc connection for >> notification: %ld, dropping.\n", >> +            PTR_ERR(connection)); >> +        return NULL; >> +    } >> + >> +    get_gh_rm(rm); >> +    connection->notification.rm = rm; >> +    INIT_WORK(&connection->notification.work, gh_rm_notif_work); >> + >> +    ret = gh_rm_init_connection_payload(connection, msg, >> sizeof(*hdr), msg_size); >> +    if (ret) { >> +        dev_err(rm->dev, "Failed to initialize connection buffer for >> notification: %d\n", >> +            ret); >> +        kfree(connection); >> +        return NULL; >> +    } >> + >> +    return connection; >> +} >> + >> +static struct gh_rm_connection *gh_rm_process_rply(struct gh_rm *rm, >> void *msg, size_t msg_size) >> +{ > > Here too, make sure there is no active connection and then > set it within this function if the errno returned is 0. > >> +    struct gh_rm_rpc_reply_hdr *reply_hdr = msg; >> +    struct gh_rm_connection *connection; >> +    u16 seq_id = le16_to_cpu(reply_hdr->hdr.seq); >> + >> +    mutex_lock(&rm->call_idr_lock); >> +    connection = idr_find(&rm->call_idr, seq_id); >> +    mutex_unlock(&rm->call_idr_lock); >> + >> +    if (!connection || connection->msg_id != reply_hdr->hdr.msg_id) >> +        return NULL; >> + >> +    if (gh_rm_init_connection_payload(connection, msg, >> sizeof(*reply_hdr), msg_size)) { >> +        dev_err(rm->dev, "Failed to alloc connection buffer for >> sequence %d\n", seq_id); >> +        /* Send connection complete and error the client. */ >> +        connection->reply.ret = -ENOMEM; >> +        complete(&connection->reply.seq_done); >> +        return NULL; >> +    } >> + >> +    connection->reply.rm_error = le32_to_cpu(reply_hdr->err_code); >> +    return connection; >> +} >> + >> +static int gh_rm_process_cont(struct gh_rm *rm, struct >> gh_rm_connection *connection, >> +                void *msg, size_t msg_size) > > Similar comment here.  Have this function verify there is > a non-null active connection.  Then process the message > and abort if there's an error (and null the active connection > pointer). > >> +{ >> +    struct gh_rm_rpc_hdr *hdr = msg; >> +    size_t payload_size = msg_size - sizeof(*hdr); >> + >> +    /* >> +     * hdr->fragments and hdr->msg_id preserves the value from first >> reply >> +     * or notif message. To detect mishandling, check it's still intact. >> +     */ >> +    if (connection->msg_id != hdr->msg_id || >> +        connection->num_fragments != FIELD_GET(RM_RPC_FRAGMENTS_MASK, >> hdr->type)) >> +        return -EINVAL; > > Maybe -EBADMSG? > >> + >> +    memcpy(connection->payload + connection->size, msg + >> sizeof(*hdr), payload_size); >> +    connection->size += payload_size; >> +    connection->fragments_received++; >> +    return 0; >> +} >> + >> +static void gh_rm_abort_connection(struct gh_rm_connection *connection) >> +{ >> +    switch (connection->type) { >> +    case RM_RPC_TYPE_REPLY: >> +        connection->reply.ret = -EIO; >> +        complete(&connection->reply.seq_done); >> +        break; >> +    case RM_RPC_TYPE_NOTIF: >> +        fallthrough; >> +    default: >> +        kfree(connection->payload); >> +        kfree(connection); >> +    } >> +} >> + >> +static bool gh_rm_complete_connection(struct gh_rm *rm, struct >> gh_rm_connection *connection) > > The only caller of this function passes rm->active_rx_connection > as the second argument.  It is available to you here, so you > can get rid of that argument. > >> +{ >> +    if (!connection || connection->fragments_received != >> connection->num_fragments) >> +        return false; >> + >> +    switch (connection->type) { >> +    case RM_RPC_TYPE_REPLY: >> +        complete(&connection->reply.seq_done); >> +        break; >> +    case RM_RPC_TYPE_NOTIF: >> +        schedule_work(&connection->notification.work); >> +        break; >> +    default: >> +        dev_err(rm->dev, "Invalid message type (%d) received\n", >> connection->type); >> +        gh_rm_abort_connection(connection); >> +        break; >> +    } >> + >> +    return true; >> +} >> + >> +static void gh_rm_msgq_rx_data(struct mbox_client *cl, void *mssg) >> +{ >> +    struct gh_rm *rm = container_of(cl, struct gh_rm, msgq_client); >> +    struct gh_msgq_rx_data *rx_data = mssg; >> +    size_t msg_size = rx_data->length; >> +    void *msg = rx_data->data; >> +    struct gh_rm_rpc_hdr *hdr; >> + > > Is it required that at least one byte (past the header) will > be received?  I.e., should the "<=" below just be "<"? > >> +    if (msg_size <= sizeof(*hdr) || msg_size > GH_MSGQ_MAX_MSG_SIZE) >> +        return; > > You previously reported a message here.  These seem like > errors, which if they occur, maybe should be reported. > They seem like "never happen" issues, but it's defensive > to make these checks (which is good). > >> + >> +    hdr = msg; >> +    if (hdr->api != RM_RPC_API) { > > If this ever happens, is the hardware failing?  It seems > like once Gunyah is initialized and you've checked the > API version once, there should be no need to check it > repeatedly. I'd need to check the API version for the first message. On subsequent messages, I'd need to check if I already checked. Might as well just check the version every time? >> + >> +void get_gh_rm(struct gh_rm *rm) > > It is often pretty handy to return the argument in > functions like this.  It simultaneously takes the > reference and assigns the pointer the reference > represents. > > I've updated so that gh_rm_get() returns a struct device * (the miscdev's device). Is this too unusual? >> +{ >> +    get_device(rm->dev); >> +} >> +EXPORT_SYMBOL_GPL(get_gh_rm); >> + >> +void put_gh_rm(struct gh_rm *rm) >> +{ >> +    put_device(rm->dev); >> +} >> +EXPORT_SYMBOL_GPL(put_gh_rm); >> + >> +static int gh_msgq_platform_probe_direction(struct platform_device >> *pdev, >> +                    bool tx, int idx, struct gunyah_resource *ghrsc) >> +{ >> +    struct device_node *node = pdev->dev.of_node; >> +    int ret; > > I think you should declare idx as a local variable. > >     int idx = tx ? 1 : 0; > >> + >> +    ghrsc->type = tx ? GUNYAH_RESOURCE_TYPE_MSGQ_TX : >> GUNYAH_RESOURCE_TYPE_MSGQ_RX; >> + >> +    ghrsc->irq = platform_get_irq(pdev, idx); > > Do you suppose you could do platform_get_irq_byname(), and then > specify the names of the IRQs ("rm_tx_irq" and "rm_rx_irq" maybe)? > >> +    if (ghrsc->irq < 0) { >> +        dev_err(&pdev->dev, "Failed to get irq%d: %d\n", idx, >> ghrsc->irq); > > Maybe:    "Failed to get %cX IRQ: %d\n", tx ? 'T' : 'R', ghrsc->irq); > >> +        return ghrsc->irq; >> +    } >> + >> +    ret = of_property_read_u64_index(node, "reg", idx, &ghrsc->capid); > > Is a capability ID a simple (but large) number? > > The *resource manager* (which is a very special VM) has to > have both TX and RX message queue capability IDs.  Is there > 'any chance that these specific capability IDs have values > that are fixed by the design?  Like, 0 and 1?  I don't know > what they are, but it seems like it *could* be something > fixed by the design, and if that were the case, there would > be no need to specify the "reg" property to get the "capid" > values. > They aren't fixed by the design in a production version of Gunyah. >> +    if (ret) { >> +        dev_err(&pdev->dev, "Failed to get capid%d: %d\n", idx, ret); >> +        return ret; >> +    } >> + >> +    return 0; >> +} >> + >> +static int gh_rm_drv_probe(struct platform_device *pdev) >> +{ >> +    struct gh_msgq_tx_data *msg; >> +    struct gh_rm *rm; >> +    int ret; >> + >> +    rm = devm_kzalloc(&pdev->dev, sizeof(*rm), GFP_KERNEL); >> +    if (!rm) >> +        return -ENOMEM; >> + >> +    platform_set_drvdata(pdev, rm); >> +    rm->dev = &pdev->dev; >> + >> +    mutex_init(&rm->call_idr_lock); >> +    idr_init(&rm->call_idr); >> +    rm->cache = kmem_cache_create("gh_rm", struct_size(msg, data, >> GH_MSGQ_MAX_MSG_SIZE), 0, >> +        SLAB_HWCACHE_ALIGN, NULL); >> +    if (!rm->cache) >> +        return -ENOMEM; > > If you abstracted the allocation interface for these messages, > you could actually survive without the slab cache here.  But > if this fails, maybe you won't get far anyway. > >> +    mutex_init(&rm->send_lock); >> +    BLOCKING_INIT_NOTIFIER_HEAD(&rm->nh); >> + >> +    ret = gh_msgq_platform_probe_direction(pdev, true, 0, >> &rm->tx_ghrsc); >> +    if (ret) >> +        goto err_cache; >> + >> +    ret = gh_msgq_platform_probe_direction(pdev, false, 1, >> &rm->rx_ghrsc); >> +    if (ret) >> +        goto err_cache; >> + >> +    rm->msgq_client.dev = &pdev->dev; >> +    rm->msgq_client.tx_block = true; >> +    rm->msgq_client.rx_callback = gh_rm_msgq_rx_data; >> +    rm->msgq_client.tx_done = gh_rm_msgq_tx_done; >> + >> +    return gh_msgq_init(&pdev->dev, &rm->msgq, &rm->msgq_client, >> &rm->tx_ghrsc, &rm->rx_ghrsc); >> +err_cache: >> +    kmem_cache_destroy(rm->cache); >> +    return ret; >> +} >> + >> +static int gh_rm_drv_remove(struct platform_device *pdev) >> +{ >> +    struct gh_rm *rm = platform_get_drvdata(pdev); >> + >> +    mbox_free_channel(gh_msgq_chan(&rm->msgq)); >> +    gh_msgq_remove(&rm->msgq); >> +    kmem_cache_destroy(rm->cache); >> + >> +    return 0; >> +} >> + >> +static const struct of_device_id gh_rm_of_match[] = { >> +    { .compatible = "gunyah-resource-manager" }, >> +    {} >> +}; >> +MODULE_DEVICE_TABLE(of, gh_rm_of_match); >> + >> +static struct platform_driver gh_rm_driver = { >> +    .probe = gh_rm_drv_probe, >> +    .remove = gh_rm_drv_remove, >> +    .driver = { >> +        .name = "gh_rsc_mgr", >> +        .of_match_table = gh_rm_of_match, >> +    }, >> +}; >> +module_platform_driver(gh_rm_driver); >> + >> +MODULE_LICENSE("GPL"); >> +MODULE_DESCRIPTION("Gunyah Resource Manager Driver"); >> diff --git a/drivers/virt/gunyah/rsc_mgr.h >> b/drivers/virt/gunyah/rsc_mgr.h >> new file mode 100644 >> index 000000000000..d4e799a7526f >> --- /dev/null >> +++ b/drivers/virt/gunyah/rsc_mgr.h >> @@ -0,0 +1,77 @@ >> +/* SPDX-License-Identifier: GPL-2.0-only */ >> +/* >> + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All >> rights reserved. >> + */ >> +#ifndef __GH_RSC_MGR_PRIV_H >> +#define __GH_RSC_MGR_PRIV_H >> + >> +#include >> +#include >> +#include >> + >> +/* RM Error codes */ >> +enum gh_rm_error { >> +    GH_RM_ERROR_OK            = 0x0, >> +    GH_RM_ERROR_UNIMPLEMENTED    = 0xFFFFFFFF, >> +    GH_RM_ERROR_NOMEM        = 0x1, >> +    GH_RM_ERROR_NORESOURCE        = 0x2, >> +    GH_RM_ERROR_DENIED        = 0x3, >> +    GH_RM_ERROR_INVALID        = 0x4, >> +    GH_RM_ERROR_BUSY        = 0x5, >> +    GH_RM_ERROR_ARGUMENT_INVALID    = 0x6, >> +    GH_RM_ERROR_HANDLE_INVALID    = 0x7, >> +    GH_RM_ERROR_VALIDATE_FAILED    = 0x8, >> +    GH_RM_ERROR_MAP_FAILED        = 0x9, >> +    GH_RM_ERROR_MEM_INVALID        = 0xA, >> +    GH_RM_ERROR_MEM_INUSE        = 0xB, >> +    GH_RM_ERROR_MEM_RELEASED    = 0xC, >> +    GH_RM_ERROR_VMID_INVALID    = 0xD, >> +    GH_RM_ERROR_LOOKUP_FAILED    = 0xE, >> +    GH_RM_ERROR_IRQ_INVALID        = 0xF, >> +    GH_RM_ERROR_IRQ_INUSE        = 0x10, >> +    GH_RM_ERROR_IRQ_RELEASED    = 0x11, >> +}; >> + >> +/** >> + * gh_rm_remap_error() - Remap Gunyah resource manager errors into a >> Linux error code >> + * @gh_error: "Standard" return value from Gunyah resource manager >> + */ >> +static inline int gh_rm_remap_error(enum gh_rm_error rm_error) >> +{ >> +    switch (rm_error) { >> +    case GH_RM_ERROR_OK: >> +        return 0; >> +    case GH_RM_ERROR_UNIMPLEMENTED: >> +        return -EOPNOTSUPP; >> +    case GH_RM_ERROR_NOMEM: >> +        return -ENOMEM; >> +    case GH_RM_ERROR_NORESOURCE: >> +        return -ENODEV; >> +    case GH_RM_ERROR_DENIED: >> +        return -EPERM; >> +    case GH_RM_ERROR_BUSY: >> +        return -EBUSY; >> +    case GH_RM_ERROR_INVALID: >> +    case GH_RM_ERROR_ARGUMENT_INVALID: >> +    case GH_RM_ERROR_HANDLE_INVALID: >> +    case GH_RM_ERROR_VALIDATE_FAILED: >> +    case GH_RM_ERROR_MAP_FAILED: >> +    case GH_RM_ERROR_MEM_INVALID: >> +    case GH_RM_ERROR_MEM_INUSE: >> +    case GH_RM_ERROR_MEM_RELEASED: >> +    case GH_RM_ERROR_VMID_INVALID: >> +    case GH_RM_ERROR_LOOKUP_FAILED: >> +    case GH_RM_ERROR_IRQ_INVALID: >> +    case GH_RM_ERROR_IRQ_INUSE: >> +    case GH_RM_ERROR_IRQ_RELEASED: >> +        return -EINVAL; >> +    default: >> +        return -EBADMSG; >> +    } >> +} >> + >> +struct gh_rm; > > This might just be my preference, but I like to see declarations > like the one above grouped at the top of the file, under includes. > >> +int gh_rm_call(struct gh_rm *rsc_mgr, u32 message_id, void *req_buff, >> size_t req_buff_size, >> +        void **resp_buf, size_t *resp_buff_size); >> + >> +#endif >> diff --git a/include/linux/gunyah_rsc_mgr.h >> b/include/linux/gunyah_rsc_mgr.h >> new file mode 100644 >> index 000000000000..c992b3188c8d >> --- /dev/null >> +++ b/include/linux/gunyah_rsc_mgr.h >> @@ -0,0 +1,24 @@ >> +/* SPDX-License-Identifier: GPL-2.0-only */ >> +/* >> + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All >> rights reserved. >> + */ >> + >> +#ifndef _GUNYAH_RSC_MGR_H >> +#define _GUNYAH_RSC_MGR_H >> + >> +#include >> +#include >> +#include >> + >> +#define GH_VMID_INVAL    U16_MAX >> + >> +/* Gunyah recognizes VMID0 as an alias to the current VM's ID */ >> +#define GH_VMID_SELF            0 > > I haven't really checked very well, bur you should *use this* > definition where a VMID is being examined. I.e., if you're > going to define this, then never just compare a VMID against 0. > I realize now the only place I *could* use GH_VMID_SELF is the one exception to usage of VMID -- in gh_rm_vmid_alloc. There, vmid of 0 means "use dynamic allocation". Since there aren't any users of the GH_VMID_SELF, I'll drop it. Thanks, Elliot >                     -Alex > >> + >> +struct gh_rm; >> +int gh_rm_notifier_register(struct gh_rm *rm, struct notifier_block >> *nb); >> +int gh_rm_notifier_unregister(struct gh_rm *rm, struct notifier_block >> *nb); >> +void get_gh_rm(struct gh_rm *rm); >> +void put_gh_rm(struct gh_rm *rm); >> + >> +#endif > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E2EA5C6FA8E for ; Fri, 24 Feb 2023 22:41:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:From:References:CC:To:Subject: MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=U457tV01nK+jl3Eas2bWRSF0mXA7534xNqcwKr696Is=; b=3LJZw8A26b5WZe 6cX2cWu4zPuNpl+w47IuAIO3q34GYrvQQYNyn39HOsUEeezD8KSjgD4JzIZVrpJcQq8UynD6r9ck0 +1XTl9PxD8bNMpu5wdaAsW5j5YPc9Aw6n+vFXKPKduE2y34oFKOKTwOfcgrhHPDdklf4LAmId9phS dY4Fa66VzhtFVx8MdaZ5ZeYg4vGM4r4sMW9XS4Qz0b0n0hXduXFE3Zc5QY1jUDbfG7dLxb5Z76DJR KRPROCJp2Gq/ifixQwXGnwY/rmtN3pWOs8vjLW6zPrHg4+DUl3Q/9YdO6hFxf1RhkLssRBa2aiPx3 nDgok55PUSjSIVSxghBg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1pVgjT-004BS5-4F; Fri, 24 Feb 2023 22:40:03 +0000 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1pVgjO-004BQt-F6 for linux-arm-kernel@lists.infradead.org; Fri, 24 Feb 2023 22:40:01 +0000 Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 31OFZaCr015746; Fri, 24 Feb 2023 22:39:40 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=message-id : date : mime-version : subject : to : cc : references : from : in-reply-to : content-type : content-transfer-encoding; s=qcppdkim1; bh=Aa6PSvz5BZk1EStzRiqlmzYuoCdHzQ0e/pseI0xLwrc=; b=eYS0+Gcy9rjHPabSaRz5Yc+Wf6gahJnBvN2zl467y/Xj89G7T/7Y/oTn1DGYJ0T8LZLt k/v92VdyEip+hZcSC1gRQBXbC889RJe2pAkfpUyZHM8dHO9q+nZqmLV4HnCvvRD7apJH I58ZKzCiALGhKTdr29kYZj4QkRHpQWLXmj6A7iJI8wj8ljl9eB5Wj/XoEipmXnrpJLNM u2+wdBBecuAxmeJEXXyzrukvrOelytFhyUNDw0gu6PD01oygIHPnWpJvkNDo1GcqJUtu yIJe0tiPSnao/pkCPK5mRr5N8MP/Ee99rfVeKOj/AF1If+DAdtt5wdJVqFM50WsRX8di Kw== Received: from nasanppmta01.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3nwybwp285-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Feb 2023 22:39:40 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 31OMdYjI010164 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Feb 2023 22:39:34 GMT Received: from [10.110.9.108] (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.41; Fri, 24 Feb 2023 14:39:33 -0800 Message-ID: <2fe3993a-b3b1-119d-e335-56979d6ecd99@quicinc.com> Date: Fri, 24 Feb 2023 14:39:32 -0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.6.1 Subject: Re: [PATCH v10 08/26] gunyah: rsc_mgr: Add resource manager RPC core Content-Language: en-US To: Alex Elder , Alex Elder , Srinivas Kandagatla , Prakruthi Deepak Heragu CC: Murali Nalajala , Trilok Soni , Srivatsa Vaddagiri , Carl van Schaik , Dmitry Baryshkov , Bjorn Andersson , "Konrad Dybcio" , Arnd Bergmann , "Greg Kroah-Hartman" , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Bagas Sanjaya , Catalin Marinas , Jassi Brar , , , , , References: <20230214211229.3239350-1-quic_eberman@quicinc.com> <20230214212327.3310128-1-quic_eberman@quicinc.com> <9c56e16e-ecd0-2ef4-14d8-476029458359@linaro.org> From: Elliot Berman In-Reply-To: <9c56e16e-ecd0-2ef4-14d8-476029458359@linaro.org> X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: CKgDjhI-4ZSijQj4g5jO2634-VPPGT9M X-Proofpoint-ORIG-GUID: CKgDjhI-4ZSijQj4g5jO2634-VPPGT9M X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.930,Hydra:6.0.562,FMLib:17.11.170.22 definitions=2023-02-24_16,2023-02-24_01,2023-02-09_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 mlxlogscore=999 malwarescore=0 impostorscore=0 bulkscore=0 spamscore=0 mlxscore=0 priorityscore=1501 adultscore=0 phishscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2302240182 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230224_143958_555180_9DEC43DC X-CRM114-Status: GOOD ( 51.01 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org CgpPbiAyLzIzLzIwMjMgMzoyOCBQTSwgQWxleCBFbGRlciB3cm90ZToKPiBPbiAyLzE0LzIzIDM6 MjMgUE0sIEVsbGlvdCBCZXJtYW4gd3JvdGU6Cj4+CjxzbmlwPgo+PiArfQo+PiArCj4+ICtzdGF0 aWMgaW50IGdoX3JtX2luaXRfY29ubmVjdGlvbl9wYXlsb2FkKHN0cnVjdCBnaF9ybV9jb25uZWN0 aW9uIAo+PiAqY29ubmVjdGlvbiwgdm9pZCAqbXNnLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgc2l6ZV90IGhkcl9zaXplLCBzaXplX3QgbXNnX3NpemUpCj4gCj4g VGhlIHZhbHVlIG9mIGhkcl9zaXplIGlzICphbHdheXMqIHNpemVvZigqaGRyKSwgc28geW91IGNh bgo+IGRvIHdpdGhvdXQgcGFzc2luZyBpdCBhcyBhbiBhcmd1bWVudC4KPiAKCmhkcl9zaXplIGlz IGRpZmZlcmVudCB3aGVuIHJlY2VpdmluZyByZXBseSAoMSBleHRyYSB3b3JkKSB2cyBub3RpZmlj YXRpb24uCgo+PiArewo+PiArwqDCoMKgIHNpemVfdCBtYXhfYnVmX3NpemUsIHBheWxvYWRfc2l6 ZTsKPj4gK8KgwqDCoCBzdHJ1Y3QgZ2hfcm1fcnBjX2hkciAqaGRyID0gbXNnOwo+PiArCj4gCj4g SXQgcHJvYmFibHkgc291bmRzIGR1bWIsIGJ1dCBJJ2QgcmV2ZXJzZSB0aGUgdmFsdWVzCj4gY29t cGFyZWQgYmVsb3cgKGFuZCB0aGUgb3BlcmF0b3IpLgo+IAo+PiArwqDCoMKgIGlmIChoZHJfc2l6 ZSA+IG1zZ19zaXplKQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FSU5WQUw7Cj4+ICsKPj4g K8KgwqDCoCBwYXlsb2FkX3NpemUgPSBtc2dfc2l6ZSAtIGhkcl9zaXplOwo+PiArCj4+ICvCoMKg wqAgY29ubmVjdGlvbi0+bnVtX2ZyYWdtZW50cyA9IEZJRUxEX0dFVChSTV9SUENfRlJBR01FTlRT X01BU0ssIAo+PiBoZHItPnR5cGUpOwo+PiArwqDCoMKgIGNvbm5lY3Rpb24tPmZyYWdtZW50c19y ZWNlaXZlZCA9IDA7Cj4+ICsKPj4gK8KgwqDCoCAvKiBUaGVyZSdzIG5vdCBnb2luZyB0byBiZSBh bnkgcGF5bG9hZCwgbm8gbmVlZCB0byBhbGxvY2F0ZSAKPj4gYnVmZmVyLiAqLwo+PiArwqDCoMKg IGlmICghcGF5bG9hZF9zaXplICYmICFjb25uZWN0aW9uLT5udW1fZnJhZ21lbnRzKQo+IAo+IFRo ZSBwYXlsb2FkIHNpemUgaXMgdGhlIHNhbWUgYWNyb3NzIGFsbCBtZXNzYWdlcyBpbiB0aGUKPiAi Y29ubmVjdGlvbiIgcmlnaHQ/wqAgQXMgaXMgdGhlIG51bWJlciBvZiBmcmFnbWVudHM/Cj4gSXQn cyBub3QgZXZlbiBwb3NzaWJsZS92YWxpZCB0byBoYXZlIGEgemVybyBwYXlsb2FkIHNpemUKPiBh bmQgbm9uLXplcm8gbnVtYmVyIG9mIGZyYWdtZW50cy7CoCBJIHRoaW5rIHRoZSBzZWNvbmQKPiBo YWxmIG9mIHRoZSBhYm92ZSB0ZXN0IGNhbiBiZSBkcm9wcGVkLgo+IAoKVGhlIFJNIFJQQyBzcGVj aWZpY2F0aW9uIGRvZXNuJ3QgcmVxdWlyZSB0aGF0IHRoZSBmaXJzdCBtZXNzYWdlIGhhdmUgCnBh eWxvYWQuIChJdCBtYWtlcyBzZW5zZSB0byBkbyBpdCBhbmQgaXQgZG9lcywgYnV0IHRoYXQncyBp bXBsZW1lbnRhdGlvbiAKZGV0YWlsKQoKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiAwOwo+PiAr Cj4+ICvCoMKgwqAgaWYgKGNvbm5lY3Rpb24tPm51bV9mcmFnbWVudHMgPiBHSF9STV9NQVhfTlVN X0ZSQUdNRU5UUykKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiAtRUlOVkFMOwo+PiArCj4+ICvC oMKgwqAgbWF4X2J1Zl9zaXplID0gcGF5bG9hZF9zaXplICsgKGNvbm5lY3Rpb24tPm51bV9mcmFn bWVudHMgKiAKPj4gR0hfUk1fTUFYX01TR19TSVpFKTsKPj4gKwo+PiArwqDCoMKgIGNvbm5lY3Rp b24tPnBheWxvYWQgPSBremFsbG9jKG1heF9idWZfc2l6ZSwgR0ZQX0tFUk5FTCk7Cj4+ICvCoMKg wqAgaWYgKCFjb25uZWN0aW9uLT5wYXlsb2FkKQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1F Tk9NRU07Cj4+ICsKPj4gK8KgwqDCoCBtZW1jcHkoY29ubmVjdGlvbi0+cGF5bG9hZCwgbXNnICsg aGRyX3NpemUsIHBheWxvYWRfc2l6ZSk7Cj4gCj4gSSB0aGluayBJIHN1Z2dlc3RlZCAoaGRyICsg MSkgcmF0aGVyIHRoYW4gKG1zZyArIHNpemUpIGVsc2V3aGVyZQo+IGFuZCB5b3UgdG9vayB0aGF0 IHN1Z2dlc3Rpb24uwqAgSSdkIHNheSBkbyBpdCBvbmUgd2F5IG9yIHRoZSBvdGhlciwKPiBjb25z aXN0ZW50bHksIGV2ZXJ5d2hlcmUuCj4gCgpoZHJfc2l6ZSAhPSBzaXplb2YoKmhkcikgd2hlbiB3 ZSByZWNlaXZlIGEgcmVwbHkgbWVzc2FnZS4KCj4+ICvCoMKgwqAgY29ubmVjdGlvbi0+c2l6ZSA9 IHBheWxvYWRfc2l6ZTsKPj4gK8KgwqDCoCByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGlj IHZvaWQgZ2hfcm1fbm90aWZfd29yayhzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCj4+ICt7Cj4+ ICvCoMKgwqAgc3RydWN0IGdoX3JtX2Nvbm5lY3Rpb24gKmNvbm5lY3Rpb24gPSBjb250YWluZXJf b2Yod29yaywgc3RydWN0IAo+PiBnaF9ybV9jb25uZWN0aW9uLAo+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgbm90aWZpY2F0 aW9uLndvcmspOwo+PiArwqDCoMKgIHN0cnVjdCBnaF9ybSAqcm0gPSBjb25uZWN0aW9uLT5ub3Rp ZmljYXRpb24ucm07Cj4+ICsKPj4gK8KgwqDCoCBibG9ja2luZ19ub3RpZmllcl9jYWxsX2NoYWlu KCZybS0+bmgsIGNvbm5lY3Rpb24tPm1zZ19pZCwgCj4+IGNvbm5lY3Rpb24tPnBheWxvYWQpOwo+ PiArCj4+ICvCoMKgwqAgcHV0X2doX3JtKHJtKTsKPj4gK8KgwqDCoCBrZnJlZShjb25uZWN0aW9u LT5wYXlsb2FkKTsKPj4gK8KgwqDCoCBrZnJlZShjb25uZWN0aW9uKTsKPj4gK30KPj4gKwo+PiAr c3RhdGljIHN0cnVjdCBnaF9ybV9jb25uZWN0aW9uICpnaF9ybV9wcm9jZXNzX25vdGlmKHN0cnVj dCBnaF9ybSAqcm0sIAo+PiB2b2lkICptc2csIHNpemVfdCBtc2dfc2l6ZSkKPiAKPiBJIHRoaW5r IGl0IG1pZ2h0IGJlIGJldHRlciBpZiB5b3UgZG8gc29tZSBvZiB3aGF0IHRoZSBjYWxsZXIKPiBk b2VzIGhlcmUuwqAgSS5lLiwgdmVyaWZ5IHRoZSBjdXJyZW50IGNvbm5lY3Rpb24gaXMgbnVsbCAo YW5kCj4gYWJvcnQgaWYgbm90IGFuZCBtYWtlIGl0IE5VTEwpLCB0aGVuIGFzc2lnbiBpdCB0byB0 aGUgbmV3Cj4gY29ubmVjdGlvbiBiZWZvcmUgeW91IHJldHVybiBzdWNjZXNzLsKgIEFuZCByZXR1 cm4gYW4gZXJybm8uCj4gCgpTaW5jZSB5b3UgYW5kIFNyaW5pIGJvdGggc3VnZ2VzdCB0byBkbyBp dCwgSSdsbCBjYXZlLiA6LSkKCj4+ICt7Cj4+ICvCoMKgwqAgc3RydWN0IGdoX3JtX2Nvbm5lY3Rp b24gKmNvbm5lY3Rpb247Cj4+ICvCoMKgwqAgc3RydWN0IGdoX3JtX3JwY19oZHIgKmhkciA9IG1z ZzsKPj4gK8KgwqDCoCBpbnQgcmV0Owo+PiArCj4+ICvCoMKgwqAgY29ubmVjdGlvbiA9IGdoX3Jt X2FsbG9jX2Nvbm5lY3Rpb24oaGRyLT5tc2dfaWQsIFJNX1JQQ19UWVBFX05PVElGKTsKPj4gK8Kg wqDCoCBpZiAoSVNfRVJSKGNvbm5lY3Rpb24pKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCBkZXZfZXJy KHJtLT5kZXYsICJGYWlsZWQgdG8gYWxsb2MgY29ubmVjdGlvbiBmb3IgCj4+IG5vdGlmaWNhdGlv bjogJWxkLCBkcm9wcGluZy5cbiIsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFBUUl9FUlIo Y29ubmVjdGlvbikpOwo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIE5VTEw7Cj4+ICvCoMKgwqAg fQo+PiArCj4+ICvCoMKgwqAgZ2V0X2doX3JtKHJtKTsKPj4gK8KgwqDCoCBjb25uZWN0aW9uLT5u b3RpZmljYXRpb24ucm0gPSBybTsKPj4gK8KgwqDCoCBJTklUX1dPUksoJmNvbm5lY3Rpb24tPm5v dGlmaWNhdGlvbi53b3JrLCBnaF9ybV9ub3RpZl93b3JrKTsKPj4gKwo+PiArwqDCoMKgIHJldCA9 IGdoX3JtX2luaXRfY29ubmVjdGlvbl9wYXlsb2FkKGNvbm5lY3Rpb24sIG1zZywgCj4+IHNpemVv ZigqaGRyKSwgbXNnX3NpemUpOwo+PiArwqDCoMKgIGlmIChyZXQpIHsKPj4gK8KgwqDCoMKgwqDC oMKgIGRldl9lcnIocm0tPmRldiwgIkZhaWxlZCB0byBpbml0aWFsaXplIGNvbm5lY3Rpb24gYnVm ZmVyIGZvciAKPj4gbm90aWZpY2F0aW9uOiAlZFxuIiwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKg wqAgcmV0KTsKPj4gK8KgwqDCoMKgwqDCoMKgIGtmcmVlKGNvbm5lY3Rpb24pOwo+PiArwqDCoMKg wqDCoMKgwqAgcmV0dXJuIE5VTEw7Cj4+ICvCoMKgwqAgfQo+PiArCj4+ICvCoMKgwqAgcmV0dXJu IGNvbm5lY3Rpb247Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgZ2hfcm1fY29ubmVjdGlv biAqZ2hfcm1fcHJvY2Vzc19ycGx5KHN0cnVjdCBnaF9ybSAqcm0sIAo+PiB2b2lkICptc2csIHNp emVfdCBtc2dfc2l6ZSkKPj4gK3sKPiAKPiBIZXJlIHRvbywgbWFrZSBzdXJlIHRoZXJlIGlzIG5v IGFjdGl2ZSBjb25uZWN0aW9uIGFuZCB0aGVuCj4gc2V0IGl0IHdpdGhpbiB0aGlzIGZ1bmN0aW9u IGlmIHRoZSBlcnJubyByZXR1cm5lZCBpcyAwLgo+IAo+PiArwqDCoMKgIHN0cnVjdCBnaF9ybV9y cGNfcmVwbHlfaGRyICpyZXBseV9oZHIgPSBtc2c7Cj4+ICvCoMKgwqAgc3RydWN0IGdoX3JtX2Nv bm5lY3Rpb24gKmNvbm5lY3Rpb247Cj4+ICvCoMKgwqAgdTE2IHNlcV9pZCA9IGxlMTZfdG9fY3B1 KHJlcGx5X2hkci0+aGRyLnNlcSk7Cj4+ICsKPj4gK8KgwqDCoCBtdXRleF9sb2NrKCZybS0+Y2Fs bF9pZHJfbG9jayk7Cj4+ICvCoMKgwqAgY29ubmVjdGlvbiA9IGlkcl9maW5kKCZybS0+Y2FsbF9p ZHIsIHNlcV9pZCk7Cj4+ICvCoMKgwqAgbXV0ZXhfdW5sb2NrKCZybS0+Y2FsbF9pZHJfbG9jayk7 Cj4+ICsKPj4gK8KgwqDCoCBpZiAoIWNvbm5lY3Rpb24gfHwgY29ubmVjdGlvbi0+bXNnX2lkICE9 IHJlcGx5X2hkci0+aGRyLm1zZ19pZCkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiBOVUxMOwo+ PiArCj4+ICvCoMKgwqAgaWYgKGdoX3JtX2luaXRfY29ubmVjdGlvbl9wYXlsb2FkKGNvbm5lY3Rp b24sIG1zZywgCj4+IHNpemVvZigqcmVwbHlfaGRyKSwgbXNnX3NpemUpKSB7Cj4+ICvCoMKgwqDC oMKgwqDCoCBkZXZfZXJyKHJtLT5kZXYsICJGYWlsZWQgdG8gYWxsb2MgY29ubmVjdGlvbiBidWZm ZXIgZm9yIAo+PiBzZXF1ZW5jZSAlZFxuIiwgc2VxX2lkKTsKPj4gK8KgwqDCoMKgwqDCoMKgIC8q IFNlbmQgY29ubmVjdGlvbiBjb21wbGV0ZSBhbmQgZXJyb3IgdGhlIGNsaWVudC4gKi8KPj4gK8Kg wqDCoMKgwqDCoMKgIGNvbm5lY3Rpb24tPnJlcGx5LnJldCA9IC1FTk9NRU07Cj4+ICvCoMKgwqDC oMKgwqDCoCBjb21wbGV0ZSgmY29ubmVjdGlvbi0+cmVwbHkuc2VxX2RvbmUpOwo+PiArwqDCoMKg wqDCoMKgwqAgcmV0dXJuIE5VTEw7Cj4+ICvCoMKgwqAgfQo+PiArCj4+ICvCoMKgwqAgY29ubmVj dGlvbi0+cmVwbHkucm1fZXJyb3IgPSBsZTMyX3RvX2NwdShyZXBseV9oZHItPmVycl9jb2RlKTsK Pj4gK8KgwqDCoCByZXR1cm4gY29ubmVjdGlvbjsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBn aF9ybV9wcm9jZXNzX2NvbnQoc3RydWN0IGdoX3JtICpybSwgc3RydWN0IAo+PiBnaF9ybV9jb25u ZWN0aW9uICpjb25uZWN0aW9uLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHZv aWQgKm1zZywgc2l6ZV90IG1zZ19zaXplKQo+IAo+IFNpbWlsYXIgY29tbWVudCBoZXJlLsKgIEhh dmUgdGhpcyBmdW5jdGlvbiB2ZXJpZnkgdGhlcmUgaXMKPiBhIG5vbi1udWxsIGFjdGl2ZSBjb25u ZWN0aW9uLsKgIFRoZW4gcHJvY2VzcyB0aGUgbWVzc2FnZQo+IGFuZCBhYm9ydCBpZiB0aGVyZSdz IGFuIGVycm9yIChhbmQgbnVsbCB0aGUgYWN0aXZlIGNvbm5lY3Rpb24KPiBwb2ludGVyKS4KPiAK Pj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3QgZ2hfcm1fcnBjX2hkciAqaGRyID0gbXNnOwo+PiArwqDC oMKgIHNpemVfdCBwYXlsb2FkX3NpemUgPSBtc2dfc2l6ZSAtIHNpemVvZigqaGRyKTsKPj4gKwo+ PiArwqDCoMKgIC8qCj4+ICvCoMKgwqDCoCAqIGhkci0+ZnJhZ21lbnRzIGFuZCBoZHItPm1zZ19p ZCBwcmVzZXJ2ZXMgdGhlIHZhbHVlIGZyb20gZmlyc3QgCj4+IHJlcGx5Cj4+ICvCoMKgwqDCoCAq IG9yIG5vdGlmIG1lc3NhZ2UuIFRvIGRldGVjdCBtaXNoYW5kbGluZywgY2hlY2sgaXQncyBzdGls bCBpbnRhY3QuCj4+ICvCoMKgwqDCoCAqLwo+PiArwqDCoMKgIGlmIChjb25uZWN0aW9uLT5tc2df aWQgIT0gaGRyLT5tc2dfaWQgfHwKPj4gK8KgwqDCoMKgwqDCoMKgIGNvbm5lY3Rpb24tPm51bV9m cmFnbWVudHMgIT0gRklFTERfR0VUKFJNX1JQQ19GUkFHTUVOVFNfTUFTSywgCj4+IGhkci0+dHlw ZSkpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVJTlZBTDsKPiAKPiBNYXliZSAtRUJBRE1T Rz8KPiAKPj4gKwo+PiArwqDCoMKgIG1lbWNweShjb25uZWN0aW9uLT5wYXlsb2FkICsgY29ubmVj dGlvbi0+c2l6ZSwgbXNnICsgCj4+IHNpemVvZigqaGRyKSwgcGF5bG9hZF9zaXplKTsKPj4gK8Kg wqDCoCBjb25uZWN0aW9uLT5zaXplICs9IHBheWxvYWRfc2l6ZTsKPj4gK8KgwqDCoCBjb25uZWN0 aW9uLT5mcmFnbWVudHNfcmVjZWl2ZWQrKzsKPj4gK8KgwqDCoCByZXR1cm4gMDsKPj4gK30KPj4g Kwo+PiArc3RhdGljIHZvaWQgZ2hfcm1fYWJvcnRfY29ubmVjdGlvbihzdHJ1Y3QgZ2hfcm1fY29u bmVjdGlvbiAqY29ubmVjdGlvbikKPj4gK3sKPj4gK8KgwqDCoCBzd2l0Y2ggKGNvbm5lY3Rpb24t PnR5cGUpIHsKPj4gK8KgwqDCoCBjYXNlIFJNX1JQQ19UWVBFX1JFUExZOgo+PiArwqDCoMKgwqDC oMKgwqAgY29ubmVjdGlvbi0+cmVwbHkucmV0ID0gLUVJTzsKPj4gK8KgwqDCoMKgwqDCoMKgIGNv bXBsZXRlKCZjb25uZWN0aW9uLT5yZXBseS5zZXFfZG9uZSk7Cj4+ICvCoMKgwqDCoMKgwqDCoCBi cmVhazsKPj4gK8KgwqDCoCBjYXNlIFJNX1JQQ19UWVBFX05PVElGOgo+PiArwqDCoMKgwqDCoMKg wqAgZmFsbHRocm91Z2g7Cj4+ICvCoMKgwqAgZGVmYXVsdDoKPj4gK8KgwqDCoMKgwqDCoMKgIGtm cmVlKGNvbm5lY3Rpb24tPnBheWxvYWQpOwo+PiArwqDCoMKgwqDCoMKgwqAga2ZyZWUoY29ubmVj dGlvbik7Cj4+ICvCoMKgwqAgfQo+PiArfQo+PiArCj4+ICtzdGF0aWMgYm9vbCBnaF9ybV9jb21w bGV0ZV9jb25uZWN0aW9uKHN0cnVjdCBnaF9ybSAqcm0sIHN0cnVjdCAKPj4gZ2hfcm1fY29ubmVj dGlvbiAqY29ubmVjdGlvbikKPiAKPiBUaGUgb25seSBjYWxsZXIgb2YgdGhpcyBmdW5jdGlvbiBw YXNzZXMgcm0tPmFjdGl2ZV9yeF9jb25uZWN0aW9uCj4gYXMgdGhlIHNlY29uZCBhcmd1bWVudC7C oCBJdCBpcyBhdmFpbGFibGUgdG8geW91IGhlcmUsIHNvIHlvdQo+IGNhbiBnZXQgcmlkIG9mIHRo YXQgYXJndW1lbnQuCj4gCj4+ICt7Cj4+ICvCoMKgwqAgaWYgKCFjb25uZWN0aW9uIHx8IGNvbm5l Y3Rpb24tPmZyYWdtZW50c19yZWNlaXZlZCAhPSAKPj4gY29ubmVjdGlvbi0+bnVtX2ZyYWdtZW50 cykKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiBmYWxzZTsKPj4gKwo+PiArwqDCoMKgIHN3aXRj aCAoY29ubmVjdGlvbi0+dHlwZSkgewo+PiArwqDCoMKgIGNhc2UgUk1fUlBDX1RZUEVfUkVQTFk6 Cj4+ICvCoMKgwqDCoMKgwqDCoCBjb21wbGV0ZSgmY29ubmVjdGlvbi0+cmVwbHkuc2VxX2RvbmUp Owo+PiArwqDCoMKgwqDCoMKgwqAgYnJlYWs7Cj4+ICvCoMKgwqAgY2FzZSBSTV9SUENfVFlQRV9O T1RJRjoKPj4gK8KgwqDCoMKgwqDCoMKgIHNjaGVkdWxlX3dvcmsoJmNvbm5lY3Rpb24tPm5vdGlm aWNhdGlvbi53b3JrKTsKPj4gK8KgwqDCoMKgwqDCoMKgIGJyZWFrOwo+PiArwqDCoMKgIGRlZmF1 bHQ6Cj4+ICvCoMKgwqDCoMKgwqDCoCBkZXZfZXJyKHJtLT5kZXYsICJJbnZhbGlkIG1lc3NhZ2Ug dHlwZSAoJWQpIHJlY2VpdmVkXG4iLCAKPj4gY29ubmVjdGlvbi0+dHlwZSk7Cj4+ICvCoMKgwqDC oMKgwqDCoCBnaF9ybV9hYm9ydF9jb25uZWN0aW9uKGNvbm5lY3Rpb24pOwo+PiArwqDCoMKgwqDC oMKgwqAgYnJlYWs7Cj4+ICvCoMKgwqAgfQo+PiArCj4+ICvCoMKgwqAgcmV0dXJuIHRydWU7Cj4+ ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGdoX3JtX21zZ3FfcnhfZGF0YShzdHJ1Y3QgbWJveF9j bGllbnQgKmNsLCB2b2lkICptc3NnKQo+PiArewo+PiArwqDCoMKgIHN0cnVjdCBnaF9ybSAqcm0g PSBjb250YWluZXJfb2YoY2wsIHN0cnVjdCBnaF9ybSwgbXNncV9jbGllbnQpOwo+PiArwqDCoMKg IHN0cnVjdCBnaF9tc2dxX3J4X2RhdGEgKnJ4X2RhdGEgPSBtc3NnOwo+PiArwqDCoMKgIHNpemVf dCBtc2dfc2l6ZSA9IHJ4X2RhdGEtPmxlbmd0aDsKPj4gK8KgwqDCoCB2b2lkICptc2cgPSByeF9k YXRhLT5kYXRhOwo+PiArwqDCoMKgIHN0cnVjdCBnaF9ybV9ycGNfaGRyICpoZHI7Cj4+ICsKPiAK PiBJcyBpdCByZXF1aXJlZCB0aGF0IGF0IGxlYXN0IG9uZSBieXRlIChwYXN0IHRoZSBoZWFkZXIp IHdpbGwKPiBiZSByZWNlaXZlZD/CoCBJLmUuLCBzaG91bGQgdGhlICI8PSIgYmVsb3cganVzdCBi ZSAiPCI/Cj4gCj4+ICvCoMKgwqAgaWYgKG1zZ19zaXplIDw9IHNpemVvZigqaGRyKSB8fCBtc2df c2l6ZSA+IEdIX01TR1FfTUFYX01TR19TSVpFKQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuOwo+ IAo+IFlvdSBwcmV2aW91c2x5IHJlcG9ydGVkIGEgbWVzc2FnZSBoZXJlLsKgIFRoZXNlIHNlZW0g bGlrZQo+IGVycm9ycywgd2hpY2ggaWYgdGhleSBvY2N1ciwgbWF5YmUgc2hvdWxkIGJlIHJlcG9y dGVkLgo+IFRoZXkgc2VlbSBsaWtlICJuZXZlciBoYXBwZW4iIGlzc3VlcywgYnV0IGl0J3MgZGVm ZW5zaXZlCj4gdG8gbWFrZSB0aGVzZSBjaGVja3MgKHdoaWNoIGlzIGdvb2QpLgo+IAo+PiArCj4+ ICvCoMKgwqAgaGRyID0gbXNnOwo+PiArwqDCoMKgIGlmIChoZHItPmFwaSAhPSBSTV9SUENfQVBJ KSB7Cj4gCj4gSWYgdGhpcyBldmVyIGhhcHBlbnMsIGlzIHRoZSBoYXJkd2FyZSBmYWlsaW5nP8Kg IEl0IHNlZW1zCj4gbGlrZSBvbmNlIEd1bnlhaCBpcyBpbml0aWFsaXplZCBhbmQgeW91J3ZlIGNo ZWNrZWQgdGhlCj4gQVBJIHZlcnNpb24gb25jZSwgdGhlcmUgc2hvdWxkIGJlIG5vIG5lZWQgdG8g Y2hlY2sgaXQKPiByZXBlYXRlZGx5LgoKSSdkIG5lZWQgdG8gY2hlY2sgdGhlIEFQSSB2ZXJzaW9u IGZvciB0aGUgZmlyc3QgbWVzc2FnZS4gT24gc3Vic2VxdWVudCAKbWVzc2FnZXMsIEknZCBuZWVk IHRvIGNoZWNrIGlmIEkgYWxyZWFkeSBjaGVja2VkLiBNaWdodCBhcyB3ZWxsIGp1c3QgCmNoZWNr IHRoZSB2ZXJzaW9uIGV2ZXJ5IHRpbWU/Cgo8ZG9uZSBmb3IgYWxsIHRoZSBjb21tZW50cyBzbmlw cGVkPgoKPj4gKwo+PiArdm9pZCBnZXRfZ2hfcm0oc3RydWN0IGdoX3JtICpybSkKPiAKPiBJdCBp cyBvZnRlbiBwcmV0dHkgaGFuZHkgdG8gcmV0dXJuIHRoZSBhcmd1bWVudCBpbgo+IGZ1bmN0aW9u cyBsaWtlIHRoaXMuwqAgSXQgc2ltdWx0YW5lb3VzbHkgdGFrZXMgdGhlCj4gcmVmZXJlbmNlIGFu ZCBhc3NpZ25zIHRoZSBwb2ludGVyIHRoZSByZWZlcmVuY2UKPiByZXByZXNlbnRzLgo+IAo+IAoK SSd2ZSB1cGRhdGVkIHNvIHRoYXQgZ2hfcm1fZ2V0KCkgcmV0dXJucyBhIHN0cnVjdCBkZXZpY2Ug KiAodGhlIAptaXNjZGV2J3MgZGV2aWNlKS4gSXMgdGhpcyB0b28gdW51c3VhbD8KCj4+ICt7Cj4+ ICvCoMKgwqAgZ2V0X2RldmljZShybS0+ZGV2KTsKPj4gK30KPj4gK0VYUE9SVF9TWU1CT0xfR1BM KGdldF9naF9ybSk7Cj4+ICsKPj4gK3ZvaWQgcHV0X2doX3JtKHN0cnVjdCBnaF9ybSAqcm0pCj4+ ICt7Cj4+ICvCoMKgwqAgcHV0X2RldmljZShybS0+ZGV2KTsKPj4gK30KPj4gK0VYUE9SVF9TWU1C T0xfR1BMKHB1dF9naF9ybSk7Cj4+ICsKPj4gK3N0YXRpYyBpbnQgZ2hfbXNncV9wbGF0Zm9ybV9w cm9iZV9kaXJlY3Rpb24oc3RydWN0IHBsYXRmb3JtX2RldmljZSAKPj4gKnBkZXYsCj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBib29sIHR4LCBpbnQgaWR4LCBzdHJ1 Y3QgZ3VueWFoX3Jlc291cmNlICpnaHJzYykKPj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3QgZGV2aWNl X25vZGUgKm5vZGUgPSBwZGV2LT5kZXYub2Zfbm9kZTsKPj4gK8KgwqDCoCBpbnQgcmV0Owo+IAo+ IEkgdGhpbmsgeW91IHNob3VsZCBkZWNsYXJlIGlkeCBhcyBhIGxvY2FsIHZhcmlhYmxlLgo+IAo+ ICDCoMKgwqDCoGludCBpZHggPSB0eCA/IDEgOiAwOwo+ID4+ICsKPj4gK8KgwqDCoCBnaHJzYy0+ dHlwZSA9IHR4ID8gR1VOWUFIX1JFU09VUkNFX1RZUEVfTVNHUV9UWCA6IAo+PiBHVU5ZQUhfUkVT T1VSQ0VfVFlQRV9NU0dRX1JYOwo+PiArCj4+ICvCoMKgwqAgZ2hyc2MtPmlycSA9IHBsYXRmb3Jt X2dldF9pcnEocGRldiwgaWR4KTsKPiAKPiBEbyB5b3Ugc3VwcG9zZSB5b3UgY291bGQgZG8gcGxh dGZvcm1fZ2V0X2lycV9ieW5hbWUoKSwgYW5kIHRoZW4KPiBzcGVjaWZ5IHRoZSBuYW1lcyBvZiB0 aGUgSVJRcyAoInJtX3R4X2lycSIgYW5kICJybV9yeF9pcnEiIG1heWJlKT8KPiAKPj4gK8KgwqDC oCBpZiAoZ2hyc2MtPmlycSA8IDApIHsKPj4gK8KgwqDCoMKgwqDCoMKgIGRldl9lcnIoJnBkZXYt PmRldiwgIkZhaWxlZCB0byBnZXQgaXJxJWQ6ICVkXG4iLCBpZHgsIAo+PiBnaHJzYy0+aXJxKTsK PiAKPiBNYXliZTrCoMKgwqAgIkZhaWxlZCB0byBnZXQgJWNYIElSUTogJWRcbiIsIHR4ID8gJ1Qn IDogJ1InLCBnaHJzYy0+aXJxKTsKPiAKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiBnaHJzYy0+ aXJxOwo+PiArwqDCoMKgIH0KPj4gKwo+PiArwqDCoMKgIHJldCA9IG9mX3Byb3BlcnR5X3JlYWRf dTY0X2luZGV4KG5vZGUsICJyZWciLCBpZHgsICZnaHJzYy0+Y2FwaWQpOwo+IAo+IElzIGEgY2Fw YWJpbGl0eSBJRCBhIHNpbXBsZSAoYnV0IGxhcmdlKSBudW1iZXI/Cj4gCj4gVGhlICpyZXNvdXJj ZSBtYW5hZ2VyKiAod2hpY2ggaXMgYSB2ZXJ5IHNwZWNpYWwgVk0pIGhhcyB0bwo+IGhhdmUgYm90 aCBUWCBhbmQgUlggbWVzc2FnZSBxdWV1ZSBjYXBhYmlsaXR5IElEcy7CoCBJcyB0aGVyZQo+ICdh bnkgY2hhbmNlIHRoYXQgdGhlc2Ugc3BlY2lmaWMgY2FwYWJpbGl0eSBJRHMgaGF2ZSB2YWx1ZXMK PiB0aGF0IGFyZSBmaXhlZCBieSB0aGUgZGVzaWduP8KgIExpa2UsIDAgYW5kIDE/wqAgSSBkb24n dCBrbm93Cj4gd2hhdCB0aGV5IGFyZSwgYnV0IGl0IHNlZW1zIGxpa2UgaXQgKmNvdWxkKiBiZSBz b21ldGhpbmcKPiBmaXhlZCBieSB0aGUgZGVzaWduLCBhbmQgaWYgdGhhdCB3ZXJlIHRoZSBjYXNl LCB0aGVyZSB3b3VsZAo+IGJlIG5vIG5lZWQgdG8gc3BlY2lmeSB0aGUgInJlZyIgcHJvcGVydHkg dG8gZ2V0IHRoZSAiY2FwaWQiCj4gdmFsdWVzLgo+IAoKVGhleSBhcmVuJ3QgZml4ZWQgYnkgdGhl IGRlc2lnbiBpbiBhIHByb2R1Y3Rpb24gdmVyc2lvbiBvZiBHdW55YWguCgo+PiArwqDCoMKgIGlm IChyZXQpIHsKPj4gK8KgwqDCoMKgwqDCoMKgIGRldl9lcnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0 byBnZXQgY2FwaWQlZDogJWRcbiIsIGlkeCwgcmV0KTsKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVy biByZXQ7Cj4+ICvCoMKgwqAgfQo+PiArCj4+ICvCoMKgwqAgcmV0dXJuIDA7Cj4+ICt9Cj4+ICsK Pj4gK3N0YXRpYyBpbnQgZ2hfcm1fZHJ2X3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBk ZXYpCj4+ICt7Cj4+ICvCoMKgwqAgc3RydWN0IGdoX21zZ3FfdHhfZGF0YSAqbXNnOwo+PiArwqDC oMKgIHN0cnVjdCBnaF9ybSAqcm07Cj4+ICvCoMKgwqAgaW50IHJldDsKPj4gKwo+PiArwqDCoMKg IHJtID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVvZigqcm0pLCBHRlBfS0VSTkVMKTsK Pj4gK8KgwqDCoCBpZiAoIXJtKQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FTk9NRU07Cj4+ ICsKPj4gK8KgwqDCoCBwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBybSk7Cj4+ICvCoMKgwqAg cm0tPmRldiA9ICZwZGV2LT5kZXY7Cj4+ICsKPj4gK8KgwqDCoCBtdXRleF9pbml0KCZybS0+Y2Fs bF9pZHJfbG9jayk7Cj4+ICvCoMKgwqAgaWRyX2luaXQoJnJtLT5jYWxsX2lkcik7Cj4+ICvCoMKg wqAgcm0tPmNhY2hlID0ga21lbV9jYWNoZV9jcmVhdGUoImdoX3JtIiwgc3RydWN0X3NpemUobXNn LCBkYXRhLCAKPj4gR0hfTVNHUV9NQVhfTVNHX1NJWkUpLCAwLAo+PiArwqDCoMKgwqDCoMKgwqAg U0xBQl9IV0NBQ0hFX0FMSUdOLCBOVUxMKTsKPj4gK8KgwqDCoCBpZiAoIXJtLT5jYWNoZSkKPj4g K8KgwqDCoMKgwqDCoMKgIHJldHVybiAtRU5PTUVNOwo+IAo+IElmIHlvdSBhYnN0cmFjdGVkIHRo ZSBhbGxvY2F0aW9uIGludGVyZmFjZSBmb3IgdGhlc2UgbWVzc2FnZXMsCj4geW91IGNvdWxkIGFj dHVhbGx5IHN1cnZpdmUgd2l0aG91dCB0aGUgc2xhYiBjYWNoZSBoZXJlLsKgIEJ1dAo+IGlmIHRo aXMgZmFpbHMsIG1heWJlIHlvdSB3b24ndCBnZXQgZmFyIGFueXdheS4KPiAKPj4gK8KgwqDCoCBt dXRleF9pbml0KCZybS0+c2VuZF9sb2NrKTsKPj4gK8KgwqDCoCBCTE9DS0lOR19JTklUX05PVElG SUVSX0hFQUQoJnJtLT5uaCk7Cj4+ICsKPj4gK8KgwqDCoCByZXQgPSBnaF9tc2dxX3BsYXRmb3Jt X3Byb2JlX2RpcmVjdGlvbihwZGV2LCB0cnVlLCAwLCAKPj4gJnJtLT50eF9naHJzYyk7Cj4+ICvC oMKgwqAgaWYgKHJldCkKPj4gK8KgwqDCoMKgwqDCoMKgIGdvdG8gZXJyX2NhY2hlOwo+PiArCj4+ ICvCoMKgwqAgcmV0ID0gZ2hfbXNncV9wbGF0Zm9ybV9wcm9iZV9kaXJlY3Rpb24ocGRldiwgZmFs c2UsIDEsIAo+PiAmcm0tPnJ4X2docnNjKTsKPj4gK8KgwqDCoCBpZiAocmV0KQo+PiArwqDCoMKg wqDCoMKgwqAgZ290byBlcnJfY2FjaGU7Cj4+ICsKPj4gK8KgwqDCoCBybS0+bXNncV9jbGllbnQu ZGV2ID0gJnBkZXYtPmRldjsKPj4gK8KgwqDCoCBybS0+bXNncV9jbGllbnQudHhfYmxvY2sgPSB0 cnVlOwo+PiArwqDCoMKgIHJtLT5tc2dxX2NsaWVudC5yeF9jYWxsYmFjayA9IGdoX3JtX21zZ3Ff cnhfZGF0YTsKPj4gK8KgwqDCoCBybS0+bXNncV9jbGllbnQudHhfZG9uZSA9IGdoX3JtX21zZ3Ff dHhfZG9uZTsKPj4gKwo+PiArwqDCoMKgIHJldHVybiBnaF9tc2dxX2luaXQoJnBkZXYtPmRldiwg JnJtLT5tc2dxLCAmcm0tPm1zZ3FfY2xpZW50LCAKPj4gJnJtLT50eF9naHJzYywgJnJtLT5yeF9n aHJzYyk7Cj4+ICtlcnJfY2FjaGU6Cj4+ICvCoMKgwqAga21lbV9jYWNoZV9kZXN0cm95KHJtLT5j YWNoZSk7Cj4+ICvCoMKgwqAgcmV0dXJuIHJldDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBn aF9ybV9kcnZfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4+ICt7Cj4+ICvC oMKgwqAgc3RydWN0IGdoX3JtICpybSA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwo+PiAr Cj4+ICvCoMKgwqAgbWJveF9mcmVlX2NoYW5uZWwoZ2hfbXNncV9jaGFuKCZybS0+bXNncSkpOwo+ PiArwqDCoMKgIGdoX21zZ3FfcmVtb3ZlKCZybS0+bXNncSk7Cj4+ICvCoMKgwqAga21lbV9jYWNo ZV9kZXN0cm95KHJtLT5jYWNoZSk7Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4gMDsKPj4gK30KPj4g Kwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgZ2hfcm1fb2ZfbWF0Y2hbXSA9 IHsKPj4gK8KgwqDCoCB7IC5jb21wYXRpYmxlID0gImd1bnlhaC1yZXNvdXJjZS1tYW5hZ2VyIiB9 LAo+PiArwqDCoMKgIHt9Cj4+ICt9Owo+PiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgZ2hfcm1f b2ZfbWF0Y2gpOwo+PiArCj4+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBnaF9ybV9k cml2ZXIgPSB7Cj4+ICvCoMKgwqAgLnByb2JlID0gZ2hfcm1fZHJ2X3Byb2JlLAo+PiArwqDCoMKg IC5yZW1vdmUgPSBnaF9ybV9kcnZfcmVtb3ZlLAo+PiArwqDCoMKgIC5kcml2ZXIgPSB7Cj4+ICvC oMKgwqDCoMKgwqDCoCAubmFtZSA9ICJnaF9yc2NfbWdyIiwKPj4gK8KgwqDCoMKgwqDCoMKgIC5v Zl9tYXRjaF90YWJsZSA9IGdoX3JtX29mX21hdGNoLAo+PiArwqDCoMKgIH0sCj4+ICt9Owo+PiAr bW9kdWxlX3BsYXRmb3JtX2RyaXZlcihnaF9ybV9kcml2ZXIpOwo+PiArCj4+ICtNT0RVTEVfTElD RU5TRSgiR1BMIik7Cj4+ICtNT0RVTEVfREVTQ1JJUFRJT04oIkd1bnlhaCBSZXNvdXJjZSBNYW5h Z2VyIERyaXZlciIpOwo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy92aXJ0L2d1bnlhaC9yc2NfbWdy LmggCj4+IGIvZHJpdmVycy92aXJ0L2d1bnlhaC9yc2NfbWdyLmgKPj4gbmV3IGZpbGUgbW9kZSAx MDA2NDQKPj4gaW5kZXggMDAwMDAwMDAwMDAwLi5kNGU3OTlhNzUyNmYKPj4gLS0tIC9kZXYvbnVs bAo+PiArKysgYi9kcml2ZXJzL3ZpcnQvZ3VueWFoL3JzY19tZ3IuaAo+PiBAQCAtMCwwICsxLDc3 IEBACj4+ICsvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5ICovCj4+ICsv Kgo+PiArICogQ29weXJpZ2h0IChjKSAyMDIyLTIwMjMgUXVhbGNvbW0gSW5ub3ZhdGlvbiBDZW50 ZXIsIEluYy4gQWxsIAo+PiByaWdodHMgcmVzZXJ2ZWQuCj4+ICsgKi8KPj4gKyNpZm5kZWYgX19H SF9SU0NfTUdSX1BSSVZfSAo+PiArI2RlZmluZSBfX0dIX1JTQ19NR1JfUFJJVl9ICj4+ICsKPj4g KyNpbmNsdWRlIDxsaW51eC9ndW55YWguaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9ndW55YWhfcnNj X21nci5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+Cj4+ICsKPj4gKy8qIFJNIEVycm9y IGNvZGVzICovCj4+ICtlbnVtIGdoX3JtX2Vycm9yIHsKPj4gK8KgwqDCoCBHSF9STV9FUlJPUl9P S8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgPSAweDAsCj4+ICvCoMKgwqAgR0hfUk1fRVJST1JfVU5J TVBMRU1FTlRFRMKgwqDCoCA9IDB4RkZGRkZGRkYsCj4+ICvCoMKgwqAgR0hfUk1fRVJST1JfTk9N RU3CoMKgwqDCoMKgwqDCoCA9IDB4MSwKPj4gK8KgwqDCoCBHSF9STV9FUlJPUl9OT1JFU09VUkNF wqDCoMKgwqDCoMKgwqAgPSAweDIsCj4+ICvCoMKgwqAgR0hfUk1fRVJST1JfREVOSUVEwqDCoMKg wqDCoMKgwqAgPSAweDMsCj4+ICvCoMKgwqAgR0hfUk1fRVJST1JfSU5WQUxJRMKgwqDCoMKgwqDC oMKgID0gMHg0LAo+PiArwqDCoMKgIEdIX1JNX0VSUk9SX0JVU1nCoMKgwqDCoMKgwqDCoCA9IDB4 NSwKPj4gK8KgwqDCoCBHSF9STV9FUlJPUl9BUkdVTUVOVF9JTlZBTElEwqDCoMKgID0gMHg2LAo+ PiArwqDCoMKgIEdIX1JNX0VSUk9SX0hBTkRMRV9JTlZBTElEwqDCoMKgID0gMHg3LAo+PiArwqDC oMKgIEdIX1JNX0VSUk9SX1ZBTElEQVRFX0ZBSUxFRMKgwqDCoCA9IDB4OCwKPj4gK8KgwqDCoCBH SF9STV9FUlJPUl9NQVBfRkFJTEVEwqDCoMKgwqDCoMKgwqAgPSAweDksCj4+ICvCoMKgwqAgR0hf Uk1fRVJST1JfTUVNX0lOVkFMSUTCoMKgwqDCoMKgwqDCoCA9IDB4QSwKPj4gK8KgwqDCoCBHSF9S TV9FUlJPUl9NRU1fSU5VU0XCoMKgwqDCoMKgwqDCoCA9IDB4QiwKPj4gK8KgwqDCoCBHSF9STV9F UlJPUl9NRU1fUkVMRUFTRUTCoMKgwqAgPSAweEMsCj4+ICvCoMKgwqAgR0hfUk1fRVJST1JfVk1J RF9JTlZBTElEwqDCoMKgID0gMHhELAo+PiArwqDCoMKgIEdIX1JNX0VSUk9SX0xPT0tVUF9GQUlM RUTCoMKgwqAgPSAweEUsCj4+ICvCoMKgwqAgR0hfUk1fRVJST1JfSVJRX0lOVkFMSUTCoMKgwqDC oMKgwqDCoCA9IDB4RiwKPj4gK8KgwqDCoCBHSF9STV9FUlJPUl9JUlFfSU5VU0XCoMKgwqDCoMKg wqDCoCA9IDB4MTAsCj4+ICvCoMKgwqAgR0hfUk1fRVJST1JfSVJRX1JFTEVBU0VEwqDCoMKgID0g MHgxMSwKPj4gK307Cj4+ICsKPj4gKy8qKgo+PiArICogZ2hfcm1fcmVtYXBfZXJyb3IoKSAtIFJl bWFwIEd1bnlhaCByZXNvdXJjZSBtYW5hZ2VyIGVycm9ycyBpbnRvIGEgCj4+IExpbnV4IGVycm9y IGNvZGUKPj4gKyAqIEBnaF9lcnJvcjogIlN0YW5kYXJkIiByZXR1cm4gdmFsdWUgZnJvbSBHdW55 YWggcmVzb3VyY2UgbWFuYWdlcgo+PiArICovCj4+ICtzdGF0aWMgaW5saW5lIGludCBnaF9ybV9y ZW1hcF9lcnJvcihlbnVtIGdoX3JtX2Vycm9yIHJtX2Vycm9yKQo+PiArewo+PiArwqDCoMKgIHN3 aXRjaCAocm1fZXJyb3IpIHsKPj4gK8KgwqDCoCBjYXNlIEdIX1JNX0VSUk9SX09LOgo+PiArwqDC oMKgwqDCoMKgwqAgcmV0dXJuIDA7Cj4+ICvCoMKgwqAgY2FzZSBHSF9STV9FUlJPUl9VTklNUExF TUVOVEVEOgo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FT1BOT1RTVVBQOwo+PiArwqDCoMKg IGNhc2UgR0hfUk1fRVJST1JfTk9NRU06Cj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVOT01F TTsKPj4gK8KgwqDCoCBjYXNlIEdIX1JNX0VSUk9SX05PUkVTT1VSQ0U6Cj4+ICvCoMKgwqDCoMKg wqDCoCByZXR1cm4gLUVOT0RFVjsKPj4gK8KgwqDCoCBjYXNlIEdIX1JNX0VSUk9SX0RFTklFRDoK Pj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiAtRVBFUk07Cj4+ICvCoMKgwqAgY2FzZSBHSF9STV9F UlJPUl9CVVNZOgo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FQlVTWTsKPj4gK8KgwqDCoCBj YXNlIEdIX1JNX0VSUk9SX0lOVkFMSUQ6Cj4+ICvCoMKgwqAgY2FzZSBHSF9STV9FUlJPUl9BUkdV TUVOVF9JTlZBTElEOgo+PiArwqDCoMKgIGNhc2UgR0hfUk1fRVJST1JfSEFORExFX0lOVkFMSUQ6 Cj4+ICvCoMKgwqAgY2FzZSBHSF9STV9FUlJPUl9WQUxJREFURV9GQUlMRUQ6Cj4+ICvCoMKgwqAg Y2FzZSBHSF9STV9FUlJPUl9NQVBfRkFJTEVEOgo+PiArwqDCoMKgIGNhc2UgR0hfUk1fRVJST1Jf TUVNX0lOVkFMSUQ6Cj4+ICvCoMKgwqAgY2FzZSBHSF9STV9FUlJPUl9NRU1fSU5VU0U6Cj4+ICvC oMKgwqAgY2FzZSBHSF9STV9FUlJPUl9NRU1fUkVMRUFTRUQ6Cj4+ICvCoMKgwqAgY2FzZSBHSF9S TV9FUlJPUl9WTUlEX0lOVkFMSUQ6Cj4+ICvCoMKgwqAgY2FzZSBHSF9STV9FUlJPUl9MT09LVVBf RkFJTEVEOgo+PiArwqDCoMKgIGNhc2UgR0hfUk1fRVJST1JfSVJRX0lOVkFMSUQ6Cj4+ICvCoMKg wqAgY2FzZSBHSF9STV9FUlJPUl9JUlFfSU5VU0U6Cj4+ICvCoMKgwqAgY2FzZSBHSF9STV9FUlJP Ul9JUlFfUkVMRUFTRUQ6Cj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVJTlZBTDsKPj4gK8Kg wqDCoCBkZWZhdWx0Ogo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FQkFETVNHOwo+PiArwqDC oMKgIH0KPj4gK30KPj4gKwo+PiArc3RydWN0IGdoX3JtOwo+IAo+IFRoaXMgbWlnaHQganVzdCBi ZSBteSBwcmVmZXJlbmNlLCBidXQgSSBsaWtlIHRvIHNlZSBkZWNsYXJhdGlvbnMKPiBsaWtlIHRo ZSBvbmUgYWJvdmUgZ3JvdXBlZCBhdCB0aGUgdG9wIG9mIHRoZSBmaWxlLCB1bmRlciBpbmNsdWRl cy4KPiAKPj4gK2ludCBnaF9ybV9jYWxsKHN0cnVjdCBnaF9ybSAqcnNjX21nciwgdTMyIG1lc3Nh Z2VfaWQsIHZvaWQgKnJlcV9idWZmLCAKPj4gc2l6ZV90IHJlcV9idWZmX3NpemUsCj4+ICvCoMKg wqDCoMKgwqDCoCB2b2lkICoqcmVzcF9idWYsIHNpemVfdCAqcmVzcF9idWZmX3NpemUpOwo+PiAr Cj4+ICsjZW5kaWYKPj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvZ3VueWFoX3JzY19tZ3Iu aCAKPj4gYi9pbmNsdWRlL2xpbnV4L2d1bnlhaF9yc2NfbWdyLmgKPj4gbmV3IGZpbGUgbW9kZSAx MDA2NDQKPj4gaW5kZXggMDAwMDAwMDAwMDAwLi5jOTkyYjMxODhjOGQKPj4gLS0tIC9kZXYvbnVs bAo+PiArKysgYi9pbmNsdWRlL2xpbnV4L2d1bnlhaF9yc2NfbWdyLmgKPj4gQEAgLTAsMCArMSwy NCBAQAo+PiArLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seSAqLwo+PiAr LyoKPj4gKyAqIENvcHlyaWdodCAoYykgMjAyMi0yMDIzIFF1YWxjb21tIElubm92YXRpb24gQ2Vu dGVyLCBJbmMuIEFsbCAKPj4gcmlnaHRzIHJlc2VydmVkLgo+PiArICovCj4+ICsKPj4gKyNpZm5k ZWYgX0dVTllBSF9SU0NfTUdSX0gKPj4gKyNkZWZpbmUgX0dVTllBSF9SU0NfTUdSX0gKPj4gKwo+ PiArI2luY2x1ZGUgPGxpbnV4L2xpc3QuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9ub3RpZmllci5o Pgo+PiArI2luY2x1ZGUgPGxpbnV4L2d1bnlhaC5oPgo+PiArCj4+ICsjZGVmaW5lIEdIX1ZNSURf SU5WQUzCoMKgwqAgVTE2X01BWAo+PiArCj4+ICsvKiBHdW55YWggcmVjb2duaXplcyBWTUlEMCBh cyBhbiBhbGlhcyB0byB0aGUgY3VycmVudCBWTSdzIElEICovCj4+ICsjZGVmaW5lIEdIX1ZNSURf U0VMRsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMAo+IAo+IEkgaGF2ZW4ndCByZWFsbHkgY2hlY2tl ZCB2ZXJ5IHdlbGwsIGJ1ciB5b3Ugc2hvdWxkICp1c2UgdGhpcyoKPiBkZWZpbml0aW9uIHdoZXJl IGEgVk1JRCBpcyBiZWluZyBleGFtaW5lZC4gSS5lLiwgaWYgeW91J3JlCj4gZ29pbmcgdG8gZGVm aW5lIHRoaXMsIHRoZW4gbmV2ZXIganVzdCBjb21wYXJlIGEgVk1JRCBhZ2FpbnN0IDAuCj4gCgpJ IHJlYWxpemUgbm93IHRoZSBvbmx5IHBsYWNlIEkgKmNvdWxkKiB1c2UgR0hfVk1JRF9TRUxGIGlz IHRoZSBvbmUgCmV4Y2VwdGlvbiB0byB1c2FnZSBvZiBWTUlEIC0tIGluIGdoX3JtX3ZtaWRfYWxs b2MuIFRoZXJlLCB2bWlkIG9mIDAgCm1lYW5zICJ1c2UgZHluYW1pYyBhbGxvY2F0aW9uIi4gU2lu Y2UgdGhlcmUgYXJlbid0IGFueSB1c2VycyBvZiB0aGUgCkdIX1ZNSURfU0VMRiwgSSdsbCBkcm9w IGl0LgoKVGhhbmtzLApFbGxpb3QKCj4gIMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIC1BbGV4Cj4gCj4+ICsKPj4gK3N0cnVjdCBnaF9ybTsKPj4gK2ludCBnaF9ybV9ub3Rp Zmllcl9yZWdpc3RlcihzdHJ1Y3QgZ2hfcm0gKnJtLCBzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgCj4+ ICpuYik7Cj4+ICtpbnQgZ2hfcm1fbm90aWZpZXJfdW5yZWdpc3RlcihzdHJ1Y3QgZ2hfcm0gKnJt LCBzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgCj4+ICpuYik7Cj4+ICt2b2lkIGdldF9naF9ybShzdHJ1 Y3QgZ2hfcm0gKnJtKTsKPj4gK3ZvaWQgcHV0X2doX3JtKHN0cnVjdCBnaF9ybSAqcm0pOwo+PiAr Cj4+ICsjZW5kaWYKPiAKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBsaXN0CmxpbnV4LWFybS1rZXJuZWxAbGlz dHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3Rp bmZvL2xpbnV4LWFybS1rZXJuZWwK