Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
dccbe6fb
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
dccbe6fb
编写于
9月 08, 2010
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote branch 'mst/for_anthony' into staging
上级
630c2689
a697a334
变更
17
显示空白变更内容
内联
并排
Showing
17 changed file
with
287 addition
and
46 deletion
+287
-46
hw/e1000.c
hw/e1000.c
+8
-3
hw/s390-virtio-bus.c
hw/s390-virtio-bus.c
+7
-1
hw/s390-virtio-bus.h
hw/s390-virtio-bus.h
+1
-0
hw/syborg_virtio.c
hw/syborg_virtio.c
+7
-1
hw/vhost_net.c
hw/vhost_net.c
+23
-1
hw/virtio-net.c
hw/virtio-net.c
+105
-24
hw/virtio-net.h
hw/virtio-net.h
+14
-0
hw/virtio-pci.c
hw/virtio-pci.c
+7
-1
hw/virtio.h
hw/virtio.h
+3
-1
net/tap-aix.c
net/tap-aix.c
+9
-0
net/tap-bsd.c
net/tap-bsd.c
+9
-0
net/tap-linux.c
net/tap-linux.c
+29
-0
net/tap-linux.h
net/tap-linux.h
+8
-0
net/tap-solaris.c
net/tap-solaris.c
+9
-0
net/tap-win32.c
net/tap-win32.c
+9
-0
net/tap.c
net/tap.c
+35
-14
net/tap.h
net/tap.h
+4
-0
未找到文件。
hw/e1000.c
浏览文件 @
dccbe6fb
...
...
@@ -345,7 +345,7 @@ is_vlan_txd(uint32_t txd_lower)
/* FCS aka Ethernet CRC-32. We don't get it from backends and can't
* fill it in, just pad descriptor length by 4 bytes unless guest
* told us to trip it off the packet. */
* told us to
s
trip it off the packet. */
static
inline
int
fcs_len
(
E1000State
*
s
)
{
...
...
@@ -690,9 +690,14 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
s
->
mac_reg
[
GPRC
]
++
;
s
->
mac_reg
[
TPR
]
++
;
n
=
s
->
mac_reg
[
TORL
];
if
((
s
->
mac_reg
[
TORL
]
+=
size
)
<
n
)
/* TOR - Total Octets Received:
* This register includes bytes received in a packet from the <Destination
* Address> field through the <CRC> field, inclusively.
*/
n
=
s
->
mac_reg
[
TORL
]
+
size
+
/* Always include FCS length. */
4
;
if
(
n
<
s
->
mac_reg
[
TORL
])
s
->
mac_reg
[
TORH
]
++
;
s
->
mac_reg
[
TORL
]
=
n
;
n
=
E1000_ICS_RXT0
;
if
((
rdt
=
s
->
mac_reg
[
RDT
])
<
s
->
mac_reg
[
RDH
])
...
...
hw/s390-virtio-bus.c
浏览文件 @
dccbe6fb
...
...
@@ -27,6 +27,7 @@
#include "elf.h"
#include "hw/virtio.h"
#include "hw/virtio-serial.h"
#include "hw/virtio-net.h"
#include "hw/sysbus.h"
#include "kvm.h"
...
...
@@ -110,7 +111,7 @@ static int s390_virtio_net_init(VirtIOS390Device *dev)
{
VirtIODevice
*
vdev
;
vdev
=
virtio_net_init
((
DeviceState
*
)
dev
,
&
dev
->
nic
);
vdev
=
virtio_net_init
((
DeviceState
*
)
dev
,
&
dev
->
nic
,
&
dev
->
net
);
if
(
!
vdev
)
{
return
-
1
;
}
...
...
@@ -327,6 +328,11 @@ static VirtIOS390DeviceInfo s390_virtio_net = {
.
qdev
.
size
=
sizeof
(
VirtIOS390Device
),
.
qdev
.
props
=
(
Property
[])
{
DEFINE_NIC_PROPERTIES
(
VirtIOS390Device
,
nic
),
DEFINE_PROP_UINT32
(
"x-txtimer"
,
VirtIOS390Device
,
net
.
txtimer
,
TX_TIMER_INTERVAL
),
DEFINE_PROP_INT32
(
"x-txburst"
,
VirtIOS390Device
,
net
.
txburst
,
TX_BURST
),
DEFINE_PROP_STRING
(
"tx"
,
VirtIOS390Device
,
net
.
tx
),
DEFINE_PROP_END_OF_LIST
(),
},
};
...
...
hw/s390-virtio-bus.h
浏览文件 @
dccbe6fb
...
...
@@ -43,6 +43,7 @@ typedef struct VirtIOS390Device {
uint32_t
host_features
;
/* Max. number of ports we can have for a the virtio-serial device */
uint32_t
max_virtserial_ports
;
virtio_net_conf
net
;
}
VirtIOS390Device
;
typedef
struct
VirtIOS390Bus
{
...
...
hw/syborg_virtio.c
浏览文件 @
dccbe6fb
...
...
@@ -68,6 +68,7 @@ typedef struct {
uint32_t
id
;
NICConf
nic
;
uint32_t
host_features
;
virtio_net_conf
net
;
}
SyborgVirtIOProxy
;
static
uint32_t
syborg_virtio_readl
(
void
*
opaque
,
target_phys_addr_t
offset
)
...
...
@@ -284,7 +285,7 @@ static int syborg_virtio_net_init(SysBusDevice *dev)
VirtIODevice
*
vdev
;
SyborgVirtIOProxy
*
proxy
=
FROM_SYSBUS
(
SyborgVirtIOProxy
,
dev
);
vdev
=
virtio_net_init
(
&
dev
->
qdev
,
&
proxy
->
nic
);
vdev
=
virtio_net_init
(
&
dev
->
qdev
,
&
proxy
->
nic
,
&
proxy
->
net
);
return
syborg_virtio_init
(
proxy
,
vdev
);
}
...
...
@@ -295,6 +296,11 @@ static SysBusDeviceInfo syborg_virtio_net_info = {
.
qdev
.
props
=
(
Property
[])
{
DEFINE_NIC_PROPERTIES
(
SyborgVirtIOProxy
,
nic
),
DEFINE_VIRTIO_NET_FEATURES
(
SyborgVirtIOProxy
,
host_features
),
DEFINE_PROP_UINT32
(
"x-txtimer"
,
SyborgVirtIOProxy
,
net
.
txtimer
,
TX_TIMER_INTERVAL
),
DEFINE_PROP_INT32
(
"x-txburst"
,
SyborgVirtIOProxy
,
net
.
txburst
,
TX_BURST
),
DEFINE_PROP_STRING
(
"tx"
,
SyborgVirtIOProxy
,
net
.
tx
),
DEFINE_PROP_END_OF_LIST
(),
}
};
...
...
hw/vhost_net.c
浏览文件 @
dccbe6fb
...
...
@@ -50,7 +50,9 @@ unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
if
(
!
(
net
->
dev
.
features
&
(
1
<<
VIRTIO_RING_F_INDIRECT_DESC
)))
{
features
&=
~
(
1
<<
VIRTIO_RING_F_INDIRECT_DESC
);
}
if
(
!
(
net
->
dev
.
features
&
(
1
<<
VIRTIO_NET_F_MRG_RXBUF
)))
{
features
&=
~
(
1
<<
VIRTIO_NET_F_MRG_RXBUF
);
}
return
features
;
}
...
...
@@ -63,6 +65,9 @@ void vhost_net_ack_features(struct vhost_net *net, unsigned features)
if
(
features
&
(
1
<<
VIRTIO_RING_F_INDIRECT_DESC
))
{
net
->
dev
.
acked_features
|=
(
1
<<
VIRTIO_RING_F_INDIRECT_DESC
);
}
if
(
features
&
(
1
<<
VIRTIO_NET_F_MRG_RXBUF
))
{
net
->
dev
.
acked_features
|=
(
1
<<
VIRTIO_NET_F_MRG_RXBUF
);
}
}
static
int
vhost_net_get_fd
(
VLANClientState
*
backend
)
...
...
@@ -97,6 +102,10 @@ struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd)
if
(
r
<
0
)
{
goto
fail
;
}
if
(
!
tap_has_vnet_hdr_len
(
backend
,
sizeof
(
struct
virtio_net_hdr_mrg_rxbuf
)))
{
net
->
dev
.
features
&=
~
(
1
<<
VIRTIO_NET_F_MRG_RXBUF
);
}
if
(
~
net
->
dev
.
features
&
net
->
dev
.
backend_features
)
{
fprintf
(
stderr
,
"vhost lacks feature mask %"
PRIu64
" for backend
\n
"
,
(
uint64_t
)(
~
net
->
dev
.
features
&
net
->
dev
.
backend_features
));
...
...
@@ -117,6 +126,10 @@ int vhost_net_start(struct vhost_net *net,
{
struct
vhost_vring_file
file
=
{
};
int
r
;
if
(
net
->
dev
.
acked_features
&
(
1
<<
VIRTIO_NET_F_MRG_RXBUF
))
{
tap_set_vnet_hdr_len
(
net
->
vc
,
sizeof
(
struct
virtio_net_hdr_mrg_rxbuf
));
}
net
->
dev
.
nvqs
=
2
;
net
->
dev
.
vqs
=
net
->
vqs
;
...
...
@@ -144,6 +157,9 @@ fail:
}
net
->
vc
->
info
->
poll
(
net
->
vc
,
true
);
vhost_dev_stop
(
&
net
->
dev
,
dev
);
if
(
net
->
dev
.
acked_features
&
(
1
<<
VIRTIO_NET_F_MRG_RXBUF
))
{
tap_set_vnet_hdr_len
(
net
->
vc
,
sizeof
(
struct
virtio_net_hdr
));
}
return
r
;
}
...
...
@@ -158,11 +174,17 @@ void vhost_net_stop(struct vhost_net *net,
}
net
->
vc
->
info
->
poll
(
net
->
vc
,
true
);
vhost_dev_stop
(
&
net
->
dev
,
dev
);
if
(
net
->
dev
.
acked_features
&
(
1
<<
VIRTIO_NET_F_MRG_RXBUF
))
{
tap_set_vnet_hdr_len
(
net
->
vc
,
sizeof
(
struct
virtio_net_hdr
));
}
}
void
vhost_net_cleanup
(
struct
vhost_net
*
net
)
{
vhost_dev_cleanup
(
&
net
->
dev
);
if
(
net
->
dev
.
acked_features
&
(
1
<<
VIRTIO_NET_F_MRG_RXBUF
))
{
tap_set_vnet_hdr_len
(
net
->
vc
,
sizeof
(
struct
virtio_net_hdr
));
}
qemu_free
(
net
);
}
#else
...
...
hw/virtio-net.c
浏览文件 @
dccbe6fb
...
...
@@ -36,7 +36,10 @@ typedef struct VirtIONet
VirtQueue
*
ctrl_vq
;
NICState
*
nic
;
QEMUTimer
*
tx_timer
;
int
tx_timer_active
;
QEMUBH
*
tx_bh
;
uint32_t
tx_timeout
;
int32_t
tx_burst
;
int
tx_waiting
;
uint32_t
has_vnet_hdr
;
uint8_t
has_ufo
;
struct
{
...
...
@@ -619,7 +622,7 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_
return
size
;
}
static
void
virtio_net_flush_tx
(
VirtIONet
*
n
,
VirtQueue
*
vq
);
static
int32_t
virtio_net_flush_tx
(
VirtIONet
*
n
,
VirtQueue
*
vq
);
static
void
virtio_net_tx_complete
(
VLANClientState
*
nc
,
ssize_t
len
)
{
...
...
@@ -635,16 +638,18 @@ static void virtio_net_tx_complete(VLANClientState *nc, ssize_t len)
}
/* TX */
static
void
virtio_net_flush_tx
(
VirtIONet
*
n
,
VirtQueue
*
vq
)
static
int32_t
virtio_net_flush_tx
(
VirtIONet
*
n
,
VirtQueue
*
vq
)
{
VirtQueueElement
elem
;
int32_t
num_packets
=
0
;
if
(
!
(
n
->
vdev
.
status
&
VIRTIO_CONFIG_S_DRIVER_OK
))
return
;
if
(
!
(
n
->
vdev
.
status
&
VIRTIO_CONFIG_S_DRIVER_OK
))
{
return
num_packets
;
}
if
(
n
->
async_tx
.
elem
.
out_num
)
{
virtio_queue_set_notification
(
n
->
tx_vq
,
0
);
return
;
return
num_packets
;
}
while
(
virtqueue_pop
(
vq
,
&
elem
))
{
...
...
@@ -681,38 +686,55 @@ static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
virtio_queue_set_notification
(
n
->
tx_vq
,
0
);
n
->
async_tx
.
elem
=
elem
;
n
->
async_tx
.
len
=
len
;
return
;
return
-
EBUSY
;
}
len
+=
ret
;
virtqueue_push
(
vq
,
&
elem
,
len
);
virtio_notify
(
&
n
->
vdev
,
vq
);
if
(
++
num_packets
>=
n
->
tx_burst
)
{
break
;
}
}
return
num_packets
;
}
static
void
virtio_net_handle_tx
(
VirtIODevice
*
vdev
,
VirtQueue
*
vq
)
static
void
virtio_net_handle_tx
_timer
(
VirtIODevice
*
vdev
,
VirtQueue
*
vq
)
{
VirtIONet
*
n
=
to_virtio_net
(
vdev
);
if
(
n
->
tx_
timer_active
)
{
if
(
n
->
tx_
waiting
)
{
virtio_queue_set_notification
(
vq
,
1
);
qemu_del_timer
(
n
->
tx_timer
);
n
->
tx_
timer_active
=
0
;
n
->
tx_
waiting
=
0
;
virtio_net_flush_tx
(
n
,
vq
);
}
else
{
qemu_mod_timer
(
n
->
tx_timer
,
qemu_get_clock
(
vm_clock
)
+
TX_TIMER_INTERVAL
);
n
->
tx_
timer_active
=
1
;
qemu_get_clock
(
vm_clock
)
+
n
->
tx_timeout
);
n
->
tx_
waiting
=
1
;
virtio_queue_set_notification
(
vq
,
0
);
}
}
static
void
virtio_net_handle_tx_bh
(
VirtIODevice
*
vdev
,
VirtQueue
*
vq
)
{
VirtIONet
*
n
=
to_virtio_net
(
vdev
);
if
(
unlikely
(
n
->
tx_waiting
))
{
return
;
}
virtio_queue_set_notification
(
vq
,
0
);
qemu_bh_schedule
(
n
->
tx_bh
);
n
->
tx_waiting
=
1
;
}
static
void
virtio_net_tx_timer
(
void
*
opaque
)
{
VirtIONet
*
n
=
opaque
;
n
->
tx_
timer_active
=
0
;
n
->
tx_
waiting
=
0
;
/* Just in case the driver is not ready on more */
if
(
!
(
n
->
vdev
.
status
&
VIRTIO_CONFIG_S_DRIVER_OK
))
...
...
@@ -722,6 +744,41 @@ static void virtio_net_tx_timer(void *opaque)
virtio_net_flush_tx
(
n
,
n
->
tx_vq
);
}
static
void
virtio_net_tx_bh
(
void
*
opaque
)
{
VirtIONet
*
n
=
opaque
;
int32_t
ret
;
n
->
tx_waiting
=
0
;
/* Just in case the driver is not ready on more */
if
(
unlikely
(
!
(
n
->
vdev
.
status
&
VIRTIO_CONFIG_S_DRIVER_OK
)))
return
;
ret
=
virtio_net_flush_tx
(
n
,
n
->
tx_vq
);
if
(
ret
==
-
EBUSY
)
{
return
;
/* Notification re-enable handled by tx_complete */
}
/* If we flush a full burst of packets, assume there are
* more coming and immediately reschedule */
if
(
ret
>=
n
->
tx_burst
)
{
qemu_bh_schedule
(
n
->
tx_bh
);
n
->
tx_waiting
=
1
;
return
;
}
/* If less than a full burst, re-enable notification and flush
* anything that may have come in while we weren't looking. If
* we find something, assume the guest is still active and reschedule */
virtio_queue_set_notification
(
n
->
tx_vq
,
1
);
if
(
virtio_net_flush_tx
(
n
,
n
->
tx_vq
)
>
0
)
{
virtio_queue_set_notification
(
n
->
tx_vq
,
0
);
qemu_bh_schedule
(
n
->
tx_bh
);
n
->
tx_waiting
=
1
;
}
}
static
void
virtio_net_save
(
QEMUFile
*
f
,
void
*
opaque
)
{
VirtIONet
*
n
=
opaque
;
...
...
@@ -735,7 +792,7 @@ static void virtio_net_save(QEMUFile *f, void *opaque)
virtio_save
(
&
n
->
vdev
,
f
);
qemu_put_buffer
(
f
,
n
->
mac
,
ETH_ALEN
);
qemu_put_be32
(
f
,
n
->
tx_
timer_active
);
qemu_put_be32
(
f
,
n
->
tx_
waiting
);
qemu_put_be32
(
f
,
n
->
mergeable_rx_bufs
);
qemu_put_be16
(
f
,
n
->
status
);
qemu_put_byte
(
f
,
n
->
promisc
);
...
...
@@ -764,7 +821,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
virtio_load
(
&
n
->
vdev
,
f
);
qemu_get_buffer
(
f
,
n
->
mac
,
ETH_ALEN
);
n
->
tx_
timer_active
=
qemu_get_be32
(
f
);
n
->
tx_
waiting
=
qemu_get_be32
(
f
);
n
->
mergeable_rx_bufs
=
qemu_get_be32
(
f
);
if
(
version_id
>=
3
)
...
...
@@ -840,9 +897,13 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
}
n
->
mac_table
.
first_multi
=
i
;
if
(
n
->
tx_timer_active
)
{
if
(
n
->
tx_waiting
)
{
if
(
n
->
tx_timer
)
{
qemu_mod_timer
(
n
->
tx_timer
,
qemu_get_clock
(
vm_clock
)
+
TX_TIMER_INTERVAL
);
qemu_get_clock
(
vm_clock
)
+
n
->
tx_timeout
);
}
else
{
qemu_bh_schedule
(
n
->
tx_bh
);
}
}
return
0
;
}
...
...
@@ -903,7 +964,8 @@ static void virtio_net_vmstate_change(void *opaque, int running, int reason)
virtio_net_set_status
(
&
n
->
vdev
,
n
->
vdev
.
status
&
status
);
}
VirtIODevice
*
virtio_net_init
(
DeviceState
*
dev
,
NICConf
*
conf
)
VirtIODevice
*
virtio_net_init
(
DeviceState
*
dev
,
NICConf
*
conf
,
virtio_net_conf
*
net
)
{
VirtIONet
*
n
;
...
...
@@ -919,7 +981,22 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf)
n
->
vdev
.
reset
=
virtio_net_reset
;
n
->
vdev
.
set_status
=
virtio_net_set_status
;
n
->
rx_vq
=
virtio_add_queue
(
&
n
->
vdev
,
256
,
virtio_net_handle_rx
);
n
->
tx_vq
=
virtio_add_queue
(
&
n
->
vdev
,
256
,
virtio_net_handle_tx
);
if
(
net
->
tx
&&
strcmp
(
net
->
tx
,
"timer"
)
&&
strcmp
(
net
->
tx
,
"bh"
))
{
fprintf
(
stderr
,
"virtio-net: "
"Unknown option tx=%s, valid options:
\"
timer
\"
\"
bh
\"\n
"
,
net
->
tx
);
fprintf
(
stderr
,
"Defaulting to
\"
bh
\"\n
"
);
}
if
(
net
->
tx
&&
!
strcmp
(
net
->
tx
,
"timer"
))
{
n
->
tx_vq
=
virtio_add_queue
(
&
n
->
vdev
,
256
,
virtio_net_handle_tx_timer
);
n
->
tx_timer
=
qemu_new_timer
(
vm_clock
,
virtio_net_tx_timer
,
n
);
n
->
tx_timeout
=
net
->
txtimer
;
}
else
{
n
->
tx_vq
=
virtio_add_queue
(
&
n
->
vdev
,
256
,
virtio_net_handle_tx_bh
);
n
->
tx_bh
=
qemu_bh_new
(
virtio_net_tx_bh
,
n
);
}
n
->
ctrl_vq
=
virtio_add_queue
(
&
n
->
vdev
,
64
,
virtio_net_handle_ctrl
);
qemu_macaddr_default_if_unset
(
&
conf
->
macaddr
);
memcpy
(
&
n
->
mac
[
0
],
&
conf
->
macaddr
,
sizeof
(
n
->
mac
));
...
...
@@ -929,8 +1006,8 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf)
qemu_format_nic_info_str
(
&
n
->
nic
->
nc
,
conf
->
macaddr
.
a
);
n
->
tx_
timer
=
qemu_new_timer
(
vm_clock
,
virtio_net_tx_timer
,
n
)
;
n
->
tx_
timer_active
=
0
;
n
->
tx_
waiting
=
0
;
n
->
tx_
burst
=
net
->
txburst
;
n
->
mergeable_rx_bufs
=
0
;
n
->
promisc
=
1
;
/* for compatibility */
...
...
@@ -962,8 +1039,12 @@ void virtio_net_exit(VirtIODevice *vdev)
qemu_free
(
n
->
mac_table
.
macs
);
qemu_free
(
n
->
vlans
);
if
(
n
->
tx_timer
)
{
qemu_del_timer
(
n
->
tx_timer
);
qemu_free_timer
(
n
->
tx_timer
);
}
else
{
qemu_bh_delete
(
n
->
tx_bh
);
}
virtio_cleanup
(
&
n
->
vdev
);
qemu_del_vlan_client
(
&
n
->
nic
->
nc
);
...
...
hw/virtio-net.h
浏览文件 @
dccbe6fb
...
...
@@ -49,6 +49,20 @@
#define TX_TIMER_INTERVAL 150000
/* 150 us */
/* Limit the number of packets that can be sent via a single flush
* of the TX queue. This gives us a guaranteed exit condition and
* ensures fairness in the io path. 256 conveniently matches the
* length of the TX queue and shows a good balance of performance
* and latency. */
#define TX_BURST 256
typedef
struct
virtio_net_conf
{
uint32_t
txtimer
;
int32_t
txburst
;
char
*
tx
;
}
virtio_net_conf
;
/* Maximum packet size we can receive from tap device: header + 64k */
#define VIRTIO_NET_MAX_BUFSIZE (sizeof(struct virtio_net_hdr) + (64 << 10))
...
...
hw/virtio-pci.c
浏览文件 @
dccbe6fb
...
...
@@ -107,6 +107,7 @@ typedef struct {
#endif
/* Max. number of ports we can have for a the virtio-serial device */
uint32_t
max_virtserial_ports
;
virtio_net_conf
net
;
}
VirtIOPCIProxy
;
/* virtio device */
...
...
@@ -613,7 +614,7 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
VirtIOPCIProxy
*
proxy
=
DO_UPCAST
(
VirtIOPCIProxy
,
pci_dev
,
pci_dev
);
VirtIODevice
*
vdev
;
vdev
=
virtio_net_init
(
&
pci_dev
->
qdev
,
&
proxy
->
nic
);
vdev
=
virtio_net_init
(
&
pci_dev
->
qdev
,
&
proxy
->
nic
,
&
proxy
->
net
);
vdev
->
nvectors
=
proxy
->
nvectors
;
virtio_init_pci
(
proxy
,
vdev
,
...
...
@@ -690,6 +691,11 @@ static PCIDeviceInfo virtio_info[] = {
DEFINE_PROP_UINT32
(
"vectors"
,
VirtIOPCIProxy
,
nvectors
,
3
),
DEFINE_VIRTIO_NET_FEATURES
(
VirtIOPCIProxy
,
host_features
),
DEFINE_NIC_PROPERTIES
(
VirtIOPCIProxy
,
nic
),
DEFINE_PROP_UINT32
(
"x-txtimer"
,
VirtIOPCIProxy
,
net
.
txtimer
,
TX_TIMER_INTERVAL
),
DEFINE_PROP_INT32
(
"x-txburst"
,
VirtIOPCIProxy
,
net
.
txburst
,
TX_BURST
),
DEFINE_PROP_STRING
(
"tx"
,
VirtIOPCIProxy
,
net
.
tx
),
DEFINE_PROP_END_OF_LIST
(),
},
.
qdev
.
reset
=
virtio_pci_reset
,
...
...
hw/virtio.h
浏览文件 @
dccbe6fb
...
...
@@ -185,7 +185,9 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
/* Base devices. */
VirtIODevice
*
virtio_blk_init
(
DeviceState
*
dev
,
BlockConf
*
conf
);
VirtIODevice
*
virtio_net_init
(
DeviceState
*
dev
,
NICConf
*
conf
);
struct
virtio_net_conf
;
VirtIODevice
*
virtio_net_init
(
DeviceState
*
dev
,
NICConf
*
conf
,
struct
virtio_net_conf
*
net
);
VirtIODevice
*
virtio_serial_init
(
DeviceState
*
dev
,
uint32_t
max_nr_ports
);
VirtIODevice
*
virtio_balloon_init
(
DeviceState
*
dev
);
#ifdef CONFIG_LINUX
...
...
net/tap-aix.c
浏览文件 @
dccbe6fb
...
...
@@ -46,6 +46,15 @@ int tap_probe_has_ufo(int fd)
return
0
;
}
int
tap_probe_vnet_hdr_len
(
int
fd
,
int
len
)
{
return
0
;
}
void
tap_fd_set_vnet_hdr_len
(
int
fd
,
int
len
)
{
}
void
tap_fd_set_offload
(
int
fd
,
int
csum
,
int
tso4
,
int
tso6
,
int
ecn
,
int
ufo
)
{
...
...
net/tap-bsd.c
浏览文件 @
dccbe6fb
...
...
@@ -116,6 +116,15 @@ int tap_probe_has_ufo(int fd)
return
0
;
}
int
tap_probe_vnet_hdr_len
(
int
fd
,
int
len
)
{
return
0
;
}
void
tap_fd_set_vnet_hdr_len
(
int
fd
,
int
len
)
{
}
void
tap_fd_set_offload
(
int
fd
,
int
csum
,
int
tso4
,
int
tso6
,
int
ecn
,
int
ufo
)
{
...
...
net/tap-linux.c
浏览文件 @
dccbe6fb
...
...
@@ -129,6 +129,35 @@ int tap_probe_has_ufo(int fd)
return
1
;
}
/* Verify that we can assign given length */
int
tap_probe_vnet_hdr_len
(
int
fd
,
int
len
)
{
int
orig
;
if
(
ioctl
(
fd
,
TUNGETVNETHDRSZ
,
&
orig
)
==
-
1
)
{
return
0
;
}
if
(
ioctl
(
fd
,
TUNSETVNETHDRSZ
,
&
len
)
==
-
1
)
{
return
0
;
}
/* Restore original length: we can't handle failure. */
if
(
ioctl
(
fd
,
TUNSETVNETHDRSZ
,
&
orig
)
==
-
1
)
{
fprintf
(
stderr
,
"TUNGETVNETHDRSZ ioctl() failed: %s. Exiting.
\n
"
,
strerror
(
errno
));
assert
(
0
);
return
-
errno
;
}
return
1
;
}
void
tap_fd_set_vnet_hdr_len
(
int
fd
,
int
len
)
{
if
(
ioctl
(
fd
,
TUNSETVNETHDRSZ
,
&
len
)
==
-
1
)
{
fprintf
(
stderr
,
"TUNSETVNETHDRSZ ioctl() failed: %s. Exiting.
\n
"
,
strerror
(
errno
));
assert
(
0
);
}
}
void
tap_fd_set_offload
(
int
fd
,
int
csum
,
int
tso4
,
int
tso6
,
int
ecn
,
int
ufo
)
{
...
...
net/tap-linux.h
浏览文件 @
dccbe6fb
...
...
@@ -27,6 +27,8 @@
#define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
#define TUNGETIFF _IOR('T', 210, unsigned int)
#define TUNSETSNDBUF _IOW('T', 212, int)
#define TUNGETVNETHDRSZ _IOR('T', 215, int)
#define TUNSETVNETHDRSZ _IOW('T', 216, int)
#endif
...
...
@@ -52,4 +54,10 @@ struct virtio_net_hdr
uint16_t
csum_offset
;
};
struct
virtio_net_hdr_mrg_rxbuf
{
struct
virtio_net_hdr
hdr
;
uint16_t
num_buffers
;
/* Number of merged rx buffers */
};
#endif
/* QEMU_TAP_H */
net/tap-solaris.c
浏览文件 @
dccbe6fb
...
...
@@ -212,6 +212,15 @@ int tap_probe_has_ufo(int fd)
return
0
;
}
int
tap_probe_vnet_hdr_len
(
int
fd
,
int
len
)
{
return
0
;
}
void
tap_fd_set_vnet_hdr_len
(
int
fd
,
int
len
)
{
}
void
tap_fd_set_offload
(
int
fd
,
int
csum
,
int
tso4
,
int
tso6
,
int
ecn
,
int
ufo
)
{
...
...
net/tap-win32.c
浏览文件 @
dccbe6fb
...
...
@@ -728,6 +728,15 @@ int tap_has_vnet_hdr(VLANClientState *vc)
return
0
;
}
int
tap_probe_vnet_hdr_len
(
int
fd
,
int
len
)
{
return
0
;
}
void
tap_fd_set_vnet_hdr_len
(
int
fd
,
int
len
)
{
}
void
tap_using_vnet_hdr
(
VLANClientState
*
vc
,
int
using_vnet_hdr
)
{
}
...
...
net/tap.c
浏览文件 @
dccbe6fb
...
...
@@ -57,10 +57,10 @@ typedef struct TAPState {
uint8_t
buf
[
TAP_BUFSIZE
];
unsigned
int
read_poll
:
1
;
unsigned
int
write_poll
:
1
;
unsigned
int
has_vnet_hdr
:
1
;
unsigned
int
using_vnet_hdr
:
1
;
unsigned
int
has_ufo
:
1
;
VHostNetState
*
vhost_net
;
unsigned
host_vnet_hdr_len
;
}
TAPState
;
static
int
launch_script
(
const
char
*
setup_script
,
const
char
*
ifname
,
int
fd
);
...
...
@@ -121,11 +121,11 @@ static ssize_t tap_receive_iov(VLANClientState *nc, const struct iovec *iov,
TAPState
*
s
=
DO_UPCAST
(
TAPState
,
nc
,
nc
);
const
struct
iovec
*
iovp
=
iov
;
struct
iovec
iov_copy
[
iovcnt
+
1
];
struct
virtio_net_hdr
hdr
=
{
0
,
};
struct
virtio_net_hdr
_mrg_rxbuf
hdr
=
{
};
if
(
s
->
h
as_vnet_hdr
&&
!
s
->
using_vnet_hdr
)
{
if
(
s
->
h
ost_vnet_hdr_len
&&
!
s
->
using_vnet_hdr
)
{
iov_copy
[
0
].
iov_base
=
&
hdr
;
iov_copy
[
0
].
iov_len
=
s
izeof
(
hdr
)
;
iov_copy
[
0
].
iov_len
=
s
->
host_vnet_hdr_len
;
memcpy
(
&
iov_copy
[
1
],
iov
,
iovcnt
*
sizeof
(
*
iov
));
iovp
=
iov_copy
;
iovcnt
++
;
...
...
@@ -139,11 +139,11 @@ static ssize_t tap_receive_raw(VLANClientState *nc, const uint8_t *buf, size_t s
TAPState
*
s
=
DO_UPCAST
(
TAPState
,
nc
,
nc
);
struct
iovec
iov
[
2
];
int
iovcnt
=
0
;
struct
virtio_net_hdr
hdr
=
{
0
,
};
struct
virtio_net_hdr
_mrg_rxbuf
hdr
=
{
};
if
(
s
->
h
as_vnet_hdr
)
{
if
(
s
->
h
ost_vnet_hdr_len
)
{
iov
[
iovcnt
].
iov_base
=
&
hdr
;
iov
[
iovcnt
].
iov_len
=
s
izeof
(
hdr
)
;
iov
[
iovcnt
].
iov_len
=
s
->
host_vnet_hdr_len
;
iovcnt
++
;
}
...
...
@@ -159,7 +159,7 @@ static ssize_t tap_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
TAPState
*
s
=
DO_UPCAST
(
TAPState
,
nc
,
nc
);
struct
iovec
iov
[
1
];
if
(
s
->
h
as_vnet_hdr
&&
!
s
->
using_vnet_hdr
)
{
if
(
s
->
h
ost_vnet_hdr_len
&&
!
s
->
using_vnet_hdr
)
{
return
tap_receive_raw
(
nc
,
buf
,
size
);
}
...
...
@@ -202,9 +202,9 @@ static void tap_send(void *opaque)
break
;
}
if
(
s
->
h
as_vnet_hdr
&&
!
s
->
using_vnet_hdr
)
{
buf
+=
s
izeof
(
struct
virtio_net_hdr
)
;
size
-=
s
izeof
(
struct
virtio_net_hdr
)
;
if
(
s
->
h
ost_vnet_hdr_len
&&
!
s
->
using_vnet_hdr
)
{
buf
+=
s
->
host_vnet_hdr_len
;
size
-=
s
->
host_vnet_hdr_len
;
}
size
=
qemu_send_packet_async
(
&
s
->
nc
,
buf
,
size
,
tap_send_completed
);
...
...
@@ -229,7 +229,28 @@ int tap_has_vnet_hdr(VLANClientState *nc)
assert
(
nc
->
info
->
type
==
NET_CLIENT_TYPE_TAP
);
return
s
->
has_vnet_hdr
;
return
!!
s
->
host_vnet_hdr_len
;
}
int
tap_has_vnet_hdr_len
(
VLANClientState
*
nc
,
int
len
)
{
TAPState
*
s
=
DO_UPCAST
(
TAPState
,
nc
,
nc
);
assert
(
nc
->
info
->
type
==
NET_CLIENT_TYPE_TAP
);
return
tap_probe_vnet_hdr_len
(
s
->
fd
,
len
);
}
void
tap_set_vnet_hdr_len
(
VLANClientState
*
nc
,
int
len
)
{
TAPState
*
s
=
DO_UPCAST
(
TAPState
,
nc
,
nc
);
assert
(
nc
->
info
->
type
==
NET_CLIENT_TYPE_TAP
);
assert
(
len
==
sizeof
(
struct
virtio_net_hdr_mrg_rxbuf
)
||
len
==
sizeof
(
struct
virtio_net_hdr
));
tap_fd_set_vnet_hdr_len
(
s
->
fd
,
len
);
s
->
host_vnet_hdr_len
=
len
;
}
void
tap_using_vnet_hdr
(
VLANClientState
*
nc
,
int
using_vnet_hdr
)
...
...
@@ -239,7 +260,7 @@ void tap_using_vnet_hdr(VLANClientState *nc, int using_vnet_hdr)
using_vnet_hdr
=
using_vnet_hdr
!=
0
;
assert
(
nc
->
info
->
type
==
NET_CLIENT_TYPE_TAP
);
assert
(
s
->
has_vnet_hdr
==
using_vnet_hdr
);
assert
(
!!
s
->
host_vnet_hdr_len
==
using_vnet_hdr
);
s
->
using_vnet_hdr
=
using_vnet_hdr
;
}
...
...
@@ -310,7 +331,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
s
=
DO_UPCAST
(
TAPState
,
nc
,
nc
);
s
->
fd
=
fd
;
s
->
h
as_vnet_hdr
=
vnet_hdr
!=
0
;
s
->
h
ost_vnet_hdr_len
=
vnet_hdr
?
sizeof
(
struct
virtio_net_hdr
)
:
0
;
s
->
using_vnet_hdr
=
0
;
s
->
has_ufo
=
tap_probe_has_ufo
(
s
->
fd
);
tap_set_offload
(
&
s
->
nc
,
0
,
0
,
0
,
0
,
0
);
...
...
net/tap.h
浏览文件 @
dccbe6fb
...
...
@@ -40,13 +40,17 @@ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen);
int
tap_has_ufo
(
VLANClientState
*
vc
);
int
tap_has_vnet_hdr
(
VLANClientState
*
vc
);
int
tap_has_vnet_hdr_len
(
VLANClientState
*
vc
,
int
len
);
void
tap_using_vnet_hdr
(
VLANClientState
*
vc
,
int
using_vnet_hdr
);
void
tap_set_offload
(
VLANClientState
*
vc
,
int
csum
,
int
tso4
,
int
tso6
,
int
ecn
,
int
ufo
);
void
tap_set_vnet_hdr_len
(
VLANClientState
*
vc
,
int
len
);
int
tap_set_sndbuf
(
int
fd
,
QemuOpts
*
opts
);
int
tap_probe_vnet_hdr
(
int
fd
);
int
tap_probe_vnet_hdr_len
(
int
fd
,
int
len
);
int
tap_probe_has_ufo
(
int
fd
);
void
tap_fd_set_offload
(
int
fd
,
int
csum
,
int
tso4
,
int
tso6
,
int
ecn
,
int
ufo
);
void
tap_fd_set_vnet_hdr_len
(
int
fd
,
int
len
);
int
tap_get_fd
(
VLANClientState
*
vc
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录