WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] hvmloader: Add a xenbus frontend so it ca

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] hvmloader: Add a xenbus frontend so it can read values from xenstore
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 09 Jul 2010 04:50:49 -0700
Delivery-date: Fri, 09 Jul 2010 04:53:21 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1278675237 -3600
# Node ID 80565319f83dbc838ca13a76ba9888546489c002
# Parent  e17e09abb349ca95cae88adb8841dda337077a3f
hvmloader: Add a xenbus frontend so it can read values from xenstore

Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
---
 tools/firmware/hvmloader/Makefile    |    2 
 tools/firmware/hvmloader/hvmloader.c |    3 
 tools/firmware/hvmloader/util.h      |   12 ++
 tools/firmware/hvmloader/xenbus.c    |  200 +++++++++++++++++++++++++++++++++++
 4 files changed, 216 insertions(+), 1 deletion(-)

diff -r e17e09abb349 -r 80565319f83d tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Fri Jul 09 12:28:03 2010 +0100
+++ b/tools/firmware/hvmloader/Makefile Fri Jul 09 12:33:57 2010 +0100
@@ -29,7 +29,7 @@ CFLAGS += $(CFLAGS_include) -I.
 CFLAGS += $(CFLAGS_include) -I.
 
 SRCS  = hvmloader.c mp_tables.c util.c smbios.c 
-SRCS += 32bitbios_support.c smp.c cacheattr.c
+SRCS += 32bitbios_support.c smp.c cacheattr.c xenbus.c
 ifeq ($(debug),y)
 SRCS += tests.c
 endif
diff -r e17e09abb349 -r 80565319f83d tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Fri Jul 09 12:28:03 2010 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c      Fri Jul 09 12:33:57 2010 +0100
@@ -704,6 +704,7 @@ int main(void)
 
     printf("CPU speed is %u MHz\n", get_cpu_mhz());
 
+    xenbus_setup();
     apic_setup();
     pci_setup();
 
@@ -803,6 +804,8 @@ int main(void)
     bios_info->madt_lapic0_addr = madt_lapic0_addr;
     bios_info->bios32_entry = bios32_addr;
 
+    xenbus_shutdown();
+
     printf("Invoking ROMBIOS ...\n");
     return 0;
 }
