Skip to contentSkip to conversation

RFC: hvmloader SeaBIOS integration

PATCH In review Ian Campbell 3 participants 14 messages Apr 5, 2011 – Apr 6, 2011

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 RFC: hvmloader SeaBIOS integration

The following patchset is a WIP/RFC/vagueidea enabling the build of two versions of hvmloader, the first using ROMBIOS and the second using SeaBIOS.

This is achieved by compiling hvmloader.c multiple times which required a certain amount of disentanglement and reworking to avoid the need to compile other files more than once. The bulk of the series consists of that work.

It's not clear to me that this is preferable to building a single hvmloader which can pollinate a VM with either BIOS.

The final patch, which actually adds the SeaBIOS support, includes a slew of ugly #ifdef'ery. Since it is not clear at the moment which of this functionality is not needed with SeaBIOS and which is simply not ready/working/tested yet I didn't put a great deal of effort into refactoring that aspect.

It's a great shame that the choice of hvmloader binary was exposed to users through the config file format. We'll have to cross that bridge later I guess...

#1 lore raw

PATCH 1/1 tools: hvmloader: move ROMBIOS configuration into tools/firmware/rombios/

# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1302013751 -3600
# Node ID fb358af97eebe1eb7536fc2812357c9d936eb792
# Parent 4d9049a0c347cb8ce4842de7b17a5fa41971fa58
tools: hvmloader: move ROMBIOS configuration into tools/firmware/rombios/

Currently rombios and hvmloader are rather intertwined. Separate the ROMBIOS configuration options out into a ROMBIOS provided file so that the dependency can become strictly from hvmloader to rombios.

tools/firmware/hvmloader/config.h +1 -34
diff -r 4d9049a0c347 -r fb358af97eeb tools/firmware/hvmloader/config.h
@@ -23,44 +23,11 @@ extern unsigned long pci_mem_start, pci_
 #define RESERVED_MEMBASE    0xfc000000
 #define RESERVED_MEMSIZE    0x01000000
 
-#define ROMBIOS_SEG            0xF000
 #define ROMBIOS_BEGIN          0x000F0000
 #define ROMBIOS_SIZE           0x00010000
 #define ROMBIOS_MAXOFFSET      0x0000FFFF
 #define ROMBIOS_END            (ROMBIOS_BEGIN + ROMBIOS_SIZE)
 
-/* Memory map. */
-#define SCRATCH_PHYSICAL_ADDRESS      0x00010000
-#define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
-#define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
-#define OPTIONROM_PHYSICAL_ADDRESS    0x000C8000
-#define OPTIONROM_PHYSICAL_END        0x000EA000
-#define BIOS_INFO_PHYSICAL_ADDRESS    0x000EA000
-#define ACPI_PHYSICAL_ADDRESS         0x000EA020
-#define E820_PHYSICAL_ADDRESS         0x000EA100
-#define SMBIOS_PHYSICAL_ADDRESS       0x000EB000
-#define SMBIOS_MAXIMUM_SIZE           0x00005000
-#define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
-
-/* Offsets from E820_PHYSICAL_ADDRESS. */
-#define E820_NR_OFFSET                0x0
-#define E820_OFFSET                   0x8
-
-/* Xen Platform Device */
-#define XEN_PF_IOBASE   0x10
-#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
-
-/* Located at BIOS_INFO_PHYSICAL_ADDRESS. */
-struct bios_info {
-    uint8_t  com1_present:1;    /* 0[0] - System has COM1? */
-    uint8_t  com2_present:1;    /* 0[1] - System has COM2? */
-    uint8_t  lpt1_present:1;    /* 0[2] - System has LPT1? */
-    uint8_t  hpet_present:1;    /* 0[3] - System has HPET? */
-    uint32_t pci_min, pci_len;  /* 4, 8 - PCI I/O hole boundaries */
-    uint32_t madt_csum_addr;    /* 12   - Address of MADT checksum */
-    uint32_t madt_lapic0_addr;  /* 16   - Address of first MADT LAPIC struct */
-    uint32_t bios32_entry;      /* 20   - Entry point for 32-bit BIOS */
-};
-#define BIOSINFO_OFF_bios32_entry 20
+#include "../rombios/config.h"
 
 #endif /* __HVMLOADER_CONFIG_H__ */
tools/firmware/rombios/32bit/pmm.c +1 -1
diff -r 4d9049a0c347 -r fb358af97eeb tools/firmware/rombios/32bit/pmm.c
@@ -65,7 +65,7 @@
 
 #include <stdint.h>
 #include <stddef.h>
-#include <../hvmloader/config.h>
+#include "config.h"
 #include <../hvmloader/e820.h>
 #include "util.h"
 
tools/firmware/rombios/config.h new file +39 -0
diff -r 4d9049a0c347 -r fb358af97eeb tools/firmware/rombios/config.h
@@ -0,0 +1,39 @@
+#ifndef _ROMBIOS_CONFIG_H
+#define _ROMBIOS_CONFIG_H
+
+/* Memory map. */
+#define SCRATCH_PHYSICAL_ADDRESS      0x00010000
+#define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
+#define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
+#define OPTIONROM_PHYSICAL_ADDRESS    0x000C8000
+#define OPTIONROM_PHYSICAL_END        0x000EA000
+#define BIOS_INFO_PHYSICAL_ADDRESS    0x000EA000
+#define ACPI_PHYSICAL_ADDRESS         0x000EA020
+#define E820_PHYSICAL_ADDRESS         0x000EA100
+#define SMBIOS_PHYSICAL_ADDRESS       0x000EB000
+#define SMBIOS_MAXIMUM_SIZE           0x00005000
+#define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
+
+/* Offsets from E820_PHYSICAL_ADDRESS. */
+#define E820_NR_OFFSET                0x0
+#define E820_OFFSET                   0x8
+
+/* Xen Platform Device */
+#define XEN_PF_IOBASE   0x10
+#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
+
+/* Located at BIOS_INFO_PHYSICAL_ADDRESS. */
+struct bios_info {
+    uint8_t  com1_present:1;    /* 0[0] - System has COM1? */
+    uint8_t  com2_present:1;    /* 0[1] - System has COM2? */
+    uint8_t  lpt1_present:1;    /* 0[2] - System has LPT1? */
+    uint8_t  hpet_present:1;    /* 0[3] - System has HPET? */
+    uint32_t pci_min, pci_len;  /* 4, 8 - PCI I/O hole boundaries */
+    uint32_t madt_csum_addr;    /* 12   - Address of MADT checksum */
+    uint32_t madt_lapic0_addr;  /* 16   - Address of first MADT LAPIC struct */
+    uint32_t bios32_entry;      /* 20   - Entry point for 32-bit BIOS */
+};
+#define BIOSINFO_OFF_bios32_entry 20
+
+#endif
+
tools/firmware/rombios/rombios.c +1 -1
diff -r 4d9049a0c347 -r fb358af97eeb tools/firmware/rombios/rombios.c
@@ -29,7 +29,7 @@
 #define uint8_t unsigned char
 #define uint16_t unsigned short
 #define uint32_t unsigned long
-#include "../hvmloader/config.h"
+#include "config.h"
 
 #define HVMASSIST
 #undef HVMTEST
#2 lore raw

PATCH 1/1 tools: hvmloader: move e820 definitions into rombios

In reply to Ian Campbell

# HG changeset patch
# User Ian Campbell <[email protected]> # Date 1302013751 -3600
# Node ID 13625a078b2a757662c5d89737cefab11247e270 # Parent fb358af97eebe1eb7536fc2812357c9d936eb792
tools: hvmloader: move e820 definitions into rombios

tools/firmware/hvmloader/config.h +1 -0
diff -r fb358af97eeb -r 13625a078b2a tools/firmware/hvmloader/config.h
@@ -29,5 +29,6 @@ extern unsigned long pci_mem_start, pci_
 #define ROMBIOS_END            (ROMBIOS_BEGIN + ROMBIOS_SIZE)
 
 #include "../rombios/config.h"
+#include "../rombios/e820.h"
 
 #endif /* __HVMLOADER_CONFIG_H__ */
