Patchwork net: qomify -netdev

login
register
mail settings
Submitter Zhiyong Wu
Date March 26, 2012, 5:40 a.m.
Message ID <1332740423-8426-4-git-send-email-zwu.kernel@gmail.com>
Download mbox | patch
Permalink /patch/148642/
State New
Headers show

Comments

Zhiyong Wu - March 26, 2012, 5:40 a.m.
From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>

Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
---
 cpu-common.h      |   13 +++++++++-
 hw/qdev-monitor.c |    4 ++-
 hw/qdev.h         |    2 +
 net.c             |   62 +++++++++++++++++++++++++++++++++++++++++++++++-----
 net.h             |    5 ++++
 net/dump.c        |    6 ++++-
 net/dump.h        |   14 ++++++++++-
 net/slirp.c       |   35 +++++++++++++++++++++++++++++
 net/slirp.h       |   13 +++++++++++
 net/socket.c      |   53 ++++++++++++++++++++++++++++++++++++--------
 net/socket.h      |   18 +++++++++++++-
 net/tap-win32.c   |    8 +++++-
 net/tap.c         |   56 ++++++++++++++++++++++++++++++++++++++++++++++-
 net/tap.h         |   26 ++++++++++++++++++++-
 net/vde.c         |    4 ++-
 net/vde.h         |    3 +-
 qemu-log.h        |    6 ++--
 qemu-timer.c      |    2 +-
 qom/Makefile      |    2 +-
 qom/object.c      |    1 -
 vl.c              |   17 ++++++++------
 21 files changed, 304 insertions(+), 46 deletions(-)

Patch

diff --git a/cpu-common.h b/cpu-common.h
index dca5175..81279aa 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -3,9 +3,7 @@ 
 
 /* CPU interfaces that are target independent.  */
 
-#ifdef TARGET_PHYS_ADDR_BITS
 #include "targphys.h"
-#endif
 
 #ifndef NEED_CPU_H
 #include "poison.h"
@@ -23,6 +21,7 @@  enum device_endian {
 };
 
 /* address in the RAM (different from a physical address) */
+#define TARGET_PHYS_ADDR_BITS 64
 #if defined(CONFIG_XEN_BACKEND) && TARGET_PHYS_ADDR_BITS == 64
 typedef uint64_t ram_addr_t;
 #  define RAM_ADDR_MAX UINT64_MAX
@@ -35,6 +34,16 @@  typedef uintptr_t ram_addr_t;
 
 /* memory API */
 
+#if TARGET_PHYS_ADDR_BITS == 32
+typedef uint32_t target_phys_addr_t;
+#define TARGET_PHYS_ADDR_MAX UINT32_MAX
+#define TARGET_FMT_plx "%08x"
+#elif TARGET_PHYS_ADDR_BITS == 64
+typedef uint64_t target_phys_addr_t;
+#define TARGET_PHYS_ADDR_MAX UINT64_MAX
+#define TARGET_FMT_plx "%016" PRIx64
+#endif
+
 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
 
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index a310cc7..82d5c50 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -19,6 +19,7 @@ 
 
 #include "qdev.h"
 #include "monitor.h"
+#include "net.h"
 
 /*
  * Aliases were a bad idea from the start.  Let's keep them
@@ -97,6 +98,8 @@  static int set_property(const char *name, const char *value, void *opaque)
         return 0;
     if (strcmp(name, "bus") == 0)
         return 0;
+    if (strcmp(name, "type") == 0)
+        return 0;
 
     if (qdev_prop_parse(dev, name, value) == -1) {
         return -1;
@@ -480,7 +483,6 @@  DeviceState *qdev_device_add(QemuOpts *opts)
     return qdev;
 }
 
-
 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
 static void qbus_print(Monitor *mon, BusState *bus, int indent);
 
diff --git a/hw/qdev.h b/hw/qdev.h
index c638b98..e0c8ffa 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -144,6 +144,8 @@  DeviceState *qdev_try_create(BusState *bus, const char *name);
 bool qdev_exists(const char *name);
 int qdev_device_help(QemuOpts *opts);
 DeviceState *qdev_device_add(QemuOpts *opts);
+void *qdev_hostdev_add(Monitor *mon, QemuOpts *opts,
+                       char *name, NetClientState *peer);
 int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT;
 void qdev_init_nofail(DeviceState *dev);
 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
diff --git a/net.c b/net.c
index dd67d16..5e4f871 100644
--- a/net.c
+++ b/net.c
@@ -624,10 +624,7 @@  static int net_init_nic(QemuOpts *opts,
         .help = "identifier for monitor commands", \
      }
 
-typedef int NetClientInitFunc(QemuOpts *opts,
-                              Monitor *mon,
-                              const char *name,
-                              NetClientState *peer);
+typedef int NetClientInitFunc(QemuOpts *opts, Monitor *mon, const char *name, NetClientState *peer);
 
 /* magic number, but compiler will warn if too small */
 #define NET_MAX_DESC 20
