aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-04-05 11:49:06 +0300
committerAvi Kivity <avi@redhat.com>2011-04-05 11:49:06 +0300
commit6cbf3357fa13059ffeb04ffb9f99166ff2834776 (patch)
tree88dbfc6d007ee9e1c2e9829d50173a12d6fb4b68
parentqemu-kvm: Fix non-PCI target build (diff)
parentMerge commit 'd4b4ba03e86eeb697f04bf1173c29530e77e0ce5' into upstream-merge (diff)
downloadqemu-kvm-6cbf3357fa13059ffeb04ffb9f99166ff2834776.tar.gz
qemu-kvm-6cbf3357fa13059ffeb04ffb9f99166ff2834776.tar.bz2
qemu-kvm-6cbf3357fa13059ffeb04ffb9f99166ff2834776.zip
Merge branch 'upstream-merge' into stable-0.14
* upstream-merge: lsi53c895a: add support for ABORT messages virtio-pci: fix bus master work around on load fix applesmc REV key rbd: don't link with -lcrypto net: Add the missing option declaration of "vhostforce" lsi53c895a: Update dnad when skipping MSGOUT bytes Revert "prep: Disable second IDE channel, as long as ISA IDE emulation doesn't support same irq for both channels" isa-bus: Remove bogus IRQ sharing check virtio-net: Fix lduw_p() pointer argument of wrong size hw/sd.c: Add missing state change for SD_STATUS, SEND_NUM_WR_BLOCKS vnc: Fix fatal crash with vnc reverse mode Signed-off-by: Avi Kivity <avi@redhat.com>
-rwxr-xr-xconfigure2
-rw-r--r--hw/applesmc.c2
-rw-r--r--hw/hpet.c1
-rw-r--r--hw/ide/piix.c2
-rw-r--r--hw/ide/via.c2
-rw-r--r--hw/isa-bus.c16
-rw-r--r--hw/isa.h2
-rw-r--r--hw/lsi53c895a.c68
-rw-r--r--hw/mips_fulong2e.c2
-rw-r--r--hw/mips_malta.c4
-rw-r--r--hw/pc.c5
-rw-r--r--hw/pc_piix.c4
-rw-r--r--hw/ppc_prep.c2
-rw-r--r--hw/sd.c2
-rw-r--r--hw/virtio-net.c4
-rw-r--r--hw/virtio-pci.c13
-rw-r--r--hw/virtio.h1
-rw-r--r--net.c6
-rw-r--r--ui/vnc.c1
19 files changed, 99 insertions, 40 deletions
diff --git a/configure b/configure
index d190f76ca..50f5de987 100755
--- a/configure
+++ b/configure
@@ -1916,7 +1916,7 @@ if test "$rbd" != "no" ; then
#include <rados/librados.h>
int main(void) { rados_initialize(0, NULL); return 0; }
EOF
- rbd_libs="-lrados -lcrypto"
+ rbd_libs="-lrados"
if compile_prog "" "$rbd_libs" ; then
librados_too_old=no
cat > $TMPC <<EOF
diff --git a/hw/applesmc.c b/hw/applesmc.c
index 29b93305e..23ed3287b 100644
--- a/hw/applesmc.c
+++ b/hw/applesmc.c
@@ -188,7 +188,7 @@ static void qdev_applesmc_isa_reset(DeviceState *dev)
QLIST_REMOVE(d, node);
}
- applesmc_add_key(s, "REV ", 6, "\0x01\0x13\0x0f\0x00\0x00\0x03");
+ applesmc_add_key(s, "REV ", 6, "\x01\x13\x0f\x00\x00\x03");
applesmc_add_key(s, "OSK0", 32, s->osk);
applesmc_add_key(s, "OSK1", 32, s->osk + 32);
applesmc_add_key(s, "NATJ", 1, "\0");
diff --git a/hw/hpet.c b/hw/hpet.c
index 80099a4fd..a48a6648c 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -720,7 +720,6 @@ static int hpet_init(SysBusDevice *dev)
s->capability |= (s->num_timers - 1) << HPET_ID_NUM_TIM_SHIFT;
s->capability |= ((HPET_CLK_PERIOD) << 32);
- isa_reserve_irq(RTC_ISA_IRQ);
qdev_init_gpio_in(&dev->qdev, hpet_handle_rtc_irq, 1);
/* HPET Area */
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index d4289af9c..c3496448c 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -122,7 +122,7 @@ static void pci_piix_init_ports(PCIIDEState *d) {
for (i = 0; i < 2; i++) {
ide_bus_new(&d->bus[i], &d->dev.qdev, i);
ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
- ide_init2(&d->bus[i], isa_reserve_irq(port_info[i].isairq));
+ ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq));
bmdma_init(&d->bus[i], &d->bmdma[i]);
d->bmdma[i].bus = &d->bus[i];
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 0e906797c..04f329096 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -145,7 +145,7 @@ static void vt82c686b_init_ports(PCIIDEState *d) {
for (i = 0; i < 2; i++) {
ide_bus_new(&d->bus[i], &d->dev.qdev, i);
ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
- ide_init2(&d->bus[i], isa_reserve_irq(port_info[i].isairq));
+ ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq));
bmdma_init(&d->bus[i], &d->bmdma[i]);
d->bmdma[i].bus = &d->bus[i];
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 0cb1afbf2..9e33e71b9 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -25,7 +25,6 @@
struct ISABus {
BusState qbus;
qemu_irq *irqs;
- uint32_t assigned;
};
static ISABus *isabus;
target_phys_addr_t isa_mem_base = 0;
@@ -61,33 +60,24 @@ void isa_bus_irqs(qemu_irq *irqs)
}
/*
- * isa_reserve_irq() reserves the ISA irq and returns the corresponding
- * qemu_irq entry for the i8259.
+ * isa_get_irq() returns the corresponding qemu_irq entry for the i8259.
*
* This function is only for special cases such as the 'ferr', and
* temporary use for normal devices until they are converted to qdev.
*/
-qemu_irq isa_reserve_irq(int isairq)
+qemu_irq isa_get_irq(int isairq)
{
if (isairq < 0 || isairq > 15) {
hw_error("isa irq %d invalid", isairq);
}
- if (isabus->assigned & (1 << isairq)) {
- hw_error("isa irq %d already assigned", isairq);
- }
- isabus->assigned |= (1 << isairq);
return isabus->irqs[isairq];
}
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
{
assert(dev->nirqs < ARRAY_SIZE(dev->isairq));
- if (isabus->assigned & (1 << isairq)) {
- hw_error("isa irq %d already assigned", isairq);
- }
- isabus->assigned |= (1 << isairq);
dev->isairq[dev->nirqs] = isairq;
- *p = isabus->irqs[isairq];
+ *p = isa_get_irq(isairq);
dev->nirqs++;
}
diff --git a/hw/isa.h b/hw/isa.h
index 19aa94c9f..f1335ff2d 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -26,7 +26,7 @@ struct ISADeviceInfo {
ISABus *isa_bus_new(DeviceState *dev);
void isa_bus_irqs(qemu_irq *irqs);
-qemu_irq isa_reserve_irq(int isairq);
+qemu_irq isa_get_irq(int isairq);
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
void isa_init_ioport(ISADevice *dev, uint16_t ioport);
void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length);
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 9c761cdb6..e4b51a8ea 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -842,10 +842,29 @@ static uint8_t lsi_get_msgbyte(LSIState *s)
return data;
}
+/* Skip the next n bytes during a MSGOUT phase. */
+static void lsi_skip_msgbytes(LSIState *s, unsigned int n)
+{
+ s->dnad += n;
+ s->dbc -= n;
+}
+
static void lsi_do_msgout(LSIState *s)
{
uint8_t msg;
int len;
+ uint32_t current_tag;
+ SCSIDevice *current_dev;
+ lsi_request *p, *p_next;
+ int id;
+
+ if (s->current) {
+ current_tag = s->current->tag;
+ } else {
+ current_tag = s->select_tag;
+ }
+ id = (current_tag >> 8) & 0xf;
+ current_dev = s->bus.devs[id];
DPRINTF("MSG out len=%d\n", s->dbc);
while (s->dbc) {
@@ -869,11 +888,11 @@ static void lsi_do_msgout(LSIState *s)
switch (msg) {
case 1:
DPRINTF("SDTR (ignored)\n");
- s->dbc -= 2;
+ lsi_skip_msgbytes(s, 2);
break;
case 3:
DPRINTF("WDTR (ignored)\n");
- s->dbc -= 1;
+ lsi_skip_msgbytes(s, 1);
break;
default:
goto bad;
@@ -891,6 +910,51 @@ static void lsi_do_msgout(LSIState *s)
BADF("ORDERED queue not implemented\n");
s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
break;
+ case 0x0d:
+ /* The ABORT TAG message clears the current I/O process only. */
+ DPRINTF("MSG: ABORT TAG tag=0x%x\n", current_tag);
+ current_dev->info->cancel_io(current_dev, current_tag);
+ lsi_disconnect(s);
+ break;
+ case 0x06:
+ case 0x0e:
+ case 0x0c:
+ /* The ABORT message clears all I/O processes for the selecting
+ initiator on the specified logical unit of the target. */
+ if (msg == 0x06) {
+ DPRINTF("MSG: ABORT tag=0x%x\n", current_tag);
+ }
+ /* The CLEAR QUEUE message clears all I/O processes for all
+ initiators on the specified logical unit of the target. */
+ if (msg == 0x0e) {
+ DPRINTF("MSG: CLEAR QUEUE tag=0x%x\n", current_tag);
+ }
+ /* The BUS DEVICE RESET message clears all I/O processes for all
+ initiators on all logical units of the target. */
+ if (msg == 0x0c) {
+ DPRINTF("MSG: BUS DEVICE RESET tag=0x%x\n", current_tag);
+ }
+
+ /* clear the current I/O process */
+ current_dev->info->cancel_io(current_dev, current_tag);
+
+ /* As the current implemented devices scsi_disk and scsi_generic
+ only support one LUN, we don't need to keep track of LUNs.
+ Clearing I/O processes for other initiators could be possible
+ for scsi_generic by sending a SG_SCSI_RESET to the /dev/sgX
+ device, but this is currently not implemented (and seems not
+ to be really necessary). So let's simply clear all queued
+ commands for the current device: */
+ id = current_tag & 0x0000ff00;
+ QTAILQ_FOREACH_SAFE(p, &s->queue, next, p_next) {
+ if ((p->tag & 0x0000ff00) == id) {
+ current_dev->info->cancel_io(current_dev, p->tag);
+ QTAILQ_REMOVE(&s->queue, p, next);
+ }
+ }
+
+ lsi_disconnect(s);
+ break;
default:
if ((msg & 0x80) == 0) {
goto bad;
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index 2783ed583..3b0abdba8 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -369,7 +369,7 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
qdev_init_nofail(eeprom);
/* init other devices */
- pit = pit_init(0x40, isa_reserve_irq(0));
+ pit = pit_init(0x40, isa_get_irq(0));
cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
DMA_init(0, cpu_exit_irq);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 2d3f242cc..7211d98a1 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -919,7 +919,7 @@ void mips_malta_init (ram_addr_t ram_size,
isa_bus_irqs(i8259);
pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
- smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_reserve_irq(9),
+ smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_get_irq(9),
NULL, NULL, 0);
eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
for (i = 0; i < 8; i++) {
@@ -930,7 +930,7 @@ void mips_malta_init (ram_addr_t ram_size,
qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
qdev_init_nofail(eeprom);
}
- pit = pit_init(0x40, isa_reserve_irq(0));
+ pit = pit_init(0x40, isa_get_irq(0));
cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
DMA_init(0, cpu_exit_irq);
diff --git a/hw/pc.c b/hw/pc.c
index 278447c34..b7bf3197d 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1127,12 +1127,11 @@ void pc_basic_device_init(qemu_irq *isa_irq,
#ifdef CONFIG_KVM_PIT
if (kvm_enabled() && kvm_pit_in_kernel())
- pit = kvm_pit_init(0x40, isa_reserve_irq(0));
+ pit = kvm_pit_init(0x40, isa_get_irq(0));
else
#endif
- pit = pit_init(0x40, isa_reserve_irq(0));
-
+ pit = pit_init(0x40, isa_get_irq(0));
pcspk_init(pit);
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index ad451480d..0a51e200a 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -128,7 +128,7 @@ static void pc_init1(ram_addr_t ram_size,
}
isa_bus_irqs(isa_irq);
- pc_register_ferr_irq(isa_reserve_irq(13));
+ pc_register_ferr_irq(isa_get_irq(13));
pc_vga_init(pci_enabled? pci_bus: NULL);
@@ -184,7 +184,7 @@ static void pc_init1(ram_addr_t ram_size,
smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
/* TODO: Populate SPD eeprom data. */
smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
- isa_reserve_irq(9), *cmos_s3, *smi_irq,
+ isa_get_irq(9), *cmos_s3, *smi_irq,
kvm_enabled());
for (i = 0; i < 8; i++) {
DeviceState *eeprom;
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 6c1499a78..6b221221c 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -690,7 +690,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
}
- for(i = 0; i < 1/*MAX_IDE_BUS*/; i++) {
+ for(i = 0; i < MAX_IDE_BUS; i++) {
isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
hd[2 * i],
hd[2 * i + 1]);
diff --git a/hw/sd.c b/hw/sd.c
index 789ca8478..5e29752d9 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -1168,6 +1168,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
case 13: /* ACMD13: SD_STATUS */
switch (sd->state) {
case sd_transfer_state:
+ sd->state = sd_sendingdata_state;
sd->data_start = 0;
sd->data_offset = 0;
return sd_r1;
@@ -1182,6 +1183,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
case sd_transfer_state:
*(uint32_t *) sd->data = sd->blk_written;
+ sd->state = sd_sendingdata_state;
sd->data_start = 0;
sd->data_offset = 0;
return sd_r1;
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 671d95292..e9775a6e7 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -79,7 +79,7 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
VirtIONet *n = to_virtio_net(vdev);
struct virtio_net_config netcfg;
- netcfg.status = lduw_p(&n->status);
+ stw_p(&netcfg.status, n->status);
memcpy(netcfg.mac, n->mac, ETH_ALEN);
memcpy(config, &netcfg, sizeof(netcfg));
}
@@ -678,7 +678,7 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_
}
if (mhdr) {
- mhdr->num_buffers = lduw_p(&i);
+ stw_p(&mhdr->num_buffers, i);
}
virtqueue_flush(n->rx_vq, i);
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 8d67bf06a..54c1a04db 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -160,13 +160,6 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
}
-
- /* Try to find out if the guest has bus master disabled, but is
- in ready state. Then we have a buggy guest OS. */
- if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
- !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
- proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
- }
return 0;
}
@@ -735,6 +728,12 @@ static void virtio_pci_vmstate_change(void *opaque, bool running)
VirtIOPCIProxy *proxy = opaque;
if (running) {
+ /* Try to find out if the guest has bus master disabled, but is
+ in ready state. Then we have a buggy guest OS. */
+ if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
+ !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
+ proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
+ }
virtio_pci_start_ioeventfd(proxy);
} else {
virtio_pci_stop_ioeventfd(proxy);
diff --git a/hw/virtio.h b/hw/virtio.h
index 31d16e1c3..d1fb8a0f5 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -92,6 +92,7 @@ typedef struct {
void (*save_queue)(void * opaque, int n, QEMUFile *f);
int (*load_config)(void * opaque, QEMUFile *f);
int (*load_queue)(void * opaque, int n, QEMUFile *f);
+ int (*load_done)(void * opaque, QEMUFile *f);
unsigned (*get_features)(void * opaque);
bool (*query_guest_notifiers)(void * opaque);
int (*set_guest_notifiers)(void * opaque, bool assigned);
diff --git a/net.c b/net.c
index 9ba5be22d..21d44432e 100644
--- a/net.c
+++ b/net.c
@@ -1025,7 +1025,11 @@ static const struct {
.name = "vhostfd",
.type = QEMU_OPT_STRING,
.help = "file descriptor of an already opened vhost net device",
- },
+ }, {
+ .name = "vhostforce",
+ .type = QEMU_OPT_BOOL,
+ .help = "force vhost on for non-MSIX virtio guests",
+ },
#endif /* _WIN32 */
{ /* end of list */ }
},
diff --git a/ui/vnc.c b/ui/vnc.c
index 560b98d44..f4fea0405 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2349,6 +2349,7 @@ static void vnc_init_timer(VncDisplay *vd)
vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
vd->timer = qemu_new_timer(rt_clock, vnc_refresh, vd);
+ vnc_dpy_resize(vd->ds);
vnc_refresh(vd);
}
}