kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] qemu: SMBIOS passing support
@ 2009-03-23 19:05 Alex Williamson
  2009-03-23 19:11 ` [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided to the VM BIOS Alex Williamson
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Alex Williamson @ 2009-03-23 19:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm, Alex Williamson


This series adds a new -smbios option for x86 that allows individual
SMBIOS entries to be passed into the guest VM.  This follows the same
basic path as the support for loading ACPI tables.  While SMBIOS is
independent of ACPI, I chose to add the smbios_entry_add() function to
acpi.c because they're both somewhat PC BIOS related (and ia64 can
support SMBIOS and might be able to make use of it there).

This feature allows the guest to see certain properties of the host if
configured correctly.  For instance, the system model and serial number
in the type 1 entry.  Obviously its only built at boot, so doesn't get
updated for migration scenarios.  User provided entries will supersede
generated entries, so care should be taken when passing entries which
describe physical properties, such as memory size and address ranges.
Thanks,

Alex 


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

* [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided to the VM BIOS
  2009-03-23 19:05 [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
@ 2009-03-23 19:11 ` Alex Williamson
  2009-04-06 19:50   ` Anthony Liguori
  2009-03-23 19:11 ` [PATCH 2/2] qemu:bios: Read external SMBIOS entries from the VM Alex Williamson
  2009-03-30 13:59 ` [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
  2 siblings, 1 reply; 14+ messages in thread
From: Alex Williamson @ 2009-03-23 19:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm, Alex Williamson


Create a new -smbios options that takes binary SMBIOS entries
to provide to the VM BIOS.  The binary can be easily generated
using something like:

dmidecode -t 1 -u | grep $'^\t\t[^"]' | xargs -n1 | \
	perl -lne 'printf "%c", hex($_)' > smbios_type_1.bin

For some inventory tools, this makes the VM report the system
information for the host.  One entry per binary file, multiple
files can be chained together as:

  -smbios file1,file2,...

or specified independently:

  -smbios file1 -smbios file2

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
--

diff --git a/hw/acpi.c b/hw/acpi.c
index 52f50a0..0bd93bf 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -915,3 +915,69 @@ out:
     }
     return -1;
 }
+
+char *smbios_entries;
+size_t smbios_entries_len;
+
+int smbios_entry_add(const char *t)
+{
+    struct stat s;
+    char file[1024], *p, *f, *n;
+    int fd, r;
+    size_t len, off;
+
+    f = (char *)t;
+    do {
+        n = strchr(f, ',');
+        if (n) {
+            strncpy(file, f, (n - f));
+            file[n - f] = '\0';
+            f = n + 1;
+        } else {
+            strcpy(file, f);
+            f += strlen(file);
+        }
+
+        fd = open(file, O_RDONLY);
+        if (fd < 0)
+            return -1;
+
+        if (fstat(fd, &s) < 0) {
+            close(fd);
+            return -1;
+        }
+
+        if (!smbios_entries) {
+            smbios_entries_len = sizeof(uint16_t);
+            smbios_entries = qemu_mallocz(smbios_entries_len);
+        }
+
+        len = s.st_size;
+        smbios_entries = qemu_realloc(smbios_entries, smbios_entries_len +
+                                                      len + sizeof(uint16_t));
+        p = smbios_entries + smbios_entries_len;
+
+        *(uint16_t *)p = cpu_to_le32(len);
+        p += sizeof(uint16_t);
+
+        off = 0;
+        do {
+            r = read(fd, p + off, len);
+            if (r > 0) {
+                off += r;
+                len -= r;
+            } else if ((r < 0 && errno != EINTR) || r == 0) {
+                close(fd);
+                return -1;
+            }
+        } while (len);
+
+        close(fd);
+
+        smbios_entries_len += s.st_size + sizeof(uint16_t);
+        (*(uint16_t *)smbios_entries) =
+	        cpu_to_le32(le32_to_cpu(*(uint16_t *)smbios_entries) + 1);
+    } while (*f);
+
+    return 0;
+}
diff --git a/hw/pc.c b/hw/pc.c
index 69f25f3..ec65e33 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -51,6 +51,7 @@
 #define ACPI_DATA_SIZE       0x10000
 #define BIOS_CFG_IOPORT 0x510
 #define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
+#define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
 
 #define MAX_IDE_BUS 2
 
@@ -442,6 +443,8 @@ static void bochs_bios_init(void)
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES, (uint8_t *)acpi_tables,
                      acpi_tables_len);
+    fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, (uint8_t *)smbios_entries,
+                     smbios_entries_len);
 }
 
 /* Generate an initial boot sector which sets state and jump to
diff --git a/hw/pc.h b/hw/pc.h
index 5b378d4..6c200b3 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -106,12 +106,15 @@ int ioport_get_a20(void);
 extern int acpi_enabled;
 extern char *acpi_tables;
 extern size_t acpi_tables_len;
+extern char *smbios_entries;
+extern size_t smbios_entries_len;
 
 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                        qemu_irq sci_irq);
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
 void acpi_bios_init(void);
 int acpi_table_add(const char *table_desc);
+int smbios_entry_add(const char *smbios_entry);
 
 /* hpet.c */
 extern int no_hpet;
diff --git a/vl.c b/vl.c
index b62a2d4..372b83c 100644
--- a/vl.c
+++ b/vl.c
@@ -4061,6 +4061,7 @@ static void help(int exitcode)
            "-no-hpet        disable HPET\n"
            "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,data=file1[:file2]...]\n"
            "                ACPI table description\n"
+           "-smbios file1[,file2]  SMBIOS entry\n"
 #endif
            "Linux boot specific:\n"
            "-kernel bzImage use 'bzImage' as kernel image\n"
@@ -4201,6 +4202,7 @@ enum {
     QEMU_OPTION_no_acpi,
     QEMU_OPTION_no_hpet,
     QEMU_OPTION_acpitable,
+    QEMU_OPTION_smbios,
 
     /* Linux boot specific: */
     QEMU_OPTION_kernel,
@@ -4322,6 +4324,7 @@ static const QEMUOption qemu_options[] = {
     { "no-acpi", 0, QEMU_OPTION_no_acpi },
     { "no-hpet", 0, QEMU_OPTION_no_hpet },
     { "acpitable", HAS_ARG, QEMU_OPTION_acpitable },
+    { "smbios", HAS_ARG, QEMU_OPTION_smbios },
 #endif
 
     /* Linux boot specific: */
@@ -5152,6 +5155,12 @@ int main(int argc, char **argv, char **envp)
                     exit(1);
                 }
                 break;
+            case QEMU_OPTION_smbios:
+                if(smbios_entry_add(optarg) < 0) {
+                    fprintf(stderr, "Wrong smbios provided\n");
+                    exit(1);
+                }
+                break;
 #endif
 #ifdef USE_KQEMU
             case QEMU_OPTION_no_kqemu:



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

* [PATCH 2/2] qemu:bios: Read external SMBIOS entries from the VM
  2009-03-23 19:05 [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
  2009-03-23 19:11 ` [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided to the VM BIOS Alex Williamson
@ 2009-03-23 19:11 ` Alex Williamson
  2009-04-06 19:52   ` Anthony Liguori
  2009-03-30 13:59 ` [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
  2 siblings, 1 reply; 14+ messages in thread
From: Alex Williamson @ 2009-03-23 19:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm, Alex Williamson


SMBIOS entries can be read from the VM using the same mechanism
as additional ACPI tables.  External entries will supercede
generated entries.

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
--

diff --git a/bios/rombios32.c b/bios/rombios32.c
index 7be4216..f0e0f8c 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -471,6 +471,7 @@ void wrmsr_smp(uint32_t index, uint64_t val)
 #define QEMU_CFG_UUID       0x02
 #define QEMU_CFG_ARCH_LOCAL     0x8000
 #define QEMU_CFG_ACPI_TABLES  (QEMU_CFG_ARCH_LOCAL + 0)
+#define QEMU_CFG_SMBIOS_ENTRIES  (QEMU_CFG_ARCH_LOCAL + 1)
 
 int qemu_cfg_port;
 
@@ -519,6 +520,16 @@ static int acpi_load_table(int i, uint32_t addr, uint16_t *len)
     qemu_cfg_read((uint8_t*)addr, *len);
     return 0;
 }
+
+static uint16_t smbios_entries(void)
+{
+    uint16_t cnt;
+
+    qemu_cfg_select(QEMU_CFG_SMBIOS_ENTRIES);
+    qemu_cfg_read((uint8_t*)&cnt, sizeof(cnt));
+
+    return cnt;
+}
 #endif
 
 void uuid_probe(void)
@@ -1966,7 +1977,7 @@ smbios_entry_point_init(void *start,
 /* Type 0 -- BIOS Information */
 #define RELEASE_DATE_STR "01/01/2007"
 static void *
-smbios_type_0_init(void *start)
+smbios_init_type_0(void *start)
 {
     struct smbios_type_0 *p = (struct smbios_type_0 *)start;
 
@@ -2002,7 +2013,7 @@ smbios_type_0_init(void *start)
 
 /* Type 1 -- System Information */
 static void *
-smbios_type_1_init(void *start)
+smbios_init_type_1(void *start)
 {
     struct smbios_type_1 *p = (struct smbios_type_1 *)start;
     p->header.type = 1;
@@ -2028,7 +2039,7 @@ smbios_type_1_init(void *start)
 
 /* Type 3 -- System Enclosure */
 static void *
-smbios_type_3_init(void *start)
+smbios_init_type_3(void *start)
 {
     struct smbios_type_3 *p = (struct smbios_type_3 *)start;
 
@@ -2058,7 +2069,7 @@ smbios_type_3_init(void *start)
 
 /* Type 4 -- Processor Information */
 static void *
-smbios_type_4_init(void *start, unsigned int cpu_number)
+smbios_init_type_4(void *start, unsigned int cpu_number)
 {
     struct smbios_type_4 *p = (struct smbios_type_4 *)start;
 
@@ -2098,7 +2109,7 @@ smbios_type_4_init(void *start, unsigned int cpu_number)
 
 /* Type 16 -- Physical Memory Array */
 static void *
-smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs)
+smbios_init_type_16(void *start, uint32_t memsize, int nr_mem_devs)
 {
     struct smbios_type_16 *p = (struct smbios_type_16*)start;
 
@@ -2121,7 +2132,7 @@ smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs)
 
 /* Type 17 -- Memory Device */
 static void *
-smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance)
+smbios_init_type_17(void *start, uint32_t memory_size_mb, int instance)
 {
     struct smbios_type_17 *p = (struct smbios_type_17 *)start;
 
@@ -2151,7 +2162,7 @@ smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance)
 
 /* Type 19 -- Memory Array Mapped Address */
 static void *
-smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance)
+smbios_init_type_19(void *start, uint32_t memory_size_mb, int instance)
 {
     struct smbios_type_19 *p = (struct smbios_type_19 *)start;
 
@@ -2172,7 +2183,7 @@ smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance)
 
 /* Type 20 -- Memory Device Mapped Address */
 static void *
-smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance)
+smbios_init_type_20(void *start, uint32_t memory_size_mb, int instance)
 {
     struct smbios_type_20 *p = (struct smbios_type_20 *)start;
 
@@ -2196,7 +2207,7 @@ smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance)
 
 /* Type 32 -- System Boot Information */
 static void *
-smbios_type_32_init(void *start)
+smbios_init_type_32(void *start)
 {
     struct smbios_type_32 *p = (struct smbios_type_32 *)start;
 
@@ -2214,7 +2225,7 @@ smbios_type_32_init(void *start)
 
 /* Type 127 -- End of Table */
 static void *
-smbios_type_127_init(void *start)
+smbios_init_type_127(void *start)
 {
     struct smbios_type_127 *p = (struct smbios_type_127 *)start;
 
@@ -2228,6 +2239,91 @@ smbios_type_127_init(void *start)
     return start + 2;
 }
 
+static int
+smbios_load_external(int type, char **p, char **q, unsigned *nr_structs,
+                     unsigned *max_struct_size)
+{
+#ifdef BX_QEMU
+    static uint64_t used_bitmap[4] = { 0 };
+    static uint16_t used_cnt = 0;
+    char *start = *p;
+    uint16_t len;
+    int i;
+
+    /* Keep track of the entry types we've already processed */
+    if (used_bitmap[(type >> 6) & 0x3] & (1ULL << (type & 0x3f)))
+        return 1;
+
+    /* Skip end markers, they could lead to bogus tables */
+    if (type == 127)
+        return 0;
+
+    /* Check if there are any tables left to report, also reset read index */
+    i = smbios_entries();
+    if (used_cnt == i)
+        return 0;
+
+    for (; i > 0; *q = *p, i--) {
+        int string_data;
+        qemu_cfg_read((uint8_t*)&len, sizeof(len));
+        if (!len)
+            continue;
+        if (len < sizeof(struct smbios_structure_header)) {
+            while (len--)
+                inb(QEMU_CFG_DATA_PORT); /* Invalid, skip to the next one */
+            continue;
+        }
+
+        qemu_cfg_read((uint8_t*)*p, sizeof(struct smbios_structure_header));
+        if (((struct smbios_structure_header *)*p)->type != type) {
+            len -= sizeof(struct smbios_structure_header);
+            while (len--)
+                inb(QEMU_CFG_DATA_PORT); /* skip to the next one */
+            continue;
+        }
+
+        /* Entries end with a double NULL char, if there's a string at
+         * the end (length is greater than formatted length), the string
+         * terminator provides the first NULL. */
+        string_data = (len > ((struct smbios_structure_header *)*p)->length);
+
+        /* Read the rest and terminate the entry */
+        len -= sizeof(struct smbios_structure_header);
+        *p += sizeof(struct smbios_structure_header);
+        qemu_cfg_read((uint8_t*)*p, len);
+        *p += len;
+        *((uint8_t*)*p) = 0;
+        (*p)++;
+        if (!string_data) {
+            *((uint8_t*)*p) = 0;
+            (*p)++;
+        }
+
+        (*nr_structs)++;
+        used_cnt++;
+        if (*p - *q > *max_struct_size)
+            *max_struct_size = *p - *q;
+
+        /* Mark that we've reported on this type */
+        used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
+
+        /* A type 1 entry provides a UUID, but so does the QEMU_CFG_UUID
+         * port.  If the QEMU_CFG_UUID value is not zero, use it, otherwise
+         * use whatever was in the provided table. */
+        if (type == 1) {
+            const static uint8_t null_uuid[16] = { 0 };
+            if (memcmp(bios_uuid, null_uuid, 16)) {
+                struct smbios_type_1 *t = (struct smbios_type_1 *)*q;
+                memcpy(t->uuid, bios_uuid, 16);
+            }
+        }
+    }
+    return (start != *p);
+#else /* !BX_QEMU */
+    return 0;
+#endif
+}
+
 void smbios_init(void)
 {
     unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
@@ -2246,34 +2342,39 @@ void smbios_init(void)
 
 	p = (char *)start + sizeof(struct smbios_entry_point);
 
-#define add_struct(fn) do{ \
-    q = (fn); \
-    nr_structs++; \
-    if ((q - p) > max_struct_size) \
-        max_struct_size = q - p; \
-    p = q; \
+#define add_struct(type, args...) do{ \
+    if (!smbios_load_external(type, &p, &q, &nr_structs, &max_struct_size)) { \
+        q = smbios_init_type_##type(args); \
+        nr_structs++; \
+        if ((q - p) > max_struct_size) \
+            max_struct_size = q - p; \
+        p = q; \
+    } \
 }while (0)
 
-    add_struct(smbios_type_0_init(p));
-    add_struct(smbios_type_1_init(p));
-    add_struct(smbios_type_3_init(p));
+    add_struct(0, p);
+    add_struct(1, p);
+    add_struct(3, p);
     for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
-        add_struct(smbios_type_4_init(p, cpu_num));
+        add_struct(4, p, cpu_num);
 
     /* Each 'memory device' covers up to 16GB of address space. */
     nr_mem_devs = (memsize + 0x3fff) >> 14;
-    add_struct(smbios_type_16_init(p, memsize, nr_mem_devs));
+    add_struct(16, p, memsize, nr_mem_devs);
     for ( i = 0; i < nr_mem_devs; i++ )
     {
         uint32_t dev_memsize = ((i == (nr_mem_devs - 1))
                                 ? (((memsize-1) & 0x3fff)+1) : 0x4000);
-        add_struct(smbios_type_17_init(p, dev_memsize, i));
-        add_struct(smbios_type_19_init(p, dev_memsize, i));
-        add_struct(smbios_type_20_init(p, dev_memsize, i));
+        add_struct(17, p, dev_memsize, i);
+        add_struct(19, p, dev_memsize, i);
+        add_struct(20, p, dev_memsize, i);
     }
 
-    add_struct(smbios_type_32_init(p));
-    add_struct(smbios_type_127_init(p));
+    add_struct(32, p);
+    /* Add any remaining provided entries before the end marker */
+    for (i = 0; i < 256; i++)
+        smbios_load_external(i, &p, &q, &nr_structs, &max_struct_size);
+    add_struct(127, p);
 
 #undef add_struct
 



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

* Re: [PATCH 0/2] qemu: SMBIOS passing support
  2009-03-23 19:05 [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
  2009-03-23 19:11 ` [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided to the VM BIOS Alex Williamson
  2009-03-23 19:11 ` [PATCH 2/2] qemu:bios: Read external SMBIOS entries from the VM Alex Williamson
@ 2009-03-30 13:59 ` Alex Williamson
  2009-03-30 14:05   ` Gleb Natapov
  2009-03-30 14:38   ` Daniel P. Berrange
  2 siblings, 2 replies; 14+ messages in thread
From: Alex Williamson @ 2009-03-30 13:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm


Is there any interest in this series?  Aside from copying host SMBIOS
entries, it also seems useful for providing information to the guest
about their virtual machine pool (perhaps via a type 3 entry), or
whatever other bits of data someone might find useful (type 11, OEM
string for instance).  Thanks,

Alex

On Mon, 2009-03-23 at 13:05 -0600, Alex Williamson wrote:
> This series adds a new -smbios option for x86 that allows individual
> SMBIOS entries to be passed into the guest VM.  This follows the same
> basic path as the support for loading ACPI tables.  While SMBIOS is
> independent of ACPI, I chose to add the smbios_entry_add() function to
> acpi.c because they're both somewhat PC BIOS related (and ia64 can
> support SMBIOS and might be able to make use of it there).
> 
> This feature allows the guest to see certain properties of the host if
> configured correctly.  For instance, the system model and serial number
> in the type 1 entry.  Obviously its only built at boot, so doesn't get
> updated for migration scenarios.  User provided entries will supersede
> generated entries, so care should be taken when passing entries which
> describe physical properties, such as memory size and address ranges.
> Thanks,
> 
> Alex 
> 



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

* Re: [PATCH 0/2] qemu: SMBIOS passing support
  2009-03-30 13:59 ` [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
@ 2009-03-30 14:05   ` Gleb Natapov
  2009-03-30 14:38   ` Daniel P. Berrange
  1 sibling, 0 replies; 14+ messages in thread
From: Gleb Natapov @ 2009-03-30 14:05 UTC (permalink / raw)
  To: Alex Williamson; +Cc: qemu-devel, kvm

On Mon, Mar 30, 2009 at 07:59:36AM -0600, Alex Williamson wrote:
> 
> Is there any interest in this series?  Aside from copying host SMBIOS
> entries, it also seems useful for providing information to the guest
> about their virtual machine pool (perhaps via a type 3 entry), or
> whatever other bits of data someone might find useful (type 11, OEM
> string for instance).  Thanks,
> 
I think the patch is useful. Haven't looked at implementation though.

> Alex
> 
> On Mon, 2009-03-23 at 13:05 -0600, Alex Williamson wrote:
> > This series adds a new -smbios option for x86 that allows individual
> > SMBIOS entries to be passed into the guest VM.  This follows the same
> > basic path as the support for loading ACPI tables.  While SMBIOS is
> > independent of ACPI, I chose to add the smbios_entry_add() function to
> > acpi.c because they're both somewhat PC BIOS related (and ia64 can
> > support SMBIOS and might be able to make use of it there).
> > 
> > This feature allows the guest to see certain properties of the host if
> > configured correctly.  For instance, the system model and serial number
> > in the type 1 entry.  Obviously its only built at boot, so doesn't get
> > updated for migration scenarios.  User provided entries will supersede
> > generated entries, so care should be taken when passing entries which
> > describe physical properties, such as memory size and address ranges.
> > Thanks,
> > 
> > Alex 
> > 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
			Gleb.

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

* Re: [PATCH 0/2] qemu: SMBIOS passing support
  2009-03-30 13:59 ` [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
  2009-03-30 14:05   ` Gleb Natapov
@ 2009-03-30 14:38   ` Daniel P. Berrange
  2009-03-30 14:59     ` Avi Kivity
  1 sibling, 1 reply; 14+ messages in thread
From: Daniel P. Berrange @ 2009-03-30 14:38 UTC (permalink / raw)
  To: Alex Williamson; +Cc: qemu-devel, kvm

On Mon, Mar 30, 2009 at 07:59:36AM -0600, Alex Williamson wrote:
> 
> Is there any interest in this series?  Aside from copying host SMBIOS
> entries, it also seems useful for providing information to the guest
> about their virtual machine pool (perhaps via a type 3 entry), or
> whatever other bits of data someone might find useful (type 11, OEM
> string for instance).  Thanks,
> 
> Alex
> 
> On Mon, 2009-03-23 at 13:05 -0600, Alex Williamson wrote:
> > This series adds a new -smbios option for x86 that allows individual
> > SMBIOS entries to be passed into the guest VM.  This follows the same
> > basic path as the support for loading ACPI tables.  While SMBIOS is
> > independent of ACPI, I chose to add the smbios_entry_add() function to
> > acpi.c because they're both somewhat PC BIOS related (and ia64 can
> > support SMBIOS and might be able to make use of it there).
> > 
> > This feature allows the guest to see certain properties of the host if
> > configured correctly.  For instance, the system model and serial number
> > in the type 1 entry.  Obviously its only built at boot, so doesn't get
> > updated for migration scenarios.  User provided entries will supersede
> > generated entries, so care should be taken when passing entries which
> > describe physical properties, such as memory size and address ranges.
> > Thanks,

I can't help thinking that if we wish to provide metadata to guest OS
like system model, serial number, etc, then we'd be better off using
explicit named flags (or QEMU config file settings once that exists)

  -system-serial 2141241521  -system-model "Some Virtual Machine"

and have QEMU generate the neccessary SMBIOS data, or other equivalent 
data tables to suit the non-PC based machine types for which SMBIOS
is not relevant.

Regards,
Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

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

* Re: [PATCH 0/2] qemu: SMBIOS passing support
  2009-03-30 14:38   ` Daniel P. Berrange
@ 2009-03-30 14:59     ` Avi Kivity
  2009-03-30 15:40       ` Alex Williamson
  0 siblings, 1 reply; 14+ messages in thread
From: Avi Kivity @ 2009-03-30 14:59 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: Alex Williamson, qemu-devel, kvm

Daniel P. Berrange wrote:
> I can't help thinking that if we wish to provide metadata to guest OS
> like system model, serial number, etc, then we'd be better off using
> explicit named flags (or QEMU config file settings once that exists)
>
>   -system-serial 2141241521  -system-model "Some Virtual Machine"
>
> and have QEMU generate the neccessary SMBIOS data, or other equivalent 
> data tables to suit the non-PC based machine types for which SMBIOS
> is not relevant.
>   

-smbios serial=blah,model=bleach ?


-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 0/2] qemu: SMBIOS passing support
  2009-03-30 14:59     ` Avi Kivity
@ 2009-03-30 15:40       ` Alex Williamson
  0 siblings, 0 replies; 14+ messages in thread
From: Alex Williamson @ 2009-03-30 15:40 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Daniel P. Berrange, qemu-devel, kvm

On Mon, 2009-03-30 at 17:59 +0300, Avi Kivity wrote:
> Daniel P. Berrange wrote:
> > I can't help thinking that if we wish to provide metadata to guest OS
> > like system model, serial number, etc, then we'd be better off using
> > explicit named flags (or QEMU config file settings once that exists)
> >
> >   -system-serial 2141241521  -system-model "Some Virtual Machine"
> >
> > and have QEMU generate the neccessary SMBIOS data, or other equivalent 
> > data tables to suit the non-PC based machine types for which SMBIOS
> > is not relevant.
> >   
> 
> -smbios serial=blah,model=bleach ?
> 

Unfortunately that does make them smbios specific, while I think Daniel
is pointing out that several options may be useful on other platforms.

This is basically the same issue we have with -uuid already.  -uuid is a
non-smbios specific option, but rombios will incorporate the data when
it builds the type 1 entry.  I've retained this functionality, so that a
-uuid option will override the uuid in a passed in type 1 entry.  This
could be further extended with separate patches to provide serial or
model numbers generically, but allow them to override smbios values.
This seems complimentary to the patches in this series, but I don't
think it replaces all the functionality we get from a raw smbios entry
interface.  Thanks,

Alex


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

* Re: [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided to the VM BIOS
  2009-03-23 19:11 ` [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided to the VM BIOS Alex Williamson
@ 2009-04-06 19:50   ` Anthony Liguori
  2009-04-06 22:34     ` Alex Williamson
  0 siblings, 1 reply; 14+ messages in thread
From: Anthony Liguori @ 2009-04-06 19:50 UTC (permalink / raw)
  To: Alex Williamson; +Cc: qemu-devel, kvm

Alex Williamson wrote:
> Create a new -smbios options that takes binary SMBIOS entries
> to provide to the VM BIOS.  The binary can be easily generated
> using something like:
>
> dmidecode -t 1 -u | grep $'^\t\t[^"]' | xargs -n1 | \
> 	perl -lne 'printf "%c", hex($_)' > smbios_type_1.bin
>
> For some inventory tools, this makes the VM report the system
> information for the host.  One entry per binary file, multiple
> files can be chained together as:
>
>   -smbios file1,file2,...
>
> or specified independently:
>
>   -smbios file1 -smbios file2
>
> Signed-off-by: Alex Williamson <alex.williamson@hp.com>
>   

Hi Alex,

I know we have to support blobs because of OEM specific smbios entries, 
but there are a number of common ones that it would probably be good to 
specify in a less user-unfriendly way.  What do you think?

Anyway, comments below.

> diff --git a/hw/acpi.c b/hw/acpi.c
> index 52f50a0..0bd93bf 100644
> --- a/hw/acpi.c
> +++ b/hw/acpi.c
> @@ -915,3 +915,69 @@ out:
>      }
>      return -1;
>  }
> +
> +char *smbios_entries;
> +size_t smbios_entries_len;
>   

I think an accessor would be better than making these variables global.

> +int smbios_entry_add(const char *t)
> +{
>   

acpi.c is hardware emulation, I'd rather see the command line parsing 
done somewhere else (like vl.c).

> +    struct stat s;
> +    char file[1024], *p, *f, *n;
> +    int fd, r;
> +    size_t len, off;
> +
> +    f = (char *)t;
> +    do {
> +        n = strchr(f, ',');
> +        if (n) {
> +            strncpy(file, f, (n - f));
> +            file[n - f] = '\0';
> +            f = n + 1;
> +        } else {
> +            strcpy(file, f);
> +            f += strlen(file);
> +        }
>   

I'm happy to just require multiple -smbios options.  I dislike 
overloading with ','s even though we do it a lot in QEMU.

> +        fd = open(file, O_RDONLY);
> +        if (fd < 0)
> +            return -1;
> +
> +        if (fstat(fd, &s) < 0) {
> +            close(fd);
> +            return -1;
> +        }
>   

May want to look at load_image/get_image_size.


-- 
Regards,

Anthony Liguori


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

* Re: [PATCH 2/2] qemu:bios: Read external SMBIOS entries from the VM
  2009-03-23 19:11 ` [PATCH 2/2] qemu:bios: Read external SMBIOS entries from the VM Alex Williamson
@ 2009-04-06 19:52   ` Anthony Liguori
  0 siblings, 0 replies; 14+ messages in thread
From: Anthony Liguori @ 2009-04-06 19:52 UTC (permalink / raw)
  To: Alex Williamson; +Cc: qemu-devel, kvm

Alex Williamson wrote:
> SMBIOS entries can be read from the VM using the same mechanism
> as additional ACPI tables.  External entries will supercede
> generated entries.
>
> Signed-off-by: Alex Williamson <alex.williamson@hp.com>
> +
> +        /* A type 1 entry provides a UUID, but so does the QEMU_CFG_UUID
> +         * port.  If the QEMU_CFG_UUID value is not zero, use it, otherwise
> +         * use whatever was in the provided table. */
> +        if (type == 1) {
> +            const static uint8_t null_uuid[16] = { 0 };
> +            if (memcmp(bios_uuid, null_uuid, 16)) {
> +                struct smbios_type_1 *t = (struct smbios_type_1 *)*q;
> +                memcpy(t->uuid, bios_uuid, 16);
> +            }
> +        }
>   

This is what I was getting at in my other post.  I'd sort of rather that 
a certain set of SMBIOS tables be specified at a higher level (like 
uuid, manufacture, vendor, etc.) and the blobs just be the OEM tables.  
I think that matches the work going on with the device configuration 
files more appropriately.

Regards,

Anthony Liguori


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

* Re: [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided to the VM BIOS
  2009-04-06 19:50   ` Anthony Liguori
@ 2009-04-06 22:34     ` Alex Williamson
  2009-04-06 22:42       ` Anthony Liguori
  0 siblings, 1 reply; 14+ messages in thread
From: Alex Williamson @ 2009-04-06 22:34 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

Hi Anthony,

On Mon, 2009-04-06 at 14:50 -0500, Anthony Liguori wrote:
> Alex Williamson wrote:
> 
> I know we have to support blobs because of OEM specific smbios entries, 
> but there are a number of common ones that it would probably be good to 
> specify in a less user-unfriendly way.  What do you think?

Yeah, I'll admit this is a pretty unfriendly interface.  I get from your
comment on the other part of the patch that you'd prefer not to get into
the mess of having both binary blobs and command line switches
augmenting the blobs.  This seems reasonable, but also means that we
need a way to fully define the tables we generate from the command line.
For a type 0 entry, that might mean the following set of switches:

-bios-version, -bios-date, -bios-characteristics, -bios-release

And for a type 1:

-system-manufacturer, -system-name, -system-version, -system-serial,
-system-sku, -system-family

type 3:

-chassis-manufacturer, -chassis-type, -chassis-version, -chassis-serial,
-chassis-asset, -chassis-oem

I'm sure I'm missing some, plus we might want to allow the memory and
processor entries to have some fields changed.  Do we want to add that
many switches and means to access them from the rombios?

> Anyway, comments below.
> 
> > diff --git a/hw/acpi.c b/hw/acpi.c
> > index 52f50a0..0bd93bf 100644
> > --- a/hw/acpi.c
> > +++ b/hw/acpi.c
> > @@ -915,3 +915,69 @@ out:
> >      }
> >      return -1;
> >  }
> > +
> > +char *smbios_entries;
> > +size_t smbios_entries_len;
> >   
> 
> I think an accessor would be better than making these variables global.

