Sort the fw_cfg file list

Entries are inserted in filename order instead of being
appended to the end in case sorting is enabled.

This will avoid any future issues of moving the file creation
around, it doesn't matter what order they are created now,
the will always be in filename order.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

Added machine type handling for compatibility.  This was
a fairly complex change, this will preserve the order of fw_cfg
for older versions no matter what order the firmware files
actually come in.  A list is kept of the correct legacy order
and the entries will be inserted based upon their order in
the list.  Except that some entries are ordered (in a specific
area of the list) based upon what order they appear on the
command line.  Special handling is added for those entries.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
diff --git a/vl.c b/vl.c
index 3629336..9df534f 100644
--- a/vl.c
+++ b/vl.c
@@ -2297,8 +2297,9 @@
     gchar *buf;
     size_t size;
     const char *name, *file, *str;
+    FWCfgState *fw_cfg = (FWCfgState *) opaque;
 
-    if (opaque == NULL) {
+    if (fw_cfg == NULL) {
         error_report("fw_cfg device not available");
         return -1;
     }
@@ -2332,7 +2333,10 @@
             return -1;
         }
     }
-    fw_cfg_add_file((FWCfgState *)opaque, name, buf, size);
+    /* For legacy, keep user files in a specific global order. */
+    fw_cfg_set_order_override(fw_cfg, FW_CFG_ORDER_OVERRIDE_USER);
+    fw_cfg_add_file(fw_cfg, name, buf, size);
+    fw_cfg_reset_order_override(fw_cfg);
     return 0;
 }
 
@@ -4535,10 +4539,12 @@
     igd_gfx_passthru();
 
     /* init generic devices */
+    rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
     if (qemu_opts_foreach(qemu_find_opts("device"),
                           device_init_func, NULL, NULL)) {
         exit(1);
     }
+    rom_reset_order_override();
 
     /* Did we create any drives that we failed to create a device for? */
     drive_check_orphaned();