aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-09-15 18:12:40 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-09-15 18:12:40 +0100
commit5f473241ac595452ae0638dc63e7af2a2294f5ec (patch)
tree1b9f7c7daf2b9866929f5fd6a4812ed1f64c9434 /hw
parent518352b601997723bd03d928d1bb5854648942e8 (diff)
parent39c88f56977f9ad2451444d70dd21d8189d74f99 (diff)
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* Support multiple -d trace:PATTERN arguments (Daniel) * SCSI cleanups/fixes for removable meia (Fam) * SCSI security fixes (Li Qiang, PJP) * qemu-char segfault fix (Lin Ma) * "make help" and qemu-socket cleanups (Marc-André) * end of the buffer_is_zero reword (Richard) * Fix target-i386 syscall segfault (Stanislav) * split irqchip fix/robustification (Wanpeng) * misc cleanups (me, Jiangang) * x86 vmstate fixes (Pavel) # gpg: Signature made Thu 15 Sep 2016 14:11:35 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: pcspk: adding vmstate for save/restore kvmvapic: fix state change handler pc: apic: introduce APIC macro target-i386: Fixed syscall posssible segfault log: fix parsing of multiple trace:PATTERN log args qemu-char: avoid segfault if user lacks of permisson of a given logfile build-sys: add make 'help' target linux-user: complete omission of removing uses of strdup target-i386: fix ordering of fields in CPUX86State pc: apic: fix touch LAPIC when irqchip is split scsi: pvscsi: limit process IO loop to ring size memory: remove memory_region_destructor_rom_device Change net/socket.c to use socket_*() functions cutils: Rewrite x86 buffer zero checking scsi: mptsas: use g_new0 to allocate MPTSASRequest object virtio-scsi: Don't abort when media is ejected scsi-disk: Cleaning up around tray open state Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/audio/pcspk.c17
-rw-r--r--hw/i386/kvmvapic.c1
-rw-r--r--hw/i386/pc.c18
-rw-r--r--hw/intc/apic.c26
-rw-r--r--hw/scsi/mptsas.c2
-rw-r--r--hw/scsi/scsi-disk.c22
-rw-r--r--hw/scsi/virtio-scsi.c15
-rw-r--r--hw/scsi/vmw_pvscsi.c5
8 files changed, 63 insertions, 43 deletions
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index 42a6f4885a..984534b2d1 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -52,8 +52,8 @@ typedef struct {
unsigned int pit_count;
unsigned int samples;
unsigned int play_pos;
- int data_on;
- int dummy_refresh_clock;
+ uint8_t data_on;
+ uint8_t dummy_refresh_clock;
} PCSpkState;
static const char *s_spk = "pcspk";
@@ -187,6 +187,18 @@ static void pcspk_realizefn(DeviceState *dev, Error **errp)
pcspk_state = s;
}
+static const VMStateDescription vmstate_spk = {
+ .name = "pcspk",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(data_on, PCSpkState),
+ VMSTATE_UINT8(dummy_refresh_clock, PCSpkState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static Property pcspk_properties[] = {
DEFINE_PROP_UINT32("iobase", PCSpkState, iobase, -1),
DEFINE_PROP_END_OF_LIST(),
@@ -198,6 +210,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
dc->realize = pcspk_realizefn;
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
+ dc->vmsd = &vmstate_spk;
dc->props = pcspk_properties;
/* Reason: realize sets global pcspk_state */
dc->cannot_instantiate_with_device_add_yet = true;
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 3bf1ddd976..a1cd9b5a29 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -768,6 +768,7 @@ static void kvmvapic_vm_state_change(void *opaque, int running,
}
qemu_del_vm_change_state_handler(s->vmsentry);
+ s->vmsentry = NULL;
}
static int vapic_post_load(void *opaque, int version_id)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e31f70f428..2d6d7920ff 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -161,13 +161,15 @@ int cpu_get_pic_interrupt(CPUX86State *env)
X86CPU *cpu = x86_env_get_cpu(env);
int intno;
- intno = apic_get_interrupt(cpu->apic_state);
- if (intno >= 0) {
- return intno;
- }
- /* read the irq from the PIC */
- if (!apic_accept_pic_intr(cpu->apic_state)) {
- return -1;
+ if (!kvm_irqchip_in_kernel()) {
+ intno = apic_get_interrupt(cpu->apic_state);
+ if (intno >= 0) {
+ return intno;
+ }
+ /* read the irq from the PIC */
+ if (!apic_accept_pic_intr(cpu->apic_state)) {
+ return -1;
+ }
}
intno = pic_read_irq(isa_pic);
@@ -180,7 +182,7 @@ static void pic_irq_request(void *opaque, int irq, int level)
X86CPU *cpu = X86_CPU(cs);
DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
- if (cpu->apic_state) {
+ if (cpu->apic_state && !kvm_irqchip_in_kernel()) {
CPU_FOREACH(cs) {
cpu = X86_CPU(cs);
if (apic_accept_pic_intr(cpu->apic_state)) {
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 45887d99c0..7bd1d279c4 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -39,6 +39,10 @@
static APICCommonState *local_apics[MAX_APICS + 1];
+#define TYPE_APIC "apic"
+#define APIC(obj) \
+ OBJECT_CHECK(APICCommonState, (obj), TYPE_APIC)
+
static void apic_set_irq(APICCommonState *s, int vector_num, int trigger_mode);
static void apic_update_irq(APICCommonState *s);
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
@@ -163,7 +167,7 @@ static void apic_local_deliver(APICCommonState *s, int vector)
void apic_deliver_pic_intr(DeviceState *dev, int level)
{
- APICCommonState *s = APIC_COMMON(dev);
+ APICCommonState *s = APIC(dev);
if (level) {
apic_local_deliver(s, APIC_LVT_LINT0);
@@ -373,7 +377,7 @@ static void apic_update_irq(APICCommonState *s)
void apic_poll_irq(DeviceState *dev)
{
- APICCommonState *s = APIC_COMMON(dev);
+ APICCommonState *s = APIC(dev);
apic_sync_vapic(s, SYNC_FROM_VAPIC);
apic_update_irq(s);
@@ -479,7 +483,7 @@ static void apic_startup(APICCommonState *s, int vector_num)
void apic_sipi(DeviceState *dev)
{
- APICCommonState *s = APIC_COMMON(dev);
+ APICCommonState *s = APIC(dev);
cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI);
@@ -493,7 +497,7 @@ static void apic_deliver(DeviceState *dev, uint8_t dest, uint8_t dest_mode,
uint8_t delivery_mode, uint8_t vector_num,
uint8_t trigger_mode)
{
- APICCommonState *s = APIC_COMMON(dev);
+ APICCommonState *s = APIC(dev);
uint32_t deliver_bitmask[MAX_APIC_WORDS];
int dest_shorthand = (s->icr[0] >> 18) & 3;
APICCommonState *apic_iter;
@@ -550,7 +554,7 @@ static bool apic_check_pic(APICCommonState *s)
int apic_get_interrupt(DeviceState *dev)
{
- APICCommonState *s = APIC_COMMON(dev);
+ APICCommonState *s = APIC(dev);
int intno;
/* if the APIC is installed or enabled, we let the 8259 handle the
@@ -584,7 +588,7 @@ int apic_get_interrupt(DeviceState *dev)
int apic_accept_pic_intr(DeviceState *dev)
{
- APICCommonState *s = APIC_COMMON(dev);
+ APICCommonState *s = APIC(dev);
uint32_t lvt0;
if (!s)
@@ -663,7 +667,7 @@ static uint32_t apic_mem_readl(void *opaque, hwaddr addr)
if (!dev) {
return 0;
}
- s = APIC_COMMON(dev);
+ s = APIC(dev);
index = (addr >> 4) & 0xff;
switch(index) {
@@ -766,7 +770,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
if (!dev) {
return;
}
- s = APIC_COMMON(dev);
+ s = APIC(dev);
trace_apic_mem_writel(addr, val);
@@ -870,7 +874,7 @@ static const MemoryRegionOps apic_io_ops = {
static void apic_realize(DeviceState *dev, Error **errp)
{
- APICCommonState *s = APIC_COMMON(dev);
+ APICCommonState *s = APIC(dev);
if (s->id >= MAX_APICS) {
error_setg(errp, "%s initialization failed. APIC ID %d is invalid",
@@ -889,7 +893,7 @@ static void apic_realize(DeviceState *dev, Error **errp)
static void apic_unrealize(DeviceState *dev, Error **errp)
{
- APICCommonState *s = APIC_COMMON(dev);
+ APICCommonState *s = APIC(dev);
timer_del(s->timer);
timer_free(s->timer);
@@ -912,7 +916,7 @@ static void apic_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo apic_info = {
- .name = "apic",
+ .name = TYPE_APIC,
.instance_size = sizeof(APICCommonState),
.parent = TYPE_APIC_COMMON,
.class_init = apic_class_init,
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
index 8a3dee17fc..ad87e78fe2 100644
--- a/hw/scsi/mptsas.c
+++ b/hw/scsi/mptsas.c
@@ -304,7 +304,7 @@ static int mptsas_process_scsi_io_request(MPTSASState *s,
goto bad;
}
- req = g_new(MPTSASRequest, 1);
+ req = g_new0(MPTSASRequest, 1);
QTAILQ_INSERT_TAIL(&s->pending, req, next);
req->scsi_io = *scsi_io;
req->dev = s;
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 77cba31e30..88beaf4bb8 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -396,7 +396,7 @@ static void scsi_read_data(SCSIRequest *req)
return;
}
- if (s->tray_open) {
+ if (!blk_is_available(req->dev->conf.blk)) {
scsi_read_complete(r, -ENOMEDIUM);
return;
}
@@ -519,7 +519,7 @@ static void scsi_write_data(SCSIRequest *req)
scsi_write_complete_noio(r, 0);
return;
}
- if (s->tray_open) {
+ if (!blk_is_available(req->dev->conf.blk)) {
scsi_write_complete_noio(r, -ENOMEDIUM);
return;
}
@@ -792,10 +792,7 @@ static inline bool media_is_dvd(SCSIDiskState *s)
if (s->qdev.type != TYPE_ROM) {
return false;
}
- if (!blk_is_inserted(s->qdev.conf.blk)) {
- return false;
- }
- if (s->tray_open) {
+ if (!blk_is_available(s->qdev.conf.blk)) {
return false;
}
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
@@ -808,10 +805,7 @@ static inline bool media_is_cd(SCSIDiskState *s)
if (s->qdev.type != TYPE_ROM) {
return false;
}
- if (!blk_is_inserted(s->qdev.conf.blk)) {
- return false;
- }
- if (s->tray_open) {
+ if (!blk_is_available(s->qdev.conf.blk)) {
return false;
}
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
@@ -875,7 +869,7 @@ static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
}
if (format != 0xff) {
- if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
+ if (!blk_is_available(s->qdev.conf.blk)) {
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
return -1;
}
@@ -1857,7 +1851,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
break;
default:
- if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
+ if (!blk_is_available(s->qdev.conf.blk)) {
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
return 0;
}
@@ -1886,7 +1880,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
memset(outbuf, 0, r->buflen);
switch (req->cmd.buf[0]) {
case TEST_UNIT_READY:
- assert(!s->tray_open && blk_is_inserted(s->qdev.conf.blk));
+ assert(blk_is_available(s->qdev.conf.blk));
break;
case INQUIRY:
buflen = scsi_disk_emulate_inquiry(req, outbuf);
@@ -2126,7 +2120,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
command = buf[0];
- if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
+ if (!blk_is_available(s->qdev.conf.blk)) {
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
return 0;
}
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index ce57ef6248..e596b64741 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -236,6 +236,13 @@ static void virtio_scsi_cancel_notify(Notifier *notifier, void *data)
g_free(n);
}
+static inline void virtio_scsi_ctx_check(VirtIOSCSI *s, SCSIDevice *d)
+{
+ if (s->dataplane_started && d && blk_is_available(d->conf.blk)) {
+ assert(blk_get_aio_context(d->conf.blk) == s->ctx);
+ }
+}
+
/* Return 0 if the request is ready to be completed and return to guest;
* -EINPROGRESS if the request is submitted and will be completed later, in the
* case of async cancellation. */
@@ -247,9 +254,7 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
int target;
int ret = 0;
- if (s->dataplane_started && d) {
- assert(blk_get_aio_context(d->conf.blk) == s->ctx);
- }
+ virtio_scsi_ctx_check(s, d);
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
req->resp.tmf.response = VIRTIO_SCSI_S_OK;
@@ -539,9 +544,7 @@ static bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req
virtio_scsi_complete_cmd_req(req);
return false;
}
- if (s->dataplane_started) {
- assert(blk_get_aio_context(d->conf.blk) == s->ctx);
- }
+ virtio_scsi_ctx_check(s, d);
req->sreq = scsi_req_new(d, req->req.cmd.tag,
virtio_scsi_get_lun(req->req.cmd.lun),
req->req.cmd.cdb, req);
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index babac5a68a..a5ce7dea8e 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -247,8 +247,11 @@ static hwaddr
pvscsi_ring_pop_req_descr(PVSCSIRingInfo *mgr)
{
uint32_t ready_ptr = RS_GET_FIELD(mgr, reqProdIdx);
+ uint32_t ring_size = PVSCSI_MAX_NUM_PAGES_REQ_RING
+ * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
- if (ready_ptr != mgr->consumed_ptr) {
+ if (ready_ptr != mgr->consumed_ptr
+ && ready_ptr - mgr->consumed_ptr < ring_size) {
uint32_t next_ready_ptr =
mgr->consumed_ptr++ & mgr->txr_len_mask;
uint32_t next_ready_page =