From patchwork Mon Oct 30 22:40:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 10033415 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 020276039A for ; Mon, 30 Oct 2017 22:43:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E800328650 for ; Mon, 30 Oct 2017 22:43:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DCB0028981; Mon, 30 Oct 2017 22:43:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 777E428650 for ; Mon, 30 Oct 2017 22:43:19 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e9Ik2-00052O-Nt; Mon, 30 Oct 2017 22:41:10 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e9Ik0-00051X-SW for xen-devel@lists.xen.org; Mon, 30 Oct 2017 22:41:08 +0000 Received: from [193.109.254.147] by server-9.bemta-6.messagelabs.com id 0E/CD-30115-48AA7F95; Mon, 30 Oct 2017 22:41:08 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpjkeJIrShJLcpLzFFi42I5NlE2Wbd51fd Ig7efFCyWfFzM4sDocXT3b6YAxijWzLyk/IoE1ozVky8yF1xTqfhybwJ7A+Ns+S5GLg4hgXVM Ep1nfrN1MXJysAg4SGy5upuli5GDg1EgRuLBD2uQMKNAmMTky0tYQWw2AUOJv082gZWLCEhLX Pt8mRFkDrPAZEaJ1+9+MYMkhAVsJSbdXMUEMVNV4uCR7ewgM3kF3CTan6SAhCUE5CROHpsMNp NTwF3ix8u1TBD3tDFKbJ59hHkCI+8CRoZVjBrFqUVlqUW6RhZ6SUWZ6RkluYmZObqGBmZ6uan FxYnpqTmJScV6yfm5mxiB4cAABDsYz68NPMQoycGkJMq70/F7pBBfUn5KZUZicUZ8UWlOavEh RhkODiUJ3sqVQDnBotT01Iq0zBxgYMKkJTh4lER4r6wASvMWFyTmFmemQ6ROMVpyHNt0+Q8TR 8fNu0Dy2czXDcxCLHn5ealS4ryBIPMEQBoySvPgxsGi5xKjrJQwLyPQgUI8BalFuZklqPKvGM U5GJWEea+ATOHJzCuB2/oK6CAmoIM0JL+AHFSSiJCSamDcaSMfISR3YPFK5/lfDolM28g9cfG Kx74l1lV3/xw1bJvqWxrhGWWbcej6mrsfTjkqHZhTGX7nXSlDdpo/f2Zk6dYL2QmLTqyoPuD9 OWjNtweiv48aHk9/rBTev/BxZE5tYGC10wWvPbI2CU4nnyoaNj5PP9v2XWH/lgw3dg3zaZosZ mu3sXxXYinOSDTUYi4qTgQAqUedlpkCAAA= X-Env-Sender: sstabellini@kernel.org X-Msg-Ref: server-15.tower-27.messagelabs.com!1509403266!61280770!1 X-Originating-IP: [198.145.29.99] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 50110 invoked from network); 30 Oct 2017 22:41:07 -0000 Received: from mail.kernel.org (HELO mail.kernel.org) (198.145.29.99) by server-15.tower-27.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 30 Oct 2017 22:41:07 -0000 Received: from localhost.localdomain (162-198-228-33.lightspeed.wlfrct.sbcglobal.net [162.198.228.33]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A1E9621947; Mon, 30 Oct 2017 22:41:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A1E9621947 From: Stefano Stabellini To: xen-devel@lists.xen.org Date: Mon, 30 Oct 2017 15:40:53 -0700 Message-Id: <1509403263-15414-3-git-send-email-sstabellini@kernel.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1509403263-15414-1-git-send-email-sstabellini@kernel.org> References: <1509403263-15414-1-git-send-email-sstabellini@kernel.org> Cc: jgross@suse.com, Stefano Stabellini , boris.ostrovsky@oracle.com, sstabellini@kernel.org, linux-kernel@vger.kernel.org Subject: [Xen-devel] [PATCH v8 03/13] xen/pvcalls: connect to the backend X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Implement the probe function for the pvcalls frontend. Read the supported versions, max-page-order and function-calls nodes from xenstore. Only one frontend<->backend connection is supported at any given time for a guest. Store the active frontend device to a static pointer. Introduce a stub functions for the event handler. Signed-off-by: Stefano Stabellini Reviewed-by: Boris Ostrovsky CC: boris.ostrovsky@oracle.com CC: jgross@suse.com --- drivers/xen/pvcalls-front.c | 132 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c index aae23d0..1618502 100644 --- a/drivers/xen/pvcalls-front.c +++ b/drivers/xen/pvcalls-front.c @@ -104,12 +104,144 @@ static int pvcalls_front_remove(struct xenbus_device *dev) static int pvcalls_front_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { + int ret = -ENOMEM, evtchn, i; + unsigned int max_page_order, function_calls, len; + char *versions; + grant_ref_t gref_head = 0; + struct xenbus_transaction xbt; + struct pvcalls_bedata *bedata = NULL; + struct xen_pvcalls_sring *sring; + + if (pvcalls_front_dev != NULL) { + dev_err(&dev->dev, "only one PV Calls connection supported\n"); + return -EINVAL; + } + + versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len); + if (!len) + return -EINVAL; + if (strcmp(versions, "1")) { + kfree(versions); + return -EINVAL; + } + kfree(versions); + max_page_order = xenbus_read_unsigned(dev->otherend, + "max-page-order", 0); + if (max_page_order < PVCALLS_RING_ORDER) + return -ENODEV; + function_calls = xenbus_read_unsigned(dev->otherend, + "function-calls", 0); + /* See XENBUS_FUNCTIONS_CALLS in pvcalls.h */ + if (function_calls != 1) + return -ENODEV; + pr_info("%s max-page-order is %u\n", __func__, max_page_order); + + bedata = kzalloc(sizeof(struct pvcalls_bedata), GFP_KERNEL); + if (!bedata) + return -ENOMEM; + + dev_set_drvdata(&dev->dev, bedata); + pvcalls_front_dev = dev; + init_waitqueue_head(&bedata->inflight_req); + INIT_LIST_HEAD(&bedata->socket_mappings); + spin_lock_init(&bedata->socket_lock); + bedata->irq = -1; + bedata->ref = -1; + + for (i = 0; i < PVCALLS_NR_RSP_PER_RING; i++) + bedata->rsp[i].req_id = PVCALLS_INVALID_ID; + + sring = (struct xen_pvcalls_sring *) __get_free_page(GFP_KERNEL | + __GFP_ZERO); + if (!sring) + goto error; + SHARED_RING_INIT(sring); + FRONT_RING_INIT(&bedata->ring, sring, XEN_PAGE_SIZE); + + ret = xenbus_alloc_evtchn(dev, &evtchn); + if (ret) + goto error; + + bedata->irq = bind_evtchn_to_irqhandler(evtchn, + pvcalls_front_event_handler, + 0, "pvcalls-frontend", dev); + if (bedata->irq < 0) { + ret = bedata->irq; + goto error; + } + + ret = gnttab_alloc_grant_references(1, &gref_head); + if (ret < 0) + goto error; + bedata->ref = gnttab_claim_grant_reference(&gref_head); + if (bedata->ref < 0) { + ret = bedata->ref; + goto error; + } + gnttab_grant_foreign_access_ref(bedata->ref, dev->otherend_id, + virt_to_gfn((void *)sring), 0); + + again: + ret = xenbus_transaction_start(&xbt); + if (ret) { + xenbus_dev_fatal(dev, ret, "starting transaction"); + goto error; + } + ret = xenbus_printf(xbt, dev->nodename, "version", "%u", 1); + if (ret) + goto error_xenbus; + ret = xenbus_printf(xbt, dev->nodename, "ring-ref", "%d", bedata->ref); + if (ret) + goto error_xenbus; + ret = xenbus_printf(xbt, dev->nodename, "port", "%u", + evtchn); + if (ret) + goto error_xenbus; + ret = xenbus_transaction_end(xbt, 0); + if (ret) { + if (ret == -EAGAIN) + goto again; + xenbus_dev_fatal(dev, ret, "completing transaction"); + goto error; + } + xenbus_switch_state(dev, XenbusStateInitialised); + return 0; + + error_xenbus: + xenbus_transaction_end(xbt, 1); + xenbus_dev_fatal(dev, ret, "writing xenstore"); + error: + pvcalls_front_remove(dev); + return ret; } static void pvcalls_front_changed(struct xenbus_device *dev, enum xenbus_state backend_state) { + switch (backend_state) { + case XenbusStateReconfiguring: + case XenbusStateReconfigured: + case XenbusStateInitialising: + case XenbusStateInitialised: + case XenbusStateUnknown: + break; + + case XenbusStateInitWait: + break; + + case XenbusStateConnected: + xenbus_switch_state(dev, XenbusStateConnected); + break; + + case XenbusStateClosed: + if (dev->state == XenbusStateClosed) + break; + /* Missed the backend's CLOSING state -- fallthrough */ + case XenbusStateClosing: + xenbus_frontend_closed(dev); + break; + } } static struct xenbus_driver pvcalls_front_driver = {