Compare commits
33
Commits
v2.4.0-rc3
...
v2.4.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c79ae3615 | ||
|
|
2d697366a1 | ||
|
|
0175409df4 | ||
|
|
e94867ed5f | ||
|
|
74aae7b22b | ||
|
|
2be4f242b5 | ||
|
|
27751aabd1 | ||
|
|
426d0e7b7e | ||
|
|
b7f26e5239 | ||
|
|
060ebfef1a | ||
|
|
260425ab40 | ||
|
|
e95edefbd0 | ||
|
|
8c6dc68f4c | ||
|
|
c69adea462 | ||
|
|
f60c87154a | ||
|
|
6cd387833d | ||
|
|
2a3612ccc1 | ||
|
|
8357946b15 | ||
|
|
4240be4563 | ||
|
|
c6296ea88d | ||
|
|
03247d43c5 | ||
|
|
e1c120a9c5 | ||
|
|
d6812d60e7 | ||
|
|
39b8e7dcaf | ||
|
|
bd80b5963f | ||
|
|
ff90f84e74 | ||
|
|
c99d69694a | ||
|
|
3c8691f568 | ||
|
|
4214a8cb7c | ||
|
|
e72c4fb81d | ||
|
|
91ced51446 | ||
|
|
0e826a061a | ||
|
|
cb48f67ad8 |
No files matched your search
+4
-6
@@ -865,12 +865,6 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA256)) {
|
||||
error_setg(errp,
|
||||
"SHA256 hash support is required for quorum device");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qdict_flatten(options);
|
||||
|
||||
/* count how many different children are present */
|
||||
@@ -1061,6 +1055,10 @@ static BlockDriver bdrv_quorum = {
|
||||
|
||||
static void bdrv_quorum_init(void)
|
||||
{
|
||||
if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA256)) {
|
||||
/* SHA256 hash support is required for quorum device */
|
||||
return;
|
||||
}
|
||||
bdrv_register(&bdrv_quorum);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -173,7 +173,7 @@ void cpu_loop(CPUX86State *env)
|
||||
//target_siginfo_t info;
|
||||
|
||||
for(;;) {
|
||||
trapnr = cpu_x86_exec(env);
|
||||
trapnr = cpu_x86_exec(cs);
|
||||
switch(trapnr) {
|
||||
case 0x80:
|
||||
/* syscall from int $0x80 */
|
||||
|
||||
@@ -1337,7 +1337,6 @@ disabled with --disable-FEATURE, default is enabled if available:
|
||||
vnc-sasl SASL encryption for VNC server
|
||||
vnc-jpeg JPEG lossy compression for VNC server
|
||||
vnc-png PNG compression for VNC server
|
||||
vnc-ws Websockets support for VNC server
|
||||
cocoa Cocoa UI (Mac OS X only)
|
||||
virtfs VirtFS
|
||||
xen xen backend driver support
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@
|
||||
#define PORT_CMD_SPIN_UP (1 << 1) /* Spin up device */
|
||||
#define PORT_CMD_START (1 << 0) /* Enable port DMA engine */
|
||||
|
||||
#define PORT_CMD_ICC_MASK (0xf << 28) /* i/f ICC state mask */
|
||||
#define PORT_CMD_ICC_MASK (0xfU << 28) /* i/f ICC state mask */
|
||||
#define PORT_CMD_ICC_ACTIVE (0x1 << 28) /* Put i/f in active state */
|
||||
#define PORT_CMD_ICC_PARTIAL (0x2 << 28) /* Put i/f in partial state */
|
||||
#define PORT_CMD_ICC_SLUMBER (0x6 << 28) /* Put i/f in slumber state */
|
||||
|
||||
@@ -208,6 +208,33 @@ static void pmac_dma_write(BlockBackend *blk,
|
||||
cb, io);
|
||||
}
|
||||
|
||||
static void pmac_dma_trim(BlockBackend *blk,
|
||||
int64_t offset, int bytes,
|
||||
void (*cb)(void *opaque, int ret), void *opaque)
|
||||
{
|
||||
DBDMA_io *io = opaque;
|
||||
MACIOIDEState *m = io->opaque;
|
||||
IDEState *s = idebus_active_if(&m->bus);
|
||||
dma_addr_t dma_addr, dma_len;
|
||||
void *mem;
|
||||
|
||||
qemu_iovec_destroy(&io->iov);
|
||||
qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1);
|
||||
|
||||
dma_addr = io->addr;
|
||||
dma_len = io->len;
|
||||
mem = dma_memory_map(&address_space_memory, dma_addr, &dma_len,
|
||||
DMA_DIRECTION_TO_DEVICE);
|
||||
|
||||
qemu_iovec_add(&io->iov, mem, io->len);
|
||||
s->io_buffer_size -= io->len;
|
||||
s->io_buffer_index += io->len;
|
||||
io->len = 0;
|
||||
|
||||
m->aiocb = ide_issue_trim(blk, (offset >> 9), &io->iov, (bytes >> 9),
|
||||
cb, io);
|
||||
}
|
||||
|
||||
static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
|
||||
{
|
||||
DBDMA_io *io = opaque;
|
||||
@@ -313,6 +340,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
|
||||
pmac_dma_write(s->blk, offset, io->len, pmac_ide_transfer_cb, io);
|
||||
break;
|
||||
case IDE_DMA_TRIM:
|
||||
pmac_dma_trim(s->blk, offset, io->len, pmac_ide_transfer_cb, io);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
|
||||
PCIIDEState *pci_ide;
|
||||
DriveInfo *di;
|
||||
int i;
|
||||
IDEDevice *idedev;
|
||||
|
||||
pci_ide = PCI_IDE(dev);
|
||||
|
||||
@@ -181,6 +182,12 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
|
||||
blk_detach_dev(blk, ds);
|
||||
}
|
||||
pci_ide->bus[di->bus].ifs[di->unit].blk = NULL;
|
||||
if (!(i % 2)) {
|
||||
idedev = pci_ide->bus[di->bus].master;
|
||||
} else {
|
||||
idedev = pci_ide->bus[di->bus].slave;
|
||||
}
|
||||
idedev->conf.blk = NULL;
|
||||
blk_unref(blk);
|
||||
}
|
||||
}
|
||||
|
||||
+206
-189
@@ -2150,6 +2150,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
|
||||
{
|
||||
DPRINTF("+++ C+ mode offloaded task checksum\n");
|
||||
|
||||
/* Large enough for Ethernet and IP headers? */
|
||||
if (saved_size < ETH_HLEN + sizeof(ip_header)) {
|
||||
goto skip_offload;
|
||||
}
|
||||
|
||||
/* ip packet header */
|
||||
ip_header *ip = NULL;
|
||||
int hlen = 0;
|
||||
@@ -2160,223 +2165,235 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
|
||||
size_t eth_payload_len = 0;
|
||||
|
||||
int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
|
||||
if (proto == ETH_P_IP)
|
||||
if (proto != ETH_P_IP)
|
||||
{
|
||||
DPRINTF("+++ C+ mode has IP packet\n");
|
||||
|
||||
/* not aligned */
|
||||
eth_payload_data = saved_buffer + ETH_HLEN;
|
||||
eth_payload_len = saved_size - ETH_HLEN;
|
||||
|
||||
ip = (ip_header*)eth_payload_data;
|
||||
|
||||
if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
|
||||
DPRINTF("+++ C+ mode packet has bad IP version %d "
|
||||
"expected %d\n", IP_HEADER_VERSION(ip),
|
||||
IP_HEADER_VERSION_4);
|
||||
ip = NULL;
|
||||
} else {
|
||||
hlen = IP_HEADER_LENGTH(ip);
|
||||
ip_protocol = ip->ip_p;
|
||||
ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
|
||||
}
|
||||
goto skip_offload;
|
||||
}
|
||||
|
||||
if (ip)
|
||||
DPRINTF("+++ C+ mode has IP packet\n");
|
||||
|
||||
/* not aligned */
|
||||
eth_payload_data = saved_buffer + ETH_HLEN;
|
||||
eth_payload_len = saved_size - ETH_HLEN;
|
||||
|
||||
ip = (ip_header*)eth_payload_data;
|
||||
|
||||
if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
|
||||
DPRINTF("+++ C+ mode packet has bad IP version %d "
|
||||
"expected %d\n", IP_HEADER_VERSION(ip),
|
||||
IP_HEADER_VERSION_4);
|
||||
goto skip_offload;
|
||||
}
|
||||
|
||||
hlen = IP_HEADER_LENGTH(ip);
|
||||
if (hlen < sizeof(ip_header) || hlen > eth_payload_len) {
|
||||
goto skip_offload;
|
||||
}
|
||||
|
||||
ip_protocol = ip->ip_p;
|
||||
|
||||
ip_data_len = be16_to_cpu(ip->ip_len);
|
||||
if (ip_data_len < hlen || ip_data_len > eth_payload_len) {
|
||||
goto skip_offload;
|
||||
}
|
||||
ip_data_len -= hlen;
|
||||
|
||||
if (txdw0 & CP_TX_IPCS)
|
||||
{
|
||||
if (txdw0 & CP_TX_IPCS)
|
||||
{
|
||||
DPRINTF("+++ C+ mode need IP checksum\n");
|
||||
DPRINTF("+++ C+ mode need IP checksum\n");
|
||||
|
||||
if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */
|
||||
/* bad packet header len */
|
||||
/* or packet too short */
|
||||
}
|
||||
else
|
||||
{
|
||||
ip->ip_sum = 0;
|
||||
ip->ip_sum = ip_checksum(ip, hlen);
|
||||
DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n",
|
||||
hlen, ip->ip_sum);
|
||||
}
|
||||
ip->ip_sum = 0;
|
||||
ip->ip_sum = ip_checksum(ip, hlen);
|
||||
DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n",
|
||||
hlen, ip->ip_sum);
|
||||
}
|
||||
|
||||
if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
|
||||
{
|
||||
/* Large enough for the TCP header? */
|
||||
if (ip_data_len < sizeof(tcp_header)) {
|
||||
goto skip_offload;
|
||||
}
|
||||
|
||||
if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
|
||||
int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
|
||||
|
||||
DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d "
|
||||
"frame data %d specified MSS=%d\n", ETH_MTU,
|
||||
ip_data_len, saved_size - ETH_HLEN, large_send_mss);
|
||||
|
||||
int tcp_send_offset = 0;
|
||||
int send_count = 0;
|
||||
|
||||
/* maximum IP header length is 60 bytes */
|
||||
uint8_t saved_ip_header[60];
|
||||
|
||||
/* save IP header template; data area is used in tcp checksum calculation */
|
||||
memcpy(saved_ip_header, eth_payload_data, hlen);
|
||||
|
||||
/* a placeholder for checksum calculation routine in tcp case */
|
||||
uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
|
||||
// size_t data_to_checksum_len = eth_payload_len - hlen + 12;
|
||||
|
||||
/* pointer to TCP header */
|
||||
tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);
|
||||
|
||||
int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);
|
||||
|
||||
/* Invalid TCP data offset? */
|
||||
if (tcp_hlen < sizeof(tcp_header) || tcp_hlen > ip_data_len) {
|
||||
goto skip_offload;
|
||||
}
|
||||
|
||||
/* ETH_MTU = ip header len + tcp header len + payload */
|
||||
int tcp_data_len = ip_data_len - tcp_hlen;
|
||||
int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
|
||||
|
||||
DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP "
|
||||
"data len %d TCP chunk size %d\n", ip_data_len,
|
||||
tcp_hlen, tcp_data_len, tcp_chunk_size);
|
||||
|
||||
/* note the cycle below overwrites IP header data,
|
||||
but restores it from saved_ip_header before sending packet */
|
||||
|
||||
int is_last_frame = 0;
|
||||
|
||||
for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size)
|
||||
{
|
||||
int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
|
||||
uint16_t chunk_size = tcp_chunk_size;
|
||||
|
||||
DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d "
|
||||
"frame data %d specified MSS=%d\n", ETH_MTU,
|
||||
ip_data_len, saved_size - ETH_HLEN, large_send_mss);
|
||||
|
||||
int tcp_send_offset = 0;
|
||||
int send_count = 0;
|
||||
|
||||
/* maximum IP header length is 60 bytes */
|
||||
uint8_t saved_ip_header[60];
|
||||
|
||||
/* save IP header template; data area is used in tcp checksum calculation */
|
||||
memcpy(saved_ip_header, eth_payload_data, hlen);
|
||||
|
||||
/* a placeholder for checksum calculation routine in tcp case */
|
||||
uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
|
||||
// size_t data_to_checksum_len = eth_payload_len - hlen + 12;
|
||||
|
||||
/* pointer to TCP header */
|
||||
tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);
|
||||
|
||||
int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);
|
||||
|
||||
/* ETH_MTU = ip header len + tcp header len + payload */
|
||||
int tcp_data_len = ip_data_len - tcp_hlen;
|
||||
int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
|
||||
|
||||
DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP "
|
||||
"data len %d TCP chunk size %d\n", ip_data_len,
|
||||
tcp_hlen, tcp_data_len, tcp_chunk_size);
|
||||
|
||||
/* note the cycle below overwrites IP header data,
|
||||
but restores it from saved_ip_header before sending packet */
|
||||
|
||||
int is_last_frame = 0;
|
||||
|
||||
for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size)
|
||||
/* check if this is the last frame */
|
||||
if (tcp_send_offset + tcp_chunk_size >= tcp_data_len)
|
||||
{
|
||||
uint16_t chunk_size = tcp_chunk_size;
|
||||
|
||||
/* check if this is the last frame */
|
||||
if (tcp_send_offset + tcp_chunk_size >= tcp_data_len)
|
||||
{
|
||||
is_last_frame = 1;
|
||||
chunk_size = tcp_data_len - tcp_send_offset;
|
||||
}
|
||||
|
||||
DPRINTF("+++ C+ mode TSO TCP seqno %08x\n",
|
||||
be32_to_cpu(p_tcp_hdr->th_seq));
|
||||
|
||||
/* add 4 TCP pseudoheader fields */
|
||||
/* copy IP source and destination fields */
|
||||
memcpy(data_to_checksum, saved_ip_header + 12, 8);
|
||||
|
||||
DPRINTF("+++ C+ mode TSO calculating TCP checksum for "
|
||||
"packet with %d bytes data\n", tcp_hlen +
|
||||
chunk_size);
|
||||
|
||||
if (tcp_send_offset)
|
||||
{
|
||||
memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size);
|
||||
}
|
||||
|
||||
/* keep PUSH and FIN flags only for the last frame */
|
||||
if (!is_last_frame)
|
||||
{
|
||||
TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);
|
||||
}
|
||||
|
||||
/* recalculate TCP checksum */
|
||||
ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
|
||||
p_tcpip_hdr->zeros = 0;
|
||||
p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
|
||||
p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size);
|
||||
|
||||
p_tcp_hdr->th_sum = 0;
|
||||
|
||||
int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);
|
||||
DPRINTF("+++ C+ mode TSO TCP checksum %04x\n",
|
||||
tcp_checksum);
|
||||
|
||||
p_tcp_hdr->th_sum = tcp_checksum;
|
||||
|
||||
/* restore IP header */
|
||||
memcpy(eth_payload_data, saved_ip_header, hlen);
|
||||
|
||||
/* set IP data length and recalculate IP checksum */
|
||||
ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size);
|
||||
|
||||
/* increment IP id for subsequent frames */
|
||||
ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id));
|
||||
|
||||
ip->ip_sum = 0;
|
||||
ip->ip_sum = ip_checksum(eth_payload_data, hlen);
|
||||
DPRINTF("+++ C+ mode TSO IP header len=%d "
|
||||
"checksum=%04x\n", hlen, ip->ip_sum);
|
||||
|
||||
int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;
|
||||
DPRINTF("+++ C+ mode TSO transferring packet size "
|
||||
"%d\n", tso_send_size);
|
||||
rtl8139_transfer_frame(s, saved_buffer, tso_send_size,
|
||||
0, (uint8_t *) dot1q_buffer);
|
||||
|
||||
/* add transferred count to TCP sequence number */
|
||||
p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));
|
||||
++send_count;
|
||||
is_last_frame = 1;
|
||||
chunk_size = tcp_data_len - tcp_send_offset;
|
||||
}
|
||||
|
||||
/* Stop sending this frame */
|
||||
saved_size = 0;
|
||||
}
|
||||
else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))
|
||||
{
|
||||
DPRINTF("+++ C+ mode need TCP or UDP checksum\n");
|
||||
|
||||
/* maximum IP header length is 60 bytes */
|
||||
uint8_t saved_ip_header[60];
|
||||
memcpy(saved_ip_header, eth_payload_data, hlen);
|
||||
|
||||
uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
|
||||
// size_t data_to_checksum_len = eth_payload_len - hlen + 12;
|
||||
DPRINTF("+++ C+ mode TSO TCP seqno %08x\n",
|
||||
be32_to_cpu(p_tcp_hdr->th_seq));
|
||||
|
||||
/* add 4 TCP pseudoheader fields */
|
||||
/* copy IP source and destination fields */
|
||||
memcpy(data_to_checksum, saved_ip_header + 12, 8);
|
||||
|
||||
if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)
|
||||
DPRINTF("+++ C+ mode TSO calculating TCP checksum for "
|
||||
"packet with %d bytes data\n", tcp_hlen +
|
||||
chunk_size);
|
||||
|
||||
if (tcp_send_offset)
|
||||
{
|
||||
DPRINTF("+++ C+ mode calculating TCP checksum for "
|
||||
"packet with %d bytes data\n", ip_data_len);
|
||||
|
||||
ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
|
||||
p_tcpip_hdr->zeros = 0;
|
||||
p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
|
||||
p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
|
||||
|
||||
tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12);
|
||||
|
||||
p_tcp_hdr->th_sum = 0;
|
||||
|
||||
int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
|
||||
DPRINTF("+++ C+ mode TCP checksum %04x\n",
|
||||
tcp_checksum);
|
||||
|
||||
p_tcp_hdr->th_sum = tcp_checksum;
|
||||
memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size);
|
||||
}
|
||||
else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)
|
||||
|
||||
/* keep PUSH and FIN flags only for the last frame */
|
||||
if (!is_last_frame)
|
||||
{
|
||||
DPRINTF("+++ C+ mode calculating UDP checksum for "
|
||||
"packet with %d bytes data\n", ip_data_len);
|
||||
|
||||
ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;
|
||||
p_udpip_hdr->zeros = 0;
|
||||
p_udpip_hdr->ip_proto = IP_PROTO_UDP;
|
||||
p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
|
||||
|
||||
udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12);
|
||||
|
||||
p_udp_hdr->uh_sum = 0;
|
||||
|
||||
int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
|
||||
DPRINTF("+++ C+ mode UDP checksum %04x\n",
|
||||
udp_checksum);
|
||||
|
||||
p_udp_hdr->uh_sum = udp_checksum;
|
||||
TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);
|
||||
}
|
||||
|
||||
/* recalculate TCP checksum */
|
||||
ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
|
||||
p_tcpip_hdr->zeros = 0;
|
||||
p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
|
||||
p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size);
|
||||
|
||||
p_tcp_hdr->th_sum = 0;
|
||||
|
||||
int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);
|
||||
DPRINTF("+++ C+ mode TSO TCP checksum %04x\n",
|
||||
tcp_checksum);
|
||||
|
||||
p_tcp_hdr->th_sum = tcp_checksum;
|
||||
|
||||
/* restore IP header */
|
||||
memcpy(eth_payload_data, saved_ip_header, hlen);
|
||||
|
||||
/* set IP data length and recalculate IP checksum */
|
||||
ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size);
|
||||
|
||||
/* increment IP id for subsequent frames */
|
||||
ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id));
|
||||
|
||||
ip->ip_sum = 0;
|
||||
ip->ip_sum = ip_checksum(eth_payload_data, hlen);
|
||||
DPRINTF("+++ C+ mode TSO IP header len=%d "
|
||||
"checksum=%04x\n", hlen, ip->ip_sum);
|
||||
|
||||
int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;
|
||||
DPRINTF("+++ C+ mode TSO transferring packet size "
|
||||
"%d\n", tso_send_size);
|
||||
rtl8139_transfer_frame(s, saved_buffer, tso_send_size,
|
||||
0, (uint8_t *) dot1q_buffer);
|
||||
|
||||
/* add transferred count to TCP sequence number */
|
||||
p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));
|
||||
++send_count;
|
||||
}
|
||||
|
||||
/* Stop sending this frame */
|
||||
saved_size = 0;
|
||||
}
|
||||
else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))
|
||||
{
|
||||
DPRINTF("+++ C+ mode need TCP or UDP checksum\n");
|
||||
|
||||
/* maximum IP header length is 60 bytes */
|
||||
uint8_t saved_ip_header[60];
|
||||
memcpy(saved_ip_header, eth_payload_data, hlen);
|
||||
|
||||
uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
|
||||
// size_t data_to_checksum_len = eth_payload_len - hlen + 12;
|
||||
|
||||
/* add 4 TCP pseudoheader fields */
|
||||
/* copy IP source and destination fields */
|
||||
memcpy(data_to_checksum, saved_ip_header + 12, 8);
|
||||
|
||||
if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)
|
||||
{
|
||||
DPRINTF("+++ C+ mode calculating TCP checksum for "
|
||||
"packet with %d bytes data\n", ip_data_len);
|
||||
|
||||
ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
|
||||
p_tcpip_hdr->zeros = 0;
|
||||
p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
|
||||
p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
|
||||
|
||||
tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12);
|
||||
|
||||
p_tcp_hdr->th_sum = 0;
|
||||
|
||||
int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
|
||||
DPRINTF("+++ C+ mode TCP checksum %04x\n",
|
||||
tcp_checksum);
|
||||
|
||||
p_tcp_hdr->th_sum = tcp_checksum;
|
||||
}
|
||||
else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)
|
||||
{
|
||||
DPRINTF("+++ C+ mode calculating UDP checksum for "
|
||||
"packet with %d bytes data\n", ip_data_len);
|
||||
|
||||
ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;
|
||||
p_udpip_hdr->zeros = 0;
|
||||
p_udpip_hdr->ip_proto = IP_PROTO_UDP;
|
||||
p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
|
||||
|
||||
udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12);
|
||||
|
||||
p_udp_hdr->uh_sum = 0;
|
||||
|
||||
int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
|
||||
DPRINTF("+++ C+ mode UDP checksum %04x\n",
|
||||
udp_checksum);
|
||||
|
||||
p_udp_hdr->uh_sum = udp_checksum;
|
||||
}
|
||||
|
||||
/* restore IP header */
|
||||
memcpy(eth_payload_data, saved_ip_header, hlen);
|
||||
}
|
||||
}
|
||||
|
||||
skip_offload:
|
||||
/* update tally counter */
|
||||
++s->tally_counters.TxOk;
|
||||
|
||||
|
||||
@@ -1049,6 +1049,61 @@ static bool virtio_64bit_features_needed(void *opaque)
|
||||
return (vdev->host_features >> 32) != 0;
|
||||
}
|
||||
|
||||
static bool virtio_virtqueue_needed(void *opaque)
|
||||
{
|
||||
VirtIODevice *vdev = opaque;
|
||||
|
||||
return virtio_host_has_feature(vdev, VIRTIO_F_VERSION_1);
|
||||
}
|
||||
|
||||
static void put_virtqueue_state(QEMUFile *f, void *pv, size_t size)
|
||||
{
|
||||
VirtIODevice *vdev = pv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
|
||||
qemu_put_be64(f, vdev->vq[i].vring.avail);
|
||||
qemu_put_be64(f, vdev->vq[i].vring.used);
|
||||
}
|
||||
}
|
||||
|
||||
static int get_virtqueue_state(QEMUFile *f, void *pv, size_t size)
|
||||
{
|
||||
VirtIODevice *vdev = pv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
|
||||
vdev->vq[i].vring.avail = qemu_get_be64(f);
|
||||
vdev->vq[i].vring.used = qemu_get_be64(f);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VMStateInfo vmstate_info_virtqueue = {
|
||||
.name = "virtqueue_state",
|
||||
.get = get_virtqueue_state,
|
||||
.put = put_virtqueue_state,
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_virtio_virtqueues = {
|
||||
.name = "virtio/virtqueues",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = &virtio_virtqueue_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
{
|
||||
.name = "virtqueues",
|
||||
.version_id = 0,
|
||||
.field_exists = NULL,
|
||||
.size = 0,
|
||||
.info = &vmstate_info_virtqueue,
|
||||
.flags = VMS_SINGLE,
|
||||
.offset = 0,
|
||||
},
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_virtio_device_endian = {
|
||||
.name = "virtio/device_endian",
|
||||
.version_id = 1,
|
||||
@@ -1082,6 +1137,7 @@ static const VMStateDescription vmstate_virtio = {
|
||||
.subsections = (const VMStateDescription*[]) {
|
||||
&vmstate_virtio_device_endian,
|
||||
&vmstate_virtio_64bit_features,
|
||||
&vmstate_virtio_virtqueues,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
@@ -350,6 +350,10 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
|
||||
.driver = "SandyBridge" "-" TYPE_X86_CPU,\
|
||||
.property = "xlevel",\
|
||||
.value = stringify(0x8000000a),\
|
||||
},{\
|
||||
.driver = "IvyBridge" "-" TYPE_X86_CPU,\
|
||||
.property = "xlevel",\
|
||||
.value = stringify(0x8000000a),\
|
||||
},{\
|
||||
.driver = "Haswell" "-" TYPE_X86_CPU,\
|
||||
.property = "xlevel",\
|
||||
|
||||
@@ -272,6 +272,12 @@ static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
|
||||
return __virtio_has_feature(vdev->guest_features, fbit);
|
||||
}
|
||||
|
||||
static inline bool virtio_host_has_feature(VirtIODevice *vdev,
|
||||
unsigned int fbit)
|
||||
{
|
||||
return __virtio_has_feature(vdev->host_features, fbit);
|
||||
}
|
||||
|
||||
static inline bool virtio_is_big_endian(VirtIODevice *vdev)
|
||||
{
|
||||
if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
|
||||
|
||||
@@ -203,4 +203,5 @@ void register_global_state(void);
|
||||
void global_state_set_optional(void);
|
||||
void savevm_skip_configuration(void);
|
||||
int global_state_store(void);
|
||||
void global_state_store_running(void);
|
||||
#endif
|
||||
@@ -122,6 +122,13 @@ int global_state_store(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void global_state_store_running(void)
|
||||
{
|
||||
const char *state = RunState_lookup[RUN_STATE_RUNNING];
|
||||
strncpy((char *)global_state.runstate,
|
||||
state, sizeof(global_state.runstate));
|
||||
}
|
||||
|
||||
static bool global_state_received(void)
|
||||
{
|
||||
return global_state.received;
|
||||
|
||||
@@ -1394,6 +1394,7 @@ void qmp_xen_save_devices_state(const char *filename, Error **errp)
|
||||
|
||||
saved_vm_running = runstate_is_running();
|
||||
vm_stop(RUN_STATE_SAVE_VM);
|
||||
global_state_store_running();
|
||||
|
||||
f = qemu_fopen(filename, "wb");
|
||||
if (!f) {
|
||||
|
||||
+32
-23
@@ -4750,48 +4750,53 @@ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
|
||||
gen_load_gpr(t1, rs);
|
||||
switch (opc) {
|
||||
case OPC_EXT:
|
||||
if (lsb + msb > 31)
|
||||
if (lsb + msb > 31) {
|
||||
goto fail;
|
||||
}
|
||||
tcg_gen_shri_tl(t0, t1, lsb);
|
||||
if (msb != 31) {
|
||||
tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
|
||||
tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
|
||||
} else {
|
||||
tcg_gen_ext32s_tl(t0, t0);
|
||||
}
|
||||
break;
|
||||
#if defined(TARGET_MIPS64)
|
||||
case OPC_DEXTM:
|
||||
tcg_gen_shri_tl(t0, t1, lsb);
|
||||
if (msb != 31) {
|
||||
tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
|
||||
}
|
||||
break;
|
||||
case OPC_DEXTU:
|
||||
tcg_gen_shri_tl(t0, t1, lsb + 32);
|
||||
tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
|
||||
break;
|
||||
lsb += 32;
|
||||
goto do_dext;
|
||||
case OPC_DEXTM:
|
||||
msb += 32;
|
||||
goto do_dext;
|
||||
case OPC_DEXT:
|
||||
do_dext:
|
||||
if (lsb + msb > 63) {
|
||||
goto fail;
|
||||
}
|
||||
tcg_gen_shri_tl(t0, t1, lsb);
|
||||
tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
|
||||
if (msb != 63) {
|
||||
tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case OPC_INS:
|
||||
if (lsb > msb)
|
||||
if (lsb > msb) {
|
||||
goto fail;
|
||||
}
|
||||
gen_load_gpr(t0, rt);
|
||||
tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
|
||||
tcg_gen_ext32s_tl(t0, t0);
|
||||
break;
|
||||
#if defined(TARGET_MIPS64)
|
||||
case OPC_DINSM:
|
||||
gen_load_gpr(t0, rt);
|
||||
tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
|
||||
break;
|
||||
case OPC_DINSU:
|
||||
gen_load_gpr(t0, rt);
|
||||
tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
|
||||
break;
|
||||
lsb += 32;
|
||||
/* FALLTHRU */
|
||||
case OPC_DINSM:
|
||||
msb += 32;
|
||||
/* FALLTHRU */
|
||||
case OPC_DINS:
|
||||
if (lsb > msb) {
|
||||
goto fail;
|
||||
}
|
||||
gen_load_gpr(t0, rt);
|
||||
tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
|
||||
break;
|
||||
@@ -13278,10 +13283,14 @@ static void gen_pool16c_r6_insn(DisasContext *ctx)
|
||||
break;
|
||||
case R6_SDBBP16:
|
||||
/* SDBBP16 */
|
||||
if (ctx->hflags & MIPS_HFLAG_SBRI) {
|
||||
generate_exception(ctx, EXCP_RI);
|
||||
if (is_uhi(extract32(ctx->opcode, 6, 4))) {
|
||||
gen_helper_do_semihosting(cpu_env);
|
||||
} else {
|
||||
generate_exception(ctx, EXCP_DBp);
|
||||
if (ctx->hflags & MIPS_HFLAG_SBRI) {
|
||||
generate_exception(ctx, EXCP_RI);
|
||||
} else {
|
||||
generate_exception(ctx, EXCP_DBp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -963,9 +963,11 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg base, TCGReg addrl,
|
||||
}
|
||||
|
||||
/* Load the tlb comparator. */
|
||||
tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, TCG_REG_A0, cmp_off + LO_OFF);
|
||||
if (TARGET_LONG_BITS == 64) {
|
||||
tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, TCG_REG_A0, cmp_off + LO_OFF);
|
||||
tcg_out_opc_imm(s, OPC_LW, base, TCG_REG_A0, cmp_off + HI_OFF);
|
||||
} else {
|
||||
tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, TCG_REG_A0, cmp_off);
|
||||
}
|
||||
|
||||
/* Mask the page bits, keeping the alignment bits to compare against.
|
||||
@@ -1103,7 +1105,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
|
||||
static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
||||
TCGReg base, TCGMemOp opc)
|
||||
{
|
||||
switch (opc) {
|
||||
switch (opc & (MO_SSIZE | MO_BSWAP)) {
|
||||
case MO_UB:
|
||||
tcg_out_opc_imm(s, OPC_LBU, datalo, base, 0);
|
||||
break;
|
||||
@@ -1193,7 +1195,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
|
||||
static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
||||
TCGReg base, TCGMemOp opc)
|
||||
{
|
||||
switch (opc) {
|
||||
switch (opc & (MO_SIZE | MO_BSWAP)) {
|
||||
case MO_8:
|
||||
tcg_out_opc_imm(s, OPC_SB, datalo, base, 0);
|
||||
break;
|
||||
@@ -1269,6 +1271,9 @@ static void tcg_out_addsub2(TCGContext *s, TCGReg rl, TCGReg rh, TCGReg al,
|
||||
if (cbl) {
|
||||
tcg_out_opc_imm(s, OPC_ADDIU, rl, al, bl);
|
||||
tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, rl, bl);
|
||||
} else if (rl == al && rl == bl) {
|
||||
tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, al, 31);
|
||||
tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
|
||||
} else {
|
||||
tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
|
||||
tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, rl, (rl == bl ? al : bl));
|
||||
|
||||
@@ -1390,7 +1390,7 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
|
||||
static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
|
||||
TCGReg base, TCGReg index, int disp)
|
||||
{
|
||||
switch (opc) {
|
||||
switch (opc & (MO_SSIZE | MO_BSWAP)) {
|
||||
case MO_UB:
|
||||
tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
|
||||
break;
|
||||
@@ -1449,7 +1449,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
|
||||
static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
|
||||
TCGReg base, TCGReg index, int disp)
|
||||
{
|
||||
switch (opc) {
|
||||
switch (opc & (MO_SIZE | MO_BSWAP)) {
|
||||
case MO_UB:
|
||||
if (disp >= 0 && disp < 0x1000) {
|
||||
tcg_out_insn(s, RX, STC, data, base, index, disp);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "qmp-commands.h"
|
||||
#include "sysemu/char.h"
|
||||
#include "sysemu/accel.h"
|
||||
#include "migration/migration.h"
|
||||
|
||||
//#define DEBUG_XEN
|
||||
|
||||
@@ -119,6 +120,10 @@ static int xen_init(MachineState *ms)
|
||||
}
|
||||
qemu_add_vm_change_state_handler(xen_change_state_handler, NULL);
|
||||
|
||||
global_state_set_optional();
|
||||
savevm_skip_configuration();
|
||||
savevm_skip_section_footers();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user