tools/firmware/hvmloader/e820.h deleted +0 -23
diff -r fb358af97eeb -r 13625a078b2a tools/firmware/hvmloader/e820.h
@@ -1,23 +0,0 @@
-#ifndef __HVMLOADER_E820_H__
-#define __HVMLOADER_E820_H__
-
-#include <xen/hvm/e820.h>
-
-/*
- * PC BIOS standard E820 types and structure.
- */
-#define E820_RAM          1
-#define E820_RESERVED     2
-#define E820_ACPI         3
-#define E820_NVS          4
-
-struct e820entry {
-    uint64_t addr;
-    uint64_t size;
-    uint32_t type;
-} __attribute__((packed));
-
-#define E820_NR ((uint16_t *)(E820_PHYSICAL_ADDRESS + E820_NR_OFFSET))
-#define E820    ((struct e820entry *)(E820_PHYSICAL_ADDRESS + E820_OFFSET))
-
-#endif /* __HVMLOADER_E820_H__ */
tools/firmware/hvmloader/hvmloader.c +0 -1
diff -r fb358af97eeb -r 13625a078b2a tools/firmware/hvmloader/hvmloader.c
@@ -27,7 +27,6 @@
 #include "config.h"
 #include "apic_regs.h"
 #include "pci_regs.h"
-#include "e820.h"
 #include "option_rom.h"
 #include <xen/version.h>
 #include <xen/hvm/params.h>
tools/firmware/hvmloader/smbios.c +0 -1
diff -r fb358af97eeb -r 13625a078b2a tools/firmware/hvmloader/smbios.c
@@ -26,7 +26,6 @@
 #include "smbios_types.h"
 #include "util.h"
 #include "hypercall.h"
