[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 09/11] xen/arm: vpl011: Modify domain_create_ring in xenconsole to map the ring buffer and event channel



Modfication in domain_create_ring():
    - Bind to the vpl011 event channel obtained from the xen store as a new 
parameter
    - Map the PFN to its address space to be used as IN/OUT ring buffers. It 
obtains
      the PFN from the xen store as a new parameter

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@xxxxxxxxxx>
---
 tools/console/daemon/io.c | 128 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 110 insertions(+), 18 deletions(-)

diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index 7e6a886..b1aa615 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -101,13 +101,18 @@ struct domain {
        struct domain *next;
        char *conspath;
        int ring_ref;
+       int vpl011_ring_ref;
        xenevtchn_port_or_error_t local_port;
        xenevtchn_port_or_error_t remote_port;
+       xenevtchn_port_or_error_t vpl011_local_port;
+       xenevtchn_port_or_error_t vpl011_remote_port;
        xenevtchn_handle *xce_handle;
        int xce_pollfd_idx;
        struct xencons_interface *interface;
+       struct xencons_interface *vpl011_interface;
        int event_count;
        long long next_period;
+       bool vpl011_initialized;
 };
 
 static struct domain *dom_head;
@@ -529,9 +534,58 @@ static void domain_unmap_interface(struct domain *dom)
        dom->ring_ref = -1;
 }
  