Ok

> > +int smbios_entry_add(const char *t)
> > +{
> >   
> 
> acpi.c is hardware emulation, I'd rather see the command line parsing 
> done somewhere else (like vl.c).

Ok.  acpi.c was just a convenient place to not bother architectures that
don't care about smbios.

> > +    struct stat s;
> > +    char file[1024], *p, *f, *n;
> > +    int fd, r;
> > +    size_t len, off;
> > +
> > +    f = (char *)t;
> > +    do {
> > +        n = strchr(f, ',');
> > +        if (n) {
> > +            strncpy(file, f, (n - f));
> > +            file[n - f] = '\0';
> > +            f = n + 1;
> > +        } else {
> > +            strcpy(file, f);
> > +            f += strlen(file);
> > +        }
> >   
> 
> I'm happy to just require multiple -smbios options.  I dislike 
> overloading with ','s even though we do it a lot in QEMU.

Yup, I didn't have it initially, but added it because I thought someone
might complain other qemu options allow it.

> > +        fd = open(file, O_RDONLY);
> > +        if (fd < 0)
> > +            return -1;
> > +
> > +        if (fstat(fd, &s) < 0) {
> > +            close(fd);
> > +            return -1;
> > +        }
> >   
> 
> May want to look at load_image/get_image_size.

Will do.  Thanks,

Alex



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

* Re: [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided to the VM BIOS
  2009-04-06 22:34     ` Alex Williamson
@ 2009-04-06 22:42       ` Anthony Liguori
  2009-04-07 19:34         ` Alex Williamson
  0 siblings, 1 reply; 14+ messages in thread
From: Anthony Liguori @ 2009-04-06 22:42 UTC (permalink / raw)
  To: Alex Williamson; +Cc: qemu-devel, kvm

Alex Williamson wrote:
> Hi Anthony,
>
> On Mon, 2009-04-06 at 14:50 -0500, Anthony Liguori wrote:
>   
>> Alex Williamson wrote:
>>
>> I know we have to support blobs because of OEM specific smbios entries, 
>> but there are a number of common ones that it would probably be good to 
>> specify in a less user-unfriendly way.  What do you think?
>>     
>
> Yeah, I'll admit this is a pretty unfriendly interface.  I get from your
> comment on the other part of the patch that you'd prefer not to get into
> the mess of having both binary blobs and command line switches
> augmenting the blobs.  This seems reasonable, but also means that we
> need a way to fully define the tables we generate from the command line.
> For a type 0 entry, that might mean the following set of switches:
>
> -bios-version, -bios-date, -bios-characteristics, -bios-release
>   

You could go one level higher:

-smbios type=0,bios-version='1.0',bios-date='2009/10/20' etc.

> I'm sure I'm missing some, plus we might want to allow the memory and
> processor entries to have some fields changed.  Do we want to add that
> many switches and means to access them from the rombios?
>   

I think it's okay to start with some of the more common tables and 
provide the parsing in QEMU.  We could then introduce humanize more 
tables down the road as people saw fit.

At the end of the day, I'm most interested in the tables that are going 
to be frequently used by management applications.  That is, the tables 
that are required for things like SVVP certification should be specified 
in a human readable format that QEMU can build reasonable defaults for 
and management tools can override.

I'm torn between exposing the tables directly to the firmware or 
providing a higher level interface.  I really don't like -uuid 
overriding a binary blob though so I'd prefer to avoid that.  -uuid 
should only be respected if using the QEMU generated version of the 
SMBIOS table.  I'll defer to whatever you think is better what is 
exposed in the firmware interface as I can see arguments for both.

-- 
Regards,

Anthony Liguori


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

* Re: Re: [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided  to the VM BIOS
  2009-04-06 22:42       ` Anthony Liguori
@ 2009-04-07 19:34         ` Alex Williamson
  2009-04-07 19:49           ` Anthony Liguori
  0 siblings, 1 reply; 14+ messages in thread
From: Alex Williamson @ 2009-04-07 19:34 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

On Mon, 2009-04-06 at 17:42 -0500, Anthony Liguori wrote:
> Alex Williamson wrote:
> > Hi Anthony,
> >
> > On Mon, 2009-04-06 at 14:50 -0500, Anthony Liguori wrote:
> >   
> >> Alex Williamson wrote:
> >>
> >> I know we have to support blobs because of OEM specific smbios entries, 
> >> but there are a number of common ones that it would probably be good to 
> >> specify in a less user-unfriendly way.  What do you think?
> >>     
> >
> > Yeah, I'll admit this is a pretty unfriendly interface.  I get from your
> > comment on the other part of the patch that you'd prefer not to get into
> > the mess of having both binary blobs and command line switches
> > augmenting the blobs.  This seems reasonable, but also means that we
> > need a way to fully define the tables we generate from the command line.
> > For a type 0 entry, that might mean the following set of switches:
> >
> > -bios-version, -bios-date, -bios-characteristics, -bios-release
> >   
> 
> You could go one level higher:
> 
> -smbios type=0,bios-version='1.0',bios-date='2009/10/20' etc.

That helps, but we have the same complexity in getting the data into the
the bios.  Adding a new QEMU_CFG_* for each field in every table we want
to specify seems excessive.  I'm half tempted to generate all the smbios
entries in qemu and push them through a port to the bios.  That would
leave a lot of duplicate code in bochs though.  Maybe the bios could
read a stream of these through the port:

uint16_t length;
uint8_t type; /* 0: field, 1: table */
union {
    struct {
        uint8_t type; /* smbios entry type */
        uint8_t offset;
        uint8_t data[];
    } field;
    struct {
        uint8_t data[]; /* binary blob */
    } table;
} entry;

We could convert uuid to use this too.  The bios doesn't have a very
effective means to seek through these, but maybe its not an issue as
long as these entries are sparsely used.  We could also use the table
generation to enforce mutual exclusion between specifying fields and
tables to avoid the uuid issue in the previous set.  Other ideas?
Thanks,

Alex



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

* Re: Re: [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided  to the VM BIOS
  2009-04-07 19:34         ` Alex Williamson
@ 2009-04-07 19:49           ` Anthony Liguori
  0 siblings, 0 replies; 14+ messages in thread
From: Anthony Liguori @ 2009-04-07 19:49 UTC (permalink / raw)
  To: Alex Williamson; +Cc: qemu-devel, kvm

Alex Williamson wrote:
> On Mon, 2009-04-06 at 17:42 -0500, Anthony Liguori wrote:
>   
> That helps, but we have the same complexity in getting the data into the
> the bios.  Adding a new QEMU_CFG_* for each field in every table we want
> to specify seems excessive.

Right.

> I'm half tempted to generate all the smbios
> entries in qemu and push them through a port to the bios.  That would
> leave a lot of duplicate code in bochs though.  Maybe the bios could
> read a stream of these through the port:
>
> uint16_t length;
> uint8_t type; /* 0: field, 1: table */
> union {
>     struct {
>         uint8_t type; /* smbios entry type */
>         uint8_t offset;
>         uint8_t data[];
>     } field;
>     struct {
>         uint8_t data[]; /* binary blob */
>     } table;
> } entry;
>
> We could convert uuid to use this too.

Yes, this is what I was leaning toward too.

>   The bios doesn't have a very
> effective means to seek through these, but maybe its not an issue as
> long as these entries are sparsely used.  We could also use the table
> generation to enforce mutual exclusion between specifying fields and
> tables to avoid the uuid issue in the previous set.  Other ideas?
>   

I'm pretty happy with this.  The argument against it is that if we pass 
higher level information down via the FW interface, other types of FW 
(like OpenBIOS) could also use that information in a meaningful way.  
The problem is, beyond things like UUID, you start to get into pretty 
specific stuff and I'm not convinced it would all generalize very well.  
OEM tables are also impossible to represent this way.

So yeah, plumbing the tables directly through to the BIOS seems to make 
sense to me.

> Thanks,
>
> Alex
>
>
>   


-- 
Regards,

Anthony Liguori


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

end of thread, other threads:[~2009-04-07 19:49 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-23 19:05 [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
2009-03-23 19:11 ` [PATCH 1/2] qemu: Allow SMBIOS entries to be loaded and provided to the VM BIOS Alex Williamson
2009-04-06 19:50   ` Anthony Liguori
2009-04-06 22:34     ` Alex Williamson
2009-04-06 22:42       ` Anthony Liguori
2009-04-07 19:34         ` Alex Williamson
2009-04-07 19:49           ` Anthony Liguori
2009-03-23 19:11 ` [PATCH 2/2] qemu:bios: Read external SMBIOS entries from the VM Alex Williamson
2009-04-06 19:52   ` Anthony Liguori
2009-03-30 13:59 ` [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
2009-03-30 14:05   ` Gleb Natapov
2009-03-30 14:38   ` Daniel P. Berrange
2009-03-30 14:59     ` Avi Kivity
2009-03-30 15:40       ` Alex Williamson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).