@@ -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);
@@ -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);
@@ -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,
@@ -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;
@@ -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;
@@ -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;
@@ -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 */
@@ -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)
@@ -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
@@ -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)
@@ -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 */
@@ -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) {
@@ -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)
@@ -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 */
@@ -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;
@@ -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 */
@@ -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: */
@@ -23,7 +23,7 @@
*/
#include "sysemu.h"
-#include "net.h"
+//#include "net.h"
#include "monitor.h"
#include "console.h"
@@ -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
@@ -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();
}
@@ -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();