aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-08-01 18:03:04 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-08-01 18:03:04 +0100
commit82d3d409b8b650164817ead0cb48298c6973d731 (patch)
tree76b2c0412952acc21ac9bf1e54d9899a9092ec8f /hw
parent3b64f272d36b310587e606217db92b0bcb6673a1 (diff)
parent33f21e4f044ac1c37f60edc1f1aee628be8f463b (diff)
downloadqemu-82d3d409b8b650164817ead0cb48298c6973d731.zip
qemu-82d3d409b8b650164817ead0cb48298c6973d731.tar.gz
qemu-82d3d409b8b650164817ead0cb48298c6973d731.tar.bz2
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* Xen fix (Anthony) * chardev fixes (Anton, Marc-André) * small dead code removal (Zhongyi) * documentation (Dan) * bugfixes (David) * decrease migration downtime (Jay) * improved error output (Laurent) * RTC tests and bugfix (me) * Bluetooth clang analyzer fix (me) * KVM CPU hotplug race (Peng Hao) * Two other patches from Philippe's clang analyzer series # gpg: Signature made Tue 01 Aug 2017 16:56:21 BST # gpg: using RSA key 0xBFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: mc146818rtc: implement UIP latching as intended mc146818rtc: simplify check_update_timer rtc-test: introduce more update tests rtc-test: cleanup register_b_set_flag test hw/scsi/vmw_pvscsi: Convert to realize hw/scsi/vmw_pvscsi: Remove the dead error handling migration: optimize the downtime qemu-options: document existance of versioned machine types bt: stop the sdp memory allocation craziness exec: Add lock parameter to qemu_ram_ptr_length target-i386: kvm_get/put_vcpu_events don't handle sipi_vector docs: document deprecation policy & deprecated features in appendix char: don't exit on hmp 'chardev-add help' char-fd: remove useless chr pointer accel: cleanup error output cpu_physical_memory_sync_dirty_bitmap: Fix alignment check vl.c/exit: pause cpus before closing block devices Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/bt/sdp.c17
-rw-r--r--hw/scsi/vmw_pvscsi.c12
-rw-r--r--hw/timer/mc146818rtc.c37
3 files changed, 35 insertions, 31 deletions
diff --git a/hw/bt/sdp.c b/hw/bt/sdp.c
index f67b3b8..3cb60b9 100644
--- a/hw/bt/sdp.c
+++ b/hw/bt/sdp.c
@@ -580,7 +580,7 @@ static void bt_l2cap_sdp_close_ch(void *opaque)
int i;
for (i = 0; i < sdp->services; i ++) {
- g_free(sdp->service_list[i].attribute_list->pair);
+ g_free(sdp->service_list[i].attribute_list[0].pair);
g_free(sdp->service_list[i].attribute_list);
g_free(sdp->service_list[i].uuid);
}
@@ -720,6 +720,8 @@ static void sdp_service_record_build(struct sdp_service_record_s *record,
len += sdp_attr_max_size(&def->attributes[record->attributes ++].data,
&record->uuids);
}
+
+ assert(len > 0);
record->uuids = pow2ceil(record->uuids);
record->attribute_list =
g_malloc0(record->attributes * sizeof(*record->attribute_list));
@@ -730,12 +732,14 @@ static void sdp_service_record_build(struct sdp_service_record_s *record,
record->attributes = 0;
uuid = record->uuid;
while (def->attributes[record->attributes].data.type) {
+ int attribute_id = def->attributes[record->attributes].id;
record->attribute_list[record->attributes].pair = data;
+ record->attribute_list[record->attributes].attribute_id = attribute_id;
len = 0;
data[len ++] = SDP_DTYPE_UINT | SDP_DSIZE_2;
- data[len ++] = def->attributes[record->attributes].id >> 8;
- data[len ++] = def->attributes[record->attributes].id & 0xff;
+ data[len ++] = attribute_id >> 8;
+ data[len ++] = attribute_id & 0xff;
len += sdp_attr_write(data + len,
&def->attributes[record->attributes].data, &uuid);
@@ -749,10 +753,15 @@ static void sdp_service_record_build(struct sdp_service_record_s *record,
data += len;
}
- /* Sort the attribute list by the AttributeID */
+ /* Sort the attribute list by the AttributeID. The first must be
+ * SDP_ATTR_RECORD_HANDLE so that bt_l2cap_sdp_close_ch can free
+ * the buffer.
+ */
qsort(record->attribute_list, record->attributes,
sizeof(*record->attribute_list),
(void *) sdp_attributeid_compare);
+ assert(record->attribute_list[0].pair == data);
+
/* Sort the searchable UUIDs list for bisection */
qsort(record->uuid, record->uuids,
sizeof(*record->uuid),
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 4a106da..77d8b6f 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1103,8 +1103,8 @@ static const struct SCSIBusInfo pvscsi_scsi_info = {
.cancel = pvscsi_request_cancelled,
};
-static int
-pvscsi_init(PCIDevice *pci_dev)
+static void
+pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
{
PVSCSIState *s = PVSCSI(pci_dev);
@@ -1138,18 +1138,12 @@ pvscsi_init(PCIDevice *pci_dev)
}
s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);
- if (!s->completion_worker) {
- pvscsi_cleanup_msi(s);
- return -ENOMEM;
- }
scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
&pvscsi_scsi_info, NULL);
/* override default SCSI bus hotplug-handler, with pvscsi's one */
qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(s), &error_abort);
pvscsi_reset_state(s);
-
- return 0;
}
static void
@@ -1282,7 +1276,7 @@ static void pvscsi_class_init(ObjectClass *klass, void *data)
PVSCSIClass *pvs_k = PVSCSI_DEVICE_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
- k->init = pvscsi_init;
+ k->realize = pvscsi_realizefn;
k->exit = pvscsi_uninit;
k->vendor_id = PCI_VENDOR_ID_VMWARE;
k->device_id = PCI_DEVICE_ID_VMWARE_PVSCSI;
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 1b8d3d7..82843ed 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -291,26 +291,15 @@ static void check_update_timer(RTCState *s)
/* From the data sheet: "Holding the dividers in reset prevents
* interrupts from operating, while setting the SET bit allows"
- * them to occur. However, it will prevent an alarm interrupt
- * from occurring, because the time of day is not updated.
+ * them to occur.
*/
if ((s->cmos_data[RTC_REG_A] & 0x60) == 0x60) {
- timer_del(s->update_timer);
- return;
- }
- if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
- (s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- timer_del(s->update_timer);
- return;
- }
- if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
- (s->cmos_data[RTC_REG_C] & REG_C_AF)) {
+ assert((s->cmos_data[RTC_REG_A] & REG_A_UIP) == 0);
timer_del(s->update_timer);
return;
}
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)
+ NANOSECONDS_PER_SECOND - guest_nsec;
@@ -321,7 +310,21 @@ static void check_update_timer(RTCState *s)
s->next_alarm_time = next_update_time +
(next_alarm_sec - 1) * NANOSECONDS_PER_SECOND;
- if (s->cmos_data[RTC_REG_C] & REG_C_UF) {
+ /* If update_in_progress latched the UIP bit, we must keep the timer
+ * programmed to the next second, so that UIP is cleared. Otherwise,
+ * if UF is already set, we might be able to optimize.
+ */
+ if (!(s->cmos_data[RTC_REG_A] & REG_A_UIP) &&
+ (s->cmos_data[RTC_REG_C] & REG_C_UF)) {
+ /* If AF cannot change (i.e. either it is set already, or
+ * SET=1 and then the time is not updated), nothing to do.
+ */
+ if ((s->cmos_data[RTC_REG_B] & REG_B_SET) ||
+ (s->cmos_data[RTC_REG_C] & REG_C_AF)) {
+ timer_del(s->update_timer);
+ return;
+ }
+
/* UF is set, but AF is clear. Program the timer to target
* the alarm time. */
next_update_time = s->next_alarm_time;
@@ -727,12 +730,10 @@ static uint64_t cmos_ioport_read(void *opaque, hwaddr addr,
ret = s->cmos_data[s->cmos_index];
break;
case RTC_REG_A:
+ ret = s->cmos_data[s->cmos_index];
if (update_in_progress(s)) {
- s->cmos_data[s->cmos_index] |= REG_A_UIP;
- } else {
- s->cmos_data[s->cmos_index] &= ~REG_A_UIP;
+ ret |= REG_A_UIP;
}
- ret = s->cmos_data[s->cmos_index];
break;
case RTC_REG_C:
ret = s->cmos_data[s->cmos_index];