-#include "e820.h"
 
 static int
 write_smbios_tables(void *start,
tools/firmware/hvmloader/util.c +0 -1
diff -r fb358af97eeb -r 13625a078b2a tools/firmware/hvmloader/util.c
@@ -20,7 +20,6 @@
 
 #include "util.h"
 #include "config.h"
-#include "e820.h"
 #include "hypercall.h"
 #include <stdint.h>
 #include <xen/xen.h>
tools/firmware/rombios/32bit/pmm.c +1 -1
diff -r fb358af97eeb -r 13625a078b2a tools/firmware/rombios/32bit/pmm.c
@@ -66,7 +66,7 @@
 #include <stdint.h>
 #include <stddef.h>
 #include "config.h"
-#include <../hvmloader/e820.h>
+#include "e820.h"
 #include "util.h"
 
 #define DEBUG_PMM 0
tools/firmware/rombios/e820.h new file +23 -0
diff -r fb358af97eeb -r 13625a078b2a tools/firmware/rombios/e820.h
@@ -0,0 +1,23 @@
+#ifndef __ROMBIOS_E820_H__
+#define __ROMBIOS_E820_H__
+
+#include <xen/hvm/e820.h>
+
+/*
+ * PC BIOS standard E820 types and structure.
+ */
+#define E820_RAM          1
+#define E820_RESERVED     2
+#define E820_ACPI         3
+#define E820_NVS          4
+
+struct e820entry {
+    uint64_t addr;
+    uint64_t size;
+    uint32_t type;
+} __attribute__((packed));
+
+#define E820_NR ((uint16_t *)(E820_PHYSICAL_ADDRESS + E820_NR_OFFSET))
+#define E820    ((struct e820entry *)(E820_PHYSICAL_ADDRESS + E820_OFFSET))
+
+#endif /* __ROMBIOS_E820_H__ */
#3 lore raw

PATCH 1/1 tools: hvmloader: pass ACPI_PHYSICAL_ADDRESS as a runtime parameter

In reply to Ian Campbell

# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1302013751 -3600
# Node ID 3cd3a30c371ac37caf37cb19033ea44a51469f89
# Parent 13625a078b2a757662c5d89737cefab11247e270
tools: hvmloader: pass ACPI_PHYSICAL_ADDRESS as a runtime parameter.

Instead of hardcoding in a header.

Reduces the number of files which will need to be multiply-compiled.

tools/firmware/hvmloader/acpi/acpi2_0.h +4 -1
diff -r 13625a078b2a -r 3cd3a30c371a tools/firmware/hvmloader/acpi/acpi2_0.h
@@ -382,7 +382,10 @@ struct acpi_20_madt_intsrcovr {
 
 #pragma pack ()
 
-void acpi_build_tables(void);
+struct acpi_parameters {
+    unsigned long phys;
+};
+void acpi_build_tables(const struct acpi_parameters *params);
 extern uint32_t madt_csum_addr, madt_lapic0_addr;
 
 #endif /* _ACPI_2_0_H_ */
tools/firmware/hvmloader/acpi/build.c +9 -8
diff -r 13625a078b2a -r 3cd3a30c371a tools/firmware/hvmloader/acpi/build.c
@@ -242,7 +242,9 @@ static int construct_secondary_tables(ui
     return align16(offset);
 }
 
-static void __acpi_build_tables(uint8_t *buf, int *low_sz, int *high_sz)
+static void __acpi_build_tables(const struct acpi_parameters *params,
+                                uint8_t *buf,
+                                int *low_sz, int *high_sz)
 {
     struct acpi_20_rsdp *rsdp;
     struct acpi_20_rsdt *rsdt;
@@ -335,11 +337,11 @@ static void __acpi_build_tables(uint8_t 
     /*
      * Fill in low-memory data structures: bios_info_table and RSDP.
      */
-
-    buf = (uint8_t *)ACPI_PHYSICAL_ADDRESS;
+    buf = (uint8_t *)params->phys;
     offset = 0;
 
     rsdp = (struct acpi_20_rsdp *)&buf[offset];
+
     memcpy(rsdp, &Rsdp, sizeof(struct acpi_20_rsdp));
     offset += align16(sizeof(struct acpi_20_rsdp));
     rsdp->rsdt_address = (unsigned long)rsdt;
@@ -354,24 +356,23 @@ static void __acpi_build_tables(uint8_t 
     *low_sz = offset;
 }
 
-void acpi_build_tables(void)
+void acpi_build_tables(const struct acpi_parameters *params)
 {
     int high_sz, low_sz;
     uint8_t *buf;
 
     /* Find out size of high-memory ACPI data area. */
     buf = (uint8_t *)&_end;
-    __acpi_build_tables(buf, &low_sz, &high_sz);
+    __acpi_build_tables(params, buf, &low_sz, &high_sz);
     memset(buf, 0, high_sz);
 
     /* Allocate data area and set up ACPI tables there. */
     buf = mem_alloc(high_sz, 0);
-    __acpi_build_tables(buf, &low_sz, &high_sz);
+    __acpi_build_tables(params, buf, &low_sz, &high_sz);
 
     printf(" - Lo data: %08lx-%08lx\n"
            " - Hi data: %08lx-%08lx\n",
-           (unsigned long)ACPI_PHYSICAL_ADDRESS,
-           (unsigned long)ACPI_PHYSICAL_ADDRESS + low_sz - 1,
+           params->phys, params->phys + low_sz - 1,
            (unsigned long)buf, (unsigned long)buf + high_sz - 1);
 }
 
tools/firmware/hvmloader/hvmloader.c +4 -1
diff -r 13625a078b2a -r 3cd3a30c371a tools/firmware/hvmloader/hvmloader.c
@@ -769,9 +769,12 @@ int main(void)
             .index = HVM_PARAM_ACPI_IOPORTS_LOCATION,
             .value = 1,
         };
+        struct acpi_parameters acpi_params = {
+            .phys = ACPI_PHYSICAL_ADDRESS,
+        };
 
         printf("Loading ACPI ...\n");
-        acpi_build_tables();
+        acpi_build_tables(&acpi_params);
         hypercall_hvm_op(HVMOP_set_param, &p);
     }
#4 lore raw

PATCH 1/1 tools: hvmloader: pass SMBIOS location as a runtime parameter

In reply to Ian Campbell

# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1302013751 -3600
# Node ID 825d013970ad7cb68b0aa6749cc501e70e14a871
# Parent 3cd3a30c371ac37caf37cb19033ea44a51469f89
tools: hvmloader: pass SMBIOS location as a runtime parameter.

Instead of hardcoding in a header.

Reduces the number of files which will need to be multiply-compiled.

tools/firmware/hvmloader/hvmloader.c +3 -1
diff -r 3cd3a30c371a -r 825d013970ad tools/firmware/hvmloader/hvmloader.c
@@ -718,7 +718,9 @@ int main(void)
     perform_tests();
 
     printf("Writing SMBIOS tables ...\n");
-    smbios_sz = hvm_write_smbios_tables();
+    smbios_sz = hvm_write_smbios_tables(SCRATCH_PHYSICAL_ADDRESS,
+                                        SMBIOS_PHYSICAL_ADDRESS,
+                                        SMBIOS_MAXIMUM_SIZE);
 
     printf("Loading ROMBIOS ...\n");
     rombios_sz = sizeof(rombios);
tools/firmware/hvmloader/smbios.c +7 -8
diff -r 3cd3a30c371a -r 825d013970ad tools/firmware/hvmloader/smbios.c
@@ -28,7 +28,7 @@
 #include "hypercall.h"
 
 static int
-write_smbios_tables(void *start,
+write_smbios_tables(void *start, unsigned long phys,
                     uint32_t vcpus, uint64_t memsize,
                     uint8_t uuid[16], char *xen_version,
                     uint32_t xen_major_version, uint32_t xen_minor_version);
@@ -85,7 +85,7 @@ get_cpu_manufacturer(char *buf, int len)
 }
 
 static int
-write_smbios_tables(void *start,
+write_smbios_tables(void *start, unsigned long phys,
                     uint32_t vcpus, uint64_t memsize,
                     uint8_t uuid[16], char *xen_version,
                     uint32_t xen_major_version, uint32_t xen_minor_version)
@@ -136,7 +136,7 @@ write_smbios_tables(void *start,
     smbios_entry_point_init(
         start, max_struct_size,
         (p - (char *)start) - sizeof(struct smbios_entry_point),
-        SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point),
+        phys + sizeof(struct smbios_entry_point),
         nr_structs);
 
     return ((char *)p - (char *)start);
@@ -162,7 +162,7 @@ get_memsize(void)
 }
 
 int
-hvm_write_smbios_tables(void)
+hvm_write_smbios_tables(unsigned long scratch, unsigned long smbios, unsigned long max)
 {
     xen_domain_handle_t uuid;
     uint16_t xen_major_version, xen_minor_version;
@@ -222,15 +222,14 @@ hvm_write_smbios_tables(void)
     xen_version_str[sizeof(xen_version_str)-1] = '\0';
 
     /* SCRATCH_PHYSICAL_ADDRESS is a safe large memory area for scratch. */
-    len = write_smbios_tables((void *)SCRATCH_PHYSICAL_ADDRESS,
+    len = write_smbios_tables((void *)scratch, smbios,
                               hvm_info->nr_vcpus, get_memsize(),
                               uuid, xen_version_str,
                               xen_major_version, xen_minor_version);
-    if ( len > SMBIOS_MAXIMUM_SIZE )
+    if ( len > max )
         goto error_out;
     /* Okay, not too large: copy out of scratch to final location. */
-    memcpy((void *)SMBIOS_PHYSICAL_ADDRESS,
-           (void *)SCRATCH_PHYSICAL_ADDRESS, len);
+    memcpy((void *)smbios, (void *)scratch, len);
 
     return len;
 
tools/firmware/hvmloader/util.h +2 -1
diff -r 3cd3a30c371a -r 825d013970ad tools/firmware/hvmloader/util.h
@@ -186,7 +186,8 @@ uint32_t highbios_setup(void);
 /* Miscellaneous. */
 void cacheattr_init(void);
 void create_mp_tables(void);
-int hvm_write_smbios_tables(void);
+int hvm_write_smbios_tables(unsigned long scratch, unsigned long smbios,
+			    unsigned long max);
 void smp_initialise(void);
 
 #ifndef NDEBUG
#5 lore raw

PATCH 1/1 tools: hvmloader: split scratch and hypercall addressing from ROMBIOS low HEAP

In reply to Ian Campbell

# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1302013752 -3600
# Node ID 5df591624c601fbe954c57d9884d27d6c4e57f6e
# Parent 825d013970ad7cb68b0aa6749cc501e70e14a871
tools: hvmloader: split scratch and hypercall addressing from ROMBIOS low HEAP

Although happen to live at the same physical address their lifespans do not overlap. The scratch and hypercall spaces are used only within hvmloader and the same area is reused as a heap within ROMBIOS. But each is free to make its own decisions about where to place things.

tools/firmware/hvmloader/config.h +3 -0
diff -r 825d013970ad -r 5df591624c60 tools/firmware/hvmloader/config.h
@@ -28,6 +28,9 @@ extern unsigned long pci_mem_start, pci_
 #define ROMBIOS_MAXOFFSET      0x0000FFFF
 #define ROMBIOS_END            (ROMBIOS_BEGIN + ROMBIOS_SIZE)
 
+#define SCRATCH_PHYSICAL_ADDRESS      0x00010000
+#define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
+
 #include "../rombios/config.h"
 #include "../rombios/e820.h"
 
tools/firmware/rombios/32bit/pmm.c +4 -3
diff -r 825d013970ad -r 5df591624c60 tools/firmware/rombios/32bit/pmm.c
@@ -147,7 +147,7 @@ typedef struct heap {
  *
  * - conventional memroy (below 1MB)
  *    In HVM, the area is fixed. 0x00010000-0x0007FFFF
- *    (from SCRATCH_PHYSICAL_ADDRESS to HYPERCALL_PHYSICAL_ADDRESS)
+ *    (LOWHEAP_SIZE bytes from LOWHEAP_PHYSICAL_ADDRESS)
  *
  * - extended memory (start at 1MB, below 4GB)
  *    In HVM, the area starts at memory address 0x00100000.
@@ -283,8 +283,9 @@ pmm_initalize(void)
     }
 
     /* convectional memory: RAM below 1MB, 0x10000-0x7FFFF */
-    pmm_init_heap(&pmm_data.heap, SCRATCH_PHYSICAL_ADDRESS,
-                  HYPERCALL_PHYSICAL_ADDRESS);
+    pmm_init_heap(&pmm_data.heap,
+		  LOWHEAP_PHYSICAL_ADDRESS,
+		  LOWHEAP_PHYSICAL_ADDRESS+LOWHEAP_SIZE);
 }
 
 static uint32_t
tools/firmware/rombios/config.h +3 -2
diff -r 825d013970ad -r 5df591624c60 tools/firmware/rombios/config.h
@@ -2,8 +2,9 @@
 #define _ROMBIOS_CONFIG_H
 
 /* Memory map. */
-#define SCRATCH_PHYSICAL_ADDRESS      0x00010000
-#define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
+#define LOWHEAP_PHYSICAL_ADDRESS      0x00010000
+#define LOWHEAP_SIZE                  0x00070000
+
 #define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
 #define OPTIONROM_PHYSICAL_ADDRESS    0x000C8000
 #define OPTIONROM_PHYSICAL_END        0x000EA000
#6 lore raw

PATCH 1/1 tools: hvmloader: only hvmloader.c needs to know about rombios

In reply to Ian Campbell

# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1302013752 -3600
# Node ID 007f810ee29857cc08c5ee8b82941119bc381130
# Parent 5df591624c601fbe954c57d9884d27d6c4e57f6e
tools: hvmloader: only hvmloader.c needs to know about rombios

tools/firmware/hvmloader/config.h +0 -3
diff -r 5df591624c60 -r 007f810ee298 tools/firmware/hvmloader/config.h
@@ -31,7 +31,4 @@ extern unsigned long pci_mem_start, pci_
 #define SCRATCH_PHYSICAL_ADDRESS      0x00010000
 #define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
 
-#include "../rombios/config.h"
-#include "../rombios/e820.h"
-
 #endif /* __HVMLOADER_CONFIG_H__ */
tools/firmware/hvmloader/hvmloader.c +3 -0
diff -r 5df591624c60 -r 007f810ee298 tools/firmware/hvmloader/hvmloader.c
@@ -33,6 +33,9 @@
 #include <xen/hvm/ioreq.h>
 #include <xen/memory.h>
 
+#include "../rombios/config.h"
+#include "../rombios/e820.h"
+
 asm (
     "    .text                       \n"
     "    .globl _start               \n"
#7 lore raw

PATCH 1/1 tools: hvmloader: abort build if BIOS is too big

In reply to Ian Campbell

# HG changeset patch
# User Ian Campbell <[email protected]> # Date 1302013752 -3600
# Node ID 2da3ecf0587edd56d37bd6d81b50906c92f1b47c # Parent 007f810ee29857cc08c5ee8b82941119bc381130
tools: hvmloader: abort build if BIOS is too big

No good can come of only copy part of the BIOS into place, so lets cause the build to break if the BIOS is too large rather than simply truncating it.

tools/firmware/hvmloader/hvmloader.c +6 -9
diff -r 007f810ee298 -r 2da3ecf0587e tools/firmware/hvmloader/hvmloader.c
@@ -702,7 +702,7 @@ static void build_e820_table(void)
 int main(void)
 {
     int option_rom_sz = 0, vgabios_sz = 0, etherboot_sz = 0;
-    int rombios_sz, smbios_sz;
+    int smbios_sz;
     uint32_t etherboot_phys_addr, option_rom_phys_addr, bios32_addr;
     struct bios_info *bios_info;
 
@@ -726,10 +726,8 @@ int main(void)
                                         SMBIOS_MAXIMUM_SIZE);
 
     printf("Loading ROMBIOS ...\n");
-    rombios_sz = sizeof(rombios);
-    if ( rombios_sz > 0x10000 )
-        rombios_sz = 0x10000;
-    memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, rombios_sz);
+    BUILD_BUG_ON(sizeof(rombios) > ROMBIOS_MAXIMUM_SIZE);
+    memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
     bios32_addr = highbios_setup();
 
     if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode )
@@ -804,10 +802,9 @@ int main(void)
         printf(" %05x-%05x: SMBIOS tables\n",
                SMBIOS_PHYSICAL_ADDRESS,
                SMBIOS_PHYSICAL_ADDRESS + smbios_sz - 1);
-    if ( rombios_sz )
-        printf(" %05x-%05x: Main BIOS\n",
-               ROMBIOS_PHYSICAL_ADDRESS,
-               ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1);
+    printf(" %05x-%05x: Main BIOS\n",
+           ROMBIOS_PHYSICAL_ADDRESS,
+           ROMBIOS_PHYSICAL_ADDRESS + sizeof(rombios) - 1);
 
     build_e820_table();
     dump_e820_table();
tools/firmware/rombios/config.h +2 -0
diff -r 007f810ee298 -r 2da3ecf0587e tools/firmware/rombios/config.h
@@ -15,6 +15,8 @@
 #define SMBIOS_MAXIMUM_SIZE           0x00005000
 #define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
 
+#define ROMBIOS_MAXIMUM_SIZE         (0x00100000 - ROMBIOS_PHYSICAL_ADDRESS)
+
 /* Offsets from E820_PHYSICAL_ADDRESS. */
 #define E820_NR_OFFSET                0x0
 #define E820_OFFSET                   0x8
#8 lore raw

PATCH 1/1 tools: hvmloader: Use more generic name for BIOS ROM image

In reply to Ian Campbell

# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1302013752 -3600
# Node ID 478740ab3110e79142ee9fde73f5b7e9d066a6ce # Parent 2da3ecf0587edd56d37bd6d81b50906c92f1b47c
tools: hvmloader: Use more generic name for BIOS ROM image

tools/firmware/hvmloader/Makefile +3 -1
diff -r 2da3ecf0587e -r 478740ab3110 tools/firmware/hvmloader/Makefile
@@ -49,7 +49,9 @@ hvmloader: $(OBJS) acpi/acpi.a
 
 roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin \
 	../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../etherboot/eb-roms.h
-	sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
+	echo "/* Autogenerated file. DO NOT EDIT */" > roms.h
+
+	sh ./mkhex biosimg ../rombios/BIOS-bochs-latest >> roms.h
 	sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
 	sh ./mkhex vgabios_cirrusvga \
 		../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
tools/firmware/hvmloader/hvmloader.c +5 -4
diff -r 2da3ecf0587e -r 478740ab3110 tools/firmware/hvmloader/hvmloader.c
@@ -726,8 +726,9 @@ int main(void)
                                         SMBIOS_MAXIMUM_SIZE);
 
     printf("Loading ROMBIOS ...\n");
-    BUILD_BUG_ON(sizeof(rombios) > ROMBIOS_MAXIMUM_SIZE);
-    memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
+    BUILD_BUG_ON(sizeof(biosimg) > BIOS_MAXIMUM_SIZE);
+    memcpy((void *)BIOS_PHYSICAL_ADDRESS, biosimg, sizeof(biosimg));
+
     bios32_addr = highbios_setup();
 
     if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode )
@@ -803,8 +804,8 @@ int main(void)
                SMBIOS_PHYSICAL_ADDRESS,
                SMBIOS_PHYSICAL_ADDRESS + smbios_sz - 1);
     printf(" %05x-%05x: Main BIOS\n",
-           ROMBIOS_PHYSICAL_ADDRESS,
-           ROMBIOS_PHYSICAL_ADDRESS + sizeof(rombios) - 1);
+           BIOS_PHYSICAL_ADDRESS,
+           BIOS_PHYSICAL_ADDRESS + sizeof(biosimg) - 1);
 
     build_e820_table();
     dump_e820_table();
tools/firmware/rombios/config.h +2 -2
diff -r 2da3ecf0587e -r 478740ab3110 tools/firmware/rombios/config.h
@@ -13,9 +13,9 @@
 #define E820_PHYSICAL_ADDRESS         0x000EA100
 #define SMBIOS_PHYSICAL_ADDRESS       0x000EB000
 #define SMBIOS_MAXIMUM_SIZE           0x00005000
-#define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
+#define BIOS_PHYSICAL_ADDRESS         0x000F0000
 
-#define ROMBIOS_MAXIMUM_SIZE         (0x00100000 - ROMBIOS_PHYSICAL_ADDRESS)
+#define BIOS_MAXIMUM_SIZE            (0x00100000 - BIOS_PHYSICAL_ADDRESS)
 
 /* Offsets from E820_PHYSICAL_ADDRESS. */
 #define E820_NR_OFFSET                0x0
#9 lore raw

PATCH 1/1 tools: hvmloader: add Makefile option to use debug video BIOS

In reply to Ian Campbell

# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1302013752 -3600
# Node ID c2fe8249899ee1772973f93897dd7cf960367822 # Parent 478740ab3110e79142ee9fde73f5b7e9d066a6ce
tools: hvmloader: add Makefile option to use debug video BIOS

Simply as a convenience.

tools/firmware/hvmloader/Makefile +8 -0
diff -r 478740ab3110 -r c2fe8249899e tools/firmware/hvmloader/Makefile
@@ -35,6 +35,8 @@ SRCS += tests.c
 endif
 OBJS  = $(patsubst %.c,%.o,$(SRCS))
 
+CIRRUSVGA_DEBUG ?= n
+
 .PHONY: all
 all: subdirs-all
 	$(MAKE) hvmloader
@@ -53,8 +55,14 @@ roms.h: ../rombios/BIOS-bochs-latest ../
 
 	sh ./mkhex biosimg ../rombios/BIOS-bochs-latest >> roms.h
 	sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
+ifeq ($(CIRRUSVGA_DEBUG),y)
+	sh ./mkhex vgabios_cirrusvga \
+		../vgabios/VGABIOS-lgpl-latest.cirrus.debug.bin >> roms.h
+else
 	sh ./mkhex vgabios_cirrusvga \
 		../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
+endif
+
 	cat ../etherboot/eb-roms.h >> roms.h
 
 .PHONY: clean
#10 lore raw

PATCH 1/1 tools: hvmloader: build and install hvmloader-rombios

In reply to Ian Campbell

# HG changeset patch
# User Ian Campbell <[email protected]> # Date 1302013752 -3600
# Node ID c387185f0a254c794b73d71d282fb941d3de5d98 # Parent c2fe8249899ee1772973f93897dd7cf960367822
tools: hvmloader: build and install hvmloader-rombios

Retain the hvmloader name as a compatibility symlink.

.hgignore +1 -1
diff -r c2fe8249899e -r c387185f0a25 .hgignore
@@ -142,7 +142,7 @@
 ^tools/firmware/extboot/signrom$
 ^tools/firmware/hvmloader/acpi/dsdt.*\.c$
 ^tools/firmware/hvmloader/acpi/ssdt_.*\.h$
-^tools/firmware/hvmloader/hvmloader$
+^tools/firmware/hvmloader/hvmloader-rombios$
 ^tools/firmware/hvmloader/roms\.h$
 ^tools/firmware/rombios/BIOS-bochs-[^/]*$
 ^tools/firmware/rombios/_rombios[^/]*_\.c$
tools/firmware/Makefile +4 -3
diff -r c2fe8249899e -r c387185f0a25 tools/firmware/Makefile
@@ -2,7 +2,7 @@ XEN_ROOT = $(CURDIR)/../..
 include $(XEN_ROOT)/tools/Rules.mk
 
 # hvmloader is a 32-bit protected mode binary.
-TARGET      := hvmloader/hvmloader
+TARGET_ROMBIOS      := hvmloader/hvmloader-rombios
 INST_DIR := $(DESTDIR)$(XENFIRMWAREDIR)
 
 SUBDIRS :=
@@ -26,7 +26,8 @@ all:
 .PHONY: install
 install: all
 	[ -d $(INST_DIR) ] || $(INSTALL_DIR) $(INST_DIR)