+static void domain_unmap_vpl011_interface(struct domain *dom)
+{
+       if ( dom->vpl011_interface == NULL )
+        return;
+
+       if ( xgt_handle && dom->vpl011_ring_ref == -1 )
+               xengnttab_unmap(xgt_handle, dom->vpl011_interface, 1);
+       else
+               munmap(dom->vpl011_interface, XC_PAGE_SIZE);
+       dom->vpl011_interface = NULL;
+       dom->vpl011_ring_ref = -1;
+}
+
+int bind_event_channel(struct domain *dom, int new_rport, int *lport, int 
*rport)
+{
+       int err = 0, rc;
+
+       /* Go no further if port has not changed and we are still bound. */
+       if ( new_rport == *rport ) {
+               xc_evtchn_status_t status = {
+               .dom = DOMID_SELF,
+               .port = *lport };
+       if ((xc_evtchn_status(xc, &status) == 0) &&
+               (status.status == EVTCHNSTAT_interdomain))
+               goto out;
+       }
+
+       /* initialize the ports */
+       *lport = -1;
+       *rport = -1;
+ 
+       /* bind to new remote port */
+       rc = xenevtchn_bind_interdomain(dom->xce_handle,
+       dom->domid, new_rport);
+
+       if ( rc == -1 ) {
+               err = errno;
+               xenevtchn_close(dom->xce_handle);
+               dom->xce_handle = NULL;
+               goto out;
+       }
+
+       /* store new local and remote event channel ports */
+       *lport = rc;
+       *rport = new_rport;
+out:
+       return err;
+}
+ 
 static int domain_create_ring(struct domain *dom)
 {
-       int err, remote_port, ring_ref, rc;
+       int err, remote_port, ring_ref, vpl011_remote_port, vpl011_ring_ref;
        char *type, path[PATH_MAX];
 
        err = xs_gather(xs, dom->conspath,
@@ -541,6 +595,20 @@ static int domain_create_ring(struct domain *dom)
        if (err)
                goto out;
 
+       /*
+       * if the vpl011 parameters are not available or are not initialized
+       * the vpl011 console is not available
+       */
+       err = xs_gather(xs, dom->conspath,
+               "vpl011-ring-ref", "%u", &vpl011_ring_ref,
+               "vpl011-port", "%i", &vpl011_remote_port,
+               NULL);
+
+       if ( err || vpl011_ring_ref == -1 )
+               dom->vpl011_initialized = false;
+       else
+               dom->vpl011_initialized = true;
+
        snprintf(path, sizeof(path), "%s/type", dom->conspath);
        type = xs_read(xs, XBT_NULL, path, NULL);
        if (type && strcmp(type, "xenconsoled") != 0) {
@@ -553,6 +621,12 @@ static int domain_create_ring(struct domain *dom)
        if (ring_ref != dom->ring_ref && dom->ring_ref != -1)
                domain_unmap_interface(dom);
 
+       /* If using vpl011 ring_ref and it has changed, remap */
+       if ( dom->vpl011_initialized && 
+               vpl011_ring_ref != dom->vpl011_ring_ref && 
+               dom->vpl011_ring_ref != -1 )
+               domain_unmap_vpl011_interface(dom);
+
        if (!dom->interface && xgt_handle) {
                /* Prefer using grant table */
                dom->interface = xengnttab_map_grant_ref(xgt_handle,
@@ -560,6 +634,8 @@ static int domain_create_ring(struct domain *dom)
                        PROT_READ|PROT_WRITE);
                dom->ring_ref = -1;
        }
+
+       /* map PV console ring buffer */
        if (!dom->interface) {
                /* Fall back to xc_map_foreign_range */
                dom->interface = xc_map_foreign_range(
@@ -573,18 +649,21 @@ static int domain_create_ring(struct domain *dom)
                dom->ring_ref = ring_ref;
        }
 
-       /* Go no further if port has not changed and we are still bound. */
-       if (remote_port == dom->remote_port) {
-               xc_evtchn_status_t status = {
-                       .dom = DOMID_SELF,
-                       .port = dom->local_port };
-               if ((xc_evtchn_status(xc, &status) == 0) &&
-                   (status.status == EVTCHNSTAT_interdomain))
+       /* map vpl011 console ring buffer */
+       if ( dom->vpl011_initialized && !dom->vpl011_interface ) {
+
+               /* Fall back to xc_map_foreign_range */
+               dom->vpl011_interface = xc_map_foreign_range(
+               xc, dom->domid, XC_PAGE_SIZE,
+               PROT_READ|PROT_WRITE,
+               (unsigned long)vpl011_ring_ref);
+               if ( dom->vpl011_interface == NULL ) {
+                       err = EINVAL;
                        goto out;
+               }
+               dom->vpl011_ring_ref = vpl011_ring_ref;
        }
 
-       dom->local_port = -1;
-       dom->remote_port = -1;
        if (dom->xce_handle != NULL)
                xenevtchn_close(dom->xce_handle);
 
@@ -596,17 +675,24 @@ static int domain_create_ring(struct domain *dom)
                goto out;
        }
  
-       rc = xenevtchn_bind_interdomain(dom->xce_handle,
-               dom->domid, remote_port);
-
-       if (rc == -1) {
-               err = errno;
+       /* bind PV console channel */
+       err = bind_event_channel(dom, remote_port, &dom->local_port, 
&dom->remote_port);
+       if (err)
+       {
                xenevtchn_close(dom->xce_handle);
-               dom->xce_handle = NULL;
                goto out;
        }
-       dom->local_port = rc;
-       dom->remote_port = remote_port;
+
+       /* bind vpl011 console channel */
+       if ( dom->vpl011_initialized )
+       {
+               err = bind_event_channel(dom, vpl011_remote_port, 
&dom->vpl011_local_port, &dom->vpl011_remote_port);
+               if (err)
+               {
+                       xenevtchn_close(dom->xce_handle);
+                       goto out;
+               }
+       }
 
        if (dom->master_fd == -1) {
                if (!domain_create_tty(dom)) {
@@ -615,6 +701,9 @@ static int domain_create_ring(struct domain *dom)
                        dom->xce_handle = NULL;
                        dom->local_port = -1;
                        dom->remote_port = -1;
+                       dom->vpl011_local_port = -1;
+                       dom->vpl011_remote_port = -1;
+                       dom->vpl011_initialized = false;
                        goto out;
                }
        }
@@ -684,8 +773,11 @@ static struct domain *create_domain(int domid)
        dom->next_period = ((long long)ts.tv_sec * 1000) + (ts.tv_nsec / 
1000000) + RATE_LIMIT_PERIOD;
 
        dom->ring_ref = -1;
+       dom->vpl011_ring_ref = -1;
        dom->local_port = -1;
        dom->remote_port = -1;
+       dom->vpl011_local_port = -1;
+       dom->vpl011_remote_port = -1;
 
        if (!watch_domain(dom, true))
                goto out;
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.