All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys
@ 2010-07-09 10:57 Tim Deegan
  2010-07-09 10:57 ` [PATCH 1 of 2] Add a xenbus frontend to hvmloader so it can read values from xenstore Tim Deegan
  2010-07-09 10:57 ` [PATCH 2 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan
  0 siblings, 2 replies; 3+ messages in thread
From: Tim Deegan @ 2010-07-09 10:57 UTC (permalink / raw)
  To: xen-devel

These patches add a read-only xenstore client to hvmloader, 
and use it to customize the SMBIOS strings based on xenstore keys

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1 of 2] Add a xenbus frontend to hvmloader so it can read values from xenstore
  2010-07-09 10:57 [PATCH 0 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan
@ 2010-07-09 10:57 ` Tim Deegan
  2010-07-09 10:57 ` [PATCH 2 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan
  1 sibling, 0 replies; 3+ messages in thread
From: Tim Deegan @ 2010-07-09 10:57 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 52 bytes --]

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>



[-- Attachment #2: xen-unstable.hg-2.patch --]
[-- Type: text/x-patch, Size: 8941 bytes --]

# HG changeset patch
# User Tim Deegan <Tim.Deegan@citrix.com>
# Date 1278671249 -3600
# Node ID 62b9338150160d6f7cea3e2c386f5e6f94e1b13b
# Parent  82f8371effffc7f3f405fc524cf27c3f07d27249
Add a xenbus frontend to hvmloader so it can read values from xenstore.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>

diff -r 82f8371effff -r 62b933815016 tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile	Thu Jul 08 17:54:42 2010 +0100
+++ b/tools/firmware/hvmloader/Makefile	Fri Jul 09 11:27:29 2010 +0100
@@ -29,7 +29,7 @@
 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 82f8371effff -r 62b933815016 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c	Thu Jul 08 17:54:42 2010 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c	Fri Jul 09 11:27:29 2010 +0100
@@ -704,6 +704,7 @@
 
     printf("CPU speed is %u MHz\n", get_cpu_mhz());
 
+    xenbus_setup();
     apic_setup();
     pci_setup();
 
@@ -803,6 +804,8 @@
     bios_info->madt_lapic0_addr = madt_lapic0_addr;
     bios_info->bios32_entry = bios32_addr;
 
+    xenbus_shutdown();
+
     printf("Invoking ROMBIOS ...\n");
     return 0;
 }
diff -r 82f8371effff -r 62b933815016 tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h	Thu Jul 08 17:54:42 2010 +0100
+++ b/tools/firmware/hvmloader/util.h	Fri Jul 09 11:27:29 2010 +0100
@@ -155,6 +155,18 @@
 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 82f8371effff -r 62b933815016 tools/firmware/hvmloader/xenbus.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/firmware/hvmloader/xenbus.c	Fri Jul 09 11:27:29 2010 +0100
@@ -0,0 +1,193 @@
+/*
+ * 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;
+    ASSERT(hypercall_hvm_op(HVMOP_get_param, &param) == 0);
+    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;
+    ASSERT(hypercall_hvm_op(HVMOP_get_param, &param) == 0);
+    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);
+    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);
+
+    /* 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:
+ */

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys
  2010-07-09 10:57 [PATCH 0 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan
  2010-07-09 10:57 ` [PATCH 1 of 2] Add a xenbus frontend to hvmloader so it can read values from xenstore Tim Deegan
@ 2010-07-09 10:57 ` Tim Deegan
  1 sibling, 0 replies; 3+ messages in thread
From: Tim Deegan @ 2010-07-09 10:57 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 94 bytes --]

written at domain creation time by xapi.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>



[-- Attachment #2: xen-unstable.hg-2.patch --]
[-- Type: text/x-patch, Size: 5189 bytes --]

# HG changeset patch
# User Tim Deegan <Tim.Deegan@citrix.com>
# Date 1278671252 -3600
# Node ID 1db4a00d68296688445df0455ff21fca1af42ab7
# Parent  62b9338150160d6f7cea3e2c386f5e6f94e1b13b
HVM firmware: customize the SMBIOS strings based on xenstore keys
written at domain creation time by xapi.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>

diff -r 62b933815016 -r 1db4a00d6829 tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c	Fri Jul 09 11:27:29 2010 +0100
+++ b/tools/firmware/hvmloader/smbios.c	Fri Jul 09 11:27:32 2010 +0100
@@ -53,6 +53,8 @@
 static void *
 smbios_type_4_init(void *start, unsigned int cpu_number,
                    char *cpu_manufacturer);
+static void *
+smbios_type_11_init(void *start);
 static void *
 smbios_type_16_init(void *start, uint32_t memory_size_mb, int nr_mem_devs);
 static void *
@@ -112,6 +114,7 @@
     do_struct(smbios_type_3_init(p));
     for ( cpu_num = 1; cpu_num <= vcpus; cpu_num++ )
         do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer));