@@ -972,6 +969,58 @@  int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
     return -1;
 }
 
+static int net_client_netdev_init(Monitor *mon, QemuOpts *opts, int is_netdev)
+{
+    const char *name;
+    const char *type;
+
+    type = qemu_opt_get(opts, "type");
+    if (!type) {
+        qerror_report(QERR_MISSING_PARAMETER, "type");
+        return -1;
+    }
+
+    if (is_netdev) {
+        if (strcmp(type, "tap") != 0 &&
+#ifdef CONFIG_NET_BRIDGE
+            strcmp(type, "bridge") != 0 &&
+#endif
+#ifdef CONFIG_SLIRP
+            strcmp(type, "user") != 0 &&
+#endif
+#ifdef CONFIG_VDE
+            strcmp(type, "vde") != 0 &&
+#endif
+            strcmp(type, "socket") != 0) {
+            qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
+                          "a netdev backend type");
+            return -1;
+        }
+
+        if (qemu_opt_get(opts, "vlan")) {
+            qerror_report(QERR_INVALID_PARAMETER, "vlan");
+            return -1;
+        }
+        if (qemu_opt_get(opts, "name")) {
+            qerror_report(QERR_INVALID_PARAMETER, "name");
+            return -1;
+        }
+        if (!qemu_opts_id(opts)) {
+            qerror_report(QERR_MISSING_PARAMETER, "id");
+            return -1;
+        }
+    }
+
+    name = qemu_opts_id(opts);
+    if (!name) {
+        name = qemu_opt_get(opts, "name");
+    }
+
+    hostdev_device_add(mon, opts, (char *)name, NULL);
+
+    return 0;
+}
+
 static int net_host_check_device(const char *device)
 {
     int i;
@@ -1188,7 +1237,7 @@  static int net_init_client(QemuOpts *opts, void *dummy)
 
 static int net_init_netdev(QemuOpts *opts, void *dummy)
 {
-    return net_client_init(NULL, opts, 1);
+    return net_client_netdev_init(NULL, opts, 1);
 }
 
 int net_init_clients(void)
@@ -1205,8 +1254,9 @@  int net_init_clients(void)
 
     QTAILQ_INIT(&net_clients);
 
-    if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1)
+    if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1) {
         return -1;
+    }
 
     if (qemu_opts_foreach(net, net_init_client, NULL, 1) == -1) {
         return -1;
diff --git a/net.h b/net.h
index 60837ab..69d93b1 100644
--- a/net.h
+++ b/net.h
@@ -6,7 +6,11 @@ 
 #include "qdict.h"
 #include "qemu-option.h"
 #include "net/queue.h"
+#include "hw/qdev.h"
 #include "vmstate.h"
+#include "hw/hw.h"
+#include "hw/pci.h"
+#include "qemu/hostdev.h"
 
 struct MACAddr {
     uint8_t a[6];
@@ -61,6 +65,7 @@  typedef struct NetClientInfo {
 } NetClientInfo;
 
 struct NetClientState {
+    HOSTDevice host_dev;
     NetClientInfo *info;
     int link_down;
     QTAILQ_ENTRY(NetClientState) next;
diff --git a/net/dump.c b/net/dump.c
index 0f191d3..9152b2e 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -29,12 +29,14 @@ 
 #include "qemu-timer.h"
 #include "hub.h"
 
+/*
 typedef struct DumpState {
     NetClientState nc;
     int64_t start_ts;
     int fd;
     int pcap_caplen;
 } DumpState;
+*/
 
 #define PCAP_MAGIC 0xa1b2c3d4
 
@@ -145,7 +147,9 @@  static int net_dump_init(NetClientState *peer, const char *device,
     return 0;
 }
 
-int net_init_dump(QemuOpts *opts, Monitor *mon, const char *name,
+int net_init_dump(QemuOpts *opts,
+                  Monitor *mon,
+                  const char *name,
                   NetClientState *peer)
 {
     int len;
diff --git a/net/dump.h b/net/dump.h
index df22afe..9066ff7 100644
--- a/net/dump.h
+++ b/net/dump.h
@@ -26,8 +26,18 @@ 
 
 #include "net.h"
 #include "qemu-common.h"
+#include "qemu/hostdev.h"
 
-int net_init_dump(QemuOpts *opts, Monitor *mon,
-                  const char *name, NetClientState *peer);
+typedef struct DumpState {
+    NetClientState nc;
+    int64_t start_ts;
+    int fd;
+    int pcap_caplen;
+} DumpState;
+
+int net_init_dump(QemuOpts *opts,
+                  Monitor *mon,
+                  const char *name,
+                  NetClientState *peer);
 
 #endif /* QEMU_NET_DUMP_H */
diff --git a/net/slirp.c b/net/slirp.c
index d3e56fc..0838fd5 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -66,6 +66,7 @@  struct slirp_config_str {
     int legacy_format;
 };
 
+/*
 typedef struct SlirpState {
     NetClientState nc;
     QTAILQ_ENTRY(SlirpState) entry;
@@ -74,6 +75,7 @@  typedef struct SlirpState {
     char smb_dir[128];
 #endif
 } SlirpState;
+*/
 
 static struct slirp_config_str *slirp_configs;
 const char *legacy_tftp_prefix;
@@ -777,3 +779,36 @@  int net_slirp_parse_legacy(QemuOptsList *opts_list, const char *optarg, int *ret
     return 1;
 }
 
+static hostdevProperty net_user_properties[] = {
+    //DEFINE_PROP_STRING("type", NetClientState, info->type),
+    DEFINE_HOSTDEV_PROP_INT32("link_down", NetClientState,link_down, 0),
+    DEFINE_HOSTDEV_PROP_PEER("peer", NetClientState, peer),
+    //DEFINE_PROP_STRING("model", NetClientState, model),
+    DEFINE_HOSTDEV_PROP_STRING("name", NetClientState, name),
+    //DEFINE_PROP_BIT("receive_disabled", NetClientState, receive_disabled, 0, true),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void net_user_class_init(ObjectClass *klass, void *data)
+{
+    HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+    k->init = net_init_slirp;
+    k->props = net_user_properties;
+}
+
+static TypeInfo net_user_type = {
+    .name          = "user",
+    .parent        = TYPE_HOSTDEV,
+    .instance_size = sizeof(NetClientState),
+    .class_init    = net_user_class_init,
+};
+
+static void net_user_register_types(void)
+{
+#ifdef CONFIG_SLIRP
+    type_register_static(&net_user_type);
+#endif
+}
+
+type_init(net_user_register_types)
diff --git a/net/slirp.h b/net/slirp.h
index e6000af..8a7622e 100644
--- a/net/slirp.h
+++ b/net/slirp.h
@@ -27,6 +27,19 @@ 
 #include "qemu-common.h"
 #include "qdict.h"
 #include "qemu-option.h"
+#include "qemu_socket.h"
+#include "slirp/libslirp.h"
+#include "net.h"
+#include "qemu/hostdev.h"
+
+typedef struct SlirpState {
+    NetClientState nc;
+    QTAILQ_ENTRY(SlirpState) entry;
+    Slirp *slirp;
+#ifndef _WIN32
+    char smb_dir[128];
+#endif
+} SlirpState;
 
 #ifdef CONFIG_SLIRP
 
diff --git a/net/socket.c b/net/socket.c
index 55d9820..4ea3e07 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -31,16 +31,17 @@ 
 #include "qemu-error.h"
 #include "qemu-option.h"
 #include "qemu_socket.h"
-
-typedef struct NetSocketState {
-    NetClientState nc;
-    int fd;
-    int state; /* 0 = getting length, 1 = getting data */
-    unsigned int index;
-    unsigned int packet_len;
-    uint8_t buf[4096];
-    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
-} NetSocketState;
+#include "qemu/hostdev.h"
+
+//typedef struct NetSocketState {
+//    NetClientState nc;
+//    int fd;
+//    int state; /* 0 = getting length, 1 = getting data */
+//    unsigned int index;
+//    unsigned int packet_len;
+//    uint8_t buf[4096];
+//    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
+//} NetSocketState;
 
 typedef struct NetSocketListenState {
     NetClientState *peer;
@@ -592,6 +593,12 @@  int net_init_socket(QemuOpts *opts,
                     const char *name,
                     NetClientState *peer)
 {
+/*
+    QemuOpts *opts = host_dev->opts;
+    Monitor *mon = host_dev->mon;
+    const char *name = strdup(host_dev->name);
+    NetClientState *peer = host_dev->peer;
+*/
     if (qemu_opt_get(opts, "fd")) {
         int fd;
 
@@ -690,3 +697,29 @@  int net_init_socket(QemuOpts *opts,
     }
     return 0;
 }
+
+static hostdevProperty net_socket_properties[] = {
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void net_socket_class_init(ObjectClass *klass, void *data)
+{
+    HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+    k->init = net_init_socket;
+    k->props = net_socket_properties;
+}
+
+static TypeInfo net_socket_type = {
+    .name          = "socket",
+    .parent        = TYPE_HOSTDEV,
+    .instance_size = sizeof(NetClientState),
+    .class_init    = net_socket_class_init,
+};
+
+static void net_socket_register_types(void)
+{
+    type_register_static(&net_socket_type);
+}
+
+type_init(net_socket_register_types)
diff --git a/net/socket.h b/net/socket.h
index 5edf17c..128af01 100644
--- a/net/socket.h
+++ b/net/socket.h
@@ -26,8 +26,22 @@ 
 
 #include "net.h"
 #include "qemu-common.h"
+#include "qemu_socket.h"
+#include "qemu/hostdev.h"
 
-int net_init_socket(QemuOpts *opts, Monitor *mon,
-                    const char *name, NetClientState *peer);
+typedef struct NetSocketState {
+    NetClientState nc;
+    int fd;
+    int state; /* 0 = getting length, 1 = getting data */
+    unsigned int index;
+    unsigned int packet_len;
+    uint8_t buf[4096];
+    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
+} NetSocketState;
+
+int net_init_socket(QemuOpts *opts,
+                    Monitor *mon,
+                    const char *name,
+                    NetClientState *peer);
 
 #endif /* QEMU_NET_SOCKET_H */
diff --git a/net/tap-win32.c b/net/tap-win32.c
index 3406717..fa17239 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -699,11 +699,15 @@  static int tap_win32_init(NetClientState *peer, const char *model,
     return 0;
 }
 
-int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name,
-                 NetClientState *peer)
+int net_init_tap(HOSTDevice *host_dev)
 {
     const char *ifname;
 
+    QemuOpts *opts = host_dev->opts;
+    Monitor *mon = host_dev->mon;
+    const char *name = strdup(host_dev->name);
+    NetClientState *peer = host_dev->peer;
+
     ifname = qemu_opt_get(opts, "ifname");
 
     if (!ifname) {
diff --git a/net/tap.c b/net/tap.c
index 65f45b8..f568c50 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -46,6 +46,7 @@ 
 /* Maximum GSO packet size (64k) plus plenty of room for
  * the ethernet and virtio_net headers
  */
+/*
 #define TAP_BUFSIZE (4096 + 65536)
 
 typedef struct TAPState {
@@ -61,6 +62,7 @@  typedef struct TAPState {
     VHostNetState *vhost_net;
     unsigned host_vnet_hdr_len;
 } TAPState;
+*/
 
 static int launch_script(const char *setup_script, const char *ifname, int fd);
 
@@ -512,7 +514,9 @@  static int net_bridge_run_helper(const char *helper, const char *bridge)
     return -1;
 }
 
-int net_init_bridge(QemuOpts *opts, Monitor *mon, const char *name,
+int net_init_bridge(QemuOpts *opts,
+                    Monitor *mon,
+                    const char *name,
                     NetClientState *peer)
 {
     TAPState *s;
@@ -583,7 +587,9 @@  static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
     return fd;
 }
 
-int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name,
+int net_init_tap(QemuOpts *opts,
+                 Monitor *mon,
+                 const char *name,
                  NetClientState *peer)
 {
     TAPState *s;
@@ -715,3 +721,49 @@  VHostNetState *tap_get_vhost_net(NetClientState *nc)
     assert(nc->info->type == NET_CLIENT_TYPE_TAP);
     return s->vhost_net;
 }
+
+static hostdevProperty net_tap_properties[] = {
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void net_tap_class_init(ObjectClass *klass, void *data)
+{
+    HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+    k->init = net_init_tap;
+    k->props = net_tap_properties;
+}
+
+static TypeInfo net_tap_type = {
+    .name          = "tap",
+    .parent        = TYPE_HOSTDEV,
+    .instance_size = sizeof(NetClientState),
+    .class_init    = net_tap_class_init,
+};
+
+static hostdevProperty net_bridge_properties[] = {
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void net_bridge_class_init(ObjectClass *klass, void *data)
+{
+    HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+    k->init = net_init_bridge;
+    k->props = net_bridge_properties;
+}
+
+static TypeInfo net_bridge_type = {
+    .name          = "bridge",
+    .parent        = TYPE_HOSTDEV,
+    .instance_size = sizeof(NetClientState),
+    .class_init    = net_bridge_class_init,
+};
+
+static void net_tap_register_types(void)
+{
+    type_register_static(&net_tap_type);
+    type_register_static(&net_bridge_type);
+}
+
+type_init(net_tap_register_types)
diff --git a/net/tap.h b/net/tap.h
index 0e35e81..a687d9a 100644
--- a/net/tap.h
+++ b/net/tap.h
@@ -28,11 +28,31 @@ 
 
 #include "qemu-common.h"
 #include "qemu-option.h"
+#include "hw/vhost_net.h"
+#include "qemu/hostdev.h"
 
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
 
-int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name,
+#define TAP_BUFSIZE (4096 + 65536)
+
+typedef struct TAPState {
+    NetClientState nc;
+    int fd;
+    char down_script[1024];
+    char down_script_arg[128];
+    uint8_t buf[TAP_BUFSIZE];
+    unsigned int read_poll : 1;
+    unsigned int write_poll : 1;
+    unsigned int using_vnet_hdr : 1;
+    unsigned int has_ufo: 1;
+    VHostNetState *vhost_net;
+    unsigned host_vnet_hdr_len;
+} TAPState;
+
+int net_init_tap(QemuOpts *opts,
+                 Monitor *mon,
+                 const char *name,
                  NetClientState *peer);
 
 int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required);
@@ -58,7 +78,9 @@  int tap_get_fd(NetClientState *nc);
 struct vhost_net;
 struct vhost_net *tap_get_vhost_net(NetClientState *nc);
 
-int net_init_bridge(QemuOpts *opts, Monitor *mon, const char *name,
+int net_init_bridge(QemuOpts *opts,
+                    Monitor *mon,
+                    const char *name,
                     NetClientState *peer);
 
 #endif /* QEMU_NET_TAP_H */
diff --git a/net/vde.c b/net/vde.c
index 8d9e1c6..5b06f67 100644
--- a/net/vde.c
+++ b/net/vde.c
@@ -110,7 +110,9 @@  static int net_vde_init(NetClientState *peer, const char *model,
     return 0;
 }
 
-int net_init_vde(QemuOpts *opts, Monitor *mon, const char *name,
+int net_init_vde(QemuOpts *opts,
+                 Monitor *mon,
+                 const char *name,
                  NetClientState *peer)
 {
     const char *sock;
diff --git a/net/vde.h b/net/vde.h
index 276e1ff..4400fa5 100644
--- a/net/vde.h
+++ b/net/vde.h
@@ -29,8 +29,7 @@ 
 
 #ifdef CONFIG_VDE
 
-int net_init_vde(QemuOpts *opts, Monitor *mon, const char *name,
-                 NetClientState *peer);
+int net_init_vde(HOSTDevice *host_dev);
 
 #endif /* CONFIG_VDE */
 
diff --git a/qemu-log.h b/qemu-log.h
index fccfb110..611f796 100644
--- a/qemu-log.h
+++ b/qemu-log.h
@@ -51,9 +51,9 @@  extern int loglevel;
 /* Special cases: */
 
 /* cpu_dump_state() logging functions: */
-#define log_cpu_state(env, f) cpu_dump_state((env), logfile, fprintf, (f));
-#define log_cpu_state_mask(b, env, f) do {           \
-      if (loglevel & (b)) log_cpu_state((env), (f)); \
+#define log_cpu_state(env1, f) cpu_dump_state((env1), logfile, fprintf, (f));
+#define log_cpu_state_mask(b, env1, f) do {           \
+      if (loglevel & (b)) log_cpu_state((env1), (f)); \
   } while (0)
 
 /* disas() and target_disas() to logfile: */
diff --git a/qemu-timer.c b/qemu-timer.c
index d7f56e5..8e48483 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -23,7 +23,7 @@ 
  */
 
 #include "sysemu.h"
-#include "net.h"
+//#include "net.h"
 #include "monitor.h"
 #include "console.h"
 
diff --git a/qom/Makefile b/qom/Makefile
index 34c6de5..4731fb9 100644
--- a/qom/Makefile
+++ b/qom/Makefile
@@ -1,2 +1,2 @@ 
 qom-y = object.o container.o qom-qobject.o
-qom-twice-y = cpu.o
+qom-twice-y = cpu.o hostdev.o
diff --git a/qom/object.c b/qom/object.c
index 9cd9506..6f60426 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -101,7 +101,6 @@  TypeImpl *type_register(const TypeInfo *info)
     g_assert(info->name != NULL);
 
     if (type_table_lookup(info->name) != NULL) {
-        fprintf(stderr, "Registering `%s' which already exists\n", info->name);
         abort();
     }
 
diff --git a/vl.c b/vl.c
index 112b0e0..5a3f425 100644
--- a/vl.c
+++ b/vl.c
@@ -2299,8 +2299,6 @@  int main(int argc, char **argv, char **envp)
 #endif
     }
 
-    module_call_init(MODULE_INIT_QOM);
-
     runstate_init();
 
     init_clocks();
@@ -3381,10 +3379,6 @@  int main(int argc, char **argv, char **envp)
     }
     configure_icount(icount_option);
 
-    if (net_init_clients() < 0) {
-        exit(1);
-    }
-
     /* init the bluetooth world */
     if (foreach_device_config(DEV_BT, bt_parse))
         exit(1);
@@ -3474,6 +3468,8 @@  int main(int argc, char **argv, char **envp)
     if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
         exit(1);
 
+    module_call_init(MODULE_INIT_QOM);
+
     /* must be after qdev registration but before machine init */
     if (vga_model) {
         select_vgahw(vga_model);
@@ -3514,9 +3510,16 @@  int main(int argc, char **argv, char **envp)
             exit(1);
     }
 
+    if (net_init_clients() < 0) {
+printf("%s: net_init_clients failed\n", __func__);
+        exit(1);
+    }
+
     /* init generic devices */
-    if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, 1) != 0)
+    if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, 1) != 0) {
+printf("%s: device_init_func failed\n", __func__);
         exit(1);
+    }
 
     net_check_clients();