From owner-svn-src-head@FreeBSD.ORG Tue Sep 30 17:27:57 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 7F23293B; Tue, 30 Sep 2014 17:27:57 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6B196D79; Tue, 30 Sep 2014 17:27:57 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s8UHRvjD012478; Tue, 30 Sep 2014 17:27:57 GMT (envelope-from royger@FreeBSD.org) Received: (from royger@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s8UHRvQu012477; Tue, 30 Sep 2014 17:27:57 GMT (envelope-from royger@FreeBSD.org) Message-Id: <201409301727.s8UHRvQu012477@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: royger set sender to royger@FreeBSD.org using -f From: Roger Pau Monné Date: Tue, 30 Sep 2014 17:27:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r272317 - head/sys/dev/xen/xenstore X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 30 Sep 2014 17:27:57 -0000 Author: royger Date: Tue Sep 30 17:27:56 2014 New Revision: 272317 URL: http://svnweb.freebsd.org/changeset/base/272317 Log: xen: defer xenstore initialization until xenstored is started The xenstore related devices in the kernel cannot be started until xenstored is running, which will happen later in the Dom0 case. If start_info_t doesn't contain a valid xenstore event channel, defer all xenstore related devices attachment to later. Sponsored by: Citrix Systems R&D dev/xen/xenstore/xenstore.c: - Prevent xenstore from trying to attach it's descendant devices if xenstore is not initialized. - Add a callback in the xenstore interrupt filter that will trigger the plug of xenstore descendant devices on the first received interrupt. This interrupt is generated when xenstored attaches to the event channel, and serves as a notification that xenstored is running. Modified: head/sys/dev/xen/xenstore/xenstore.c Modified: head/sys/dev/xen/xenstore/xenstore.c ============================================================================== --- head/sys/dev/xen/xenstore/xenstore.c Tue Sep 30 17:26:34 2014 (r272316) +++ head/sys/dev/xen/xenstore/xenstore.c Tue Sep 30 17:27:56 2014 (r272317) @@ -48,6 +48,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include @@ -249,6 +251,20 @@ struct xs_softc { * with the XenStore service) are available. */ struct intr_config_hook xs_attachcb; + + /** + * Xenstore is a user-space process that usually runs in Dom0, + * so if this domain is booting as Dom0, xenstore wont we accessible, + * and we have to defer the initialization of xenstore related + * devices to later (when xenstore is started). + */ + bool initialized; + + /** + * Task to run when xenstore is initialized (Dom0 only), will + * take care of attaching xenstore related devices. + */ + struct task xs_late_init; }; /*-------------------------------- Global Data ------------------------------*/ @@ -352,6 +368,16 @@ static void xs_intr(void * arg __unused /*__attribute__((unused))*/) { + /* If xenstore has not been initialized, initialize it now */ + if (!xs.initialized) { + xs.initialized = true; + /* + * Since this task is probing and attaching devices we + * have to hold the Giant lock. + */ + taskqueue_enqueue(taskqueue_swi_giant, &xs.xs_late_init); + } + /* * Hold ring lock across wakeup so that clients * cannot miss a wakeup. @@ -1112,6 +1138,15 @@ xs_attach_deferred(void *arg) config_intrhook_disestablish(&xs.xs_attachcb); } +static void +xs_attach_late(void *arg, int pending) +{ + + KASSERT((pending == 1), ("xs late attach queued several times")); + bus_generic_probe(xs.xs_dev); + bus_generic_attach(xs.xs_dev); +} + /** * Attach to the XenStore. * @@ -1130,12 +1165,37 @@ xs_attach(device_t dev) /* Initialize the interface to xenstore. */ struct proc *p; + xs.initialized = false; if (xen_hvm_domain()) { xs.evtchn = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN); xs.gpfn = hvm_get_parameter(HVM_PARAM_STORE_PFN); xen_store = pmap_mapdev(xs.gpfn * PAGE_SIZE, PAGE_SIZE); + xs.initialized = true; } else if (xen_pv_domain()) { - xs.evtchn = HYPERVISOR_start_info->store_evtchn; + if (HYPERVISOR_start_info->store_evtchn == 0) { + struct evtchn_alloc_unbound alloc_unbound; + + /* Allocate a local event channel for xenstore */ + alloc_unbound.dom = DOMID_SELF; + alloc_unbound.remote_dom = DOMID_SELF; + error = HYPERVISOR_event_channel_op( + EVTCHNOP_alloc_unbound, &alloc_unbound); + if (error != 0) + panic( + "unable to alloc event channel for Dom0: %d", + error); + + HYPERVISOR_start_info->store_evtchn = + alloc_unbound.port; + xs.evtchn = alloc_unbound.port; + + /* Allocate memory for the xs shared ring */ + xen_store = malloc(PAGE_SIZE, M_XENSTORE, + M_WAITOK | M_ZERO); + } else { + xs.evtchn = HYPERVISOR_start_info->store_evtchn; + xs.initialized = true; + } } else { panic("Unknown domain type, cannot initialize xenstore."); } @@ -1167,7 +1227,11 @@ xs_attach(device_t dev) xs.xs_attachcb.ich_func = xs_attach_deferred; xs.xs_attachcb.ich_arg = NULL; - config_intrhook_establish(&xs.xs_attachcb); + if (xs.initialized) { + config_intrhook_establish(&xs.xs_attachcb); + } else { + TASK_INIT(&xs.xs_late_init, 0, xs_attach_late, NULL); + } return (error); }