From patchwork Thu Aug 6 09:42:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nastya Vicodin X-Patchwork-Id: 1341548 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=hTqr3ELX; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BMk9H3py7z9sR4 for ; Thu, 6 Aug 2020 19:44:35 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E5FF6821FF; Thu, 6 Aug 2020 11:43:28 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hTqr3ELX"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 918E5821C0; Thu, 6 Aug 2020 11:43:24 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-lj1-x229.google.com (mail-lj1-x229.google.com [IPv6:2a00:1450:4864:20::229]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4EFFA821D3 for ; Thu, 6 Aug 2020 11:43:14 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=vicooodin@gmail.com Received: by mail-lj1-x229.google.com with SMTP id w14so21184402ljj.4 for ; Thu, 06 Aug 2020 02:43:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qDQoNiLoNS5oKrRzz4J9N+Q3xRFhkDeAcJl3AwTnq1w=; b=hTqr3ELXE/gK8yqtZEa4QFOCKAfzSjn2Lg22zRi9RrNFr2uRGGbvi8+C3usnVy1M9m QAopYQJOHzhI8mS2EnWgCMA63IiI8mhnHfSVR4a3UZOSy7K/IuxkKhe6Uy3H+454U1UR /FGXzq3yfEr7BQqtU8Ppo6K7xhphGts7ZQK0N2RPq68IKY7eXcJucypbRoliPftqgSAU KmYaXDb138Lj5zgPq8k4N37GK7YX2YgvUIA9wj1A5E7Z768UTa7EE5xro+rAvxU0KJjy LjrBU5MT1wWQMm4Litgod2XtD/pwXE5sxb03em4IuLTsbBuDMTy9Atdx5aJ9WpVJmqcw YSRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qDQoNiLoNS5oKrRzz4J9N+Q3xRFhkDeAcJl3AwTnq1w=; b=meqY0BpMIB04FroYFMeB0iv8PsTljV1MD+p1GVqqoTl1RY6aR1blU8PeoDbjRFCpTP xLoa70YMW/HOQvB07/9Xio2UFEkFpjtiwzg8V9ObrpAtPdmRh0ysrtyPEYzi7rujU1EV VGsGfpIBYbNbFmL9nE0yxuGuKMnqp7H6pwSrRtUvXFn5ZvpiGzsdWhCysvGFtFJzPUDz 4S/EPiihWqL9/7ukQ3aZX1n8PT8dEu54DlDjqaVvVIaRGZHuODSI3r6Xg+8e2WCd6wak K/n52MsngSI1qirX608gPVDJoGdMlrqX5mvRWf8IKAhBdgTgty7By2W7SZaPJ8gGq49Y WMMw== X-Gm-Message-State: AOAM5311Jhnzx+GgS74Jd69tfWVOa0ioTifCn9uXlafYKdsshLgJ1vT4 R+MSIhAI9ZNHVXAC2ovqtY56vI3syI/ZEQ== X-Google-Smtp-Source: ABdhPJzrZedwOkOjNOXsmzlSKwXCahpLZus8YMzkyjX1jKiRRGz6+MF96LuN9SEH2ZdsQOc90YZaiQ== X-Received: by 2002:a2e:87cd:: with SMTP id v13mr3708896ljj.180.1596706993163; Thu, 06 Aug 2020 02:43:13 -0700 (PDT) Received: from localhost.localdomain (host-176-36-213-80.la.net.ua. [176.36.213.80]) by smtp.gmail.com with ESMTPSA id j13sm2151866ljh.83.2020.08.06.02.43.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2020 02:43:12 -0700 (PDT) From: Anastasiia Lukianenko To: u-boot@lists.denx.de, sjg@chromium.org, ye.li@nxp.com, bmeng.cn@gmail.com, xypron.glpk@gmx.de Cc: julien@xen.org, sstabellini@kernel.org, peng.fan@nxp.com, roman@zededa.com, volodymyr_babchuk@epam.com, andr2000@gmail.com, vicooodin@gmail.com, Oleksandr Andrushchenko , Anastasiia Lukianenko Subject: [RESEND PATCH v2 06/18] xen: Port Xen event channel driver from mini-os Date: Thu, 6 Aug 2020 12:42:49 +0300 Message-Id: <20200806094301.4999-7-vicooodin@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200806094301.4999-1-vicooodin@gmail.com> References: <20200806094301.4999-1-vicooodin@gmail.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean From: Oleksandr Andrushchenko Make required updates to run on u-boot. Strip functionality not needed by U-boot. Signed-off-by: Oleksandr Andrushchenko Signed-off-by: Anastasiia Lukianenko --- Changes since v1: - correct code style - remove typedefs - add comments drivers/xen/Makefile | 1 + drivers/xen/events.c | 195 +++++++++++++++++++++++++++++++++++++++ drivers/xen/hypervisor.c | 6 +- include/xen.h | 2 +- include/xen/events.h | 42 +++++++++ 5 files changed, 242 insertions(+), 4 deletions(-) create mode 100644 drivers/xen/events.c create mode 100644 include/xen/events.h diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 1211bf2386..0ad35edefb 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -3,3 +3,4 @@ # (C) Copyright 2020 EPAM Systems Inc. obj-y += hypervisor.o +obj-y += events.o diff --git a/drivers/xen/events.c b/drivers/xen/events.c new file mode 100644 index 0000000000..b4c84814c5 --- /dev/null +++ b/drivers/xen/events.c @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge + * (C) 2005 - Grzegorz Milos - Intel Research Cambridge + * (C) 2020 - EPAM Systems Inc. + * + * File: events.c [1] + * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk) + * Changes: Grzegorz Milos (gm281@cam.ac.uk) + * + * Date: Jul 2003, changes Jun 2005 + * + * Description: Deals with events received on event channels + * + * [1] - http://xenbits.xen.org/gitweb/?p=mini-os.git;a=summary + */ +#include +#include + +#include +#include + +#include +#include + +#define NR_EVS 1024 + +/** + * struct _ev_action - represents a event handler. + * + * Chaining or sharing is not allowed + */ +struct _ev_action { + void (*handler)(evtchn_port_t port, struct pt_regs *regs, void *data); + void *data; + u32 count; +}; + +static struct _ev_action ev_actions[NR_EVS]; +void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data); + +static unsigned long bound_ports[NR_EVS / (8 * sizeof(unsigned long))]; + +void unbind_all_ports(void) +{ + int i; + int cpu = 0; + struct shared_info *s = HYPERVISOR_shared_info; + struct vcpu_info *vcpu_info = &s->vcpu_info[cpu]; + + for (i = 0; i < NR_EVS; i++) { + if (test_and_clear_bit(i, bound_ports)) { + printf("port %d still bound!\n", i); + unbind_evtchn(i); + } + } + vcpu_info->evtchn_upcall_pending = 0; + vcpu_info->evtchn_pending_sel = 0; +} + +int do_event(evtchn_port_t port, struct pt_regs *regs) +{ + struct _ev_action *action; + + clear_evtchn(port); + + if (port >= NR_EVS) { + printk("WARN: do_event(): Port number too large: %d\n", port); + return 1; + } + + action = &ev_actions[port]; + action->count++; + + /* call the handler */ + action->handler(port, regs, action->data); + + return 1; +} + +evtchn_port_t bind_evtchn(evtchn_port_t port, + void (*handler)(evtchn_port_t, struct pt_regs *, void *), + void *data) +{ + if (ev_actions[port].handler != default_handler) + printf("WARN: Handler for port %d already registered, replacing\n", + port); + + ev_actions[port].data = data; + wmb(); + ev_actions[port].handler = handler; + synch_set_bit(port, bound_ports); + + return port; +} + +/** + * unbind_evtchn() - Unbind event channel for selected port + */ +void unbind_evtchn(evtchn_port_t port) +{ + struct evtchn_close close; + int rc; + + if (ev_actions[port].handler == default_handler) + printf("WARN: No handler for port %d when unbinding\n", port); + mask_evtchn(port); + clear_evtchn(port); + + ev_actions[port].handler = default_handler; + wmb(); + ev_actions[port].data = NULL; + synch_clear_bit(port, bound_ports); + + close.port = port; + rc = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); + if (rc) + printf("WARN: close_port %d failed rc=%d. ignored\n", port, rc); +} + +void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore) +{ + debug("[Port %d] - event received\n", port); +} + +/** + * evtchn_alloc_unbound() - Create a port available to the pal for + * exchanging notifications. + * + * Unfortunate confusion of terminology: the port is unbound as far + * as Xen is concerned, but we automatically bind a handler to it. + * + * Return: The result of the hypervisor call. + */ +int evtchn_alloc_unbound(domid_t pal, + void (*handler)(evtchn_port_t, struct pt_regs *, void *), + void *data, evtchn_port_t *port) +{ + int rc; + + struct evtchn_alloc_unbound op; + + op.dom = DOMID_SELF; + op.remote_dom = pal; + rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); + if (rc) { + printf("ERROR: alloc_unbound failed with rc=%d", rc); + return rc; + } + if (!handler) + handler = default_handler; + *port = bind_evtchn(op.port, handler, data); + return rc; +} + +/** + * eventchn_poll() - Event channel polling function + * + * Check and process any pending events + */ +void eventchn_poll(void) +{ + do_hypervisor_callback(NULL); +} + +/** + * init_events() - Initialize event handler + * + * Initially all events are without a handler and disabled. + */ +void init_events(void) +{ + int i; + + debug("%s\n", __func__); + + for (i = 0; i < NR_EVS; i++) { + ev_actions[i].handler = default_handler; + mask_evtchn(i); + } +} + +/** + * fini_events() - Close all ports + * + * Mask and clear event channels. Close port using EVTCHNOP_close + * hypercall. + */ +void fini_events(void) +{ + debug("%s\n", __func__); + /* Dealloc all events */ + unbind_all_ports(); +} + diff --git a/drivers/xen/hypervisor.c b/drivers/xen/hypervisor.c index 108e9701d6..63fed6074f 100644 --- a/drivers/xen/hypervisor.c +++ b/drivers/xen/hypervisor.c @@ -20,6 +20,7 @@ #include #include +#include #include #define active_evtchns(cpu, sh, idx) \ @@ -163,9 +164,7 @@ void do_hypervisor_callback(struct pt_regs *regs) l2 &= ~(1UL << l2i); port = (l1i * (sizeof(unsigned long) * 8)) + l2i; - /* TODO: handle new event: do_event(port, regs); */ - /* Suppress -Wunused-but-set-variable */ - (void)(port); + do_event(port, regs); } } @@ -236,5 +235,6 @@ void xen_init(void) debug("%s\n", __func__); map_shared_info(NULL); + init_events(); } diff --git a/include/xen.h b/include/xen.h index abc3546dd2..64ed3f0654 100644 --- a/include/xen.h +++ b/include/xen.h @@ -8,7 +8,7 @@ /** * xen_init() - Xen initialization * - * Map Xen memory pages. + * Map Xen memory pages, initialize event handler. */ void xen_init(void); diff --git a/include/xen/events.h b/include/xen/events.h new file mode 100644 index 0000000000..82bd18b48c --- /dev/null +++ b/include/xen/events.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge + * (C) 2005 - Grzegorz Milos - Intel Reseach Cambridge + * (C) 2020 - EPAM Systems Inc. + * + * File: events.h + * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk) + * Changes: Grzegorz Milos (gm281@cam.ac.uk) + * + * Date: Jul 2003, changes Jun 2005 + * + * Description: Deals with events on the event channels + */ +#ifndef _EVENTS_H_ +#define _EVENTS_H_ + +#include +#include + +void init_events(void); +void fini_events(void); + +int do_event(evtchn_port_t port, struct pt_regs *regs); +void unbind_evtchn(evtchn_port_t port); +void unbind_all_ports(void); +int evtchn_alloc_unbound(domid_t pal, + void (*handler)(evtchn_port_t, struct pt_regs *, void *), + void *data, evtchn_port_t *port); + +/* Send notification via event channel */ +static inline int notify_remote_via_evtchn(evtchn_port_t port) +{ + struct evtchn_send op; + + op.port = port; + return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op); +} + +void eventchn_poll(void); + +#endif /* _EVENTS_H_ */