All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Williamson <alex.williamson@hp.com>
To: qemu-devel <qemu-devel@nongnu.org>
Cc: kvm <kvm@vger.kernel.org>, Alex Williamson <alex.williamson@hp.com>
Subject: [PATCH 2/2] qemu:bios: Read external SMBIOS entries from the VM
Date: Mon, 23 Mar 2009 13:11:07 -0600	[thread overview]
Message-ID: <1237835467.15558.5.camel@lappy> (raw)
In-Reply-To: <1237835133.7276.1107.camel@lappy>


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
 



WARNING: multiple messages have this Message-ID (diff)
From: Alex Williamson <alex.williamson@hp.com>
To: qemu-devel <qemu-devel@nongnu.org>
Cc: Alex Williamson <alex.williamson@hp.com>, kvm <kvm@vger.kernel.org>
Subject: [Qemu-devel] [PATCH 2/2] qemu:bios: Read external SMBIOS entries from the VM
Date: Mon, 23 Mar 2009 13:11:07 -0600	[thread overview]
Message-ID: <1237835467.15558.5.camel@lappy> (raw)
In-Reply-To: <1237835133.7276.1107.camel@lappy>


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
 

  parent reply	other threads:[~2009-03-23 19:11 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-23 19:05 [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
2009-03-23 19:05 ` [Qemu-devel] " 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   ` [Qemu-devel] " Alex Williamson
2009-04-06 19:50   ` Anthony Liguori
2009-04-06 19:50     ` [Qemu-devel] " Anthony Liguori
2009-04-06 22:34     ` Alex Williamson
2009-04-06 22:34       ` [Qemu-devel] " Alex Williamson
2009-04-06 22:42       ` Anthony Liguori
2009-04-06 22:42         ` [Qemu-devel] " Anthony Liguori
2009-04-07 19:34         ` Alex Williamson
2009-04-07 19:34           ` [Qemu-devel] Re: [kvm] " Alex Williamson
2009-04-07 19:49           ` Anthony Liguori
2009-04-07 19:49             ` [Qemu-devel] Re: [kvm] " Anthony Liguori
2009-03-23 19:11 ` Alex Williamson [this message]
2009-03-23 19:11   ` [Qemu-devel] [PATCH 2/2] qemu:bios: Read external SMBIOS entries from the VM Alex Williamson
2009-04-06 19:52   ` Anthony Liguori
2009-04-06 19:52     ` [Qemu-devel] " Anthony Liguori
2009-03-30 13:59 ` [PATCH 0/2] qemu: SMBIOS passing support Alex Williamson
2009-03-30 13:59   ` [Qemu-devel] " Alex Williamson
2009-03-30 14:05   ` Gleb Natapov
2009-03-30 14:05     ` [Qemu-devel] " Gleb Natapov
2009-03-30 14:38   ` Daniel P. Berrange
2009-03-30 14:38     ` [Qemu-devel] " Daniel P. Berrange
2009-03-30 14:59     ` Avi Kivity
2009-03-30 14:59       ` [Qemu-devel] " Avi Kivity
2009-03-30 15:40       ` Alex Williamson
2009-03-30 15:40         ` [Qemu-devel] " Alex Williamson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1237835467.15558.5.camel@lappy \
    --to=alex.williamson@hp.com \
    --cc=kvm@vger.kernel.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.