-	[ ! -e $(TARGET) ] || $(INSTALL_DATA) $(TARGET) $(INST_DIR)
+	[ ! -e $(TARGET_ROMBIOS) ] || $(INSTALL_DATA) $(TARGET_ROMBIOS) $(INST_DIR)
+	[ ! -e $(TARGET_ROMBIOS) ] || ln -nfs hvmloader-rombios $(INST_DIR)/hvmloader
 
 .PHONY: clean
 clean: subdirs-clean
@@ -35,4 +36,4 @@ clean: subdirs-clean
 distclean: subdirs-distclean
 
 subdir-distclean-etherboot: .phony
-	$(MAKE) -C etherboot distclean
\ No newline at end of file
+	$(MAKE) -C etherboot distclean
tools/firmware/hvmloader/Makefile +15 -7
diff -r c2fe8249899e -r c387185f0a25 tools/firmware/hvmloader/Makefile
@@ -28,32 +28,39 @@ LOADADDR = 0x100000
 
 CFLAGS += $(CFLAGS_xeninclude)
 
-SRCS  = hvmloader.c mp_tables.c util.c smbios.c 
+SRCS  = mp_tables.c util.c smbios.c 
 SRCS += 32bitbios_support.c smp.c cacheattr.c xenbus.c
 ifeq ($(debug),y)
 SRCS += tests.c
 endif
 OBJS  = $(patsubst %.c,%.o,$(SRCS))
 
+TARGETS := hvmloader-rombios
+
 CIRRUSVGA_DEBUG ?= n
 
 .PHONY: all
 all: subdirs-all
-	$(MAKE) hvmloader
+	$(MAKE) $(TARGETS)
 
-hvmloader.o: roms.h
+hvmloader-rombios.o: hvmloader.c roms.h
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_$*.o) -DBIOS_ROM_rombios=1 -DBIOS_ROM_STR=\"ROMBIOS\" -c -o $@ hvmloader.c
+
 smbios.o: CFLAGS += -D__SMBIOS_DATE__="\"$(shell date +%m/%d/%Y)\""
 
-hvmloader: $(OBJS) acpi/acpi.a
-	$(LD) $(LDFLAGS_DIRECT) -N -Ttext $(LOADADDR) -o hvmloader.tmp $^
-	$(OBJCOPY) hvmloader.tmp hvmloader
-	rm -f hvmloader.tmp
+hvmloader-%: hvmloader-%.o $(OBJS) acpi/acpi.a
+	$(LD) $(LDFLAGS_DIRECT) -N -Ttext $(LOADADDR) -o [email protected] $^
+	$(OBJCOPY) [email protected] $@
+	rm -f [email protected]
 
 roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin \
 	../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../etherboot/eb-roms.h
 	echo "/* Autogenerated file. DO NOT EDIT */" > roms.h
 
+	echo "#ifdef BIOS_ROM_rombios" >> roms.h
 	sh ./mkhex biosimg ../rombios/BIOS-bochs-latest >> roms.h
+	echo "#endif" >> roms.h
+
 	sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
 ifeq ($(CIRRUSVGA_DEBUG),y)
 	sh ./mkhex vgabios_cirrusvga \
@@ -69,5 +76,6 @@ endif
 clean: subdirs-clean
 	rm -f roms.h acpi.h
 	rm -f hvmloader hvmloader.tmp *.o $(DEPS)
+	rm -f hvmloader-rombios hvmloader-rombios.tmp
 
 -include $(DEPS)
tools/firmware/hvmloader/hvmloader.c +8 -4
diff -r c2fe8249899e -r c387185f0a25 tools/firmware/hvmloader/hvmloader.c
@@ -33,8 +33,12 @@
 #include <xen/hvm/ioreq.h>
 #include <xen/memory.h>
 
-#include "../rombios/config.h"
-#include "../rombios/e820.h"
+#if defined(BIOS_ROM_rombios)
+#  include "../rombios/config.h"
+#  include "../rombios/e820.h"
+#else
+#  error "Building for unknown BIOS"
+#endif
 
 asm (
     "    .text                       \n"
@@ -725,7 +729,7 @@ int main(void)
                                         SMBIOS_PHYSICAL_ADDRESS,
                                         SMBIOS_MAXIMUM_SIZE);
 
-    printf("Loading ROMBIOS ...\n");
+    printf("Loading " BIOS_ROM_STR "...\n");
     BUILD_BUG_ON(sizeof(biosimg) > BIOS_MAXIMUM_SIZE);
     memcpy((void *)BIOS_PHYSICAL_ADDRESS, biosimg, sizeof(biosimg));
 
@@ -824,7 +828,7 @@ int main(void)
 
     xenbus_shutdown();
 
-    printf("Invoking ROMBIOS ...\n");
+    printf("Invoking " BIOS_ROM_STR " ...\n");
     return 0;
 }
#11 lore raw

PATCH 1/1 tools: hvmloader: build and install hvmloader-seabios

In reply to Ian Campbell

# HG changeset patch
# User Ian Campbell <[email protected]> # Date 1302013752 -3600
# Node ID e471a31bf22626a5686c3d17141cdb9a6a65abbe # Parent c387185f0a254c794b73d71d282fb941d3de5d98
tools: hvmloader: build and install hvmloader-seabios

.hgignore +1 -0
diff -r c387185f0a25 -r e471a31bf226 .hgignore
@@ -143,6 +143,7 @@
 ^tools/firmware/hvmloader/acpi/dsdt.*\.c$
 ^tools/firmware/hvmloader/acpi/ssdt_.*\.h$
 ^tools/firmware/hvmloader/hvmloader-rombios$
+^tools/firmware/hvmloader/hvmloader-seabios$
 ^tools/firmware/hvmloader/roms\.h$
 ^tools/firmware/rombios/BIOS-bochs-[^/]*$
 ^tools/firmware/rombios/_rombios[^/]*_\.c$
Config.mk +12 -0
diff -r c387185f0a25 -r e471a31bf226 Config.mk
@@ -184,6 +184,18 @@ QEMU_TAG := xen-4.1.0-rc6
 # Fri Feb 11 17:54:51 2011 +0000
 # qemu-xen: fix segfault with empty cdroms
 
+# Short answer -- do not enable this unless you know what you are
+# doing and are prepared for some pain.
+
+# SeaBIOS integration is a work in progress. Before enabling this
+# option you must clone git://git.qemu.org/seabios.git/, possibly add
+# some development patches and then build it yourself before pointing
+# this variable to it (using an absolute path).
+#
+# Note that using SeaBIOS requires the use the upstream qemu as the
+# device model.
+SEABIOS_DIR ?= 
+
 # Optional components
 XENSTAT_XENTOP     ?= y
 VTPM_TOOLS         ?= n
tools/firmware/Makefile +2 -0
diff -r c387185f0a25 -r e471a31bf226 tools/firmware/Makefile
@@ -3,6 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 # hvmloader is a 32-bit protected mode binary.
 TARGET_ROMBIOS      := hvmloader/hvmloader-rombios
+TARGET_SEABIOS      := hvmloader/hvmloader-seabios
 INST_DIR := $(DESTDIR)$(XENFIRMWAREDIR)
 
 SUBDIRS :=
@@ -28,6 +29,7 @@ install: all
 	[ -d $(INST_DIR) ] || $(INSTALL_DIR) $(INST_DIR)
 	[ ! -e $(TARGET_ROMBIOS) ] || $(INSTALL_DATA) $(TARGET_ROMBIOS) $(INST_DIR)
 	[ ! -e $(TARGET_ROMBIOS) ] || ln -nfs hvmloader-rombios $(INST_DIR)/hvmloader
+	[ ! -e $(TARGET_SEABIOS) ] || $(INSTALL_DATA) $(TARGET_SEABIOS) $(INST_DIR)
 
 .PHONY: clean
 clean: subdirs-clean
tools/firmware/hvmloader/Makefile +15 -1
diff -r c387185f0a25 -r e471a31bf226 tools/firmware/hvmloader/Makefile
@@ -36,6 +36,10 @@ endif
 OBJS  = $(patsubst %.c,%.o,$(SRCS))
 
 TARGETS := hvmloader-rombios
+ifneq ($(SEABIOS_DIR),)
+TARGETS += hvmloader-seabios
+ROM_SEABIOS := $(SEABIOS_DIR)/out/bios.bin
+endif
 
 CIRRUSVGA_DEBUG ?= n
 
@@ -46,6 +50,9 @@ all: subdirs-all
 hvmloader-rombios.o: hvmloader.c roms.h
 	$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_$*.o) -DBIOS_ROM_rombios=1 -DBIOS_ROM_STR=\"ROMBIOS\" -c -o $@ hvmloader.c
 