diff -r e17e09abb349 -r 80565319f83d tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Fri Jul 09 12:28:03 2010 +0100
+++ b/tools/firmware/hvmloader/util.h   Fri Jul 09 12:33:57 2010 +0100
@@ -155,6 +155,18 @@ void *mem_alloc(uint32_t size, uint32_t 
 void *mem_alloc(uint32_t size, uint32_t align);
 #define virt_to_phys(v) ((unsigned long)(v))
 
+/* Connect our xenbus client to the backend.  
+ * Call once, before any other xenbus actions. */
+void xenbus_setup(void);
+
+/* Reset the xenbus connection so the next kernel can start again. */
+void xenbus_shutdown(void);
+
+/* Read a xenstore key.  Returns a nul-terminated string (even if the XS
+ * data wasn't nul-terminated) or NULL.  The returned string is in a
+ * static buffer, so only valid until the next xenstore/xenbus operation. */
+char *xenstore_read(char *path);
+
 /* Prepare the 32bit BIOS */
 uint32_t highbios_setup(void);
 
diff -r e17e09abb349 -r 80565319f83d tools/firmware/hvmloader/xenbus.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/firmware/hvmloader/xenbus.c Fri Jul 09 12:33:57 2010 +0100
@@ -0,0 +1,200 @@
+/*
+ * xenbus.c: static, synchronous, read-only xenbus client for hvmloader.
+ *
+ * Copyright (c) 2009 Tim Deegan, Citrix Systems (R&D) Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "util.h"
+#include "hypercall.h"
+#include <errno.h>
+#include <xen/sched.h>
+#include <xen/event_channel.h>
+#include <xen/hvm/params.h>
+#include <xen/io/xs_wire.h>
+
+struct xenstore_domain_interface *rings; /* Shared ring with dom0 */
+evtchn_port_t event;                     /* Event-channel to dom0 */
+char payload[XENSTORE_PAYLOAD_MAX + 1];  /* Unmarshalling area */
+
+/* Connect our xenbus client to the backend.
+ * Call once, before any other xenbus actions. */
+void xenbus_setup(void)
+{
+    xen_hvm_param_t param;
+
+    /* Ask Xen where the xenbus shared page is. */
+    param.domid = DOMID_SELF;
+    param.index = HVM_PARAM_STORE_PFN;
+    if ( hypercall_hvm_op(HVMOP_get_param, &param) )
+        BUG();
+    rings = (void *) (unsigned long) (param.value << PAGE_SHIFT);
+
+    /* Ask Xen where the xenbus event channel is. */
+    param.domid = DOMID_SELF;
+    param.index = HVM_PARAM_STORE_EVTCHN;
+    if ( hypercall_hvm_op(HVMOP_get_param, &param) )
+        BUG();
+    event = param.value;
+
+    printf("Xenbus rings @0x%lx, event channel %lu\n",
+           (unsigned long) rings, (unsigned long) event);
+}
+
+/* Reset the xenbus connection so the next kernel can start again. 
+ * We zero out the whole ring -- the backend can handle this, and it's 
+ * not going to surprise any frontends since it's equivalent to never 
+ * having used the rings. */
+void xenbus_shutdown(void)
+{
+    ASSERT(rings != NULL);
+    memset(rings, 0, sizeof *rings);
+    rings = NULL;
+}
+
+/* Helper functions: copy data in and out of the ring */
+static void ring_write(char *data, uint32_t len)
+{
+    uint32_t part;
+
+    ASSERT(len <= XENSTORE_PAYLOAD_MAX);
+
+    while ( len )
+    {
+        /* Don't overrun the consumer pointer */
+        part = (XENSTORE_RING_SIZE - 1) -
+            MASK_XENSTORE_IDX(rings->req_prod - rings->req_cons);
+        /* Don't overrun the end of the ring */
+        if ( part > (XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->req_prod)) )
+            part = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->req_prod);
+        /* Don't write more than we were asked for */
+        if ( part > len ) 
+            part = len;
+
+        memcpy(rings->req + MASK_XENSTORE_IDX(rings->req_prod), data, part);
+        barrier(); /* = wmb before prod write, rmb before next cons read */
+        rings->req_prod += part;
+        len -= part;
+
+        if ( len )
+            hypercall_sched_op(SCHEDOP_yield, NULL);
+    }
+}
+
+static void ring_read(char *data, uint32_t len)
+{
+    uint32_t part;
+
+    ASSERT(len <= XENSTORE_PAYLOAD_MAX);
+
+    while ( len )
+    {
+        /* Don't overrun the producer pointer */
+        part = MASK_XENSTORE_IDX(rings->rsp_prod - rings->rsp_cons);
+        /* Don't overrun the end of the ring */
+        if ( part > (XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->rsp_cons)) )
+            part = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->rsp_cons);
+        /* Don't read more than we were asked for */
+        if ( part > len )
+            part = len;
+
+        memcpy(data, rings->rsp + MASK_XENSTORE_IDX(rings->rsp_cons), part);
+        barrier(); /* = wmb before cons write, rmb before next prod read */
+        rings->rsp_cons += part;
+        len -= part;
+        
+        if ( len )
+            hypercall_sched_op(SCHEDOP_yield, NULL);
+    }
+}
+
+
+/* Send a request and wait for the answer.
+ * Returns 0 for success, or an errno for error.
+ * The answer is returned in a static buffer which is only
+ * valid until the next call of xenbus_send(). */
+static int xenbus_send(uint32_t type, uint32_t len, char *data,
+                       uint32_t *reply_len, char **reply_data)
+{
+    struct xsd_sockmsg hdr;
+    evtchn_send_t send;
+    int i;
+
+    /* Not acceptable to use xenbus before setting it up */
+    ASSERT(rings != NULL);
+
+    /* Put the request on the ring */
+    hdr.type = type;
+    hdr.req_id = 0;  /* We only ever issue one request at a time */
+    hdr.tx_id = 0;   /* We never use transactions */
+    hdr.len = len;
+    ring_write((char *) &hdr, sizeof hdr);
+    ring_write(data, len);
+
+    /* Tell the other end about the request */
+    send.port = event;
+    hypercall_event_channel_op(EVTCHNOP_send, &send);
+
+    /* Properly we should poll the event channel now but that involves
+     * mapping the shared-info page and handling the bitmaps. */
+
+    /* Pull the reply off the ring */
+    ring_read((char *) &hdr, sizeof(hdr));
+    ring_read(payload, hdr.len);
+    /* For sanity's sake, nul-terminate the answer */
+    payload[hdr.len] = '\0';
+
+    /* Handle errors */
+    if ( hdr.type == XS_ERROR )
+    {
+        *reply_len = 0;
+        for ( i = 0; i < ((sizeof xsd_errors) / (sizeof xsd_errors[0])); i++ )
+            if ( !strcmp(xsd_errors[i].errstring, payload) )
+                return xsd_errors[i].errnum;
+        /* Default error value if we couldn't decode the ASCII error */
+        return EIO;
+    }
+
+    *reply_data = payload;
+    *reply_len = hdr.len;
+    return 0;
+}
+
+
+/* Read a xenstore key.  Returns a nul-terminated string (even if the XS
+ * data wasn't nul-terminated) or NULL.  The returned string is in a
+ * static buffer, so only valid until the next xenstore/xenbus operation. */
+char *xenstore_read(char *path)
+{
+    uint32_t len = 0;
+    char *answer = NULL;
+
+    /* Include the nul in the request */
+    if ( xenbus_send(XS_READ, strlen(path) + 1, path, &len, &answer) )
+        return NULL;
+    /* We know xenbus_send() nul-terminates its answer, so just pass it on. */
+    return answer;
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] hvmloader: Add a xenbus frontend so it can read values from xenstore, Xen patchbot-unstable <=