+    do_struct(smbios_type_11_init(p));
 
     /* Each 'memory device' covers up to 16GB of address space. */
     nr_mem_devs = (memsize + 0x3fff) >> 14;
@@ -283,6 +286,7 @@
 {
     struct smbios_type_0 *p = (struct smbios_type_0 *)start;
     static const char *smbios_release_date = __SMBIOS_DATE__;
+    const char *s;
 
     memset(p, 0, sizeof(*p));
 
@@ -309,10 +313,16 @@
     p->embedded_controller_minor = 0xff;
 
     start += sizeof(struct smbios_type_0);
-    strcpy((char *)start, "Xen");
-    start += strlen("Xen") + 1;
-    strcpy((char *)start, xen_version);
-    start += strlen(xen_version) + 1;
+    if ((s = xenstore_read("bios-strings/bios-vendor")) == NULL || *s == '\0')
+        s = "Xen";
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
+    if ((s = xenstore_read("bios-strings/bios-version")) == NULL || *s == '\0')
+        s = xen_version;
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
     strcpy((char *)start, smbios_release_date);
     start += strlen(smbios_release_date) + 1;
 
@@ -327,6 +337,7 @@
 {
     char uuid_str[37];
     struct smbios_type_1 *p = (struct smbios_type_1 *)start;
+    const char *s;
 
     memset(p, 0, sizeof(*p));
 
@@ -347,15 +358,31 @@
 
     start += sizeof(struct smbios_type_1);
     
-    strcpy((char *)start, "Xen");
-    start += strlen("Xen") + 1;
-    strcpy((char *)start, "HVM domU");
-    start += strlen("HVM domU") + 1;
-    strcpy((char *)start, xen_version);
-    start += strlen(xen_version) + 1;
+    if ((s = xenstore_read("bios-strings/system-manufacturer")) == NULL  
+        || *s == '\0')
+        s = "Xen";
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
+    if ((s = xenstore_read("bios-strings/system-product-name")) == NULL
+         || *s == '\0')
+        s = "HVM domU";
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
+    if ((s = xenstore_read("bios-strings/system-version")) == NULL
+        || *s == '\0')
+        s = xen_version;
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
     uuid_to_string(uuid_str, uuid); 
-    strcpy((char *)start, uuid_str);
-    start += strlen(uuid_str) + 1;
+    if ((s = xenstore_read("bios-strings/system-serial-number")) == NULL
+        || *s == '\0')
+        s = uuid_str;
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
     *((uint8_t *)start) = 0;
     
     return start+1; 
@@ -438,6 +465,45 @@
     start += strlen(cpu_manufacturer) + 1;
 
     *((uint8_t *)start) = 0;
+    return start+1;
+}
+
+/* Type 11 -- OEM Strings */
+static void *
+smbios_type_11_init(void *start) 
+{
+    struct smbios_type_11 *p = (struct smbios_type_11 *)start;
+    char path[20] = "bios-strings/oem-XX";
+    const char *s;
+    int i;
+
+    p->header.type = 11;
+    p->header.length = sizeof(struct smbios_type_11);
+    p->header.handle = 0xB00;
+
+    p->count = 0;
+
+    start += sizeof(struct smbios_type_11);
+
+    /* Pull out as many oem-* strings we find in xenstore */
+    for (i = 1; i < 100; i++) {
+        path[(sizeof path) - 3] = '0' + ((i < 10) ? i : i / 10);
+        path[(sizeof path) - 2] = (i < 10) ? '\0' : '0' + (i % 10);
+        if ((s = xenstore_read(path)) == NULL || *s == '\0')
+            break;
+        strcpy((char *)start, s);
+        start += strlen(s) + 1;
+        p->count++;
+    }
+    
+    /* Make sure there's at least one type-11 string */
+    if (p->count == 0) {
+        strcpy((char *)start, "Xen");
+        start += strlen("Xen") + 1;
+        p->count++;
+    }
+    *((uint8_t *)start) = 0;
+
     return start+1;
 }
 
diff -r 62b933815016 -r 1db4a00d6829 tools/firmware/hvmloader/smbios_types.h
--- a/tools/firmware/hvmloader/smbios_types.h	Fri Jul 09 11:27:29 2010 +0100
+++ b/tools/firmware/hvmloader/smbios_types.h	Fri Jul 09 11:27:32 2010 +0100
@@ -115,6 +115,12 @@
 	uint8_t upgrade;
 } __attribute__ ((packed));
 
+/* SMBIOS type 11 - OEM Strings */
+struct smbios_type_11 {
+   struct smbios_structure_header header;
+   uint8_t count;
+} __attribute__ ((packed));
+
 /* SMBIOS type 16 - Physical Memory Array
  *   Associated with one type 17 (Memory Device).
  */

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-07-09 10:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-09 10:57 [PATCH 0 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan
2010-07-09 10:57 ` [PATCH 1 of 2] Add a xenbus frontend to hvmloader so it can read values from xenstore Tim Deegan
2010-07-09 10:57 ` [PATCH 2 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.