+hvmloader-seabios.o: hvmloader.c roms.h
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_$*.o) -DBIOS_ROM_seabios=1 -DBIOS_ROM_STR=\"SeaBIOS\" -c -o $@ hvmloader.c
+
 smbios.o: CFLAGS += -D__SMBIOS_DATE__="\"$(shell date +%m/%d/%Y)\""
 
 hvmloader-%: hvmloader-%.o $(OBJS) acpi/acpi.a
@@ -54,13 +61,19 @@ hvmloader-%: hvmloader-%.o $(OBJS) acpi/
 	rm -f [email protected]
 
 roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin \
-	../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../etherboot/eb-roms.h
+	../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../etherboot/eb-roms.h $(ROM_SEABIOS)
 	echo "/* Autogenerated file. DO NOT EDIT */" > roms.h
 
 	echo "#ifdef BIOS_ROM_rombios" >> roms.h
 	sh ./mkhex biosimg ../rombios/BIOS-bochs-latest >> roms.h
 	echo "#endif" >> roms.h
 
+ifneq ($(ROM_SEABIOS),)
+	echo "#ifdef BIOS_ROM_seabios" >> roms.h
+	sh ./mkhex biosimg $(ROM_SEABIOS) >> roms.h
+	echo "#endif" >> roms.h
+endif
+
 	sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
 ifeq ($(CIRRUSVGA_DEBUG),y)
 	sh ./mkhex vgabios_cirrusvga \
@@ -77,5 +90,6 @@ clean: subdirs-clean
 	rm -f roms.h acpi.h
 	rm -f hvmloader hvmloader.tmp *.o $(DEPS)
 	rm -f hvmloader-rombios hvmloader-rombios.tmp
+	rm -f hvmloader-seabios hvmloader-seabios.tmp
 
 -include $(DEPS)
tools/firmware/hvmloader/config-seabios.h new file +13 -0
diff -r c387185f0a25 -r e471a31bf226 tools/firmware/hvmloader/config-seabios.h
@@ -0,0 +1,13 @@
+#ifndef __HVMLOADER_CONFIG_SEABIOS_H__
+#define __HVMLOADER_CONFIG_SEABIOS_H__
+
+/* Memory map. */
+#define VGABIOS_PHYSICAL_ADDRESS    0x000C0000
+#define OPTIONROM_PHYSICAL_ADDRESS  0x000C8000
+
+#define OPTIONROM_PHYSICAL_END      0x000E0000
+
+#define BIOS_PHYSICAL_ADDRESS       0x000E0000
+#define BIOS_MAXIMUM_SIZE           (0x00100000 - BIOS_PHYSICAL_ADDRESS)
+
+#endif /* __HVMLOADER_CONFIG_SEABIOS_H__ */
tools/firmware/hvmloader/hvmloader.c +39 -2

172 lines not on this page · raw message

#12 lore raw

libxl: hiding hvmloader and device_model options from users by default (Was: Re: [PATCH 00 of 11] RFC: hvmloader SeaBIOS integration)

In reply to Ian Campbell
Quoted 4 lines · Ian Campbell

It's a great shame that the choice of hvmloader binary was exposed to users through the config file format. We'll have to cross that bridge later I guess...

IMHO these should never have been exposed to users as something they are required to think about, unless they want to.

What about something like the following as a transition plan:

At the libxl API level:
* Move libxl_domain_build_info.kernel into the PV side of the tagged union (using this field to specify both PV kernel and hvmloader is confusing)
* Add hvmloader (a string) to the HVM side of the tagged union or perhaps to libxl_device_model_info?
* Add libxl_device_model_info.version allowing the user to say which qemu version (e.g. old qemu-xen or qemu upstream) they want for a domain
* Default both the hvmloader and device_model fields to NULL (or some other explicit "do the right thing" default) and DTRT when building a domain with that value in those fields, but still allow users to override.

At the xl level:
* WARN if an HVM guest cfg uses the "kernel" config option, and direct users to the "hvmloader_override" option if they really do not want the default.
* WARN if an HVM guest cfg uses the "device_model" config option, and again direct users to the "device_model_override" option if they really do not want the default.
* Support a new "device_model_version" option which sets the new libxl_device_model_info.version field.

(other toolstacks would do something similar presumably)

I suspect that the vast majority of users only have these config options because they've copied them from somewhere and they normally have no interest in which specific hvmloader or device model is used. Renaming the fields and warning when they are used makes these decisions internal. This will allow us to make decisions at a platform level regarding the preferred hvmloader, device model, stub domain etc without requiring everyone to change their configuration files.

(we could consider a period where we simply print a deprecation message but still honour the option, I don't think it's necessary though)

Adding a device model version to the API is intended to make it easy for users to select what they need without having to know about the paths to specific binaries etc. It also feeds the hvmloader decision. Most importantly it gets rid of the parsing of the output of qemu -h...

The following is a quick lashup of the above. It is missing the key Do The Right Thing functions at the moment so it won't even link...

Opinions? Shall I persist with this path?

Ian.

