Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging # gpg: Signature made Mon Jul 20 19:27:04 2015 BST using RSA key ID AAFC390E # gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: FAEB 9711 A12C F475 812F 18F2 88A9 064D 1835 61EB # Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76 CBD0 7DEF 8106 AAFC 390E * remotes/jnsnow/tags/ide-pull-request: tests: Fix broken targets check-report-qtest-* ahci: Force ICC bits in PxCMD to zero qtest/ide: add another short PRDT test flavor Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index a3b1314..42f66b3 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c
@@ -187,11 +187,6 @@ le32_to_cpus(&desc->next); } -static int eth_can_receive(NetClientState *nc) -{ - return 1; -} - static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size) { mv88w8618_eth_state *s = qemu_get_nic_opaque(nc); @@ -381,7 +376,6 @@ static NetClientInfo net_mv88w8618_info = { .type = NET_CLIENT_OPTIONS_KIND_NIC, .size = sizeof(NICState), - .can_receive = eth_can_receive, .receive = eth_receive, .cleanup = eth_cleanup, };
diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c index 4773dea..d600275 100644 --- a/hw/net/etraxfs_eth.c +++ b/hw/net/etraxfs_eth.c
@@ -520,11 +520,6 @@ return match; } -static int eth_can_receive(NetClientState *nc) -{ - return 1; -} - static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size) { unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -584,7 +579,6 @@ static NetClientInfo net_etraxfs_info = { .type = NET_CLIENT_OPTIONS_KIND_NIC, .size = sizeof(NICState), - .can_receive = eth_can_receive, .receive = eth_receive, .link_status_changed = eth_set_link, };
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c index f169c38..4f0e840 100644 --- a/hw/net/lan9118.c +++ b/hw/net/lan9118.c
@@ -461,11 +461,6 @@ lan9118_reload_eeprom(s); } -static int lan9118_can_receive(NetClientState *nc) -{ - return 1; -} - static void rx_fifo_push(lan9118_state *s, uint32_t val) { int fifo_pos; @@ -1312,7 +1307,6 @@ static NetClientInfo net_lan9118_info = { .type = NET_CLIENT_OPTIONS_KIND_NIC, .size = sizeof(NICState), - .can_receive = lan9118_can_receive, .receive = lan9118_receive, .link_status_changed = lan9118_set_link, };
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 706e060..59b06b8 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c
@@ -885,6 +885,63 @@ } } +/* In case packet was csum offloaded (either NEEDS_CSUM or DATA_VALID), + * the implementation always passes an RxCompDesc with a "Checksum + * calculated and found correct" to the OS (cnc=0 and tuc=1, see + * vmxnet3_rx_update_descr). This emulates the observed ESXi behavior. + * + * Therefore, if packet has the NEEDS_CSUM set, we must calculate + * and place a fully computed checksum into the tcp/udp header. + * Otherwise, the OS driver will receive a checksum-correct indication + * (CHECKSUM_UNNECESSARY), but with the actual tcp/udp checksum field + * having just the pseudo header csum value. + * + * While this is not a problem if packet is destined for local delivery, + * in the case the host OS performs forwarding, it will forward an + * incorrectly checksummed packet. + */ +static void vmxnet3_rx_need_csum_calculate(struct VmxnetRxPkt *pkt, + const void *pkt_data, + size_t pkt_len) +{ + struct virtio_net_hdr *vhdr; + bool isip4, isip6, istcp, isudp; + uint8_t *data; + int len; + + if (!vmxnet_rx_pkt_has_virt_hdr(pkt)) { + return; + } + + vhdr = vmxnet_rx_pkt_get_vhdr(pkt); + if (!VMXNET_FLAG_IS_SET(vhdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) { + return; + } + + vmxnet_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp); + if (!(isip4 || isip6) || !(istcp || isudp)) { + return; + } + + vmxnet3_dump_virt_hdr(vhdr); + + /* Validate packet len: csum_start + scum_offset + length of csum field */ + if (pkt_len < (vhdr->csum_start + vhdr->csum_offset + 2)) { + VMW_PKPRN("packet len:%d < csum_start(%d) + csum_offset(%d) + 2, " + "cannot calculate checksum", + len, vhdr->csum_start, vhdr->csum_offset); + return; + } + + data = (uint8_t *)pkt_data + vhdr->csum_start; + len = pkt_len - vhdr->csum_start; + /* Put the checksum obtained into the packet */ + stw_be_p(data + vhdr->csum_offset, net_raw_checksum(data, len)); + + vhdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM; + vhdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID; +} + static void vmxnet3_rx_update_descr(struct VmxnetRxPkt *pkt, struct Vmxnet3_RxCompDesc *rxcd) { @@ -1897,6 +1954,8 @@ get_eth_packet_type(PKT_GET_ETH_HDR(buf))); if (vmxnet3_rx_filter_may_indicate(s, buf, size)) { + vmxnet_rx_pkt_set_protocols(s->rx_pkt, buf, size); + vmxnet3_rx_need_csum_calculate(s->rx_pkt, buf, size); vmxnet_rx_pkt_attach_data(s->rx_pkt, buf, size, s->rx_vlan_stripping); bytes_indicated = vmxnet3_indicate_packet(s) ? size : -1; if (bytes_indicated < size) {
diff --git a/hw/net/vmxnet_rx_pkt.c b/hw/net/vmxnet_rx_pkt.c index acbca6a..aa54629 100644 --- a/hw/net/vmxnet_rx_pkt.c +++ b/hw/net/vmxnet_rx_pkt.c
@@ -92,9 +92,6 @@ } pkt->tci = tci; - - eth_get_protocols(data, len, &pkt->isip4, &pkt->isip6, - &pkt->isudp, &pkt->istcp); } void vmxnet_rx_pkt_dump(struct VmxnetRxPkt *pkt) @@ -131,6 +128,15 @@ return pkt->tot_len; } +void vmxnet_rx_pkt_set_protocols(struct VmxnetRxPkt *pkt, const void *data, + size_t len) +{ + assert(pkt); + + eth_get_protocols(data, len, &pkt->isip4, &pkt->isip6, + &pkt->isudp, &pkt->istcp); +} + void vmxnet_rx_pkt_get_protocols(struct VmxnetRxPkt *pkt, bool *isip4, bool *isip6, bool *isudp, bool *istcp)
diff --git a/hw/net/vmxnet_rx_pkt.h b/hw/net/vmxnet_rx_pkt.h index 5f8352a..a425846 100644 --- a/hw/net/vmxnet_rx_pkt.h +++ b/hw/net/vmxnet_rx_pkt.h
@@ -55,6 +55,17 @@ size_t vmxnet_rx_pkt_get_total_len(struct VmxnetRxPkt *pkt); /** + * parse and set packet analysis results + * + * @pkt: packet + * @data: pointer to the data buffer to be parsed + * @len: data length + * + */ +void vmxnet_rx_pkt_set_protocols(struct VmxnetRxPkt *pkt, const void *data, + size_t len); + +/** * fetches packet analysis results * * @pkt: packet
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 2a4b8e1..b77e303 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c
@@ -873,8 +873,9 @@ */ host_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST); ns_diff = MAX(0, host_ns - tb_remote->time_of_the_day_ns); - migration_duration_ns = MIN(NSEC_PER_SEC, ns_diff); - migration_duration_tb = muldiv64(migration_duration_ns, freq, NSEC_PER_SEC); + migration_duration_ns = MIN(NANOSECONDS_PER_SECOND, ns_diff); + migration_duration_tb = muldiv64(migration_duration_ns, freq, + NANOSECONDS_PER_SECOND); guest_tb = tb_remote->guest_timebase + MIN(0, migration_duration_tb); tb_off_adj = guest_tb - cpu_get_real_ticks();
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c index d20b8f2..34b27db 100644 --- a/hw/ppc/spapr_rtc.c +++ b/hw/ppc/spapr_rtc.c
@@ -51,7 +51,7 @@ assert(rtc); guest_ns = host_ns + rtc->ns_offset; - guest_s = guest_ns / NSEC_PER_SEC; + guest_s = guest_ns / NANOSECONDS_PER_SECOND; if (tm) { gmtime_r(&guest_s, tm); @@ -71,7 +71,7 @@ rtc = SPAPR_RTC(dev); - rtc->ns_offset = legacy_offset * NSEC_PER_SEC; + rtc->ns_offset = legacy_offset * NANOSECONDS_PER_SECOND; return 0; } @@ -146,7 +146,7 @@ host_ns = qemu_clock_get_ns(rtc_clock); - rtc->ns_offset = (new_s * NSEC_PER_SEC) - host_ns; + rtc->ns_offset = (new_s * NANOSECONDS_PER_SECOND) - host_ns; rtas_st(rets, 0, RTAS_OUT_SUCCESS); } @@ -168,7 +168,7 @@ qemu_get_timedate(&tm, 0); host_s = mktimegm(&tm); rtc_ns = qemu_clock_get_ns(rtc_clock); - rtc->ns_offset = host_s * NSEC_PER_SEC - rtc_ns; + rtc->ns_offset = host_s * NANOSECONDS_PER_SECOND - rtc_ns; object_property_add_tm(OBJECT(rtc), "date", spapr_rtc_qom_date, NULL); }
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 954c34d..a9f0efd 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c
@@ -56,7 +56,7 @@ #define RTC_REINJECT_ON_ACK_COUNT 20 #define RTC_CLOCK_RATE 32768 -#define UIP_HOLD_LENGTH (8 * NSEC_PER_SEC / 32768) +#define UIP_HOLD_LENGTH (8 * NANOSECONDS_PER_SECOND / 32768) #define MC146818_RTC(obj) OBJECT_CHECK(RTCState, (obj), TYPE_MC146818_RTC) @@ -105,7 +105,7 @@ uint64_t guest_rtc; uint64_t guest_clock = qemu_clock_get_ns(rtc_clock); - guest_rtc = s->base_rtc * NSEC_PER_SEC + guest_rtc = s->base_rtc * NANOSECONDS_PER_SECOND + guest_clock - s->last_update + s->offset; return guest_rtc; } @@ -231,16 +231,17 @@ return; } - guest_nsec = get_guest_rtc_ns(s) % NSEC_PER_SEC; + guest_nsec = get_guest_rtc_ns(s) % NANOSECONDS_PER_SECOND; /* if UF is clear, reprogram to next second */ next_update_time = qemu_clock_get_ns(rtc_clock) - + NSEC_PER_SEC - guest_nsec; + + NANOSECONDS_PER_SECOND - guest_nsec; /* Compute time of next alarm. One second is already accounted * for in next_update_time. */ next_alarm_sec = get_next_alarm(s); - s->next_alarm_time = next_update_time + (next_alarm_sec - 1) * NSEC_PER_SEC; + s->next_alarm_time = next_update_time + + (next_alarm_sec - 1) * NANOSECONDS_PER_SECOND; if (s->cmos_data[RTC_REG_C] & REG_C_UF) { /* UF is set, but AF is clear. Program the timer to target @@ -456,7 +457,7 @@ /* if disabling set mode, update the time */ if ((s->cmos_data[RTC_REG_B] & REG_B_SET) && (s->cmos_data[RTC_REG_A] & 0x70) <= 0x20) { - s->offset = get_guest_rtc_ns(s) % NSEC_PER_SEC; + s->offset = get_guest_rtc_ns(s) % NANOSECONDS_PER_SECOND; rtc_set_time(s); } } @@ -580,7 +581,7 @@ int64_t guest_nsec; guest_nsec = get_guest_rtc_ns(s); - guest_sec = guest_nsec / NSEC_PER_SEC; + guest_sec = guest_nsec / NANOSECONDS_PER_SECOND; gmtime_r(&guest_sec, &ret); /* Is SET flag of Register B disabled? */ @@ -608,7 +609,8 @@ guest_nsec = get_guest_rtc_ns(s); /* UIP bit will be set at last 244us of every second. */ - if ((guest_nsec % NSEC_PER_SEC) >= (NSEC_PER_SEC - UIP_HOLD_LENGTH)) { + if ((guest_nsec % NANOSECONDS_PER_SECOND) >= + (NANOSECONDS_PER_SECOND - UIP_HOLD_LENGTH)) { return 1; } return 0;
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index d7cd40b..64a54c6 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c
@@ -32,7 +32,7 @@ #include "trace.h" #define FRAME_TIMER_FREQ 1000 -#define FRAME_TIMER_NS (NSEC_PER_SEC / FRAME_TIMER_FREQ) +#define FRAME_TIMER_NS (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ) #define UFRAME_TIMER_NS (FRAME_TIMER_NS / 8) #define NB_MAXINTRATE 8 // Max rate at which controller issues ints
diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 4dda20b..5923d60 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h
@@ -5,7 +5,7 @@ #include "qemu-common.h" #include "qemu/notify.h" -#define NSEC_PER_SEC 1000000000LL +#define NANOSECONDS_PER_SECOND 1000000000LL /* timers */
diff --git a/net/net.c b/net/net.c index 6ff7fec..28a5597 100644 --- a/net/net.c +++ b/net/net.c
@@ -1257,14 +1257,19 @@ static void net_vm_change_state_handler(void *opaque, int running, RunState state) { - /* Complete all queued packets, to guarantee we don't modify - * state later when VM is not running. - */ - if (!running) { - NetClientState *nc; - NetClientState *tmp; + NetClientState *nc; + NetClientState *tmp; - QTAILQ_FOREACH_SAFE(nc, &net_clients, next, tmp) { + QTAILQ_FOREACH_SAFE(nc, &net_clients, next, tmp) { + if (running) { + /* Flush queued packets and wake up backends. */ + if (nc->peer && qemu_can_send_packet(nc)) { + qemu_flush_queued_packets(nc->peer); + } + } else { + /* Complete all queued packets, to guarantee we don't modify + * state later when VM is not running. + */ qemu_flush_or_purge_queued_packets(nc, true); } }
diff --git a/net/socket.c b/net/socket.c index c752696..b1e3b1c 100644 --- a/net/socket.c +++ b/net/socket.c
@@ -213,7 +213,7 @@ if (s->index >= s->packet_len) { s->index = 0; s->state = 0; - if (qemu_send_packet_async(&s->nc, s->buf, size, + if (qemu_send_packet_async(&s->nc, s->buf, s->packet_len, net_socket_send_completed) == 0) { net_socket_read_poll(s, false); break;
diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c index 3bff0e3..e749be3 100644 --- a/tests/rtl8139-test.c +++ b/tests/rtl8139-test.c
@@ -86,7 +86,7 @@ fatal("time too big %u\n", curr); } for (cnt = 0; ; ) { - clock_step(1 * NSEC_PER_SEC); + clock_step(1 * NANOSECONDS_PER_SECOND); prev = curr; curr = in_Timer(); @@ -125,7 +125,7 @@ out_IntrStatus(0x4000); curr = in_Timer(); out_TimerInt(curr + 0.5 * CLK); - clock_step(1 * NSEC_PER_SEC); + clock_step(1 * NANOSECONDS_PER_SECOND); out_Timer(0); if ((in_IntrStatus() & 0x4000) == 0) { fatal("we should have an interrupt here!\n"); @@ -137,7 +137,7 @@ out_IntrStatus(0x4000); curr = in_Timer(); out_TimerInt(curr + 0.5 * CLK); - clock_step(1 * NSEC_PER_SEC); + clock_step(1 * NANOSECONDS_PER_SECOND); out_TimerInt(0); if ((in_IntrStatus() & 0x4000) == 0) { fatal("we should have an interrupt here!\n"); @@ -148,7 +148,7 @@ next = curr + 5.0 * CLK; out_TimerInt(next); for (cnt = 0; ; ) { - clock_step(1 * NSEC_PER_SEC); + clock_step(1 * NANOSECONDS_PER_SECOND); prev = curr; curr = in_Timer(); diff = (curr-prev) & 0xffffffffu;
diff --git a/tests/test-throttle.c b/tests/test-throttle.c index 33b6b95..0168445 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c
@@ -40,19 +40,19 @@ bkt.level = 1.5; /* leak an op work of time */ - throttle_leak_bucket(&bkt, NSEC_PER_SEC / 150); + throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150); g_assert(bkt.avg == 150); g_assert(bkt.max == 15); g_assert(double_cmp(bkt.level, 0.5)); /* leak again emptying the bucket */ - throttle_leak_bucket(&bkt, NSEC_PER_SEC / 150); + throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150); g_assert(bkt.avg == 150); g_assert(bkt.max == 15); g_assert(double_cmp(bkt.level, 0)); /* check that the bucket level won't go lower */ - throttle_leak_bucket(&bkt, NSEC_PER_SEC / 150); + throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150); g_assert(bkt.avg == 150); g_assert(bkt.max == 15); g_assert(double_cmp(bkt.level, 0)); @@ -90,7 +90,7 @@ bkt.level = 15.5; wait = throttle_compute_wait(&bkt); /* time required to do half an operation */ - result = (int64_t) NSEC_PER_SEC / 150 / 2; + result = (int64_t) NANOSECONDS_PER_SECOND / 150 / 2; g_assert(wait == result); }
diff --git a/tests/wdt_ib700-test.c b/tests/wdt_ib700-test.c index 10a5472..82ca597 100644 --- a/tests/wdt_ib700-test.c +++ b/tests/wdt_ib700-test.c
@@ -40,29 +40,29 @@ static QDict *ib700_program_and_wait(QTestState *s) { - clock_step(NSEC_PER_SEC * 40); + clock_step(NANOSECONDS_PER_SECOND * 40); qmp_check_no_event(); /* 2 second limit */ outb(0x443, 14); /* Ping */ - clock_step(NSEC_PER_SEC); + clock_step(NANOSECONDS_PER_SECOND); qmp_check_no_event(); outb(0x443, 14); /* Disable */ - clock_step(NSEC_PER_SEC); + clock_step(NANOSECONDS_PER_SECOND); qmp_check_no_event(); outb(0x441, 1); - clock_step(3 * NSEC_PER_SEC); + clock_step(3 * NANOSECONDS_PER_SECOND); qmp_check_no_event(); /* Enable and let it fire */ outb(0x443, 13); - clock_step(3 * NSEC_PER_SEC); + clock_step(3 * NANOSECONDS_PER_SECOND); qmp_check_no_event(); - clock_step(2 * NSEC_PER_SEC); + clock_step(2 * NANOSECONDS_PER_SECOND); return qmp_get_event("WATCHDOG"); }
diff --git a/util/throttle.c b/util/throttle.c index ec70476..706c131 100644 --- a/util/throttle.c +++ b/util/throttle.c
@@ -36,7 +36,7 @@ double leak; /* compute how much to leak */ - leak = (bkt->avg * (double) delta_ns) / NSEC_PER_SEC; + leak = (bkt->avg * (double) delta_ns) / NANOSECONDS_PER_SECOND; /* make the bucket leak */ bkt->level = MAX(bkt->level - leak, 0); @@ -72,7 +72,7 @@ */ static int64_t throttle_do_compute_wait(double limit, double extra) { - double wait = extra * NSEC_PER_SEC; + double wait = extra * NANOSECONDS_PER_SECOND; wait /= limit; return wait; }