tools/libxl/libxl.c +1 -1
diff -r e471a31bf226 tools/libxl/libxl.c
@@ -2283,7 +2283,7 @@ int libxl_domain_need_memory(libxl_ctx *
     *need_memkb = b_info->target_memkb;
     if (b_info->hvm) {
         *need_memkb += b_info->shadow_memkb + LIBXL_HVM_EXTRA_MEMORY;
-        if (strstr(dm_info->device_model, "stubdom-dm"))
+        if (strstr(libxl_domain_device_model(dm_info), "stubdom-dm"))
             *need_memkb += 32 * 1024;
     } else
         *need_memkb += b_info->shadow_memkb + LIBXL_PV_EXTRA_MEMORY;
tools/libxl/libxl.h +10 -0
diff -r e471a31bf226 tools/libxl/libxl.h
@@ -209,6 +209,12 @@ enum {
 
 #define LIBXL_VERSION 0
 
+/*
+ * 1 - Historical qemu-xen device model
+ * 2 - Upstream qemu
+ */
+#define LIBXL_DEVICE_MODEL_VERSION_DEFAULT 2
+
 typedef struct {
     libxl_domain_create_info c_info;
     libxl_domain_build_info b_info;
@@ -249,6 +255,10 @@ int libxl_domain_shutdown(libxl_ctx *ctx
 int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force);
 int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, libxl_domain_create_info *info, const char *name_suffix, libxl_uuid new_uuid);
 
+/* Returns the device model */
+const char *libxl_domain_device_model(libxl_device_model_info *dm_info);
+/* Returns the hvmloader to use for this device model */
+char *libxl_domain_hvmloader(libxl_device_model_info *dm_info);
 /* get max. number of cpus supported by hypervisor */
 int libxl_get_max_cpus(libxl_ctx *ctx);
 
tools/libxl/libxl.idl +6 -4
diff -r e471a31bf226 tools/libxl/libxl.idl
@@ -151,12 +151,12 @@ libxl_domain_build_info = Struct("domain
     ("video_memkb",     uint32),
     ("shadow_memkb",    uint32),
     ("disable_migrate", bool),
-    ("kernel",          libxl_file_reference),
     ("cpuid",           libxl_cpuid_policy_list),
     ("hvm",             integer),
     ("u", KeyedUnion(None, "hvm",
                 [("hvm", "%s", Struct(None,
-                                       [("pae", bool),
+                                       [("hvmloader", string),
+                                        ("pae", bool),
                                         ("apic", bool),
                                         ("acpi", bool),
                                         ("nx", bool),
@@ -167,7 +167,8 @@ libxl_domain_build_info = Struct("domain
                                         ("timer_mode", integer),
                                         ])),
                  ("pv", "!%s", Struct(None,
-                                       [("slack_memkb", uint32),
+                                       [("kernel", libxl_file_reference),
+                                        ("slack_memkb", uint32),
                                         ("bootloader", string),
                                         ("bootloader_args", string),
                                         ("cmdline", string),
@@ -194,7 +195,8 @@ libxl_device_model_info = Struct("device
     ("domid",            integer),
     ("uuid",             libxl_uuid,  False, "this is use only with stubdom, and must be different from the domain uuid"),
     ("dom_name",         string),
-    ("device_model",     string),
+    ("device_model_version", integer),
+    ("device_model_override", string, False, "force a particular device model binary. You must set device_model_version too"),
     ("saved_state",      string),
     ("type",             libxl_qemu_machine_type),
     ("target_ram",       uint32),
tools/libxl/libxl_bootloader.c +7 -6
diff -r e471a31bf226 tools/libxl/libxl_bootloader.c
@@ -44,8 +44,9 @@ static char **make_bootloader_args(libxl
 
     flexarray_set(args, nr++, (char *)info->u.pv.bootloader);
 
-    if (info->kernel.path)
-        flexarray_set(args, nr++, libxl__sprintf(gc, "--kernel=%s", info->kernel.path));
+    if (info->u.pv.kernel.path)
+        flexarray_set(args, nr++, libxl__sprintf(gc, "--kernel=%s",
+                                                 info->u.pv.kernel.path));
     if (info->u.pv.ramdisk.path)
         flexarray_set(args, nr++, libxl__sprintf(gc, "--ramdisk=%s", info->u.pv.ramdisk.path));
     if (info->u.pv.cmdline && *info->u.pv.cmdline != '\0')
@@ -277,10 +278,10 @@ static void parse_bootloader_result(libx
 {
     while (*o != '\0') {
         if (strncmp("kernel ", o, strlen("kernel ")) == 0) {
-            free(info->kernel.path);
-            info->kernel.path = strdup(o + strlen("kernel "));
-            libxl__file_reference_map(&info->kernel);
-            unlink(info->kernel.path);
+            free(info->u.pv.kernel.path);
+            info->u.pv.kernel.path = strdup(o + strlen("kernel "));
+            libxl__file_reference_map(&info->u.pv.kernel);
+            unlink(info->u.pv.kernel.path);
         } else if (strncmp("ramdisk ", o, strlen("ramdisk ")) == 0) {
             free(info->u.pv.ramdisk.path);
             info->u.pv.ramdisk.path = strdup(o + strlen("ramdisk "));
tools/libxl/libxl_create.c +9 -7
diff -r e471a31bf226 tools/libxl/libxl_create.c
@@ -88,8 +88,8 @@ void libxl_init_build_info(libxl_domain_
     b_info->shadow_memkb = 0;
     if (c_info->hvm) {
         b_info->video_memkb = 8 * 1024;
-        b_info->kernel.path = strdup("hvmloader");
         b_info->hvm = 1;
+        b_info->u.hvm.hvmloader = NULL;
         b_info->u.hvm.pae = 1;
         b_info->u.hvm.apic = 1;
         b_info->u.hvm.acpi = 1;
@@ -111,7 +111,8 @@ void libxl_init_dm_info(libxl_device_mod
     libxl_uuid_generate(&dm_info->uuid);
 
     dm_info->dom_name = strdup(c_info->name);
-    dm_info->device_model = strdup("qemu-dm");
+    dm_info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_DEFAULT;
+    dm_info->device_model_override = NULL;
     dm_info->target_ram = libxl__sizekb_to_mb(b_info->target_memkb);
     dm_info->videoram = libxl__sizekb_to_mb(b_info->video_memkb);
     dm_info->apic = b_info->u.hvm.apic;
@@ -181,7 +182,7 @@ int libxl__domain_build(libxl__gc *gc, l
         vments[i++] = "image/ostype";
         vments[i++] = "linux";
         vments[i++] = "image/kernel";
-        vments[i++] = (char*) info->kernel.path;
+        vments[i++] = (char*) info->u.pv.kernel.path;
         vments[i++] = "start_time";
         vments[i++] = libxl__sprintf(gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
         if (info->u.pv.ramdisk.path) {
@@ -231,7 +232,7 @@ static int domain_restore(libxl__gc *gc,
         vments[i++] = "image/ostype";
         vments[i++] = "linux";
         vments[i++] = "image/kernel";
-        vments[i++] = (char*) info->kernel.path;
+        vments[i++] = (char*) info->u.pv.kernel.path;
         vments[i++] = "start_time";
         vments[i++] = libxl__sprintf(gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
         if (info->u.pv.ramdisk.path) {
@@ -255,9 +256,10 @@ static int domain_restore(libxl__gc *gc,
     }
 
 out:
-    libxl__file_reference_unmap(&info->kernel);
-    if (!info->hvm)
-	    libxl__file_reference_unmap(&info->u.pv.ramdisk);
+    if (!info->hvm) {
+        libxl__file_reference_unmap(&info->u.pv.kernel);
+        libxl__file_reference_unmap(&info->u.pv.ramdisk);
+    }
 
     esave = errno;
 
tools/libxl/libxl_dm.c +16 -11
diff -r e471a31bf226 tools/libxl/libxl_dm.c
@@ -199,7 +199,7 @@ static char ** libxl__build_device_model
     if (!dm_args)
         return NULL;
 
-    flexarray_vappend(dm_args, libxl__strdup(gc, info->device_model),
+    flexarray_vappend(dm_args, libxl__strdup(gc, libxl_domain_device_model(info)),
                         "-xen-domid", libxl__sprintf(gc, "%d", info->domid), NULL);
 
     if (info->type == LIBXL_QEMU_MACHINE_TYPE_PV) {
@@ -390,14 +390,16 @@ static char ** libxl__build_device_model
                                               libxl_device_nic *vifs, int num_vifs)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    int new_qemu;
 
-    new_qemu = libxl_check_device_model_version(ctx, info->device_model);
-
-    if (new_qemu == 1) {
+    switch (info->device_model_version) {
+    case 1:
+        return libxl__build_device_model_args_old(gc, info, disks, num_disks, vifs, num_vifs);
+    case 2:
         return libxl__build_device_model_args_new(gc, info, disks, num_disks, vifs, num_vifs);
-    } else {
-        return libxl__build_device_model_args_old(gc, info, disks, num_disks, vifs, num_vifs);
+    default:
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unknown device model version %d",
+                         info->device_model_version);
+        return NULL;
     }
 }
 
@@ -534,7 +536,8 @@ static int libxl__create_stubdom(libxl__
     b_info.max_vcpus = 1;
     b_info.max_memkb = 32 * 1024;
     b_info.target_memkb = b_info.max_memkb;
-    b_info.kernel.path = libxl__abs_path(gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path());
+    b_info.u.pv.kernel.path = libxl__abs_path(gc, "ioemu-stubdom.gz",
+                                              libxl_xenfirmwaredir_path());
     b_info.u.pv.cmdline = libxl__sprintf(gc, " -d %d", info->domid);
     b_info.u.pv.ramdisk.path = "";
     b_info.u.pv.features = "";
@@ -678,7 +681,7 @@ int libxl__create_device_model(libxl__gc
     char *vm_path;
     char **pass_stuff;
 
-    if (strstr(info->device_model, "stubdom-dm")) {
+    if (strstr(libxl_domain_device_model(info), "stubdom-dm")) {
         libxl_device_vfb vfb;
         libxl_device_vkb vkb;
 
@@ -744,7 +747,8 @@ retry_transaction:
     if (!rc) { /* inner child */
         setsid();
         libxl__exec(null, logfile_w, logfile_w,
-                   libxl__abs_path(gc, info->device_model, libxl_libexec_path()),
+                    libxl__abs_path(gc, libxl_domain_device_model(info),
+                                    libxl_libexec_path()),
                    args);
     }
 
@@ -844,7 +848,8 @@ static int libxl__build_xenpv_qemu_args(
         info->nographic = 1;
     info->domid = domid;
     info->dom_name = libxl_domid_to_name(ctx, domid);
-    info->device_model = libxl__abs_path(gc, "qemu-dm", libxl_libexec_path());
+    info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_DEFAULT;
+    info->device_model_override = NULL;
     info->type = LIBXL_QEMU_MACHINE_TYPE_PV;
     return 0;
 }
tools/libxl/libxl_dom.c +9 -10
diff -r e471a31bf226 tools/libxl/libxl_dom.c
@@ -160,13 +160,17 @@ int libxl__build_pv(libxl__gc *gc, uint3
         return ERROR_FAIL;
     }
 
-    if (info->kernel.mapped) {
-        if ( (ret = xc_dom_kernel_mem(dom, info->kernel.data, info->kernel.size)) != 0) {
+    if (info->u.pv.kernel.mapped) {
+        ret = xc_dom_kernel_mem(dom,
+                                info->u.pv.kernel.data,
+                                info->u.pv.kernel.size);
+        if ( ret != 0) {
             LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_kernel_mem failed");
             goto out;
         }
     } else {
-        if ( (ret = xc_dom_kernel_file(dom, info->kernel.path)) != 0) {
+        ret = xc_dom_kernel_file(dom, info->u.pv.kernel.path);
+        if ( ret != 0) {
             LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_kernel_file failed");
             goto out;
         }
@@ -269,19 +273,14 @@ int libxl__build_hvm(libxl__gc *gc, uint
     libxl_ctx *ctx = libxl__gc_owner(gc);
     int ret, rc = ERROR_INVAL;
 
-    if (info->kernel.mapped) {
-        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "libxl__build_hvm kernel cannot be mmapped");
-        goto out;
-    }
-
     rc = ERROR_FAIL;
     ret = xc_hvm_build_target_mem(
         ctx->xch,
         domid,
         (info->max_memkb - info->video_memkb) / 1024,
         (info->target_memkb - info->video_memkb) / 1024,
-        libxl__abs_path(gc, (char *)info->kernel.path,
-                       libxl_xenfirmwaredir_path()));
+        libxl__abs_path(gc, info->u.hvm.hvmloader,
+                        libxl_xenfirmwaredir_path()));
     if (ret) {
         LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "hvm building failed");
         goto out;
tools/libxl/libxl_internal.c +2 -2
diff -r e471a31bf226 tools/libxl/libxl_internal.c
@@ -184,10 +184,10 @@ void libxl__log(libxl_ctx *ctx, xentooll
     va_end(ap);
 }
 
-char *libxl__abs_path(libxl__gc *gc, char *s, const char *path)
+char *libxl__abs_path(libxl__gc *gc, const char *s, const char *path)
 {
     if (!s || s[0] == '/')
-        return s;
+        return libxl__strdup(gc, s);
     return libxl__sprintf(gc, "%s/%s", path, s);
 }
 
tools/libxl/libxl_internal.h +1 -1
diff -r e471a31bf226 tools/libxl/libxl_internal.h
@@ -289,7 +289,7 @@ _hidden void libxl__exec(int stdinfd, in
 _hidden void libxl__log_child_exitstatus(libxl__gc *gc,
                                 const char *what, pid_t pid, int status);
 
-_hidden char *libxl__abs_path(libxl__gc *gc, char *s, const char *path);
+_hidden char *libxl__abs_path(libxl__gc *gc, const char *s, const char *path);
 
 #define LIBXL__LOG_DEBUG   XTL_DEBUG
 #define LIBXL__LOG_INFO    XTL_INFO
tools/libxl/libxl_utils.c +0 -83

89 lines not on this page · raw message

tools/libxl/libxl_utils.h +0 -6
diff -r e471a31bf226 tools/libxl/libxl_utils.h
@@ -71,12 +71,6 @@ int libxl_strtomac(const char *mac_s, ui
 int libxl_devid_to_device_net2(libxl_ctx *ctx, uint32_t domid,
                                const char *devid, libxl_device_net2 *net2);
 
-/* check the version of qemu
- * return 1 if is the new one
- * return 0 if is the old one
- * return -1 if there are an error */
-int libxl_check_device_model_version(libxl_ctx *ctx, char *path);
-
 int libxl_cpumap_alloc(libxl_ctx *ctx, libxl_cpumap *cpumap);
 int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu);
 void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu);
tools/libxl/xl_cmdimpl.c +27 -7
diff -r e471a31bf226 tools/libxl/xl_cmdimpl.c
@@ -337,7 +337,7 @@ static void printf_info(int domid,
     printf("\t(image\n");
     if (c_info->hvm) {
         printf("\t\t(hvm\n");
-        printf("\t\t\t(loader %s)\n", b_info->kernel.path);
+        printf("\t\t\t(loader %s)\n", b_info->u.hvm.hvmloader);
         printf("\t\t\t(video_memkb %d)\n", b_info->video_memkb);
         printf("\t\t\t(shadow_memkb %d)\n", b_info->shadow_memkb);
         printf("\t\t\t(pae %d)\n", b_info->u.hvm.pae);
@@ -349,7 +349,7 @@ static void printf_info(int domid,
         printf("\t\t\t(vpt_align %d)\n", b_info->u.hvm.vpt_align);
         printf("\t\t\t(timer_mode %d)\n", b_info->u.hvm.timer_mode);
 
-        printf("\t\t\t(device_model %s)\n", dm_info->device_model);
+        printf("\t\t\t(device_model %s)\n", libxl_domain_device_model(dm_info));
         printf("\t\t\t(videoram %d)\n", dm_info->videoram);
         printf("\t\t\t(stdvga %d)\n", dm_info->stdvga);
         printf("\t\t\t(vnc %d)\n", dm_info->vnc);
@@ -369,7 +369,7 @@ static void printf_info(int domid,
         printf("\t\t)\n");
     } else {
         printf("\t\t(linux %d)\n", b_info->hvm);
-        printf("\t\t\t(kernel %s)\n", b_info->kernel.path);
+        printf("\t\t\t(kernel %s)\n", b_info->u.pv.kernel.path);
         printf("\t\t\t(cmdline %s)\n", b_info->u.pv.cmdline);
         printf("\t\t\t(ramdisk %s)\n", b_info->u.pv.ramdisk.path);
         printf("\t\t)\n");
@@ -741,12 +741,16 @@ static void parse_config_data(const char
     if (!xlu_cfg_get_long (config, "videoram", &l))
         b_info->video_memkb = l * 1024;
 
-    xlu_cfg_replace_string (config, "kernel", &b_info->kernel.path);
-
     if (!xlu_cfg_get_long (config, "gfx_passthru", &l))
         dm_info->gfx_passthru = l;
 
     if (c_info->hvm == 1) {
+        if (!xlu_cfg_get_string (config, "kernel", &buf))
+            fprintf(stderr, "WARNING: ignoring \"kernel\" directive for HVM guest. "
+                    "Use \"hvmloader_override\" instead if you really want a non-default hvmloader\n");
+
+        xlu_cfg_replace_string (config, "hvmloader_override",
+                                &b_info->u.hvm.hvmloader);
         if (!xlu_cfg_get_long (config, "pae", &l))
             b_info->u.hvm.pae = l;
         if (!xlu_cfg_get_long (config, "apic", &l))
@@ -767,6 +771,8 @@ static void parse_config_data(const char
         char *cmdline = NULL;
         const char *root = NULL, *extra = "";
 
+        xlu_cfg_replace_string (config, "kernel", &b_info->u.pv.kernel.path);
+
         xlu_cfg_get_string (config, "root", &root);
         xlu_cfg_get_string (config, "extra", &extra);
 
@@ -785,7 +791,7 @@ static void parse_config_data(const char
         xlu_cfg_replace_string (config, "bootloader", &b_info->u.pv.bootloader);
         xlu_cfg_replace_string (config, "bootloader_args", &b_info->u.pv.bootloader_args);
 
-        if (!b_info->u.pv.bootloader && !b_info->kernel.path) {
+        if (!b_info->u.pv.bootloader && !b_info->u.pv.kernel.path) {
             fprintf(stderr, "Neither kernel nor bootloader specified\n");
             exit(1);
         }
@@ -1120,7 +1126,17 @@ skip_vfb:
         libxl_init_dm_info(dm_info, c_info, b_info);
 
         /* then process config related to dm */
-        xlu_cfg_replace_string (config, "device_model", &dm_info->device_model);
+        if (!xlu_cfg_get_string (config, "device_model", &buf))
+            fprintf(stderr, "WARNING: ignoring device_model directive. "
+                    "Use \"device_model_override\" instead if you really want a non-default device_model\n");
+
+        xlu_cfg_replace_string (config, "device_model_override",
+                                &dm_info->device_model_override);
+        if (!xlu_cfg_get_long (config, "device_model_version", &l))
+            dm_info->device_model_version = l;
+        else if (dm_info->device_model_override)
+            fprintf(stderr, "WARNING: device model override given without specific DM version, assuming latest\n");
+
         if (!xlu_cfg_get_long (config, "stdvga", &l))
             dm_info->stdvga = l;
         if (!xlu_cfg_get_long (config, "vnc", &l))
@@ -1159,6 +1175,10 @@ skip_vfb:
                 dm_info->extra[i] = a ? strdup(a) : NULL;
             }
         }
+
+        /* Now we can select an hvmloader */
+        if ( b_info->u.hvm.hvmloader )
+            b_info->u.hvm.hvmloader = libxl_domain_hvmloader(dm_info);
     }
 
     dm_info->type = c_info->hvm ? LIBXL_QEMU_MACHINE_TYPE_FV : LIBXL_QEMU_MACHINE_TYPE_PV;
#13 lore raw

libxl: hiding hvmloader and device_model options from users by default (Was: Re: [PATCH 00 of 11] RFC: hvmloader SeaBIOS integration)

Ian Campbell writes ("[Xen-devel] libxl: hiding hvmloader and device_model options from users by default (Was: Re: [PATCH 00 of 11] RFC: hvmloader SeaBIOS integration)"):

Quoted 1 line

What about something like the following as a transition plan:

Yes.

Quoted 1 line

Opinions? Shall I persist with this path?

Yes :-)

Ian.