[Spice-commits] 112 commits - Makefile.objs Makefile.target arm-semi.c block/raw-posix.c blockdev.c configure cpu-common.h cpu-exec.c cpus.c docs/ich9-ehci-uhci.cfg docs/usb2.txt exec-all.h exec.c hw/arm-misc.h hw/arm_boot.c hw/esp.c hw/framebuffer.c hw/hpet.c hw/ide hw/intel-hda.c hw/milkymist-softusb.c hw/msi.c hw/msix.c hw/nseries.c hw/pci_ids.h hw/piix_pci.c hw/pl080.c hw/ppc405_uc.c hw/pxa2xx_lcd.c hw/qxl-logger.c hw/qxl.c hw/s390-virtio-bus.c hw/s390-virtio-bus.h hw/s390-virtio.c hw/spapr.h hw/spapr_hcall.c hw/usb-bt.c hw/usb-bus.c hw/usb-ehci.c hw/usb-hub.c hw/usb-musb.c hw/usb-ohci.c hw/usb-uhci.c hw/usb.c hw/usb.h hw/vhost.c hw/virtio-blk.c hw/virtio-blk.h hw/virtio-console.c hw/virtio-pci.c hw/virtio-pci.h hw/virtio-serial-bus.c hw/virtio.c hw/virtio.h hw/xen.h hw/xen_common.h hw/xen_console.c hw/xen_disk.c hw/xen_platform.c hw/xenfb.c input.c linux-user/alpha linux-user/arm linux-user/cris linux-user/elfload.c linux-user/i386 linux-user/ioctls.h linux-user/m68k linux-user /main.c linux-user/microblaze linux-user/mips linux-user/mips64 linux-user/mipsn32 linux-user/ppc linux-user/s390x linux-user/sh4 linux-user/signal.c linux-user/sparc linux-user/sparc64 linux-user/syscall.c linux-user/syscall_defs.h linux-user/syscall_types.h linux-user/x86_64 os-posix.c qemu-common.h qemu-img-cmds.hx qemu-img.c qemu-img.texi qemu-options.hx scripts/checkpatch.pl target-alpha/cpu.h target-arm/cpu.h target-ppc/cpu.h target-sparc/cpu.h target-sparc/op_helper.c target-sparc/translate.c tcg/README trace-events ui/spice-core.c ui/spice-display.c vl.c xen-all.c xen-mapcache-stub.c xen-mapcache.c xen-mapcache.h xen-stub.c
Gerd Hoffmann
kraxel at kemper.freedesktop.org
Wed Jul 20 03:23:00 PDT 2011
Makefile.objs | 4
Makefile.target | 14 -
arm-semi.c | 113 +++++++++------
block/raw-posix.c | 14 +
blockdev.c | 14 -
configure | 2
cpu-common.h | 14 +
cpu-exec.c | 4
cpus.c | 12 +
docs/ich9-ehci-uhci.cfg | 37 +++++
docs/usb2.txt | 33 +++-
exec-all.h | 6
exec.c | 260 ++++++++++++++++++++++++++++++-----
hw/arm-misc.h | 2
hw/arm_boot.c | 6
hw/esp.c | 2
hw/framebuffer.c | 3
hw/hpet.c | 2
hw/ide/core.c | 50 +++++-
hw/intel-hda.c | 21 --
hw/milkymist-softusb.c | 9 -
hw/msi.c | 2
hw/msix.c | 2
hw/nseries.c | 4
hw/pci_ids.h | 13 +
hw/piix_pci.c | 3
hw/pl080.c | 8 -
hw/ppc405_uc.c | 43 +++--
hw/pxa2xx_lcd.c | 109 +++++++++++++-
hw/qxl-logger.c | 4
hw/qxl.c | 50 ++++--
hw/s390-virtio-bus.c | 14 +
hw/s390-virtio-bus.h | 1
hw/s390-virtio.c | 6
hw/spapr.h | 4
hw/spapr_hcall.c | 12 -
hw/usb-bt.c | 24 +--
hw/usb-bus.c | 46 +++++-
hw/usb-ehci.c | 270 ++++++++++++++++++++++++++-----------
hw/usb-hub.c | 90 ++----------
hw/usb-musb.c | 24 ++-
hw/usb-ohci.c | 89 ++++++++----
hw/usb-uhci.c | 95 ++++++++++---
hw/usb.c | 13 -
hw/usb.h | 20 ++
hw/vhost.c | 1
hw/virtio-blk.c | 29 ++-
hw/virtio-blk.h | 2
hw/virtio-console.c | 25 +++
hw/virtio-pci.c | 4
hw/virtio-pci.h | 1
hw/virtio-serial-bus.c | 9 +
hw/virtio.c | 8 +
hw/virtio.h | 3
hw/xen.h | 10 -
hw/xen_common.h | 12 +
hw/xen_console.c | 25 ++-
hw/xen_disk.c | 37 ++++-
hw/xen_platform.c | 15 --
hw/xenfb.c | 19 +-
input.c | 34 +++-
linux-user/alpha/syscall_nr.h | 23 +++
linux-user/arm/syscall_nr.h | 13 +
linux-user/cris/syscall_nr.h | 2
linux-user/elfload.c | 6
linux-user/i386/syscall_nr.h | 12 +
linux-user/ioctls.h | 13 +
linux-user/m68k/syscall_nr.h | 16 ++
linux-user/main.c | 33 ++++
linux-user/microblaze/syscall_nr.h | 14 +
linux-user/mips/syscall_nr.h | 13 +
linux-user/mips64/syscall_nr.h | 13 +
linux-user/mipsn32/syscall_nr.h | 14 +
linux-user/ppc/syscall_nr.h | 30 ++++
linux-user/s390x/syscall_nr.h | 13 +
linux-user/sh4/syscall_nr.h | 34 ++++
linux-user/signal.c | 30 ++--
linux-user/sparc/syscall_nr.h | 12 +
linux-user/sparc64/syscall_nr.h | 12 +
linux-user/syscall.c | 153 +++++++++++++++++---
linux-user/syscall_defs.h | 51 ++++++
linux-user/syscall_types.h | 20 ++
linux-user/x86_64/syscall_nr.h | 12 +
os-posix.c | 6
qemu-common.h | 1
qemu-img-cmds.hx | 6
qemu-img.c | 80 +++++++++-
qemu-img.texi | 6
qemu-options.hx | 9 +
scripts/checkpatch.pl | 4
target-alpha/cpu.h | 2
target-arm/cpu.h | 2
target-ppc/cpu.h | 2
target-sparc/cpu.h | 49 ++++--
target-sparc/op_helper.c | 75 ++++++----
target-sparc/translate.c | 29 ++-
tcg/README | 10 +
trace-events | 17 +-
ui/spice-core.c | 5
ui/spice-display.c | 5
vl.c | 11 +
xen-all.c | 73 +++++++++-
xen-mapcache-stub.c | 36 ----
xen-mapcache.c | 41 +++--
xen-mapcache.h | 14 -
xen-stub.c | 4
106 files changed, 2108 insertions(+), 720 deletions(-)
New commits:
commit 03ff09580ef6cbc4a893b6e3e6bbff33180ec70a
Merge: b4dabf9... 25a1181...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date: Tue Jul 19 08:04:35 2011 -0500
Merge remote-tracking branch 'agraf/xen-next' into staging
commit b4dabf9587d8e1d5d5edc6d3326021e390b9a532
Merge: de20fbc... 3dc345d...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date: Tue Jul 19 08:03:20 2011 -0500
Merge remote-tracking branch 'kraxel/usb.19' into staging
diff --cc hw/pci_ids.h
index b49c602,927f2b0..83f3893
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@@ -109,6 -109,13 +109,14 @@@
#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
+ #define PCI_DEVICE_ID_INTEL_82801I_UHCI1 0x2934
+ #define PCI_DEVICE_ID_INTEL_82801I_UHCI2 0x2935
+ #define PCI_DEVICE_ID_INTEL_82801I_UHCI3 0x2936
+ #define PCI_DEVICE_ID_INTEL_82801I_UHCI4 0x2937
+ #define PCI_DEVICE_ID_INTEL_82801I_UHCI5 0x2938
+ #define PCI_DEVICE_ID_INTEL_82801I_UHCI6 0x2939
+ #define PCI_DEVICE_ID_INTEL_82801I_EHCI1 0x293a
+ #define PCI_DEVICE_ID_INTEL_82801I_EHCI2 0x293c
-#define PCI_VENDOR_ID_XENSOURCE 0x5853
+#define PCI_VENDOR_ID_XEN 0x5853
+#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
commit de20fbcac9d71fc91635919bfbe0883a7df71887
Merge: 6734529... a3d1405...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date: Tue Jul 19 08:02:35 2011 -0500
Merge remote-tracking branch 'spice/spice.v38' into staging
commit 6734529435bafb0c59c951b3e16f4600c685ee39
Merge: 81773a5... c8eac1c...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date: Tue Jul 19 07:43:54 2011 -0500
Merge remote-tracking branch 'mst/for_anthony' into staging
commit 81773a505554dfbe3f3f48653ab1a02455e9e5ff
Merge: 0219d73... 6fea2ea...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date: Tue Jul 19 07:43:51 2011 -0500
Merge remote-tracking branch 'riku/linux-user-for-upstream' into staging
commit 0219d73283b6399a737ef5a098f849b956618eaa
Author: Amit Shah <amit.shah at redhat.com>
Date: Thu Jul 7 17:35:27 2011 +0530
virtio-console: Prevent abort()s in case of host chardev close
A host chardev could close just before the guest sends some data to be
written. This will cause an -EPIPE error. This shouldn't be propagated
to virtio-serial-bus.
Ideally we should close the port once -EPIPE is received, but since the
chardev interface doesn't return such meaningful values to its users,
all we get is -1 for any kind of error. Just return 0 for now and wait
for chardevs to return better error messages to act better on the return
messages.
Signed-off-by: Amit Shah <amit.shah at redhat.com>
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 713a761..7ebfa26 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -28,8 +28,22 @@ static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
ssize_t ret;
ret = qemu_chr_write(vcon->chr, buf, len);
-
trace_virtio_console_flush_buf(port->id, len, ret);
+
+ if (ret < 0) {
+ /*
+ * Ideally we'd get a better error code than just -1, but
+ * that's what the chardev interface gives us right now. If
+ * we had a finer-grained message, like -EPIPE, we could close
+ * this connection. Absent such error messages, the most we
+ * can do is to return 0 here.
+ *
+ * This will prevent stray -1 values to go to
+ * virtio-serial-bus.c and cause abort()s in
+ * do_flush_queued_data().
+ */
+ ret = 0;
+ }
return ret;
}
commit 95c9cde2dff9de9f4afa0450697bd70f56715be1
Author: Amit Shah <amit.shah at redhat.com>
Date: Thu Jul 7 18:16:13 2011 +0530
virtio-serial-bus: Fix trailing \n in error_report string
Markus fixed offenders in the file but one instance sneaked in via
another patch. Fix it.
Signed-off-by: Amit Shah <amit.shah at redhat.com>
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 9859f9f..6d73386 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -351,7 +351,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
port = find_port_by_id(vser, ldl_p(&gcpkt->id));
if (!port) {
- error_report("virtio-serial-bus: Unexpected port id %u for device %s\n",
+ error_report("virtio-serial-bus: Unexpected port id %u for device %s",
ldl_p(&gcpkt->id), vser->bus.qbus.name);
return;
}
commit d02e4fa4a8e180c0a312b7c520a167894a0c8a83
Author: Amit Shah <amit.shah at redhat.com>
Date: Tue Jul 5 16:37:49 2011 +0530
virtio-console: Add some trace events
Add some trace events for messages passed between the char layer and the
virtio-serial bus.
Signed-off-by: Amit Shah <amit.shah at redhat.com>
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index b076331..713a761 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -12,6 +12,7 @@
#include "qemu-char.h"
#include "qemu-error.h"
+#include "trace.h"
#include "virtio-serial.h"
typedef struct VirtConsole {
@@ -24,8 +25,12 @@ typedef struct VirtConsole {
static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
{
VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+ ssize_t ret;
- return qemu_chr_write(vcon->chr, buf, len);
+ ret = qemu_chr_write(vcon->chr, buf, len);
+
+ trace_virtio_console_flush_buf(port->id, len, ret);
+ return ret;
}
/* Callback function that's called when the guest opens the port */
@@ -57,6 +62,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
{
VirtConsole *vcon = opaque;
+ trace_virtio_console_chr_read(vcon->port.id, size);
virtio_serial_write(&vcon->port, buf, size);
}
@@ -64,6 +70,7 @@ static void chr_event(void *opaque, int event)
{
VirtConsole *vcon = opaque;
+ trace_virtio_console_chr_event(vcon->port.id, event);
switch (event) {
case CHR_EVENT_OPENED:
virtio_serial_open(&vcon->port);
diff --git a/trace-events b/trace-events
index 59420e8..765a15e 100644
--- a/trace-events
+++ b/trace-events
@@ -52,6 +52,11 @@ disable virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u,
disable virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event %u, value %u"
disable virtio_serial_handle_control_message_port(unsigned int port) "port %u"
+# hw/virtio-console.c
+disable virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) "port %u, in_len %zu, out_len %zd"
+disable virtio_console_chr_read(unsigned int port, int size) "port %u, size %d"
+disable virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
+
# block.c
disable multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
disable bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
commit 49e3fdd7f2f3ecccc6f75d976246124d0edaec3f
Author: Amit Shah <amit.shah at redhat.com>
Date: Tue Jul 5 16:36:39 2011 +0530
virtio-serial-bus: Add trace events
Add some trace events for messages passed between the guest and host.
Signed-off-by: Amit Shah <amit.shah at redhat.com>
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 7f6db7b..9859f9f 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -19,6 +19,7 @@
#include "monitor.h"
#include "qemu-queue.h"
#include "sysbus.h"
+#include "trace.h"
#include "virtio-serial.h"
/* The virtio-serial bus on top of which the ports will ride as devices */
@@ -221,6 +222,7 @@ static size_t send_control_event(VirtIOSerialPort *port, uint16_t event,
stw_p(&cpkt.event, event);
stw_p(&cpkt.value, value);
+ trace_virtio_serial_send_control_event(port->id, event, value);
return send_control_msg(port, &cpkt, sizeof(cpkt));
}
@@ -302,6 +304,7 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
return;
}
+ trace_virtio_serial_throttle_port(port->id, throttle);
port->throttled = throttle;
if (throttle) {
return;
@@ -328,6 +331,8 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
cpkt.event = lduw_p(&gcpkt->event);
cpkt.value = lduw_p(&gcpkt->value);
+ trace_virtio_serial_handle_control_message(cpkt.event, cpkt.value);
+
if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) {
if (!cpkt.value) {
error_report("virtio-serial-bus: Guest failure in adding device %s",
@@ -351,6 +356,8 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
return;
}
+ trace_virtio_serial_handle_control_message_port(port->id);
+
info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
switch(cpkt.event) {
diff --git a/trace-events b/trace-events
index bebf612..59420e8 100644
--- a/trace-events
+++ b/trace-events
@@ -46,6 +46,12 @@ disable virtio_queue_notify(void *vdev, int n, void *vq) "vdev %p n %d vq %p"
disable virtio_irq(void *vq) "vq %p"
disable virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
+# hw/virtio-serial-bus.c
+disable virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) "port %u, event %u, value %u"
+disable virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u, throttle %d"
+disable virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event %u, value %u"
+disable virtio_serial_handle_control_message_port(unsigned int port) "port %u"
+
# block.c
disable multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
disable bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
commit c8eac1cfa1e9104a658b4614ada758861b8d823a
Author: Michael S. Tsirkin <mst at redhat.com>
Date: Mon Jun 20 13:42:27 2011 +0300
virtio: fix indirect descriptor buffer overflow
We were previously allowing arbitrarily-long indirect descriptors, which
could lead to a buffer overflow in qemu-kvm process.
CVE-2011-2212
Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
diff --git a/hw/virtio.c b/hw/virtio.c
index cc47a06..a8f4940 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -449,9 +449,17 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
struct iovec *sg;
if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
+ if (elem->in_num >= ARRAY_SIZE(elem->in_sg)) {
+ error_report("Too many write descriptors in indirect table");
+ exit(1);
+ }
elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i);
sg = &elem->in_sg[elem->in_num++];
} else {
+ if (elem->out_num >= ARRAY_SIZE(elem->out_sg)) {
+ error_report("Too many read descriptors in indirect table");
+ exit(1);
+ }
elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i);
sg = &elem->out_sg[elem->out_num++];
}
commit 0d2b962d16feaf1eb1a4658a4c1b85642418cd07
Author: Michael S. Tsirkin <mst at redhat.com>
Date: Sun Jun 26 16:30:45 2011 +0300
xen: move to new pci initializers
move ids to pci info structure
Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index 9a01735..f43e175 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -290,18 +290,10 @@ static int xen_platform_initfn(PCIDevice *dev)
pci_conf = d->pci_dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_XEN);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_XEN_PLATFORM);
- pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_XEN);
- pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, PCI_DEVICE_ID_XEN_PLATFORM);
-
pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
- pci_config_set_revision(pci_conf, 1);
pci_config_set_prog_interface(pci_conf, 0);
- pci_config_set_class(pci_conf, PCI_CLASS_OTHERS << 8 | 0x80);
-
pci_conf[PCI_INTERRUPT_PIN] = 1;
pci_register_bar(&d->pci_dev, 0, 0x100,
@@ -330,6 +322,13 @@ static PCIDeviceInfo xen_platform_info = {
.qdev.size = sizeof(PCIXenPlatformState),
.qdev.vmsd = &vmstate_xen_platform,
.qdev.reset = platform_reset,
+
+ .vendor_id = PCI_VENDOR_ID_XEN,
+ .device_id = PCI_DEVICE_ID_XEN_PLATFORM,
+ .class_id = PCI_CLASS_OTHERS << 8 | 0x80,
+ .subsystem_vendor_id = PCI_VENDOR_ID_XEN,
+ .subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM,
+ .revision = 1,
};
static void xen_platform_register(void)
commit ce4fd422a6c5119baf4a2c3115c7ea63efb0f68e
Author: Anthony PERARD <anthony.perard at citrix.com>
Date: Wed Jun 22 16:58:31 2011 +0100
hw/piix_pci.c: Fix PIIX3-xen to initialize ids
Signed-off-by: Anthony PERARD <anthony.perard at citrix.com>
Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 26ce904..d08b31a 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -478,6 +478,9 @@ static PCIDeviceInfo i440fx_info[] = {
.no_hotplug = 1,
.init = piix3_initfn,
.config_write = piix3_write_config_xen,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+ .class_id = PCI_CLASS_BRIDGE_ISA,
},{
/* end of list */
}
commit 33d5ad53c1039989c4ecf583ed52a584d3888495
Author: Michael S. Tsirkin <mst at redhat.com>
Date: Sun Jun 26 16:17:27 2011 +0300
pci_ids: tweak names to match linux/pci_ids.h
Sync xen names to ones used by linux. Add
xen platform device id as well.
Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index d94578c..b49c602 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -110,4 +110,5 @@
#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
-#define PCI_VENDOR_ID_XENSOURCE 0x5853
+#define PCI_VENDOR_ID_XEN 0x5853
+#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index b167eee..9a01735 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -290,10 +290,10 @@ static int xen_platform_initfn(PCIDevice *dev)
pci_conf = d->pci_dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_XENSOURCE);
- pci_config_set_device_id(pci_conf, 0x0001);
- pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_XENSOURCE);
- pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0001);
+ pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_XEN);
+ pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_XEN_PLATFORM);
+ pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_XEN);
+ pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, PCI_DEVICE_ID_XEN_PLATFORM);
pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
commit c1be973ae1135588ed77b365bfd3bf063bac78ae
Author: Michael S. Tsirkin <mst at redhat.com>
Date: Tue Jun 21 20:34:17 2011 +0300
vhost: fix double free on device stop
vhost dev stop failed to clear the log field.
Typically not an issue as dev start overwrites this field,
but if logging gets disabled before the following start,
it doesn't so this causes a double free.
Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
diff --git a/hw/vhost.c b/hw/vhost.c
index 80f771e..c3d8821 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -784,5 +784,6 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
hdev->started = false;
qemu_free(hdev->log);
+ hdev->log = NULL;
hdev->log_size = 0;
}
commit 25a118130fde0d20b0f5a223642849b392b2f2ee
Author: Alexander Graf <agraf at suse.de>
Date: Sun Jul 3 09:44:48 2011 +0200
xen_console: fall back to qemu serial device
The new xen_console protocol changed the default xen_console output device
from whatever Qemu chose to whatever xenstore choses and "pty" as fallback.
This is not how Qemu works. It has its own serial redirection semantics. So
it xenstore doesn't contain information on what to do, Qemu is the place to
ask.
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/hw/xen_console.c b/hw/xen_console.c
index bdb8540..8ef104c 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -196,12 +196,15 @@ static int con_init(struct XenDevice *xendev)
}
output = xenstore_read_str(con->console, "output");
- /* output is a pty by default */
+
+ /* no Xen override, use qemu output device */
if (output == NULL) {
- output = "pty";
+ con->chr = serial_hds[con->xendev.dev];
+ } else {
+ snprintf(label, sizeof(label), "xencons%d", con->xendev.dev);
+ con->chr = qemu_chr_open(label, output, NULL);
}
- snprintf(label, sizeof(label), "xencons%d", con->xendev.dev);
- con->chr = qemu_chr_open(label, output, NULL);
+
xenstore_store_pv_console_info(con->xendev.dev, con->chr);
out:
commit 0f51726adcdb620214405a88b2601d9edd059db4
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date: Thu Jun 30 18:26:29 2011 +0100
xen_console: support the new extended xenstore protocol
Since CS 21994 on xen-unstable.hg and CS
466608f3a32e1f9808acdf832a5843af37e5fcec on qemu-xen-unstable.git, few
changes have been introduced to the PV console xenstore protocol, as
described by the document docs/misc/console.txt under xen-unstable.hg.
From the Qemu point of view, very few modifications are needed to
correctly support the protocol: read from xenstore the "output" node
that tell us what the output of the PV console is going to be.
In case the output is a tty, write to xenstore the device name.
Changes in v2:
- fix error paths: free malloc'ed strings and close the xenstore
connection before returning;
- remove useless snprintf in xenstore_store_pv_console_info if i == 0.
Changes in v3:
- replace xs_daemon_open/xs_daemon_close with xs_open/xs_close.
Changes in v4:
- add a compatibility implementation of xs_open/xs_close.
Changes in v5:
- fix code style.
[agraf] fix build error due to missing stub
Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/hw/xen.h b/hw/xen.h
index 95029bb..e432705 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -41,6 +41,7 @@ qemu_irq *xen_interrupt_controller_init(void);
int xen_init(void);
int xen_hvm_init(void);
void xen_vcpu_init(void);
+void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);
#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size);
diff --git a/hw/xen_common.h b/hw/xen_common.h
index 2c79af6..0409ac7 100644
--- a/hw/xen_common.h
+++ b/hw/xen_common.h
@@ -85,6 +85,18 @@ static inline int xc_domain_add_to_physmap(int xc_handle, uint32_t domid,
return xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
}
+static inline struct xs_handle *xs_open(unsigned long flags)
+{
+ return xs_daemon_open();
+}
+
+static inline void xs_close(struct xs_handle *xsh)
+{
+ if (xsh != NULL) {
+ xs_daemon_close(xsh);
+ }
+}
+
/* Xen 4.1 */
#else
diff --git a/hw/xen_console.c b/hw/xen_console.c
index 2d613ee..bdb8540 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -179,8 +179,9 @@ static void xencons_send(struct XenConsole *con)
static int con_init(struct XenDevice *xendev)
{
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
- char *type, *dom;
+ char *type, *dom, label[32];
int ret = 0;
+ const char *output;
/* setup */
dom = xs_get_domain_path(xenstore, con->xendev.dom);
@@ -194,11 +195,14 @@ static int con_init(struct XenDevice *xendev)
goto out;
}
- if (!serial_hds[con->xendev.dev])
- xen_be_printf(xendev, 1, "WARNING: serial line %d not configured\n",
- con->xendev.dev);
- else
- con->chr = serial_hds[con->xendev.dev];
+ output = xenstore_read_str(con->console, "output");
+ /* output is a pty by default */
+ if (output == NULL) {
+ output = "pty";
+ }
+ snprintf(label, sizeof(label), "xencons%d", con->xendev.dev);
+ con->chr = qemu_chr_open(label, output, NULL);
+ xenstore_store_pv_console_info(con->xendev.dev, con->chr);
out:
qemu_free(type);
diff --git a/xen-all.c b/xen-all.c
index fb9bcc8..8105c83 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -737,6 +737,66 @@ static void cpu_handle_ioreq(void *opaque)
}
}
+static int store_dev_info(int domid, CharDriverState *cs, const char *string)
+{
+ struct xs_handle *xs = NULL;
+ char *path = NULL;
+ char *newpath = NULL;
+ char *pts = NULL;
+ int ret = -1;
+
+ /* Only continue if we're talking to a pty. */
+ if (strncmp(cs->filename, "pty:", 4)) {
+ return 0;
+ }
+ pts = cs->filename + 4;
+
+ /* We now have everything we need to set the xenstore entry. */
+ xs = xs_open(0);
+ if (xs == NULL) {
+ fprintf(stderr, "Could not contact XenStore\n");
+ goto out;
+ }
+
+ path = xs_get_domain_path(xs, domid);
+ if (path == NULL) {
+ fprintf(stderr, "xs_get_domain_path() error\n");
+ goto out;
+ }
+ newpath = realloc(path, (strlen(path) + strlen(string) +
+ strlen("/tty") + 1));
+ if (newpath == NULL) {
+ fprintf(stderr, "realloc error\n");
+ goto out;
+ }
+ path = newpath;
+
+ strcat(path, string);
+ strcat(path, "/tty");
+ if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
+ fprintf(stderr, "xs_write for '%s' fail", string);
+ goto out;
+ }
+ ret = 0;
+
+out:
+ free(path);
+ xs_close(xs);
+
+ return ret;
+}
+
+void xenstore_store_pv_console_info(int i, CharDriverState *chr)
+{
+ if (i == 0) {
+ store_dev_info(xen_domid, chr, "/console");
+ } else {
+ char buf[32];
+ snprintf(buf, sizeof(buf), "/device/console/%d", i);
+ store_dev_info(xen_domid, chr, buf);
+ }
+}
+
static void xenstore_record_dm_state(XenIOState *s, const char *state)
{
char path[50];
diff --git a/xen-stub.c b/xen-stub.c
index a4f35a1..efe2ab5 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -9,6 +9,10 @@
#include "qemu-common.h"
#include "hw/xen.h"
+void xenstore_store_pv_console_info(int i, CharDriverState *chr)
+{
+}
+
int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
{
return -1;
commit 9fbe4784449f6248224ac95e0aa9e56a0bfdd155
Author: Alexander Graf <agraf at suse.de>
Date: Wed Jun 29 08:04:27 2011 +0200
checkpatch: don't error out on },{ lines
When having code like this:
static PCIDeviceInfo piix_ide_info[] = {
{
.qdev.name = "piix3-ide",
.qdev.size = sizeof(PCIIDEState),
.qdev.no_user = 1,
.no_hotplug = 1,
.init = pci_piix_ide_initfn,
.vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82371SB_1,
.class_id = PCI_CLASS_STORAGE_IDE,
},{
.qdev.name = "piix4-ide",
.qdev.size = sizeof(PCIIDEState),
.qdev.no_user = 1,
.no_hotplug = 1,
.init = pci_piix_ide_initfn,
.vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82371AB,
.class_id = PCI_CLASS_STORAGE_IDE,
},{
/* end of list */
}
};
checkpatch currently errors out, claiming that spaces need to follow
commas. However, this particular style of defining structs is pretty
common in qemu code and very readable. So let's declare it as supported
for the above case.
Reported-by: Kevin Wolf <kwolf at redhat.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 075b614..70a2111 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2068,8 +2068,10 @@ sub process {
}
# , must have a space on the right.
+ # not required when having a single },{ on one line
} elsif ($op eq ',') {
- if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
+ if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/ &&
+ ($elements[$n] . $elements[$n + 2]) !~ " *}{") {
ERROR("space required after that '$op' $at\n" . $hereptr);
}
commit 7cef3f4fdbe813ac7d495e15a81531f1181b19f9
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date: Thu Jun 30 15:42:31 2011 +0100
xen_disk: treat "aio" as "raw"
Sometimes the toolstack uses "aio" without an additional format
identifier, in such cases use "raw".
Updated in v2:
- fix code style.
Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index f14e5a6..add815f 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -633,6 +633,9 @@ static int blk_init(struct XenDevice *xendev)
blkdev->filename = blkdev->params;
}
}
+ if (!strcmp("aio", blkdev->fileproto)) {
+ blkdev->fileproto = "raw";
+ }
if (blkdev->mode == NULL) {
blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode");
}
commit 8ab934f93b5ad3d0af4ad419d2531235a75d672c
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date: Mon Jun 27 18:26:06 2011 +0100
qemu_ram_ptr_length: take ram_addr_t as arguments
qemu_ram_ptr_length should take ram_addr_t as argument rather than
target_phys_addr_t because is doing comparisons with RAMBlock addresses.
cpu_physical_memory_map should create a ram_addr_t address to pass to
qemu_ram_ptr_length from PhysPageDesc phys_offset.
Remove code after abort() in qemu_ram_ptr_length.
Changes in v2:
- handle 0 size in qemu_ram_ptr_length;
- rename addr1 to raddr;
- initialize raddr to ULONG_MAX.
Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/cpu-common.h b/cpu-common.h
index c6a2b5f..a5b80e1 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -65,7 +65,7 @@ void qemu_ram_free_from_ptr(ram_addr_t addr);
void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
/* This should only be used for ram local to a device. */
void *qemu_get_ram_ptr(ram_addr_t addr);
-void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size);
+void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size);
/* Same but slower, to use for migration, where the order of
* RAMBlocks must not change. */
void *qemu_safe_ram_ptr(ram_addr_t addr);
diff --git a/exec.c b/exec.c
index 067bb34..8277900 100644
--- a/exec.c
+++ b/exec.c
@@ -3167,8 +3167,11 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
/* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr
* but takes a size argument */
-void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size)
+void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size)
{
+ if (*size == 0) {
+ return NULL;
+ }
if (xen_enabled()) {
return xen_map_cache(addr, *size, 1);
} else {
@@ -3184,9 +3187,6 @@ void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size)
fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
abort();
-
- *size = 0;
- return NULL;
}
}
@@ -4052,7 +4052,9 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
target_phys_addr_t page;
unsigned long pd;
PhysPageDesc *p;
- target_phys_addr_t addr1 = addr;
+ ram_addr_t raddr = ULONG_MAX;
+ ram_addr_t rlen;
+ void *ret;
while (len > 0) {
page = addr & TARGET_PAGE_MASK;
@@ -4080,13 +4082,18 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
*plen = l;
return bounce.buffer;
}
+ if (!todo) {
+ raddr = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
+ }
len -= l;
addr += l;
todo += l;
}
- *plen = todo;
- return qemu_ram_ptr_length(addr1, plen);
+ rlen = todo;
+ ret = qemu_ram_ptr_length(raddr, &rlen);
+ *plen = rlen;
+ return ret;
}
/* Unmaps a memory region previously mapped by cpu_physical_memory_map().
commit 5ea3c2b405e1a0937e8ccfdb57345628eb904525
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date: Mon Jun 27 16:10:01 2011 +0100
xen_disk: cope with missing xenstore "params" node
When disk is a cdrom and the drive is empty the "params" node in
xenstore might be missing completely: cope with it instead of
segfaulting.
Updated in v2:
- actually removed the strchr(blkdev->params, ':') that caused the
segfault;
- free all the allocated strings from xenstore before returning;
Updated in v3:
- set blkdev fields to NULL after free'ing them.
Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 0c298af..f14e5a6 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -616,12 +616,14 @@ static int blk_init(struct XenDevice *xendev)
{
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
int index, qflags, have_barriers, info = 0;
- char *h;
/* read xenstore entries */
if (blkdev->params == NULL) {
+ char *h = NULL;
blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params");
- h = strchr(blkdev->params, ':');
+ if (blkdev->params != NULL) {
+ h = strchr(blkdev->params, ':');
+ }
if (h != NULL) {
blkdev->fileproto = blkdev->params;
blkdev->filename = h+1;
@@ -649,7 +651,7 @@ static int blk_init(struct XenDevice *xendev)
blkdev->mode == NULL ||
blkdev->type == NULL ||
blkdev->dev == NULL) {
- return -1;
+ goto out_error;
}
/* read-only ? */
@@ -672,10 +674,15 @@ static int blk_init(struct XenDevice *xendev)
/* setup via xenbus -> create new block driver instance */
xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
blkdev->bs = bdrv_new(blkdev->dev);
- if (bdrv_open(blkdev->bs, blkdev->filename, qflags,
- bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) {
- bdrv_delete(blkdev->bs);
- return -1;
+ if (blkdev->bs) {
+ if (bdrv_open(blkdev->bs, blkdev->filename, qflags,
+ bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) {
+ bdrv_delete(blkdev->bs);
+ blkdev->bs = NULL;
+ }
+ }
+ if (!blkdev->bs) {
+ goto out_error;
}
} else {
/* setup via qemu cmdline -> already setup for us */
@@ -704,6 +711,19 @@ static int blk_init(struct XenDevice *xendev)
xenstore_write_be_int(&blkdev->xendev, "sectors",
blkdev->file_size / blkdev->file_blk);
return 0;
+
+out_error:
+ qemu_free(blkdev->params);
+ blkdev->params = NULL;
+ qemu_free(blkdev->mode);
+ blkdev->mode = NULL;
+ qemu_free(blkdev->type);
+ blkdev->type = NULL;
+ qemu_free(blkdev->dev);
+ blkdev->dev = NULL;
+ qemu_free(blkdev->devtype);
+ blkdev->devtype = NULL;
+ return -1;
}
static int blk_connect(struct XenDevice *xendev)
commit 37cdfcf194825d03334542297bee3a3a4723e6e3
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date: Fri Jun 24 17:36:11 2011 +0100
xen: add vkbd support for PV on HVM guests
Register the vkbd backend even when running as device emulator for HVM
guests: it is useful because it doesn't need a frequent timer like usb.
Check whether the XenInput DisplayState has been set in the initialise
state, rather than the input state.
In case the DisplayState hasn't been set and there is no vfb for this
domain, then set the XenInput DisplayState to the default one.
Changed in v2:
- use qemu_free instead of free;
Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 1db75fb..0a01ae3 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -347,13 +347,6 @@ static void xenfb_mouse_event(void *opaque,
static int input_init(struct XenDevice *xendev)
{
- struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
-
- if (!in->c.ds) {
- xen_be_printf(xendev, 1, "ds not set (yet)\n");
- return -1;
- }
-
xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
return 0;
}
@@ -367,6 +360,18 @@ static int input_connect(struct XenDevice *xendev)
&in->abs_pointer_wanted) == -1)
in->abs_pointer_wanted = 0;
+ if (!in->c.ds) {
+ char *vfb = xenstore_read_str(NULL, "device/vfb");
+ if (vfb == NULL) {
+ /* there is no vfb, run vkbd on its own */
+ in->c.ds = get_displaystate();
+ } else {
+ qemu_free(vfb);
+ xen_be_printf(xendev, 1, "ds not set (yet)\n");
+ return -1;
+ }
+ }
+
rc = common_bind(&in->c);
if (rc != 0)
return rc;
diff --git a/xen-all.c b/xen-all.c
index 3d40ab0..fb9bcc8 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -868,6 +868,7 @@ int xen_hvm_init(void)
exit(1);
}
xen_be_register("console", &xen_console_ops);
+ xen_be_register("vkbd", &xen_kbdmouse_ops);
xen_be_register("qdisk", &xen_blkdev_ops);
return 0;
commit 5e6b701aba8689a336297dda047bf760ffc05291
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date: Fri Jun 24 16:59:46 2011 +0100
xen_console: fix memory leak
con_init leaks the string "type", fix it.
Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/hw/xen_console.c b/hw/xen_console.c
index c6c8163..2d613ee 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -180,6 +180,7 @@ static int con_init(struct XenDevice *xendev)
{
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
char *type, *dom;
+ int ret = 0;
/* setup */
dom = xs_get_domain_path(xenstore, con->xendev.dom);
@@ -189,7 +190,8 @@ static int con_init(struct XenDevice *xendev)
type = xenstore_read_str(con->console, "type");
if (!type || strcmp(type, "ioemu") != 0) {
xen_be_printf(xendev, 1, "not for me (type=%s)\n", type);
- return -1;
+ ret = -1;
+ goto out;
}
if (!serial_hds[con->xendev.dev])
@@ -198,7 +200,9 @@ static int con_init(struct XenDevice *xendev)
else
con->chr = serial_hds[con->xendev.dev];
- return 0;
+out:
+ qemu_free(type);
+ return ret;
}
static int con_connect(struct XenDevice *xendev)
commit ad35a7da1a0a40cd8920ba829640bd43e1613ec1
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date: Fri Jun 24 15:54:48 2011 +0100
xen: enable console and disk backend in HVM mode
Initialize the Xen console backend and the Xen disk backend even when
running in HVM mode so that PV on HVM drivers can connect to them.
Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/xen-all.c b/xen-all.c
index 4827d6a..3d40ab0 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -862,6 +862,14 @@ int xen_hvm_init(void)
cpu_register_phys_memory_client(&state->client);
state->log_for_dirtybit = NULL;
+ /* Initialize backend core & drivers */
+ if (xen_be_init() != 0) {
+ fprintf(stderr, "%s: xen backend core setup failed\n", __FUNCTION__);
+ exit(1);
+ }
+ xen_be_register("console", &xen_console_ops);
+ xen_be_register("qdisk", &xen_blkdev_ops);
+
return 0;
}
commit 868bb33faa643c7ee291bb308a829122b72d4845
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date: Tue Jun 21 22:59:09 2011 +0200
xen: Fold CONFIG_XEN_MAPCACHE into CONFIG_XEN
Xen won't be enabled if there is no backend support available for the
host. And that also means the map cache will work. So drop the separate
config switch and move the required stubs over to xen-stub.c.
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/Makefile.target b/Makefile.target
index c347176..c566eb1 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -4,7 +4,6 @@ GENERATED_HEADERS = config-target.h
CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
-CONFIG_NO_XEN_MAPCACHE = $(if $(subst n,,$(CONFIG_XEN_MAPCACHE)),n,y)
include ../config-host.mak
include config-devices.mak
@@ -207,10 +206,8 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
# xen support
-obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o
+obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o xen-mapcache.o
obj-$(CONFIG_NO_XEN) += xen-stub.o
-obj-i386-$(CONFIG_XEN_MAPCACHE) += xen-mapcache.o
-obj-$(CONFIG_NO_XEN_MAPCACHE) += xen-mapcache-stub.o
obj-i386-$(CONFIG_XEN) += xen_platform.o
diff --git a/exec.c b/exec.c
index 50bccd8..067bb34 100644
--- a/exec.c
+++ b/exec.c
@@ -2953,7 +2953,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
abort();
}
#else
- if (xen_mapcache_enabled()) {
+ if (xen_enabled()) {
xen_ram_alloc(new_block->offset, size);
} else {
new_block->host = qemu_vmalloc(size);
@@ -3019,7 +3019,7 @@ void qemu_ram_free(ram_addr_t addr)
#if defined(TARGET_S390X) && defined(CONFIG_KVM)
munmap(block->host, block->length);
#else
- if (xen_mapcache_enabled()) {
+ if (xen_enabled()) {
xen_invalidate_map_cache_entry(block->host);
} else {
qemu_vfree(block->host);
@@ -3112,7 +3112,7 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
QLIST_REMOVE(block, next);
QLIST_INSERT_HEAD(&ram_list.blocks, block, next);
}
- if (xen_mapcache_enabled()) {
+ if (xen_enabled()) {
/* We need to check if the requested address is in the RAM
* because we don't want to map the entire memory in QEMU.
* In that case just map until the end of the page.
@@ -3143,7 +3143,7 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (addr - block->offset < block->length) {
- if (xen_mapcache_enabled()) {
+ if (xen_enabled()) {
/* We need to check if the requested address is in the RAM
* because we don't want to map the entire memory in QEMU.
* In that case just map until the end of the page.
@@ -3169,9 +3169,9 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
* but takes a size argument */
void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size)
{
- if (xen_mapcache_enabled())
+ if (xen_enabled()) {
return xen_map_cache(addr, *size, 1);
- else {
+ } else {
RAMBlock *block;
QLIST_FOREACH(block, &ram_list.blocks, next) {
@@ -3200,7 +3200,7 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
RAMBlock *block;
uint8_t *host = ptr;
- if (xen_mapcache_enabled()) {
+ if (xen_enabled()) {
*ram_addr = xen_ram_addr_from_mapcache(ptr);
return 0;
}
@@ -4115,7 +4115,7 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
access_len -= l;
}
}
- if (xen_mapcache_enabled()) {
+ if (xen_enabled()) {
xen_invalidate_map_cache_entry(buffer);
}
return;
diff --git a/hw/xen.h b/hw/xen.h
index d435ca0..95029bb 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -31,15 +31,6 @@ static inline int xen_enabled(void)
#endif
}
-static inline int xen_mapcache_enabled(void)
-{
-#ifdef CONFIG_XEN_MAPCACHE
- return xen_enabled();
-#else
- return 0;
-#endif
-}
-
int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
void xen_piix3_set_irq(void *opaque, int irq_num, int level);
void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
diff --git a/xen-mapcache-stub.c b/xen-mapcache-stub.c
deleted file mode 100644
index f037016..0000000
--- a/xen-mapcache-stub.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2011 Citrix Ltd.
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "config.h"
-
-#include "cpu.h"
-#include "qemu-common.h"
-#include "cpu-common.h"
-#include "xen-mapcache.h"
-
-void xen_map_cache_init(void)
-{
-}
-
-uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
- uint8_t lock)
-{
- return qemu_get_ram_ptr(phys_addr);
-}
-
-ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
-{
- return -1;
-}
-
-void xen_invalidate_map_cache(void)
-{
-}
-
-void xen_invalidate_map_cache_entry(uint8_t *buffer)
-{
-}
commit e41d7c691ad7f4ad78573f72048eecb16f78974a
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date: Tue Jun 21 22:59:08 2011 +0200
xen: Clean up map cache API naming
The map cache is a Xen thing, so its API should make this clear.
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/exec.c b/exec.c
index f1777e6..50bccd8 100644
--- a/exec.c
+++ b/exec.c
@@ -3020,7 +3020,7 @@ void qemu_ram_free(ram_addr_t addr)
munmap(block->host, block->length);
#else
if (xen_mapcache_enabled()) {
- qemu_invalidate_entry(block->host);
+ xen_invalidate_map_cache_entry(block->host);
} else {
qemu_vfree(block->host);
}
@@ -3118,9 +3118,10 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
* In that case just map until the end of the page.
*/
if (block->offset == 0) {
- return qemu_map_cache(addr, 0, 0);
+ return xen_map_cache(addr, 0, 0);
} else if (block->host == NULL) {
- block->host = qemu_map_cache(block->offset, block->length, 1);
+ block->host =
+ xen_map_cache(block->offset, block->length, 1);
}
}
return block->host + (addr - block->offset);
@@ -3148,9 +3149,10 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
* In that case just map until the end of the page.
*/
if (block->offset == 0) {
- return qemu_map_cache(addr, 0, 0);
+ return xen_map_cache(addr, 0, 0);
} else if (block->host == NULL) {
- block->host = qemu_map_cache(block->offset, block->length, 1);
+ block->host =
+ xen_map_cache(block->offset, block->length, 1);
}
}
return block->host + (addr - block->offset);
@@ -3168,7 +3170,7 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size)
{
if (xen_mapcache_enabled())
- return qemu_map_cache(addr, *size, 1);
+ return xen_map_cache(addr, *size, 1);
else {
RAMBlock *block;
@@ -3199,7 +3201,7 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
uint8_t *host = ptr;
if (xen_mapcache_enabled()) {
- *ram_addr = qemu_ram_addr_from_mapcache(ptr);
+ *ram_addr = xen_ram_addr_from_mapcache(ptr);
return 0;
}
@@ -4114,7 +4116,7 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
}
}
if (xen_mapcache_enabled()) {
- qemu_invalidate_entry(buffer);
+ xen_invalidate_map_cache_entry(buffer);
}
return;
}
diff --git a/trace-events b/trace-events
index bebf612..2372385 100644
--- a/trace-events
+++ b/trace-events
@@ -399,9 +399,9 @@ disable xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#
disable xen_client_set_memory(uint64_t start_addr, unsigned long size, unsigned long phys_offset, bool log_dirty) "%#"PRIx64" size %#lx, offset %#lx, log_dirty %i"
# xen-mapcache.c
-disable qemu_map_cache(uint64_t phys_addr) "want %#"PRIx64""
-disable qemu_remap_bucket(uint64_t index) "index %#"PRIx64""
-disable qemu_map_cache_return(void* ptr) "%p"
+disable xen_map_cache(uint64_t phys_addr) "want %#"PRIx64""
+disable xen_remap_bucket(uint64_t index) "index %#"PRIx64""
+disable xen_map_cache_return(void* ptr) "%p"
disable xen_map_block(uint64_t phys_addr, uint64_t size) "%#"PRIx64", size %#"PRIx64""
disable xen_unmap_block(void* addr, unsigned long size) "%p, size %#lx"
diff --git a/xen-all.c b/xen-all.c
index fcb106f..4827d6a 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -644,7 +644,7 @@ static void handle_ioreq(ioreq_t *req)
case IOREQ_TYPE_TIMEOFFSET:
break;
case IOREQ_TYPE_INVALIDATE:
- qemu_invalidate_map_cache();
+ xen_invalidate_map_cache();
break;
default:
hw_error("Invalid ioreq type 0x%x\n", req->type);
@@ -852,7 +852,7 @@ int xen_hvm_init(void)
}
/* Init RAM management */
- qemu_map_cache_init();
+ xen_map_cache_init();
xen_ram_init(ram_size);
qemu_add_vm_change_state_handler(xen_vm_change_state_handler, state);
diff --git a/xen-mapcache-stub.c b/xen-mapcache-stub.c
index 90a994d..f037016 100644
--- a/xen-mapcache-stub.c
+++ b/xen-mapcache-stub.c
@@ -13,24 +13,25 @@
#include "cpu-common.h"
#include "xen-mapcache.h"
-void qemu_map_cache_init(void)
+void xen_map_cache_init(void)
{
}
-uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock)
+uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
+ uint8_t lock)
{
return qemu_get_ram_ptr(phys_addr);
}
-ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
+ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
{
return -1;
}
-void qemu_invalidate_map_cache(void)
+void xen_invalidate_map_cache(void)
{
}
-void qemu_invalidate_entry(uint8_t *buffer)
+void xen_invalidate_map_cache_entry(uint8_t *buffer)
{
}
diff --git a/xen-mapcache.c b/xen-mapcache.c
index fac47cd..007136a 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -40,6 +40,9 @@
#endif
#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
+#define mapcache_lock() ((void)0)
+#define mapcache_unlock() ((void)0)
+
typedef struct MapCacheEntry {
target_phys_addr_t paddr_index;
uint8_t *vaddr_base;
@@ -79,7 +82,7 @@ static inline int test_bits(int nr, int size, const unsigned long *addr)
return 0;
}
-void qemu_map_cache_init(void)
+void xen_map_cache_init(void)
{
unsigned long size;
struct rlimit rlimit_as;
@@ -106,13 +109,14 @@ void qemu_map_cache_init(void)
size = mapcache->nr_buckets * sizeof (MapCacheEntry);
size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
- DPRINTF("qemu_map_cache_init, nr_buckets = %lx size %lu\n", mapcache->nr_buckets, size);
+ DPRINTF("%s, nr_buckets = %lx size %lu\n", __func__,
+ mapcache->nr_buckets, size);
mapcache->entry = qemu_mallocz(size);
}
-static void qemu_remap_bucket(MapCacheEntry *entry,
- target_phys_addr_t size,
- target_phys_addr_t address_index)
+static void xen_remap_bucket(MapCacheEntry *entry,
+ target_phys_addr_t size,
+ target_phys_addr_t address_index)
{
uint8_t *vaddr_base;
xen_pfn_t *pfns;
@@ -120,7 +124,7 @@ static void qemu_remap_bucket(MapCacheEntry *entry,
unsigned int i;
target_phys_addr_t nb_pfn = size >> XC_PAGE_SHIFT;
- trace_qemu_remap_bucket(address_index);
+ trace_xen_remap_bucket(address_index);
pfns = qemu_mallocz(nb_pfn * sizeof (xen_pfn_t));
err = qemu_mallocz(nb_pfn * sizeof (int));
@@ -164,17 +168,18 @@ static void qemu_remap_bucket(MapCacheEntry *entry,
qemu_free(err);
}
-uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock)
+uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
+ uint8_t lock)
{
MapCacheEntry *entry, *pentry = NULL;
target_phys_addr_t address_index = phys_addr >> MCACHE_BUCKET_SHIFT;
target_phys_addr_t address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
target_phys_addr_t __size = size;
- trace_qemu_map_cache(phys_addr);
+ trace_xen_map_cache(phys_addr);
if (address_index == mapcache->last_address_index && !lock && !__size) {
- trace_qemu_map_cache_return(mapcache->last_address_vaddr + address_offset);
+ trace_xen_map_cache_return(mapcache->last_address_vaddr + address_offset);
return mapcache->last_address_vaddr + address_offset;
}
@@ -198,20 +203,20 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u
if (!entry) {
entry = qemu_mallocz(sizeof (MapCacheEntry));
pentry->next = entry;
- qemu_remap_bucket(entry, __size, address_index);
+ xen_remap_bucket(entry, __size, address_index);
} else if (!entry->lock) {
if (!entry->vaddr_base || entry->paddr_index != address_index ||
entry->size != __size ||
!test_bits(address_offset >> XC_PAGE_SHIFT, size >> XC_PAGE_SHIFT,
entry->valid_mapping)) {
- qemu_remap_bucket(entry, __size, address_index);
+ xen_remap_bucket(entry, __size, address_index);
}
}
if(!test_bits(address_offset >> XC_PAGE_SHIFT, size >> XC_PAGE_SHIFT,
entry->valid_mapping)) {
mapcache->last_address_index = -1;
- trace_qemu_map_cache_return(NULL);
+ trace_xen_map_cache_return(NULL);
return NULL;
}
@@ -226,11 +231,11 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u
QTAILQ_INSERT_HEAD(&mapcache->locked_entries, reventry, next);
}
- trace_qemu_map_cache_return(mapcache->last_address_vaddr + address_offset);
+ trace_xen_map_cache_return(mapcache->last_address_vaddr + address_offset);
return mapcache->last_address_vaddr + address_offset;
}
-ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
+ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
{
MapCacheEntry *entry = NULL, *pentry = NULL;
MapCacheRev *reventry;
@@ -247,7 +252,7 @@ ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
}
}
if (!found) {
- fprintf(stderr, "qemu_ram_addr_from_mapcache, could not find %p\n", ptr);
+ fprintf(stderr, "%s, could not find %p\n", __func__, ptr);
QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
DPRINTF(" "TARGET_FMT_plx" -> %p is present\n", reventry->paddr_index,
reventry->vaddr_req);
@@ -269,7 +274,7 @@ ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
((unsigned long) ptr - (unsigned long) entry->vaddr_base);
}
-void qemu_invalidate_entry(uint8_t *buffer)
+void xen_invalidate_map_cache_entry(uint8_t *buffer)
{
MapCacheEntry *entry = NULL, *pentry = NULL;
MapCacheRev *reventry;
@@ -290,7 +295,7 @@ void qemu_invalidate_entry(uint8_t *buffer)
}
}
if (!found) {
- DPRINTF("qemu_invalidate_entry, could not find %p\n", buffer);
+ DPRINTF("%s, could not find %p\n", __func__, buffer);
QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
DPRINTF(" "TARGET_FMT_plx" -> %p is present\n", reventry->paddr_index, reventry->vaddr_req);
}
@@ -322,7 +327,7 @@ void qemu_invalidate_entry(uint8_t *buffer)
qemu_free(entry);
}
-void qemu_invalidate_map_cache(void)
+void xen_invalidate_map_cache(void)
{
unsigned long i;
MapCacheRev *reventry;
diff --git a/xen-mapcache.h b/xen-mapcache.h
index 6216cc3..606b8af 100644
--- a/xen-mapcache.h
+++ b/xen-mapcache.h
@@ -9,13 +9,11 @@
#ifndef XEN_MAPCACHE_H
#define XEN_MAPCACHE_H
-void qemu_map_cache_init(void);
-uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock);
-ram_addr_t qemu_ram_addr_from_mapcache(void *ptr);
-void qemu_invalidate_entry(uint8_t *buffer);
-void qemu_invalidate_map_cache(void);
-
-#define mapcache_lock() ((void)0)
-#define mapcache_unlock() ((void)0)
+void xen_map_cache_init(void);
+uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
+ uint8_t lock);
+ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
+void xen_invalidate_map_cache_entry(uint8_t *buffer);
+void xen_invalidate_map_cache(void);
#endif /* !XEN_MAPCACHE_H */
commit 6dbd588a412ce1ac2a4ba640b418278e92a71890
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date: Tue Jun 21 22:59:07 2011 +0200
xen: Clean up build system
Introduce CONFIG_XEN_BACKEND so that this new config solely controls the
target-independent backend build and CONFIG_XEN can focus on per-target
building.
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/Makefile.objs b/Makefile.objs
index cea15e4..1635df6 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -155,8 +155,8 @@ slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
# xen backend driver support
-common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
-common-obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
+common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o
+common-obj-$(CONFIG_XEN_BACKEND) += xen_console.o xenfb.o xen_disk.o xen_nic.o
######################################################################
# libuser
diff --git a/Makefile.target b/Makefile.target
index a53a2ff..c347176 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -3,6 +3,8 @@
GENERATED_HEADERS = config-target.h
CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
+CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
+CONFIG_NO_XEN_MAPCACHE = $(if $(subst n,,$(CONFIG_XEN_MAPCACHE)),n,y)
include ../config-host.mak
include config-devices.mak
@@ -204,17 +206,8 @@ QEMU_CFLAGS += $(VNC_SASL_CFLAGS)
QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
-# xen backend driver support
-obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
-
-ifeq ($(TARGET_BASE_ARCH), i386)
- CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
-else
- CONFIG_NO_XEN = y
-endif
# xen support
-CONFIG_NO_XEN_MAPCACHE = $(if $(subst n,,$(CONFIG_XEN_MAPCACHE)),n,y)
-obj-i386-$(CONFIG_XEN) += xen-all.o
+obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o
obj-$(CONFIG_NO_XEN) += xen-stub.o
obj-i386-$(CONFIG_XEN_MAPCACHE) += xen-mapcache.o
obj-$(CONFIG_NO_XEN_MAPCACHE) += xen-mapcache-stub.o
diff --git a/configure b/configure
index 88159ac..e57efb1 100755
--- a/configure
+++ b/configure
@@ -2850,7 +2850,7 @@ if test "$bluez" = "yes" ; then
echo "BLUEZ_CFLAGS=$bluez_cflags" >> $config_host_mak
fi
if test "$xen" = "yes" ; then
- echo "CONFIG_XEN=y" >> $config_host_mak
+ echo "CONFIG_XEN_BACKEND=y" >> $config_host_mak
echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak
fi
if test "$io_thread" = "yes" ; then
commit 89b9ba661bd2d6155308f895ec075d813f0e129b
Author: Alexandre Raymond <cerbere at gmail.com>
Date: Wed Jun 15 01:20:31 2011 -0400
Fix signal handling of SIG_IPI when io-thread is enabled
Both the signal thread (via sigwait()) and the cpu thread (via
a normal signal handler) were attempting to catch SIG_IPI.
This resulted in random freezes under Darwin.
This patch separates SIG_IPI from the rest of the signals handled
by the signal thread, because it is independently caught by the cpu
thread.
Signed-off-by: Alexandre Raymond <cerbere at gmail.com>
Acked-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/cpus.c b/cpus.c
index e02576c..3035314 100644
--- a/cpus.c
+++ b/cpus.c
@@ -396,10 +396,18 @@ static int qemu_signal_init(void)
sigaddset(&set, SIGUSR2);
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+ /*
+ * SIG_IPI must be blocked in the main thread and must not be caught
+ * by sigwait() in the signal thread. Otherwise, the cpu thread will
+ * not catch it reliably.
+ */
+ sigemptyset(&set);
+ sigaddset(&set, SIG_IPI);
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
+
sigemptyset(&set);
sigaddset(&set, SIGIO);
sigaddset(&set, SIGALRM);
- sigaddset(&set, SIG_IPI);
sigaddset(&set, SIGBUS);
#else
sigemptyset(&set);
commit 5664aed99a4ab6e661b40e475449a32150f46184
Author: Alexandre Raymond <cerbere at gmail.com>
Date: Tue Jun 14 10:05:36 2011 -0400
Fix signal handling when io-thread is disabled
Changes since v1:
- take pthread_sigmask() out of the ifdef as it is now common
to both parts.
This fix effectively blocks, in the main thread, the signals handled
by signalfd or the compatibility signal thread.
This way, such signals are received synchronously in the main thread
through sigfd_handler() instead of triggering the signal handler
directly, asynchronously.
Signed-off-by: Alexandre Raymond <cerbere at gmail.com>
Acked-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/cpus.c b/cpus.c
index abd24ab..e02576c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -401,7 +401,6 @@ static int qemu_signal_init(void)
sigaddset(&set, SIGALRM);
sigaddset(&set, SIG_IPI);
sigaddset(&set, SIGBUS);
- pthread_sigmask(SIG_BLOCK, &set, NULL);
#else
sigemptyset(&set);
sigaddset(&set, SIGBUS);
@@ -414,6 +413,7 @@ static int qemu_signal_init(void)
sigaddset(&set, SIGALRM);
}
#endif
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
sigfd = qemu_signalfd(&set);
if (sigfd == -1) {
commit 107a47cc2dac1b6c5edae0121831713161cb70c5
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Wed Jun 22 15:40:06 2011 +0100
tcg/README: Expand advice on number of TCG ops per target insn
Expand the note on the number of TCG ops generated per target insn,
to be clearer about the range of applicability of the 20 op rule
of thumb. Also add a note about the hard MAX_OP_PER_INSTR limit.
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/tcg/README b/tcg/README
index 6600122..cfdfd96 100644
--- a/tcg/README
+++ b/tcg/README
@@ -504,7 +504,15 @@ register.
- Don't hesitate to use helpers for complicated or seldom used target
instructions. There is little performance advantage in using TCG to
implement target instructions taking more than about twenty TCG
- instructions.
+ instructions. Note that this rule of thumb is more applicable to
+ helpers doing complex logic or arithmetic, where the C compiler has
+ scope to do a good job of optimisation; it is less relevant where
+ the instruction is mostly doing loads and stores, and in those cases
+ inline TCG may still be faster for longer sequences.
+
+- The hard limit on the number of TCG instructions you can generate
+ per target instruction is set by MAX_OP_PER_INSTR in exec-all.h --
+ you cannot exceed this without risking a buffer overrun.
- Use the 'discard' instruction if you know that TCG won't be able to
prove that a given global is "dead" at a given program point. The
commit cf973e469bd9d47c0460347764c1315a6180e13c
Author: Artyom Tarasenko <atar4qemu at gmail.com>
Date: Thu Jul 14 19:37:06 2011 +0200
set ELF_HWCAP for SPARC and SPARC64
setting ELF_HWCAP fixes dynamic library loading for Linux/sparc64
This patch allows loading busybox from Debian 6 initrd
Signed-off-by: Artyom Tarasenko <atar4qemu at gmail.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index b2746f2..443d246 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -417,7 +417,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
#ifdef TARGET_SPARC64
#define ELF_START_MMAP 0x80000000
-
+#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
+ | HWCAP_SPARC_MULDIV | HWCAP_SPARC_V9)
#ifndef TARGET_ABI32
#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
#else
@@ -450,7 +451,8 @@ static inline void init_thread(struct target_pt_regs *regs,
#else
#define ELF_START_MMAP 0x80000000
-
+#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
+ | HWCAP_SPARC_MULDIV)
#define elf_check_arch(x) ( (x) == EM_SPARC )
#define ELF_CLASS ELFCLASS32
commit f838e2c535e47dc8e99ae7ec711407b849700cc9
Author: Blue Swirl <blauwirbel at gmail.com>
Date: Thu Jul 14 17:30:43 2011 +0000
Sparc: fix FPU and AM enable checks for translation
Translation used incorrectly CPUState fields directly to check
for FPU enable state and 32 bit address masking on Sparc64.
Fix by using TB flags instead.
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 4edae78..22ee274 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -606,17 +606,6 @@ static inline int cpu_pil_allowed(CPUState *env1, int pil)
#endif
}
-static inline int cpu_fpu_enabled(CPUState *env1)
-{
-#if defined(CONFIG_USER_ONLY)
- return 1;
-#elif !defined(TARGET_SPARC64)
- return env1->psref;
-#else
- return ((env1->pstate & PS_PEF) != 0) && ((env1->fprs & FPRS_FEF) != 0);
-#endif
-}
-
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
@@ -639,6 +628,9 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit);
trap_state* cpu_tsptr(CPUState* env);
#endif
+#define TB_FLAG_FPU_ENABLED (1 << 4)
+#define TB_FLAG_AM_ENABLED (1 << 5)
+
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
@@ -646,16 +638,41 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
*cs_base = env->npc;
#ifdef TARGET_SPARC64
// AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
- *flags = ((env->pstate & PS_AM) << 2) /* 5 */
- | (((env->pstate & PS_PEF) >> 1) /* 3 */
- | ((env->fprs & FPRS_FEF) << 2)) /* 4 */
- | (env->pstate & PS_PRIV) /* 2 */
+ *flags = (env->pstate & PS_PRIV) /* 2 */
| ((env->lsu & (DMMU_E | IMMU_E)) >> 2) /* 1, 0 */
| ((env->tl & 0xff) << 8)
| (env->dmmu.mmu_primary_context << 16); /* 16... */
+ if (env->pstate & PS_AM) {
+ *flags |= TB_FLAG_AM_ENABLED;
+ }
+ if ((env->def->features & CPU_FEATURE_FLOAT) && (env->pstate & PS_PEF)
+ && (env->fprs & FPRS_FEF)) {
+ *flags |= TB_FLAG_FPU_ENABLED;
+ }
#else
// FPU enable . Supervisor
- *flags = (env->psref << 4) | env->psrs;
+ *flags = env->psrs;
+ if ((env->def->features & CPU_FEATURE_FLOAT) && env->psref) {
+ *flags |= TB_FLAG_FPU_ENABLED;
+ }
+#endif
+}
+
+static inline bool tb_fpu_enabled(int tb_flags)
+{
+#if defined(CONFIG_USER_ONLY)
+ return true;
+#else
+ return tb_flags & TB_FLAG_FPU_ENABLED;
+#endif
+}
+
+static inline bool tb_am_enabled(int tb_flags)
+{
+#ifndef TARGET_SPARC64
+ return false;
+#else
+ return tb_flags & TB_FLAG_AM_ENABLED;
#endif
}
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 5f92dbb..27c2cf9 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4879,13 +4879,8 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
dc->cc_op = CC_OP_DYNAMIC;
dc->mem_idx = cpu_mmu_index(env);
dc->def = env->def;
- if ((dc->def->features & CPU_FEATURE_FLOAT))
- dc->fpu_enabled = cpu_fpu_enabled(env);
- else
- dc->fpu_enabled = 0;
-#ifdef TARGET_SPARC64
- dc->address_mask_32bit = env->pstate & PS_AM;
-#endif
+ dc->fpu_enabled = tb_fpu_enabled(tb->flags);
+ dc->address_mask_32bit = tb_am_enabled(tb->flags);
dc->singlestep = (env->singlestep_enabled || singlestep);
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
commit d8e586ffccd73c9c7758166241564c63109fc8d3
Author: Tsuneo Saito <tsnsaito at gmail.com>
Date: Thu Jul 14 18:41:43 2011 +0900
SPARC64: C99 comment fix for block-transfer ASIs
Fixed C99 comments on block-tranfer ASIs.
Signed-off-by: Tsuneo Saito <tsnsaito at gmail.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index 2a28d5f..15af27b 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -3337,10 +3337,10 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
addr = asi_address_mask(env, asi, addr);
switch (asi) {
- case 0xf0: // Block load primary
- case 0xf1: // Block load secondary
- case 0xf8: // Block load primary LE
- case 0xf9: // Block load secondary LE
+ case 0xf0: /* UA2007/JPS1 Block load primary */
+ case 0xf1: /* UA2007/JPS1 Block load secondary */
+ case 0xf8: /* UA2007/JPS1 Block load primary LE */
+ case 0xf9: /* UA2007/JPS1 Block load secondary LE */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
@@ -3357,8 +3357,8 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
case 0x17: /* UA2007 Block load secondary, user privilege */
case 0x1e: /* UA2007 Block load primary LE, user privilege */
case 0x1f: /* UA2007 Block load secondary LE, user privilege */
- case 0x70: // Block load primary, user privilege
- case 0x71: // Block load secondary, user privilege
+ case 0x70: /* JPS1 Block load primary, user privilege */
+ case 0x71: /* JPS1 Block load secondary, user privilege */
case 0x78: /* JPS1 Block load primary LE, user privilege */
case 0x79: /* JPS1 Block load secondary LE, user privilege */
if (rd & 7) {
@@ -3408,12 +3408,12 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
addr = asi_address_mask(env, asi, addr);
switch (asi) {
- case 0xe0: // UA2007 Block commit store primary (cache flush)
- case 0xe1: // UA2007 Block commit store secondary (cache flush)
- case 0xf0: // Block store primary
- case 0xf1: // Block store secondary
- case 0xf8: // Block store primary LE
- case 0xf9: // Block store secondary LE
+ case 0xe0: /* UA2007/JPS1 Block commit store primary (cache flush) */
+ case 0xe1: /* UA2007/JPS1 Block commit store secondary (cache flush) */
+ case 0xf0: /* UA2007/JPS1 Block store primary */
+ case 0xf1: /* UA2007/JPS1 Block store secondary */
+ case 0xf8: /* UA2007/JPS1 Block store primary LE */
+ case 0xf9: /* UA2007/JPS1 Block store secondary LE */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
@@ -3430,8 +3430,8 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
case 0x17: /* UA2007 Block load secondary, user privilege */
case 0x1e: /* UA2007 Block load primary LE, user privilege */
case 0x1f: /* UA2007 Block load secondary LE, user privilege */
- case 0x70: // Block store primary, user privilege
- case 0x71: // Block store secondary, user privilege
+ case 0x70: /* JPS1 Block store primary, user privilege */
+ case 0x71: /* JPS1 Block store secondary, user privilege */
case 0x78: /* JPS1 Block load primary LE, user privilege */
case 0x79: /* JPS1 Block load secondary LE, user privilege */
if (rd & 7) {
commit d920bde9235f718f62e73f06be1922b36913f800
Author: Tsuneo Saito <tsnsaito at gmail.com>
Date: Thu Jul 14 18:41:42 2011 +0900
SPARC64: Add JPS1 ASI_BLK_AIU[PS]L ASIs for ldfa and stfa
Support JPS1 little endian block transfer ASIs.
Signed-off-by: Tsuneo Saito <tsnsaito at gmail.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index 4faa709..2a28d5f 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -3359,6 +3359,8 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
case 0x1f: /* UA2007 Block load secondary LE, user privilege */
case 0x70: // Block load primary, user privilege
case 0x71: // Block load secondary, user privilege
+ case 0x78: /* JPS1 Block load primary LE, user privilege */
+ case 0x79: /* JPS1 Block load secondary LE, user privilege */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
@@ -3430,6 +3432,8 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
case 0x1f: /* UA2007 Block load secondary LE, user privilege */
case 0x70: // Block store primary, user privilege
case 0x71: // Block store secondary, user privilege
+ case 0x78: /* JPS1 Block load primary LE, user privilege */
+ case 0x79: /* JPS1 Block load secondary LE, user privilege */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
commit 073a0444104767cce1668799476eb882f8badf59
Author: Tsuneo Saito <tsnsaito at gmail.com>
Date: Thu Jul 14 18:41:41 2011 +0900
SPARC64: Add UA2007 ASI_BLK_AIU[PS]L? ASIs for stfa
Support UA2007 block store ASIs for stfa instructions.
Signed-off-by: Tsuneo Saito <tsnsaito at gmail.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index b76ffb6..4faa709 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -3424,6 +3424,10 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
}
return;
+ case 0x16: /* UA2007 Block load primary, user privilege */
+ case 0x17: /* UA2007 Block load secondary, user privilege */
+ case 0x1e: /* UA2007 Block load primary LE, user privilege */
+ case 0x1f: /* UA2007 Block load secondary LE, user privilege */
case 0x70: // Block store primary, user privilege
case 0x71: // Block store secondary, user privilege
if (rd & 7) {
@@ -3433,7 +3437,7 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
helper_check_align(addr, 0x3f);
for (i = 0; i < 16; i++) {
val = *(uint32_t *)&env->fpr[rd++];
- helper_st_asi(addr, val, asi & 0x1f, 4);
+ helper_st_asi(addr, val, asi & 0x19, 4);
addr += 4;
}
commit 41317e2e2b58426ac9a5e1c3083c81840da3ae2b
Author: Tsuneo Saito <tsnsaito at gmail.com>
Date: Thu Jul 14 18:41:40 2011 +0900
SPARC64: Add UA2007 ASI_BLK_AIU[PS]L? ASIs for ldfa
Support UA2007 block load ASIs for ldfa instructions.
Signed-off-by: Tsuneo Saito <tsnsaito at gmail.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index fe71829..b76ffb6 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -3353,6 +3353,10 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
}
return;
+ case 0x16: /* UA2007 Block load primary, user privilege */
+ case 0x17: /* UA2007 Block load secondary, user privilege */
+ case 0x1e: /* UA2007 Block load primary LE, user privilege */
+ case 0x1f: /* UA2007 Block load secondary LE, user privilege */
case 0x70: // Block load primary, user privilege
case 0x71: // Block load secondary, user privilege
if (rd & 7) {
@@ -3361,7 +3365,7 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
}
helper_check_align(addr, 0x3f);
for (i = 0; i < 16; i++) {
- *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x1f, 4,
+ *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x19, 4,
0);
addr += 4;
}
commit 5f06b54718b063840e14a93cd1059c3a92e4603a
Author: Tsuneo Saito <tsnsaito at gmail.com>
Date: Thu Jul 14 18:41:39 2011 +0900
SPARC64: fp_disabled checks on stfa/stdfa/stqfa
stfa/stdfa/stqfa instructions should raise fp_disabled exceptions
if %pstate.PEF==0 or %fprs.FEF==0.
Signed-off-by: Tsuneo Saito <tsnsaito at gmail.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index a5a8eaf..5f92dbb 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4732,6 +4732,9 @@ static void disas_sparc_insn(DisasContext * dc)
switch (xop) {
#ifdef TARGET_SPARC64
case 0x34: /* V9 stfa */
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
gen_stf_asi(cpu_addr, insn, 4, rd);
break;
case 0x36: /* V9 stqfa */
@@ -4739,6 +4742,9 @@ static void disas_sparc_insn(DisasContext * dc)
TCGv_i32 r_const;
CHECK_FPU_FEATURE(dc, FLOAT128);
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
r_const = tcg_const_i32(7);
gen_helper_check_align(cpu_addr, r_const);
tcg_temp_free_i32(r_const);
@@ -4746,6 +4752,9 @@ static void disas_sparc_insn(DisasContext * dc)
}
break;
case 0x37: /* V9 stdfa */
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
break;
case 0x3c: /* V9 casa */
commit e1ef36c4a34082a075182ec0ba44c80a2dbf43c2
Author: Tsuneo Saito <tsnsaito at gmail.com>
Date: Thu Jul 14 18:41:38 2011 +0900
SPARC64: Implement stfa/stdfa/stqfa instrcutions properly
This patch implements sparcv9 stfa/stdfa/stqfa instructions
with non block-store ASIs.
Signed-off-by: Tsuneo Saito <tsnsaito at gmail.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index a75ac4f..fe71829 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -3396,6 +3396,7 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
{
unsigned int i;
target_ulong val = 0;
+ CPU_DoubleU u;
helper_check_align(addr, 3);
addr = asi_address_mask(env, asi, addr);
@@ -3440,16 +3441,22 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
switch(size) {
default:
case 4:
- val = *((uint32_t *)&env->fpr[rd]);
+ helper_st_asi(addr, *(uint32_t *)&env->fpr[rd], asi, size);
break;
case 8:
- val = *((int64_t *)&DT0);
+ u.l.upper = *(uint32_t *)&env->fpr[rd++];
+ u.l.lower = *(uint32_t *)&env->fpr[rd++];
+ helper_st_asi(addr, u.ll, asi, size);
break;
case 16:
- // XXX
+ u.l.upper = *(uint32_t *)&env->fpr[rd++];
+ u.l.lower = *(uint32_t *)&env->fpr[rd++];
+ helper_st_asi(addr, u.ll, asi, 8);
+ u.l.upper = *(uint32_t *)&env->fpr[rd++];
+ u.l.lower = *(uint32_t *)&env->fpr[rd++];
+ helper_st_asi(addr + 8, u.ll, asi, 8);
break;
}
- helper_st_asi(addr, val, asi, size);
}
target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 1e7e68d..a5a8eaf 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4742,12 +4742,10 @@ static void disas_sparc_insn(DisasContext * dc)
r_const = tcg_const_i32(7);
gen_helper_check_align(cpu_addr, r_const);
tcg_temp_free_i32(r_const);
- gen_op_load_fpr_QT0(QFPREG(rd));
gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
}
break;
case 0x37: /* V9 stdfa */
- gen_op_load_fpr_DT0(DFPREG(rd));
gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
break;
case 0x3c: /* V9 casa */
commit 8872eb4f567b9ae36dbd9c320f6a86c53a776d43
Author: Tsuneo Saito <tsnsaito at gmail.com>
Date: Thu Jul 14 18:41:37 2011 +0900
SPARC64: fp_disabled checks on ldfa/lddfa/ldqfa
ldfa/lddfa/ldqfa instructions should raise fp_disabled exceptions
if %pstate.PEF==0 or %fprs.FEF==0.
Signed-off-by: Tsuneo Saito <tsnsaito at gmail.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index f32a674..1e7e68d 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4484,10 +4484,16 @@ static void disas_sparc_insn(DisasContext * dc)
case 0x2d: /* V9 prefetch, no effect */
goto skip_move;
case 0x30: /* V9 ldfa */
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
save_state(dc, cpu_cond);
gen_ldf_asi(cpu_addr, insn, 4, rd);
goto skip_move;
case 0x33: /* V9 lddfa */
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
save_state(dc, cpu_cond);
gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
goto skip_move;
@@ -4495,6 +4501,9 @@ static void disas_sparc_insn(DisasContext * dc)
goto skip_move;
case 0x32: /* V9 ldqfa */
CHECK_FPU_FEATURE(dc, FLOAT128);
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
save_state(dc, cpu_cond);
gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
goto skip_move;
commit 4183f36df0bf8cb82dda423414aa3b1a82e91ce9
Author: Tsuneo Saito <tsnsaito at gmail.com>
Date: Thu Jul 14 18:41:36 2011 +0900
SPARC64: Implement ldfa/lddfa/ldqfa instructions properly
This patch implements sparcv9 ldfa/lddfa/ldqfa instructions
with non block-load ASIs.
Signed-off-by: Tsuneo Saito <tsnsaito at gmail.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index fd0cfbd..a75ac4f 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -3331,7 +3331,7 @@ void helper_ldda_asi(target_ulong addr, int asi, int rd)
void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
{
unsigned int i;
- target_ulong val;
+ CPU_DoubleU u;
helper_check_align(addr, 3);
addr = asi_address_mask(env, asi, addr);
@@ -3371,17 +3371,23 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
break;
}
- val = helper_ld_asi(addr, asi, size, 0);
switch(size) {
default:
case 4:
- *((uint32_t *)&env->fpr[rd]) = val;
+ *((uint32_t *)&env->fpr[rd]) = helper_ld_asi(addr, asi, size, 0);
break;
case 8:
- *((int64_t *)&DT0) = val;
+ u.ll = helper_ld_asi(addr, asi, size, 0);
+ *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+ *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
break;
case 16:
- // XXX
+ u.ll = helper_ld_asi(addr, asi, 8, 0);
+ *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+ *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
+ u.ll = helper_ld_asi(addr + 8, asi, 8, 0);
+ *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+ *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
break;
}
}
commit 6fea2ea462f4f726249f0e646012d21f24c024b5
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Tue Jul 12 21:27:15 2011 +0100
linux-user/signal.c: Rename s390 target_ucontext fields to fix ia64
The ia64 sys/ucontext.h defines macros 'uc_link', 'uc_sigmask' and
'uc_stack'. Rename the s390 target_ucontext struct members to tuc_*,
bringing them into line with the other targets and fixing a compile
failure on ia64 hosts caused by this clash.
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 7d168e1..07ad07a 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -3662,11 +3662,11 @@ typedef struct {
} sigframe;
struct target_ucontext {
- target_ulong uc_flags;
- struct target_ucontext *uc_link;
- target_stack_t uc_stack;
- target_sigregs uc_mcontext;
- target_sigset_t uc_sigmask; /* mask last for extensibility */
+ target_ulong tuc_flags;
+ struct target_ucontext *tuc_link;
+ target_stack_t tuc_stack;
+ target_sigregs tuc_mcontext;
+ target_sigset_t tuc_sigmask; /* mask last for extensibility */
};
typedef struct {
@@ -3814,16 +3814,16 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
}
/* Create the ucontext. */
- __put_user(0, &frame->uc.uc_flags);
- __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.uc_link);
- __put_user(target_sigaltstack_used.ss_sp, &frame->uc.uc_stack.ss_sp);
+ __put_user(0, &frame->uc.tuc_flags);
+ __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
+ __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
__put_user(sas_ss_flags(get_sp_from_cpustate(env)),
- &frame->uc.uc_stack.ss_flags);
- __put_user(target_sigaltstack_used.ss_size, &frame->uc.uc_stack.ss_size);
- save_sigregs(env, &frame->uc.uc_mcontext);
+ &frame->uc.tuc_stack.ss_flags);
+ __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
+ save_sigregs(env, &frame->uc.tuc_mcontext);
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
__put_user((abi_ulong)set->sig[i],
- (abi_ulong *)&frame->uc.uc_sigmask.sig[i]);
+ (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
}
/* Set up to return from userspace. If provided, use a stub
@@ -3928,15 +3928,15 @@ long do_rt_sigreturn(CPUState *env)
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
goto badframe;
}
- target_to_host_sigset(&set, &frame->uc.uc_sigmask);
+ target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
- if (restore_sigregs(env, &frame->uc.uc_mcontext)) {
+ if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
goto badframe;
}
- if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.uc_stack), 0,
+ if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
get_sp_from_cpustate(env)) == -EFAULT) {
goto badframe;
}
commit 48e515d4fa7c6ffdc21944ffc8620a161c772c09
Author: Riku Voipio <riku.voipio at linaro.org>
Date: Tue Jul 12 15:40:51 2011 +0300
linux-user: make MIPS and ARM eabi use same argument reordering
MIPS uses similar calling convention than ARM eabi, where when using
64-bit values some registers are skipped. This patch makes MIPS and ARM
eabi share the argument reordering code.
This affects ftruncate64, creating insane sized fails (or just failing).
Cc: Wesley W. Terpstra <terpstra at debian.org>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9eb41a0..1dd7aad 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -580,6 +580,17 @@ extern int setfsuid(int);
extern int setfsgid(int);
extern int setgroups(int, gid_t *);
+/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
+#ifdef TARGET_ARM
+static inline int regpairs_aligned(void *cpu_env) {
+ return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
+}
+#elif defined(TARGET_MIPS)
+static inline int regpairs_aligned(void *cpu_env) { return 1; }
+#else
+static inline int regpairs_aligned(void *cpu_env) { return 0; }
+#endif
+
#define ERRNO_TABLE_SIZE 1200
/* target_to_host_errno_table[] is initialized from
@@ -4375,13 +4386,10 @@ static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
abi_long arg3,
abi_long arg4)
{
-#ifdef TARGET_ARM
- if (((CPUARMState *)cpu_env)->eabi)
- {
+ if (regpairs_aligned(cpu_env)) {
arg2 = arg3;
arg3 = arg4;
- }
-#endif
+ }
return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
}
#endif
@@ -4392,13 +4400,10 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
abi_long arg3,
abi_long arg4)
{
-#ifdef TARGET_ARM
- if (((CPUARMState *)cpu_env)->eabi)
- {
+ if (regpairs_aligned(cpu_env)) {
arg2 = arg3;
arg3 = arg4;
- }
-#endif
+ }
return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
}
#endif
@@ -6857,20 +6862,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#endif
#ifdef TARGET_NR_pread
case TARGET_NR_pread:
-#ifdef TARGET_ARM
- if (((CPUARMState *)cpu_env)->eabi)
+ if (regpairs_aligned(cpu_env))
arg4 = arg5;
-#endif
if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
goto efault;
ret = get_errno(pread(arg1, p, arg3, arg4));
unlock_user(p, arg2, ret);
break;
case TARGET_NR_pwrite:
-#ifdef TARGET_ARM
- if (((CPUARMState *)cpu_env)->eabi)
+ if (regpairs_aligned(cpu_env))
arg4 = arg5;
-#endif
if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
goto efault;
ret = get_errno(pwrite(arg1, p, arg3, arg4));
@@ -7621,14 +7622,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#ifdef TARGET_NR_readahead
case TARGET_NR_readahead:
#if TARGET_ABI_BITS == 32
-#ifdef TARGET_ARM
- if (((CPUARMState *)cpu_env)->eabi)
- {
+ if (regpairs_aligned(cpu_env)) {
arg2 = arg3;
arg3 = arg4;
arg4 = arg5;
}
-#endif
ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
#else
ret = get_errno(readahead(arg1, arg2, arg3));
commit c3edf3472faf3dad73a0c504db8e9d853debfde6
Author: Riku Voipio <riku.voipio at linaro.org>
Date: Tue Jul 12 16:01:54 2011 +0300
linux-user: correct syscall 123 on sh4
As reported by Cédric VINCENT:
The syscall #123 on SH4 should be "TARGET_NR_cacheflush" instead of
"TARGET_NR_modify_ldt" [1]. The only consequence of this misnaming is
that many "Unsupported syscall" warnings are issued when emulating JIT
compilers.
Reported-by: Cédric VINCENT <cedric.vincent at st.com>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h
index 6173a7c..365db58 100644
--- a/linux-user/sh4/syscall_nr.h
+++ b/linux-user/sh4/syscall_nr.h
@@ -125,7 +125,7 @@
#define TARGET_NR_clone 120
#define TARGET_NR_setdomainname 121
#define TARGET_NR_uname 122
-#define TARGET_NR_modify_ldt 123
+#define TARGET_NR_cacheflush 123
#define TARGET_NR_adjtimex 124
#define TARGET_NR_mprotect 125
#define TARGET_NR_sigprocmask 126
commit cc4662f9642995c78bed587707eeb9ad8500035b
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date: Sat Jul 9 10:22:07 2011 +0100
os-posix: set groups properly for -runas
Andrew Griffiths reports that -runas does not set supplementary group
IDs. This means that gid 0 (root) is not dropped when switching to an
unprivileged user.
Add an initgroups(3) call to use the -runas user's /etc/groups
membership to update the supplementary group IDs.
Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Acked-by: Chris Wright <chrisw at sous-sol.org>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/os-posix.c b/os-posix.c
index 7dfb278..6f8d488 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -31,6 +31,7 @@
/*needed for MAP_POPULATE before including qemu-options.h */
#include <sys/mman.h>
#include <pwd.h>
+#include <grp.h>
#include <libgen.h>
/* Needed early for CONFIG_BSD etc. */
@@ -199,6 +200,11 @@ static void change_process_uid(void)
fprintf(stderr, "Failed to setgid(%d)\n", user_pwd->pw_gid);
exit(1);
}
+ if (initgroups(user_pwd->pw_name, user_pwd->pw_gid) < 0) {
+ fprintf(stderr, "Failed to initgroups(\"%s\", %d)\n",
+ user_pwd->pw_name, user_pwd->pw_gid);
+ exit(1);
+ }
if (setuid(user_pwd->pw_uid) < 0) {
fprintf(stderr, "Failed to setuid(%d)\n", user_pwd->pw_uid);
exit(1);
commit 429bef6912bd3d504593b9aefdbcb39e981d387e
Author: Hervé Poussineau <hpoussin at reactos.org>
Date: Sat Jul 9 16:44:41 2011 +0200
esp: cancel current request only if some request is in flight
This bug was introduced in 94d3f98a3f3caddd7875f9a11776daeb84962a7b:
scsi_cancel_io was checking if some request was pending before trying
to cancel it, while scsi_req_cancel always cancels the request.
This may lead to a crash of Qemu due to dereferencing a NULL pointer,
as exhibited by NetBSD 5.1 installer on MIPS Magnum emulation.
Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/esp.c b/hw/esp.c
index 8e95672..aa50800 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -219,7 +219,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
s->ti_rptr = 0;
s->ti_wptr = 0;
- if (s->current_dev) {
+ if (s->current_req) {
/* Started a new command before the old one finished. Cancel it. */
scsi_req_cancel(s->current_req);
s->async_len = 0;
commit f5fc40bb8133849618e0d05adc798c5f07f7b17f
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Mon Jul 4 22:02:46 2011 +0100
target-alpha, target-ppc: Remove unnecessary setjmp.h include
Remove the include of setjmp.h from the cpu.h of target-alpha
and target-ppc. This is unnecessary because cpu-defs.h already
includes this header; this change brings these two targets
into line with all the rest.
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 411bd55..78caa79 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -28,8 +28,6 @@
#include "cpu-defs.h"
-#include <setjmp.h>
-
#include "softfloat.h"
#define TARGET_HAS_ICE 1
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 84f8ff6..d903366 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -75,8 +75,6 @@
#include "cpu-defs.h"
-#include <setjmp.h>
-
#include "softfloat.h"
#define TARGET_HAS_ICE 1
commit 462df2887cf55bb95faa7a76a0fd07722c63bb0c
Author: Stefan Weil <weil at mail.berlios.de>
Date: Mon Jul 4 20:52:38 2011 +0200
Remove unneeded setjmp.h (fix compilation on Debian "lenny")
Some versions of png.h cannot be included after setjmp.h,
even when PNG_SKIP_SETJMP_CHECK was defined.
setjmp.h was included from qemu-common.h and is not needed there.
Removing the include statement fixes compilation of ui/vnc-enc-tight.c
with CONFIG_VNC_PNG defined.
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/qemu-common.h b/qemu-common.h
index abd7a75..c2b79bd 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -117,7 +117,6 @@ static inline char *realpath(const char *path, char *resolved_path)
/* FIXME: Remove NEED_CPU_H. */
#ifndef NEED_CPU_H
-#include <setjmp.h>
#include "osdep.h"
#include "bswap.h"
commit 0d10193870b5a81c3bce13a602a5403c3a55cf6c
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date: Sat Jul 2 09:50:51 2011 +0200
tcg: Reload local variables after return from longjmp
Recent compilers look deep into cpu_exec, find longjmp as a noreturn
function and decide to smash some stack variables as they won't be used
again. This may lead to env becoming invalid after return from setjmp,
causing crashes. Fix it by reloading env from cpu_single_env in that
case.
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/cpu-exec.c b/cpu-exec.c
index 20e3ec4..de0d716 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -587,6 +587,10 @@ int cpu_exec(CPUState *env)
/* reset soft MMU for next block (it can currently
only be set by a memory fault) */
} /* for(;;) */
+ } else {
+ /* Reload env after longjmp - the compiler may have smashed all
+ * local variables as longjmp is marked 'noreturn'. */
+ env = cpu_single_env;
}
} /* for(;;) */
commit 5b620fb698e69a5386f2f02c7c455bdbdd59a52b
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Wed Jun 22 15:16:32 2011 +0100
exec-all.h: Make MAX_OP_PER_INSTR large enough for target-arm's uses
The target-arm frontend's worst-case TCG ops per instr is 194 (and in
general many of the "load multiple registers" ARM instructions generate
more than 100 TCG ops). Raise MAX_OP_PER_INSTR accordingly to avoid
possible buffer overruns.
Since it doesn't make any sense for the "64 bit guest on 32 bit host"
case to have a smaller limit than the normal case, we collapse the
two cases back into each other again.
(This increase costs us about 14K in extra static buffer space and
21K of extra margin at the end of a 32MB codegen buffer.)
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/exec-all.h b/exec-all.h
index 21a69d6..69acf3b 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -44,11 +44,7 @@ struct TranslationBlock;
typedef struct TranslationBlock TranslationBlock;
/* XXX: make safe guess about sizes */
-#if (HOST_LONG_BITS == 32) && (TARGET_LONG_BITS == 64)
-#define MAX_OP_PER_INSTR 128
-#else
-#define MAX_OP_PER_INSTR 96
-#endif
+#define MAX_OP_PER_INSTR 208
#if HOST_LONG_BITS == 32
#define MAX_OPC_PARAM_PER_ARG 2
commit a884da8a06806d55fa83c8011bb17d6838583f9b
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Wed Jun 22 11:58:25 2011 +0100
exec.c: Fix calculation of code_gen_buffer_max_size
When calculating the point at which we should not try to put another
TB into the code gen buffer, we have to allow not just for OPC_MAX_SIZE
but OPC_BUF_SIZE. This is because the target translate.c will only
stop when an instruction has put it past the OPC_MAX_SIZE limit, so
we have to include the MAX_OP_PER_INSTR margin which that final insn
might have used.
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/exec.c b/exec.c
index 9e6913e..f1777e6 100644
--- a/exec.c
+++ b/exec.c
@@ -555,8 +555,8 @@ static void code_gen_alloc(unsigned long tb_size)
#endif
#endif /* !USE_STATIC_CODE_GEN_BUFFER */
map_exec(code_gen_prologue, sizeof(code_gen_prologue));
- code_gen_buffer_max_size = code_gen_buffer_size -
- (TCG_MAX_OP_SIZE * OPC_MAX_SIZE);
+ code_gen_buffer_max_size = code_gen_buffer_size -
+ (TCG_MAX_OP_SIZE * OPC_BUF_SIZE);
code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
}
commit 06c46bbab04faa3b5a1c10756be7db4f09af1ffb
Author: Alexander Graf <agraf at suse.de>
Date: Tue Jul 5 18:28:10 2011 +0200
spapr: use specific endian ld/st_phys
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/spapr.h b/hw/spapr.h
index b52133a..263691b 100644
--- a/hw/spapr.h
+++ b/hw/spapr.h
@@ -280,12 +280,12 @@ target_ulong spapr_hypercall(CPUState *env, target_ulong opcode,
static inline uint32_t rtas_ld(target_ulong phys, int n)
{
- return ldl_phys(phys + 4*n);
+ return ldl_be_phys(phys + 4*n);
}
static inline void rtas_st(target_ulong phys, int n, uint32_t val)
{
- stl_phys(phys + 4*n, val);
+ stl_be_phys(phys + 4*n, val);
}
typedef void (*spapr_rtas_fn)(sPAPREnvironment *spapr, uint32_t token,
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index 84da8fc..5cd8d8f 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -278,7 +278,7 @@ static target_ulong register_vpa(CPUState *env, target_ulong vpa)
}
/* FIXME: bounds check the address */
- size = lduw_phys(vpa + 0x4);
+ size = lduw_be_phys(vpa + 0x4);
if (size < VPA_MIN_SIZE) {
return H_PARAMETER;
@@ -321,7 +321,7 @@ static target_ulong register_slb_shadow(CPUState *env, target_ulong addr)
return H_HARDWARE;
}
- size = ldl_phys(addr + 0x4);
+ size = ldl_be_phys(addr + 0x4);
if (size < 0x8) {
return H_PARAMETER;
}
@@ -354,7 +354,7 @@ static target_ulong register_dtl(CPUState *env, target_ulong addr)
return H_HARDWARE;
}
- size = ldl_phys(addr + 0x4);
+ size = ldl_be_phys(addr + 0x4);
if (size < 48) {
return H_PARAMETER;
@@ -441,9 +441,9 @@ static target_ulong h_rtas(CPUState *env, sPAPREnvironment *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong rtas_r3 = args[0];
- uint32_t token = ldl_phys(rtas_r3);
- uint32_t nargs = ldl_phys(rtas_r3 + 4);
- uint32_t nret = ldl_phys(rtas_r3 + 8);
+ uint32_t token = ldl_be_phys(rtas_r3);
+ uint32_t nargs = ldl_be_phys(rtas_r3 + 4);
+ uint32_t nret = ldl_be_phys(rtas_r3 + 8);
return spapr_rtas_call(spapr, token, nargs, rtas_r3 + 12,
nret, rtas_r3 + 12 + 4*nargs);
commit 04bc74edecef1b671c84be0b402998e96a282889
Author: Alexander Graf <agraf at suse.de>
Date: Tue Jul 5 18:28:09 2011 +0200
s390-virtio: use specific endian ld/st_phys
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 2bf4821..e2f3e32 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -166,7 +166,7 @@ static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
(vq * VIRTIO_VQCONFIG_LEN) +
VIRTIO_VQCONFIG_OFFS_TOKEN;
- return ldq_phys(token_off);
+ return ldq_be_phys(token_off);
}
static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
@@ -220,8 +220,8 @@ void s390_virtio_device_sync(VirtIOS390Device *dev)
vring = s390_virtio_next_ring(bus);
virtio_queue_set_addr(dev->vdev, i, vring);
virtio_queue_set_vector(dev->vdev, i, i);
- stq_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
- stw_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
+ stq_be_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
+ stw_be_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
}
cur_offs = dev->dev_offs;
@@ -229,7 +229,7 @@ void s390_virtio_device_sync(VirtIOS390Device *dev)
cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
/* Sync feature bitmap */
- stl_phys(cur_offs, bswap32(dev->host_features));
+ stl_le_phys(cur_offs, dev->host_features);
dev->feat_offs = cur_offs + dev->feat_len;
cur_offs += dev->feat_len * 2;
@@ -253,7 +253,7 @@ void s390_virtio_device_update_status(VirtIOS390Device *dev)
/* Update guest supported feature bitmap */
- features = bswap32(ldl_phys(dev->feat_offs));
+ features = bswap32(ldl_be_phys(dev->feat_offs));
if (vdev->set_features) {
vdev->set_features(vdev, features);
}
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 3eba7ea..abe954d 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -193,7 +193,7 @@ static void s390_init(ram_addr_t my_ram_size,
if (kernel_filename) {
kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));
- if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) {
+ if (lduw_be_phys(KERN_IMAGE_START) != 0x0dd0) {
fprintf(stderr, "Specified image is not an s390 boot image\n");
exit(1);
}
@@ -232,8 +232,8 @@ static void s390_init(ram_addr_t my_ram_size,
}
initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset));
- stq_phys(INITRD_PARM_START, initrd_offset);
- stq_phys(INITRD_PARM_SIZE, initrd_size);
+ stq_be_phys(INITRD_PARM_START, initrd_offset);
+ stq_be_phys(INITRD_PARM_SIZE, initrd_size);
}
if (kernel_cmdline) {
commit db663d0f7aae936d10e2452d0eab8bb3b0147e74
Author: Alexander Graf <agraf at suse.de>
Date: Tue Jul 5 18:28:08 2011 +0200
ppc405_uc: use specific endian ld/st_phys
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c
index 2ce79ee..06a053b 100644
--- a/hw/ppc405_uc.c
+++ b/hw/ppc405_uc.c
@@ -51,39 +51,42 @@ ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd,
bdloc = 0x01000000UL - sizeof(struct ppc4xx_bd_info_t);
else
bdloc = bd->bi_memsize - sizeof(struct ppc4xx_bd_info_t);
- stl_phys(bdloc + 0x00, bd->bi_memstart);
- stl_phys(bdloc + 0x04, bd->bi_memsize);
- stl_phys(bdloc + 0x08, bd->bi_flashstart);
- stl_phys(bdloc + 0x0C, bd->bi_flashsize);
- stl_phys(bdloc + 0x10, bd->bi_flashoffset);
- stl_phys(bdloc + 0x14, bd->bi_sramstart);
- stl_phys(bdloc + 0x18, bd->bi_sramsize);
- stl_phys(bdloc + 0x1C, bd->bi_bootflags);
- stl_phys(bdloc + 0x20, bd->bi_ipaddr);
- for (i = 0; i < 6; i++)
+ stl_be_phys(bdloc + 0x00, bd->bi_memstart);
+ stl_be_phys(bdloc + 0x04, bd->bi_memsize);
+ stl_be_phys(bdloc + 0x08, bd->bi_flashstart);
+ stl_be_phys(bdloc + 0x0C, bd->bi_flashsize);
+ stl_be_phys(bdloc + 0x10, bd->bi_flashoffset);
+ stl_be_phys(bdloc + 0x14, bd->bi_sramstart);
+ stl_be_phys(bdloc + 0x18, bd->bi_sramsize);
+ stl_be_phys(bdloc + 0x1C, bd->bi_bootflags);
+ stl_be_phys(bdloc + 0x20, bd->bi_ipaddr);
+ for (i = 0; i < 6; i++) {
stb_phys(bdloc + 0x24 + i, bd->bi_enetaddr[i]);
- stw_phys(bdloc + 0x2A, bd->bi_ethspeed);
- stl_phys(bdloc + 0x2C, bd->bi_intfreq);
- stl_phys(bdloc + 0x30, bd->bi_busfreq);
- stl_phys(bdloc + 0x34, bd->bi_baudrate);
- for (i = 0; i < 4; i++)
+ }
+ stw_be_phys(bdloc + 0x2A, bd->bi_ethspeed);
+ stl_be_phys(bdloc + 0x2C, bd->bi_intfreq);
+ stl_be_phys(bdloc + 0x30, bd->bi_busfreq);
+ stl_be_phys(bdloc + 0x34, bd->bi_baudrate);
+ for (i = 0; i < 4; i++) {
stb_phys(bdloc + 0x38 + i, bd->bi_s_version[i]);
+ }
for (i = 0; i < 32; i++) {
stb_phys(bdloc + 0x3C + i, bd->bi_r_version[i]);
}
- stl_phys(bdloc + 0x5C, bd->bi_plb_busfreq);
- stl_phys(bdloc + 0x60, bd->bi_pci_busfreq);
- for (i = 0; i < 6; i++)
+ stl_be_phys(bdloc + 0x5C, bd->bi_plb_busfreq);
+ stl_be_phys(bdloc + 0x60, bd->bi_pci_busfreq);
+ for (i = 0; i < 6; i++) {
stb_phys(bdloc + 0x64 + i, bd->bi_pci_enetaddr[i]);
+ }
n = 0x6A;
if (flags & 0x00000001) {
for (i = 0; i < 6; i++)
stb_phys(bdloc + n++, bd->bi_pci_enetaddr2[i]);
}
- stl_phys(bdloc + n, bd->bi_opbfreq);
+ stl_be_phys(bdloc + n, bd->bi_opbfreq);
n += 4;
for (i = 0; i < 2; i++) {
- stl_phys(bdloc + n, bd->bi_iic_fast[i]);
+ stl_be_phys(bdloc + n, bd->bi_iic_fast[i]);
n += 4;
}
commit 75b0646f9e25e42cdf1d73f7d2407c4966be48f1
Author: Alexander Graf <agraf at suse.de>
Date: Tue Jul 5 18:28:07 2011 +0200
pl080: use specific endian ld/st_phys
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/pl080.c b/hw/pl080.c
index 901f04a..dd8139b 100644
--- a/hw/pl080.c
+++ b/hw/pl080.c
@@ -199,10 +199,10 @@ again:
if (size == 0) {
/* Transfer complete. */
if (ch->lli) {
- ch->src = ldl_phys(ch->lli);
- ch->dest = ldl_phys(ch->lli + 4);
- ch->ctrl = ldl_phys(ch->lli + 12);
- ch->lli = ldl_phys(ch->lli + 8);
+ ch->src = ldl_le_phys(ch->lli);
+ ch->dest = ldl_le_phys(ch->lli + 4);
+ ch->ctrl = ldl_le_phys(ch->lli + 12);
+ ch->lli = ldl_le_phys(ch->lli + 8);
} else {
ch->conf &= ~PL080_CCONF_E;
}
commit ae5d3eb4745dbcc38a4d6bbaff563f4c2d0e7a16
Author: Alexander Graf <agraf at suse.de>
Date: Tue Jul 5 18:28:06 2011 +0200
msix: use specific endian ld/st_phys
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/msix.c b/hw/msix.c
index 03d7bec..e67e700 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -359,7 +359,7 @@ void msix_notify(PCIDevice *dev, unsigned vector)
address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
- stl_phys(address, data);
+ stl_le_phys(address, data);
}
void msix_reset(PCIDevice *dev)
commit c5d29d2fecff299d4b65bfd5546d58915d8e25e0
Author: Alexander Graf <agraf at suse.de>
Date: Tue Jul 5 18:28:05 2011 +0200
msi: use specific endian ld/st_phys
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/msi.c b/hw/msi.c
index e8c5607..f214fcf 100644
--- a/hw/msi.c
+++ b/hw/msi.c
@@ -249,7 +249,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
"notify vector 0x%x"
" address: 0x%"PRIx64" data: 0x%"PRIx32"\n",
vector, address, data);
- stl_phys(address, data);
+ stl_le_phys(address, data);
}
/* call this function after updating configs by pci_default_write_config(). */
commit 6c7796e5c17bc23d0add756b5248fcf419e999a9
Author: Alexander Graf <agraf at suse.de>
Date: Tue Jul 5 18:28:04 2011 +0200
intel-hda: use specific endian ld/st_phys
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 0ffffce..5a2bc3a 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -224,19 +224,6 @@ static target_phys_addr_t intel_hda_addr(uint32_t lbase, uint32_t ubase)
return addr;
}
-static void stl_phys_le(target_phys_addr_t addr, uint32_t value)
-{
- uint32_t value_le = cpu_to_le32(value);
- cpu_physical_memory_write(addr, (uint8_t*)(&value_le), sizeof(value_le));
-}
-
-static uint32_t ldl_phys_le(target_phys_addr_t addr)
-{
- uint32_t value_le;
- cpu_physical_memory_read(addr, (uint8_t*)(&value_le), sizeof(value_le));
- return le32_to_cpu(value_le);
-}
-
static void intel_hda_update_int_sts(IntelHDAState *d)
{
uint32_t sts = 0;
@@ -341,7 +328,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
rp = (d->corb_rp + 1) & 0xff;
addr = intel_hda_addr(d->corb_lbase, d->corb_ubase);
- verb = ldl_phys_le(addr + 4*rp);
+ verb = ldl_le_phys(addr + 4*rp);
d->corb_rp = rp;
dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __FUNCTION__, rp, verb);
@@ -373,8 +360,8 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
ex = (solicited ? 0 : (1 << 4)) | dev->cad;
wp = (d->rirb_wp + 1) & 0xff;
addr = intel_hda_addr(d->rirb_lbase, d->rirb_ubase);
- stl_phys_le(addr + 8*wp, response);
- stl_phys_le(addr + 8*wp + 4, ex);
+ stl_le_phys(addr + 8*wp, response);
+ stl_le_phys(addr + 8*wp + 4, ex);
d->rirb_wp = wp;
dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n",
@@ -461,7 +448,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
}
if (d->dp_lbase & 0x01) {
addr = intel_hda_addr(d->dp_lbase & ~0x01, d->dp_ubase);
- stl_phys_le(addr + 8*s, st->lpib);
+ stl_le_phys(addr + 8*s, st->lpib);
}
dprint(d, 3, "dma: --\n");
commit 8517263fcbf2182ce97e3335f2a20b52d4e33fce
Author: Alexander Graf <agraf at suse.de>
Date: Tue Jul 5 18:28:03 2011 +0200
hpet: use specific endian ld/st_phys
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/hpet.c b/hw/hpet.c
index ef9a2a0..4eda33d 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -192,7 +192,7 @@ static void update_irq(struct HPETTimer *timer, int set)
qemu_irq_lower(s->irqs[route]);
}
} else if (timer_fsb_route(timer)) {
- stl_phys(timer->fsb >> 32, timer->fsb & 0xffffffff);
+ stl_le_phys(timer->fsb >> 32, timer->fsb & 0xffffffff);
} else if (timer->config & HPET_TN_TYPE_LEVEL) {
s->isr |= mask;
qemu_irq_raise(s->irqs[route]);
commit 1e78bcc19c60c60c11ece020ab35952b5b2895ec
Author: Alexander Graf <agraf at suse.de>
Date: Wed Jul 6 09:09:23 2011 +0200
exec: add endian specific phys ld/st functions
Device code some times needs to access physical memory and does that
through the ld./st._phys functions. However, these are the exact same
functions that the CPU uses to access memory, which means they will
be endianness swapped depending on the target CPU.
However, devices don't know about the CPU's endianness, but instead
access memory directly using their own interface to the memory bus,
so they need some way to read data with their native endianness.
This patch adds _le and _be functions to ld./st._phys.
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/cpu-common.h b/cpu-common.h
index b027e43..c6a2b5f 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -135,14 +135,26 @@ void qemu_flush_coalesced_mmio_buffer(void);
uint32_t ldub_phys(target_phys_addr_t addr);
uint32_t lduw_phys(target_phys_addr_t addr);
+uint32_t lduw_le_phys(target_phys_addr_t addr);
+uint32_t lduw_be_phys(target_phys_addr_t addr);
uint32_t ldl_phys(target_phys_addr_t addr);
+uint32_t ldl_le_phys(target_phys_addr_t addr);
+uint32_t ldl_be_phys(target_phys_addr_t addr);
uint64_t ldq_phys(target_phys_addr_t addr);
+uint64_t ldq_le_phys(target_phys_addr_t addr);
+uint64_t ldq_be_phys(target_phys_addr_t addr);
void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
void stb_phys(target_phys_addr_t addr, uint32_t val);
void stw_phys(target_phys_addr_t addr, uint32_t val);
+void stw_le_phys(target_phys_addr_t addr, uint32_t val);
+void stw_be_phys(target_phys_addr_t addr, uint32_t val);
void stl_phys(target_phys_addr_t addr, uint32_t val);
+void stl_le_phys(target_phys_addr_t addr, uint32_t val);
+void stl_be_phys(target_phys_addr_t addr, uint32_t val);
void stq_phys(target_phys_addr_t addr, uint64_t val);
+void stq_le_phys(target_phys_addr_t addr, uint64_t val);
+void stq_be_phys(target_phys_addr_t addr, uint64_t val);
void cpu_physical_memory_write_rom(target_phys_addr_t addr,
const uint8_t *buf, int len);
diff --git a/exec.c b/exec.c
index 4c45299..9e6913e 100644
--- a/exec.c
+++ b/exec.c
@@ -4127,7 +4127,8 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
}
/* warning: addr must be aligned */
-uint32_t ldl_phys(target_phys_addr_t addr)
+static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
+ enum device_endian endian)
{
int io_index;
uint8_t *ptr;
@@ -4149,17 +4150,52 @@ uint32_t ldl_phys(target_phys_addr_t addr)
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
+#if defined(TARGET_WORDS_BIGENDIAN)
+ if (endian == DEVICE_LITTLE_ENDIAN) {
+ val = bswap32(val);
+ }
+#else
+ if (endian == DEVICE_BIG_ENDIAN) {
+ val = bswap32(val);
+ }
+#endif
} else {
/* RAM case */
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
- val = ldl_p(ptr);
+ switch (endian) {
+ case DEVICE_LITTLE_ENDIAN:
+ val = ldl_le_p(ptr);
+ break;
+ case DEVICE_BIG_ENDIAN:
+ val = ldl_be_p(ptr);
+ break;
+ default:
+ val = ldl_p(ptr);
+ break;
+ }
}
return val;
}
+uint32_t ldl_phys(target_phys_addr_t addr)
+{
+ return ldl_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
+}
+
+uint32_t ldl_le_phys(target_phys_addr_t addr)
+{
+ return ldl_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
+}
+
+uint32_t ldl_be_phys(target_phys_addr_t addr)
+{
+ return ldl_phys_internal(addr, DEVICE_BIG_ENDIAN);
+}
+
/* warning: addr must be aligned */
-uint64_t ldq_phys(target_phys_addr_t addr)
+static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
+ enum device_endian endian)
{
int io_index;
uint8_t *ptr;
@@ -4180,6 +4216,9 @@ uint64_t ldq_phys(target_phys_addr_t addr)
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+
+ /* XXX This is broken when device endian != cpu endian.
+ Fix and add "endian" variable check */
#ifdef TARGET_WORDS_BIGENDIAN
val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
@@ -4191,11 +4230,36 @@ uint64_t ldq_phys(target_phys_addr_t addr)
/* RAM case */
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
- val = ldq_p(ptr);
+ switch (endian) {
+ case DEVICE_LITTLE_ENDIAN:
+ val = ldq_le_p(ptr);
+ break;
+ case DEVICE_BIG_ENDIAN:
+ val = ldq_be_p(ptr);
+ break;
+ default:
+ val = ldq_p(ptr);
+ break;
+ }
}
return val;
}
+uint64_t ldq_phys(target_phys_addr_t addr)
+{
+ return ldq_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
+}
+
+uint64_t ldq_le_phys(target_phys_addr_t addr)
+{
+ return ldq_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
+}
+
+uint64_t ldq_be_phys(target_phys_addr_t addr)
+{
+ return ldq_phys_internal(addr, DEVICE_BIG_ENDIAN);
+}
+
/* XXX: optimize */
uint32_t ldub_phys(target_phys_addr_t addr)
{
@@ -4205,7 +4269,8 @@ uint32_t ldub_phys(target_phys_addr_t addr)
}
/* warning: addr must be aligned */
-uint32_t lduw_phys(target_phys_addr_t addr)
+static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
+ enum device_endian endian)
{
int io_index;
uint8_t *ptr;
@@ -4227,15 +4292,49 @@ uint32_t lduw_phys(target_phys_addr_t addr)
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
+#if defined(TARGET_WORDS_BIGENDIAN)
+ if (endian == DEVICE_LITTLE_ENDIAN) {
+ val = bswap16(val);
+ }
+#else
+ if (endian == DEVICE_BIG_ENDIAN) {
+ val = bswap16(val);
+ }
+#endif
} else {
/* RAM case */
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
- val = lduw_p(ptr);
+ switch (endian) {
+ case DEVICE_LITTLE_ENDIAN:
+ val = lduw_le_p(ptr);
+ break;
+ case DEVICE_BIG_ENDIAN:
+ val = lduw_be_p(ptr);
+ break;
+ default:
+ val = lduw_p(ptr);
+ break;
+ }
}
return val;
}
+uint32_t lduw_phys(target_phys_addr_t addr)
+{
+ return lduw_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
+}
+
+uint32_t lduw_le_phys(target_phys_addr_t addr)
+{
+ return lduw_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
+}
+
+uint32_t lduw_be_phys(target_phys_addr_t addr)
+{
+ return lduw_phys_internal(addr, DEVICE_BIG_ENDIAN);
+}
+
/* warning: addr must be aligned. The ram page is not masked as dirty
and the code inside is not invalidated. It is useful if the dirty
bits are used to track modified PTEs */
@@ -4308,7 +4407,8 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
}
/* warning: addr must be aligned */
-void stl_phys(target_phys_addr_t addr, uint32_t val)
+static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
+ enum device_endian endian)
{
int io_index;
uint8_t *ptr;
@@ -4326,13 +4426,32 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+#if defined(TARGET_WORDS_BIGENDIAN)
+ if (endian == DEVICE_LITTLE_ENDIAN) {
+ val = bswap32(val);
+ }
+#else
+ if (endian == DEVICE_BIG_ENDIAN) {
+ val = bswap32(val);
+ }
+#endif
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
} else {
unsigned long addr1;
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
/* RAM case */
ptr = qemu_get_ram_ptr(addr1);
- stl_p(ptr, val);
+ switch (endian) {
+ case DEVICE_LITTLE_ENDIAN:
+ stl_le_p(ptr, val);
+ break;
+ case DEVICE_BIG_ENDIAN:
+ stl_be_p(ptr, val);
+ break;
+ default:
+ stl_p(ptr, val);
+ break;
+ }
if (!cpu_physical_memory_is_dirty(addr1)) {
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
@@ -4343,6 +4462,21 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
}
}
+void stl_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stl_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN);
+}
+
+void stl_le_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stl_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN);
+}
+
+void stl_be_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stl_phys_internal(addr, val, DEVICE_BIG_ENDIAN);
+}
+
/* XXX: optimize */
void stb_phys(target_phys_addr_t addr, uint32_t val)
{
@@ -4351,7 +4485,8 @@ void stb_phys(target_phys_addr_t addr, uint32_t val)
}
/* warning: addr must be aligned */
-void stw_phys(target_phys_addr_t addr, uint32_t val)
+static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
+ enum device_endian endian)
{
int io_index;
uint8_t *ptr;
@@ -4369,13 +4504,32 @@ void stw_phys(target_phys_addr_t addr, uint32_t val)
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+#if defined(TARGET_WORDS_BIGENDIAN)
+ if (endian == DEVICE_LITTLE_ENDIAN) {
+ val = bswap16(val);
+ }
+#else
+ if (endian == DEVICE_BIG_ENDIAN) {
+ val = bswap16(val);
+ }
+#endif
io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
} else {
unsigned long addr1;
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
/* RAM case */
ptr = qemu_get_ram_ptr(addr1);
- stw_p(ptr, val);
+ switch (endian) {
+ case DEVICE_LITTLE_ENDIAN:
+ stw_le_p(ptr, val);
+ break;
+ case DEVICE_BIG_ENDIAN:
+ stw_be_p(ptr, val);
+ break;
+ default:
+ stw_p(ptr, val);
+ break;
+ }
if (!cpu_physical_memory_is_dirty(addr1)) {
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + 2, 0);
@@ -4386,6 +4540,21 @@ void stw_phys(target_phys_addr_t addr, uint32_t val)
}
}
+void stw_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stw_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN);
+}
+
+void stw_le_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stw_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN);
+}
+
+void stw_be_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stw_phys_internal(addr, val, DEVICE_BIG_ENDIAN);
+}
+
/* XXX: optimize */
void stq_phys(target_phys_addr_t addr, uint64_t val)
{
@@ -4393,6 +4562,18 @@ void stq_phys(target_phys_addr_t addr, uint64_t val)
cpu_physical_memory_write(addr, &val, 8);
}
+void stq_le_phys(target_phys_addr_t addr, uint64_t val)
+{
+ val = cpu_to_le64(val);
+ cpu_physical_memory_write(addr, &val, 8);
+}
+
+void stq_be_phys(target_phys_addr_t addr, uint64_t val)
+{
+ val = cpu_to_be64(val);
+ cpu_physical_memory_write(addr, &val, 8);
+}
+
/* virtual memory access for debug (includes writing to ROM) */
int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
uint8_t *buf, int len, int is_write)
commit e22b7015353be824620b1f0f5e32a8575b898a8c
Author: Wesley W. Terpstra <terpstra at debian.org>
Date: Tue Jul 12 14:42:00 2011 +0300
mips: rlimit codes are not the same
The codes for get/setrlimit differ between linux target platforms.
This patch adds conversion.
This is important else programs (rsyslog, python, ...) can go into a
near infinite loop trying to close all the file descriptors from 0 to
-1.
Signed-off-by: Wesley W. Terpstra <terpstra at debian.org>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4b9e3b8..9eb41a0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -960,6 +960,44 @@ static inline target_ulong host_to_target_rlim(rlim_t rlim)
return result;
}
+static inline int target_to_host_resource(int code)
+{
+ switch (code) {
+ case TARGET_RLIMIT_AS:
+ return RLIMIT_AS;
+ case TARGET_RLIMIT_CORE:
+ return RLIMIT_CORE;
+ case TARGET_RLIMIT_CPU:
+ return RLIMIT_CPU;
+ case TARGET_RLIMIT_DATA:
+ return RLIMIT_DATA;
+ case TARGET_RLIMIT_FSIZE:
+ return RLIMIT_FSIZE;
+ case TARGET_RLIMIT_LOCKS:
+ return RLIMIT_LOCKS;
+ case TARGET_RLIMIT_MEMLOCK:
+ return RLIMIT_MEMLOCK;
+ case TARGET_RLIMIT_MSGQUEUE:
+ return RLIMIT_MSGQUEUE;
+ case TARGET_RLIMIT_NICE:
+ return RLIMIT_NICE;
+ case TARGET_RLIMIT_NOFILE:
+ return RLIMIT_NOFILE;
+ case TARGET_RLIMIT_NPROC:
+ return RLIMIT_NPROC;
+ case TARGET_RLIMIT_RSS:
+ return RLIMIT_RSS;
+ case TARGET_RLIMIT_RTPRIO:
+ return RLIMIT_RTPRIO;
+ case TARGET_RLIMIT_SIGPENDING:
+ return RLIMIT_SIGPENDING;
+ case TARGET_RLIMIT_STACK:
+ return RLIMIT_STACK;
+ default:
+ return code;
+ }
+}
+
static inline abi_long copy_from_user_timeval(struct timeval *tv,
abi_ulong target_tv_addr)
{
@@ -5570,7 +5608,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
case TARGET_NR_setrlimit:
{
- int resource = arg1;
+ int resource = target_to_host_resource(arg1);
struct target_rlimit *target_rlim;
struct rlimit rlim;
if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
@@ -5583,7 +5621,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
case TARGET_NR_getrlimit:
{
- int resource = arg1;
+ int resource = target_to_host_resource(arg1);
struct target_rlimit *target_rlim;
struct rlimit rlim;
@@ -6892,7 +6930,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_ugetrlimit:
{
struct rlimit rlim;
- ret = get_errno(getrlimit(arg1, &rlim));
+ int resource = target_to_host_resource(arg1);
+ ret = get_errno(getrlimit(resource, &rlim));
if (!is_error(ret)) {
struct target_rlimit *target_rlim;
if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 1fdc84d..a117407 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -693,6 +693,40 @@ struct target_rlimit {
#define TARGET_RLIM_INFINITY ((target_ulong)~0UL)
#endif
+#if defined(TARGET_MIPS)
+#define TARGET_RLIMIT_CPU 0
+#define TARGET_RLIMIT_FSIZE 1
+#define TARGET_RLIMIT_DATA 2
+#define TARGET_RLIMIT_STACK 3
+#define TARGET_RLIMIT_CORE 4
+#define TARGET_RLIMIT_RSS 7
+#define TARGET_RLIMIT_NPROC 8
+#define TARGET_RLIMIT_NOFILE 5
+#define TARGET_RLIMIT_MEMLOCK 9
+#define TARGET_RLIMIT_AS 6
+#define TARGET_RLIMIT_LOCKS 10
+#define TARGET_RLIMIT_SIGPENDING 11
+#define TARGET_RLIMIT_MSGQUEUE 12
+#define TARGET_RLIMIT_NICE 13
+#define TARGET_RLIMIT_RTPRIO 14
+#else
+#define TARGET_RLIMIT_CPU 0
+#define TARGET_RLIMIT_FSIZE 1
+#define TARGET_RLIMIT_DATA 2
+#define TARGET_RLIMIT_STACK 3
+#define TARGET_RLIMIT_CORE 4
+#define TARGET_RLIMIT_RSS 5
+#define TARGET_RLIMIT_NPROC 6
+#define TARGET_RLIMIT_NOFILE 7
+#define TARGET_RLIMIT_MEMLOCK 8
+#define TARGET_RLIMIT_AS 9
+#define TARGET_RLIMIT_LOCKS 10
+#define TARGET_RLIMIT_SIGPENDING 11
+#define TARGET_RLIMIT_MSGQUEUE 12
+#define TARGET_RLIMIT_NICE 13
+#define TARGET_RLIMIT_RTPRIO 14
+#endif
+
struct target_pollfd {
int fd; /* file descriptor */
short events; /* requested events */
commit 95b33b2f4f0293068d1a42b3ab5badcc6333c6ba
Author: Wesley W. Terpstra <terpstra at debian.org>
Date: Tue Jul 12 14:38:22 2011 +0300
mips: rlimit incorrectly converts values
Byte swap was applied in the wrong order with testing for
RLIM_INFINITY. On mips bigendian from an amd64 system this results in
infinity being misinterpretted as 2^31-1.
This is a serious bug because it causes setrlimit stack size to kill
all child processes. This means (for example) that 'make' can run no
children. The mechanism of failure:
1. parent sets stack size rlimit to 'infinity'
2. qemu screws this value up
3. child process fetches stack size as a large (but non-infinite) value
4. qemu tries to allocate stack before execution
5. stack allocation fails (too big) and child process dies
Signed-off-by: Wesley W. Terpstra <terpstra at debian.org>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 90f6789..4b9e3b8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -934,18 +934,30 @@ static inline abi_long host_to_target_rusage(abi_ulong target_addr,
static inline rlim_t target_to_host_rlim(target_ulong target_rlim)
{
- if (target_rlim == TARGET_RLIM_INFINITY)
- return RLIM_INFINITY;
+ target_ulong target_rlim_swap;
+ rlim_t result;
+
+ target_rlim_swap = tswapl(target_rlim);
+ if (target_rlim_swap == TARGET_RLIM_INFINITY || target_rlim_swap != (rlim_t)target_rlim_swap)
+ result = RLIM_INFINITY;
else
- return tswapl(target_rlim);
+ result = target_rlim_swap;
+
+ return result;
}
static inline target_ulong host_to_target_rlim(rlim_t rlim)
{
+ target_ulong target_rlim_swap;
+ target_ulong result;
+
if (rlim == RLIM_INFINITY || rlim != (target_long)rlim)
- return TARGET_RLIM_INFINITY;
+ target_rlim_swap = TARGET_RLIM_INFINITY;
else
- return tswapl(rlim);
+ target_rlim_swap = rlim;
+ result = tswapl(target_rlim_swap);
+
+ return result;
}
static inline abi_long copy_from_user_timeval(struct timeval *tv,
commit e6e5bd2dd1868b5a244bc572422f585cef579ffb
Author: Wesley W. Terpstra <terpstra at debian.org>
Date: Tue Jul 12 14:34:23 2011 +0300
mips: null pointer deref should segfault
Dereferencing a null pointer causes an exception 0xC (EXCP_AdEL)
instead of EXCP_TLBL. This should also trigger a segfault.
Signed-off-by: Wesley W. Terpstra <terpstra at debian.org>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/main.c b/linux-user/main.c
index e32f987..2135b9c 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2120,6 +2120,8 @@ void cpu_loop(CPUMIPSState *env)
break;
case EXCP_TLBL:
case EXCP_TLBS:
+ case EXCP_AdEL:
+ case EXCP_AdES:
info.si_signo = TARGET_SIGSEGV;
info.si_errno = 0;
/* XXX: check env->error_code */
commit 7c2f6157d833cb95b355c7321597bc5a5ac976e4
Author: Wesley W. Terpstra <terpstra at debian.org>
Date: Tue Jul 12 14:33:23 2011 +0300
mips: missing syscall returns wrong errno
Return -TARGET_ENOSYS instead of -ENOSYS from linux-user/main.c
* Caused strange 'Level 2 synchronization messages' instead of
correctly reporting the syscall was missing.
* Made glibc simply fail instead of using older syscalls
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
Signed-off-by: Wesley W. Terpstra <terpstra at debian.org>
diff --git a/linux-user/main.c b/linux-user/main.c
index d695610..e32f987 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2080,7 +2080,7 @@ void cpu_loop(CPUMIPSState *env)
syscall_num = env->active_tc.gpr[2] - 4000;
env->active_tc.PC += 4;
if (syscall_num >= sizeof(mips_syscall_args)) {
- ret = -ENOSYS;
+ ret = -TARGET_ENOSYS;
} else {
int nb_args;
abi_ulong sp_reg;
commit 053ebb2726c17af6133cfcc8de2193121a107eb5
Author: Wesley W. Terpstra <terpstra at debian.org>
Date: Tue Jul 12 14:32:31 2011 +0300
mips: sigaltstack args
The syscall sigaltstack takes two parameters, not zero. This patch
should have no impact as only values above 4 influence the runtime
behaviour. Nevertheless, it is wrong.
Signed-off-by: Wesley W. Terpstra <terpstra at debian.org>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/main.c b/linux-user/main.c
index 48f0443..d695610 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1875,7 +1875,7 @@ static const uint8_t mips_syscall_args[] = {
MIPS_SYS(sys_getcwd , 2)
MIPS_SYS(sys_capget , 2)
MIPS_SYS(sys_capset , 2) /* 4205 */
- MIPS_SYS(sys_sigaltstack , 0)
+ MIPS_SYS(sys_sigaltstack , 2)
MIPS_SYS(sys_sendfile , 4)
MIPS_SYS(sys_ni_syscall , 0)
MIPS_SYS(sys_ni_syscall , 0)
commit 8f04eeb3c094bf370f131e50b7e3da85d08d518f
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Tue Jun 28 12:21:57 2011 +0100
linux-user/syscall.c: Enforce pselect6 sigset size restrictions
Enforce the same restriction on the size of the sigset passed to
pselect6 as the Linux kernel does. This is both correct and silences
a gcc 4.6 warning about a write-only variable.
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e2f356b..90f6789 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5699,6 +5699,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
if (arg_sigset) {
sig.set = &set;
+ if (arg_sigsize != sizeof(*target_sigset)) {
+ /* Like the kernel, we enforce correct size sigsets */
+ ret = -TARGET_EINVAL;
+ goto fail;
+ }
target_sigset = lock_user(VERIFY_READ, arg_sigset,
sizeof(*target_sigset), 1);
if (!target_sigset) {
commit 163a05a8398bc4b56c7498fa9901422a159168bf
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Mon Jun 27 17:44:52 2011 +0100
linux-user: Implement prlimit64 syscall
Implement the prlimit64 syscall.
Slightly modified to apply upstream -Riku
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fed7a8f..e2f356b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -559,6 +559,21 @@ _syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
#endif
+#if defined(TARGET_NR_prlimit64)
+#ifndef __NR_prlimit64
+# define __NR_prlimit64 -1
+#endif
+#define __NR_sys_prlimit64 __NR_prlimit64
+/* The glibc rlimit structure may not be that used by the underlying syscall */
+struct host_rlimit64 {
+ uint64_t rlim_cur;
+ uint64_t rlim_max;
+};
+_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
+ const struct host_rlimit64 *, new_limit,
+ struct host_rlimit64 *, old_limit)
+#endif
+
extern int personality(int);
extern int flock(int, int);
extern int setfsuid(int);
@@ -7990,6 +8005,34 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
#endif
#endif
+#ifdef TARGET_NR_prlimit64
+ case TARGET_NR_prlimit64:
+ {
+ /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
+ struct target_rlimit64 *target_rnew, *target_rold;
+ struct host_rlimit64 rnew, rold, *rnewp = 0;
+ if (arg3) {
+ if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
+ goto efault;
+ }
+ rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
+ rnew.rlim_max = tswap64(target_rnew->rlim_max);
+ unlock_user_struct(target_rnew, arg3, 0);
+ rnewp = &rnew;
+ }
+
+ ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
+ if (!is_error(ret) && arg4) {
+ if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
+ goto efault;
+ }
+ target_rold->rlim_cur = tswap64(rold.rlim_cur);
+ target_rold->rlim_max = tswap64(rold.rlim_max);
+ unlock_user_struct(target_rold, arg4, 1);
+ }
+ break;
+ }
+#endif
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 1b73451..1fdc84d 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2293,3 +2293,7 @@ struct target_epoll_event {
target_epoll_data_t data;
};
#endif
+struct target_rlimit64 {
+ uint64_t rlim_cur;
+ uint64_t rlim_max;
+};
commit d979e8eb544da31df78bc76358a73f0d1c823c17
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Mon Jun 27 17:44:51 2011 +0100
linux-user: Add syscall numbers from kernel 2.6.39.2
Add syscall numbers for new syscall numbers; this brings us
into line with Linux 2.6.39.2.
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h
index e3127df..f6284db 100644
--- a/linux-user/alpha/syscall_nr.h
+++ b/linux-user/alpha/syscall_nr.h
@@ -411,4 +411,25 @@
#define TARGET_NR_signalfd 476
#define TARGET_NR_timerfd 477
#define TARGET_NR_eventfd 478
-
+#define TARGET_NR_recvmmsg 479
+#define TARGET_NR_fallocate 480
+#define TARGET_NR_timerfd_create 481
+#define TARGET_NR_timerfd_settime 482
+#define TARGET_NR_timerfd_gettime 483
+#define TARGET_NR_signalfd4 484
+#define TARGET_NR_eventfd2 485
+#define TARGET_NR_epoll_create1 486
+#define TARGET_NR_dup3 487
+#define TARGET_NR_pipe2 488
+#define TARGET_NR_inotify_init1 489
+#define TARGET_NR_preadv 490
+#define TARGET_NR_pwritev 491
+#define TARGET_NR_rt_tgsigqueueinfo 492
+#define TARGET_NR_perf_event_open 493
+#define TARGET_NR_fanotify_init 494
+#define TARGET_NR_fanotify_mark 495
+#define TARGET_NR_prlimit64 496
+#define TARGET_NR_name_to_handle_at 497
+#define TARGET_NR_open_by_handle_at 498
+#define TARGET_NR_clock_adjtime 499
+#define TARGET_NR_syncfs 500
diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h
index 79a216a..7f05879 100644
--- a/linux-user/arm/syscall_nr.h
+++ b/linux-user/arm/syscall_nr.h
@@ -365,3 +365,16 @@
#define TARGET_NR_dup3 (358)
#define TARGET_NR_pipe2 (359)
#define TARGET_NR_inotify_init1 (360)
+#define TARGET_NR_preadv (361)
+#define TARGET_NR_pwritev (362)
+#define TARGET_NR_rt_tgsigqueueinfo (363)
+#define TARGET_NR_perf_event_open (364)
+#define TARGET_NR_recvmmsg (365)
+#define TARGET_NR_accept4 (366)
+#define TARGET_NR_fanotify_init (367)
+#define TARGET_NR_fanotify_mark (368)
+#define TARGET_NR_prlimit64 (369)
+#define TARGET_NR_name_to_handle_at (370)
+#define TARGET_NR_open_by_handle_at (371)
+#define TARGET_NR_clock_adjtime (372)
+#define TARGET_NR_syncfs (373)
diff --git a/linux-user/cris/syscall_nr.h b/linux-user/cris/syscall_nr.h
index 6132817..98f1a0b 100644
--- a/linux-user/cris/syscall_nr.h
+++ b/linux-user/cris/syscall_nr.h
@@ -333,3 +333,5 @@
#define TARGET_NR_dup3 330
#define TARGET_NR_pipe2 331
#define TARGET_NR_inotify_init1 332
+#define TARGET_NR_preadv 333
+#define TARGET_NR_pwritev 334
diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h
index 3ef71ce..74abfca 100644
--- a/linux-user/i386/syscall_nr.h
+++ b/linux-user/i386/syscall_nr.h
@@ -335,3 +335,15 @@
#define TARGET_NR_dup3 330
#define TARGET_NR_pipe2 331
#define TARGET_NR_inotify_init1 332
+#define TARGET_NR_preadv 333
+#define TARGET_NR_pwritev 334
+#define TARGET_NR_rt_tgsigqueueinfo 335
+#define TARGET_NR_perf_event_open 336
+#define TARGET_NR_recvmmsg 337
+#define TARGET_NR_fanotify_init 338
+#define TARGET_NR_fanotify_mark 339
+#define TARGET_NR_prlimit64 340
+#define TARGET_NR_name_to_handle_at 341
+#define TARGET_NR_open_by_handle_at 342
+#define TARGET_NR_clock_adjtime 343
+#define TARGET_NR_syncfs 344
diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h
index 1c0ba07..4d0937e 100644
--- a/linux-user/m68k/syscall_nr.h
+++ b/linux-user/m68k/syscall_nr.h
@@ -328,3 +328,19 @@
#define TARGET_NR_dup3 326
#define TARGET_NR_pipe2 327
#define TARGET_NR_inotify_init1 328
+#define TARGET_NR_inotify_init1 328
+#define TARGET_NR_preadv 329
+#define TARGET_NR_pwritev 330
+#define TARGET_NR_rt_tgsigqueueinfo 331
+#define TARGET_NR_perf_event_open 332
+#define TARGET_NR_get_thread_area 333
+#define TARGET_NR_set_thread_area 334
+#define TARGET_NR_atomic_cmpxchg_32 335
+#define TARGET_NR_atomic_barrier 336
+#define TARGET_NR_fanotify_init 337
+#define TARGET_NR_fanotify_mark 338
+#define TARGET_NR_prlimit64 339
+#define TARGET_NR_name_to_handle_at 340
+#define TARGET_NR_open_by_handle_at 341
+#define TARGET_NR_clock_adjtime 342
+#define TARGET_NR_syncfs 343
diff --git a/linux-user/main.c b/linux-user/main.c
index 289054b..48f0443 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1985,6 +1985,33 @@ static const uint8_t mips_syscall_args[] = {
MIPS_SYS(sys_epoll_pwait, 6)
MIPS_SYS(sys_ioprio_set, 3)
MIPS_SYS(sys_ioprio_get, 2)
+ MIPS_SYS(sys_utimensat, 4)
+ MIPS_SYS(sys_signalfd, 3)
+ MIPS_SYS(sys_ni_syscall, 0) /* was timerfd */
+ MIPS_SYS(sys_eventfd, 1)
+ MIPS_SYS(sys_fallocate, 6) /* 4320 */
+ MIPS_SYS(sys_timerfd_create, 2)
+ MIPS_SYS(sys_timerfd_gettime, 2)
+ MIPS_SYS(sys_timerfd_settime, 4)
+ MIPS_SYS(sys_signalfd4, 4)
+ MIPS_SYS(sys_eventfd2, 2) /* 4325 */
+ MIPS_SYS(sys_epoll_create1, 1)
+ MIPS_SYS(sys_dup3, 3)
+ MIPS_SYS(sys_pipe2, 2)
+ MIPS_SYS(sys_inotify_init1, 1)
+ MIPS_SYS(sys_preadv, 6) /* 4330 */
+ MIPS_SYS(sys_pwritev, 6)
+ MIPS_SYS(sys_rt_tgsigqueueinfo, 4)
+ MIPS_SYS(sys_perf_event_open, 5)
+ MIPS_SYS(sys_accept4, 4)
+ MIPS_SYS(sys_recvmmsg, 5) /* 4335 */
+ MIPS_SYS(sys_fanotify_init, 2)
+ MIPS_SYS(sys_fanotify_mark, 6)
+ MIPS_SYS(sys_prlimit64, 4)
+ MIPS_SYS(sys_name_to_handle_at, 5)
+ MIPS_SYS(sys_open_by_handle_at, 3) /* 4340 */
+ MIPS_SYS(sys_clock_adjtime, 2)
+ MIPS_SYS(sys_syncfs, 1)
};
#undef MIPS_SYS
diff --git a/linux-user/microblaze/syscall_nr.h b/linux-user/microblaze/syscall_nr.h
index 3e641cd..f1fe0e7 100644
--- a/linux-user/microblaze/syscall_nr.h
+++ b/linux-user/microblaze/syscall_nr.h
@@ -364,6 +364,16 @@
#define TARGET_NR_sendmsg 360 /* new */
#define TARGET_NR_recvmsg 361 /* new */
#define TARGET_NR_accept04 362 /* new */
-
-#define TARGET_NR_syscalls 363
+#define TARGET_NR_preadv 363 /* new */
+#define TARGET_NR_pwritev 364 /* new */
+#define TARGET_NR_rt_tgsigqueueinfo 365 /* new */
+#define TARGET_NR_perf_event_open 366 /* new */
+#define TARGET_NR_recvmmsg 367 /* new */
+#define TARGET_NR_fanotify_init 368
+#define TARGET_NR_fanotify_mark 369
+#define TARGET_NR_prlimit64 370
+#define TARGET_NR_name_to_handle_at 371
+#define TARGET_NR_open_by_handle_at 372
+#define TARGET_NR_clock_adjtime 373
+#define TARGET_NR_syncfs 374
diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h
index 0595308..fbdc348 100644
--- a/linux-user/mips/syscall_nr.h
+++ b/linux-user/mips/syscall_nr.h
@@ -332,3 +332,16 @@
#define TARGET_NR_dup3 (TARGET_NR_Linux + 327)
#define TARGET_NR_pipe2 (TARGET_NR_Linux + 328)
#define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 329)
+#define TARGET_NR_preadv (TARGET_NR_Linux + 330)
+#define TARGET_NR_pwritev (TARGET_NR_Linux + 331)
+#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 332)
+#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 333)
+#define TARGET_NR_accept4 (TARGET_NR_Linux + 334)
+#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 335)
+#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 336)
+#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 337)
+#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 338)
+#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 339)
+#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 340)
+#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 341)
+#define TARGET_NR_syncfs (TARGET_NR_Linux + 342)
diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h
index ee1d134..36d27b5 100644
--- a/linux-user/mips64/syscall_nr.h
+++ b/linux-user/mips64/syscall_nr.h
@@ -291,3 +291,16 @@
#define TARGET_NR_dup3 (TARGET_NR_Linux + 286)
#define TARGET_NR_pipe2 (TARGET_NR_Linux + 287)
#define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 288)
+#define TARGET_NR_preadv (TARGET_NR_Linux + 289)
+#define TARGET_NR_pwritev (TARGET_NR_Linux + 290)
+#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 291)
+#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 292)
+#define TARGET_NR_accept4 (TARGET_NR_Linux + 293)
+#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 294)
+#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 295)
+#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 296)
+#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 297)
+#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 298)
+#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 299)
+#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 300)
+#define TARGET_NR_syncfs (TARGET_NR_Linux + 301)
diff --git a/linux-user/mipsn32/syscall_nr.h b/linux-user/mipsn32/syscall_nr.h
index 60a99dd..4e1aca3 100644
--- a/linux-user/mipsn32/syscall_nr.h
+++ b/linux-user/mipsn32/syscall_nr.h
@@ -295,3 +295,17 @@
#define TARGET_NR_dup3 (TARGET_NR_Linux + 290)
#define TARGET_NR_pipe2 (TARGET_NR_Linux + 291)
#define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 292)
+#define TARGET_NR_preadv (TARGET_NR_Linux + 293)
+#define TARGET_NR_pwritev (TARGET_NR_Linux + 294)
+#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 295)
+#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 296)
+#define TARGET_NR_accept4 (TARGET_NR_Linux + 297)
+#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 298)
+#define TARGET_NR_getdents64 (TARGET_NR_Linux + 299)
+#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 300)
+#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 301)
+#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 302)
+#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 303)
+#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 304)
+#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 305)
+#define TARGET_NR_syncfs (TARGET_NR_Linux + 306)
diff --git a/linux-user/ppc/syscall_nr.h b/linux-user/ppc/syscall_nr.h
index cc84a4c..0673b7d 100644
--- a/linux-user/ppc/syscall_nr.h
+++ b/linux-user/ppc/syscall_nr.h
@@ -332,3 +332,33 @@
#define TARGET_NR_dup3 316
#define TARGET_NR_pipe2 317
#define TARGET_NR_inotify_init1 318
+#define TARGET_NR_perf_event_open 319
+#define TARGET_NR_preadv 320
+#define TARGET_NR_pwritev 321
+#define TARGET_NR_rt_tgsigqueueinfo 322
+#define TARGET_NR_fanotify_init 323
+#define TARGET_NR_fanotify_mark 324
+#define TARGET_NR_prlimit64 325
+#define TARGET_NR_socket 326
+#define TARGET_NR_bind 327
+#define TARGET_NR_connect 328
+#define TARGET_NR_listen 329
+#define TARGET_NR_accept 330
+#define TARGET_NR_getsockname 331
+#define TARGET_NR_getpeername 332
+#define TARGET_NR_socketpair 333
+#define TARGET_NR_send 334
+#define TARGET_NR_sendto 335
+#define TARGET_NR_recv 336
+#define TARGET_NR_recvfrom 337
+#define TARGET_NR_shutdown 338
+#define TARGET_NR_setsockopt 339
+#define TARGET_NR_getsockopt 340
+#define TARGET_NR_sendmsg 341
+#define TARGET_NR_recvmsg 342
+#define TARGET_NR_recvmmsg 343
+#define TARGET_NR_accept4 344
+#define TARGET_NR_name_to_handle_at 345
+#define TARGET_NR_open_by_handle_at 346
+#define TARGET_NR_clock_adjtime 347
+#define TARGET_NR_syncfs 348
diff --git a/linux-user/s390x/syscall_nr.h b/linux-user/s390x/syscall_nr.h
index 7cc6db2..d4529ac 100644
--- a/linux-user/s390x/syscall_nr.h
+++ b/linux-user/s390x/syscall_nr.h
@@ -254,8 +254,17 @@
#define TARGET_NR_pipe2 325
#define TARGET_NR_dup3 326
#define TARGET_NR_epoll_create1 327
-#undef NR_syscalls
-#define NR_syscalls 328
+#define TARGET_NR_preadv 328
+#define TARGET_NR_pwritev 329
+#define TARGET_NR_rt_tgsigqueueinfo 330
+#define TARGET_NR_perf_event_open 331
+#define TARGET_NR_fanotify_init 332
+#define TARGET_NR_fanotify_mark 333
+#define TARGET_NR_prlimit64 334
+#define TARGET_NR_name_to_handle_at 335
+#define TARGET_NR_open_by_handle_at 336
+#define TARGET_NR_clock_adjtime 337
+#define TARGET_NR_syncfs 338
/*
* There are some system calls that are not present on 64 bit, some
diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h
index 262b236..6173a7c 100644
--- a/linux-user/sh4/syscall_nr.h
+++ b/linux-user/sh4/syscall_nr.h
@@ -334,3 +334,35 @@
#define TARGET_NR_dup3 330
#define TARGET_NR_pipe2 331
#define TARGET_NR_inotify_init1 332
+#define TARGET_NR_preadv 333
+#define TARGET_NR_pwritev 334
+#define TARGET_NR_rt_tgsigqueueinfo 335
+#define TARGET_NR_perf_event_open 336
+#define TARGET_NR_fanotify_init 337
+#define TARGET_NR_fanotify_mark 338
+#define TARGET_NR_prlimit64 339
+
+/* Non-multiplexed socket family */
+#define TARGET_NR_socket 340
+#define TARGET_NR_bind 341
+#define TARGET_NR_connect 342
+#define TARGET_NR_listen 343
+#define TARGET_NR_accept 344
+#define TARGET_NR_getsockname 345
+#define TARGET_NR_getpeername 346
+#define TARGET_NR_socketpair 347
+#define TARGET_NR_send 348
+#define TARGET_NR_sendto 349
+#define TARGET_NR_recv 350
+#define TARGET_NR_recvfrom 351
+#define TARGET_NR_shutdown 352
+#define TARGET_NR_setsockopt 353
+#define TARGET_NR_getsockopt 354
+#define TARGET_NR_sendmsg 355
+#define TARGET_NR_recvmsg 356
+#define TARGET_NR_recvmmsg 357
+#define TARGET_NR_accept4 358
+#define TARGET_NR_name_to_handle_at 359
+#define TARGET_NR_open_by_handle_at 360
+#define TARGET_NR_clock_adjtime 361
+#define TARGET_NR_syncfs 362
diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h
index 5d1ac21..be503f2 100644
--- a/linux-user/sparc/syscall_nr.h
+++ b/linux-user/sparc/syscall_nr.h
@@ -285,3 +285,15 @@
#define TARGET_NR_pipe2 321
#define TARGET_NR_inotify_init1 322
#define TARGET_NR_accept4 323
+#define TARGET_NR_preadv 324
+#define TARGET_NR_pwritev 325
+#define TARGET_NR_rt_tgsigqueueinfo 326
+#define TARGET_NR_perf_event_open 327
+#define TARGET_NR_recvmmsg 328
+#define TARGET_NR_fanotify_init 329
+#define TARGET_NR_fanotify_mark 330
+#define TARGET_NR_prlimit64 331
+#define TARGET_NR_name_to_handle_at 332
+#define TARGET_NR_open_by_handle_at 333
+#define TARGET_NR_clock_adjtime 334
+#define TARGET_NR_syncfs 335
diff --git a/linux-user/sparc64/syscall_nr.h b/linux-user/sparc64/syscall_nr.h
index bdca2a7..70988b2 100644
--- a/linux-user/sparc64/syscall_nr.h
+++ b/linux-user/sparc64/syscall_nr.h
@@ -322,3 +322,15 @@
#define TARGET_NR_pipe2 321
#define TARGET_NR_inotify_init1 322
#define TARGET_NR_accept4 323
+#define TARGET_NR_preadv 324
+#define TARGET_NR_pwritev 325
+#define TARGET_NR_rt_tgsigqueueinfo 326
+#define TARGET_NR_perf_event_open 327
+#define TARGET_NR_recvmmsg 328
+#define TARGET_NR_fanotify_init 329
+#define TARGET_NR_fanotify_mark 330
+#define TARGET_NR_prlimit64 331
+#define TARGET_NR_name_to_handle_at 332
+#define TARGET_NR_open_by_handle_at 333
+#define TARGET_NR_clock_adjtime 334
+#define TARGET_NR_syncfs 335
diff --git a/linux-user/x86_64/syscall_nr.h b/linux-user/x86_64/syscall_nr.h
index 568a901..947e961 100644
--- a/linux-user/x86_64/syscall_nr.h
+++ b/linux-user/x86_64/syscall_nr.h
@@ -293,3 +293,15 @@
#define TARGET_NR_dup3 292
#define TARGET_NR_pipe2 293
#define TARGET_NR_inotify_init1 294
+#define TARGET_NR_preadv 295
+#define TARGET_NR_pwritev 296
+#define TARGET_NR_rt_tgsigqueueinfo 297
+#define TARGET_NR_perf_event_open 298
+#define TARGET_NR_recvmmsg 299
+#define TARGET_NR_fanotify_init 300
+#define TARGET_NR_fanotify_mark 301
+#define TARGET_NR_prlimit64 302
+#define TARGET_NR_name_to_handle_at 303
+#define TARGET_NR_open_by_handle_at 304
+#define TARGET_NR_clock_adjtime 305
+#define TARGET_NR_syncfs 306
commit 12b81b7145ec28a3c608d1eee5abcd5cdd6a677b
Author: Cédric VINCENT <cedric.vincent at st.com>
Date: Wed Jun 29 15:09:11 2011 +0200
linux-user: Add support for even more FB ioctls
This patch was validated with programs from DirectFB-1.0 and
WebKit/DirectFB.
Signed-off-by: Cédric VINCENT <cedric.vincent at st.com>
Cc: Riku Voipio <riku.voipio at iki.fi>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 7bc1c48..6514502 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -329,6 +329,11 @@
IOCTL(FBIOGET_FSCREENINFO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_fb_fix_screeninfo)))
IOCTL(FBIOGET_VSCREENINFO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo)))
IOCTL(FBIOPUT_VSCREENINFO, IOC_W, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo)))
+ IOCTL(FBIOGETCMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_cmap)))
+ IOCTL(FBIOPUTCMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_cmap)))
+ IOCTL(FBIOPAN_DISPLAY, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo)))
+ IOCTL(FBIOGET_CON2FBMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_con2fbmap)))
+ IOCTL(FBIOPUT_CON2FBMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_con2fbmap)))
IOCTL(VT_OPENQRY, IOC_R, MK_PTR(TYPE_INT))
IOCTL(VT_GETSTATE, IOC_R, MK_PTR(MK_STRUCT(STRUCT_vt_stat)))
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 4a59b36..1b73451 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -932,6 +932,11 @@ struct target_pollfd {
#define TARGET_FBIOGET_VSCREENINFO 0x4600
#define TARGET_FBIOPUT_VSCREENINFO 0x4601
#define TARGET_FBIOGET_FSCREENINFO 0x4602
+#define TARGET_FBIOGETCMAP 0x4604
+#define TARGET_FBIOPUTCMAP 0x4605
+#define TARGET_FBIOPAN_DISPLAY 0x4606
+#define TARGET_FBIOGET_CON2FBMAP 0x460F
+#define TARGET_FBIOPUT_CON2FBMAP 0x4610
/* vt ioctls */
#define TARGET_VT_OPENQRY 0x5600
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index 94b0ce0..c370125 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -161,6 +161,19 @@ STRUCT(fb_var_screeninfo,
TYPE_INT, /* rotate */
MK_ARRAY(TYPE_INT, 5)) /* reserved */
+STRUCT(fb_cmap,
+ TYPE_INT, /* start */
+ TYPE_INT, /* len */
+ TYPE_PTRVOID, /* red */
+ TYPE_PTRVOID, /* green */
+ TYPE_PTRVOID, /* blue */
+ TYPE_PTRVOID) /* transp */
+
+STRUCT(fb_con2fbmap,
+ TYPE_INT, /* console */
+ TYPE_INT) /* framebuffer */
+
+
STRUCT(vt_stat,
TYPE_SHORT, /* v_active */
TYPE_SHORT, /* v_signal */
commit 774750c088192112df1623610dc35d9e03983d49
Author: Cédric VINCENT <cedric.vincent at st.com>
Date: Wed Jun 29 15:09:10 2011 +0200
linux-user: Add support for more VT ioctls
DirectFB-1.0 uses at least two of the four added ioctls, and the two
others were added for completeness. This patch was validated with the
program "vlock -all/-new".
Signed-off-by: Cédric VINCENT <cedric.vincent at st.com>
Cc: Riku Voipio <riku.voipio at iki.fi>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 68418e4..7bc1c48 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -336,3 +336,7 @@
IOCTL(VT_WAITACTIVE, 0, TYPE_INT)
IOCTL(VT_LOCKSWITCH, 0, TYPE_INT)
IOCTL(VT_UNLOCKSWITCH, 0, TYPE_INT)
+ IOCTL(VT_GETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode)))
+ IOCTL(VT_SETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode)))
+ IOCTL(VT_RELDISP, 0, TYPE_INT)
+ IOCTL(VT_DISALLOCATE, 0, TYPE_INT)
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 2b74547..4a59b36 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -940,6 +940,10 @@ struct target_pollfd {
#define TARGET_VT_WAITACTIVE 0x5607
#define TARGET_VT_LOCKSWITCH 0x560b
#define TARGET_VT_UNLOCKSWITCH 0x560c
+#define TARGET_VT_GETMODE 0x5601
+#define TARGET_VT_SETMODE 0x5602
+#define TARGET_VT_RELDISP 0x5605
+#define TARGET_VT_DISALLOCATE 0x5608
/* from asm/termbits.h */
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index 0e67cd8..94b0ce0 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -166,6 +166,13 @@ STRUCT(vt_stat,
TYPE_SHORT, /* v_signal */
TYPE_SHORT) /* v_state */
+STRUCT(vt_mode,
+ TYPE_CHAR, /* mode */
+ TYPE_CHAR, /* waitv */
+ TYPE_SHORT, /* relsig */
+ TYPE_SHORT, /* acqsig */
+ TYPE_SHORT) /* frsig */
+
STRUCT(fiemap_extent,
TYPE_ULONGLONG, /* fe_logical */
TYPE_ULONGLONG, /* fe_physical */
commit e6fe18fb318cb399623246e2561581442ffc0372
Author: Cédric VINCENT <cedric.vincent at st.com>
Date: Wed Jun 29 15:09:09 2011 +0200
linux-user: Add support for KD...LED ioctls
DirectFB-1.0 uses at least one of the four added ioctls, and the three
others were added for completeness. This patch was validated with the
program "setleds" and the following Makefile:
SETLEDS_INIT = setleds -v -num -caps -scroll
SETLEDS_TESTS = sh -c ' \
setleds -v +num +caps +scroll; \
setleds -v -num -caps -scroll; \
setleds -v +num -caps -scroll; \
setleds -v +num +caps -scroll; \
setleds -v +num +caps +scroll; \
setleds -v -num +caps +scroll; \
setleds -v -num -caps +scroll; \
setleds -v -num -caps -scroll'
SETLEDS_HOST = setleds
SETLEDS_QEMU = "SETLEDS_QEMU not set"
.PHONY: setleds_tests
setleds_tests:
rm -f setleds.host setleds.target
$(SETLEDS_INIT:setleds=$(SETLEDS_HOST))
$(SETLEDS_TESTS:setleds=$(SETLEDS_HOST)) >> setleds.host
$(SETLEDS_INIT:setleds=$(SETLEDS_QEMU))
$(SETLEDS_TESTS:setleds=$(SETLEDS_QEMU)) >> setleds.target
cmp setleds.host setleds.target
Signed-off-by: Cédric VINCENT <cedric.vincent at st.com>
Cc: Riku Voipio <riku.voipio at iki.fi>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 42b3ae3..68418e4 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -59,6 +59,10 @@
IOCTL(KDSKBMODE, 0, TYPE_INT)
IOCTL(KDGKBENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbentry)))
IOCTL(KDGKBSENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbsentry)))
+ IOCTL(KDGKBLED, 0, TYPE_INT)
+ IOCTL(KDSKBLED, 0, TYPE_INT)
+ IOCTL(KDGETLED, 0, TYPE_INT)
+ IOCTL(KDSETLED, 0, TYPE_INT)
IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT))
IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT))
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 04c268d..2b74547 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -708,6 +708,10 @@ struct target_pollfd {
#define TARGET_KDSKBMODE 0x4b45
#define TARGET_KDGKBENT 0x4B46 /* gets one entry in translation table */
#define TARGET_KDGKBSENT 0x4B48 /* gets one function key string entry */
+#define TARGET_KDGKBLED 0x4B64 /* get led flags (not lights) */
+#define TARGET_KDSKBLED 0x4B65 /* set led flags (not lights) */
+#define TARGET_KDGETLED 0x4B31 /* return current led state */
+#define TARGET_KDSETLED 0x4B32 /* set led state [lights, not flags] */
#define TARGET_SIOCATMARK 0x8905
commit 1c1b40c162a6964e1898e84304230a308f4d16c3
Author: Cédric VINCENT <cedric.vincent at st.com>
Date: Wed Jun 29 12:49:41 2011 +0200
arm-semi: Provide access to CLI arguments passed through the "-append" option
This patch basically adapts the new semi-hosting command-line support
-- introduced by Wolfgang Schildbach in the commit 2e8785ac -- for use
in system-mode.
Note that the "arm_cmdline_len" and "host_cmdline_len" variables were
renamed respectively "input_size" and "output_size" because:
* in C, the term "length" is generally used to count the number of
character in a string, not to count the number of bytes in a
buffer (as it is the case here).
* in QEMU, the term "host" is used to name variables that are in
the host address space, not to name variables in the target
address space (as it is the case here).
* in the case of this system-call, the terms "input" and "output"
fit the semantic of the official ARM semi-hosting specification
quite well.
I know renaming can be considered harmful but I do think in this case
the semantic really matters to keep this code more understandable.
Signed-off-by: Cédric VINCENT <cedric.vincent at st.com>
Reviewed-by: Christophe Lyon <christophe.lyon at st.com>
Cc: Peter Maydell <peter.maydell at linaro.org>
Cc: Paul Brook <paul at codesourcery.com>
Cc: Wolfgang Schildbach <wschi at dolby.com>
Cc: Riku Voipio <riku.voipio at iki.fi>
Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
diff --git a/arm-semi.c b/arm-semi.c
index 5a62d03..873518a 100644
--- a/arm-semi.c
+++ b/arm-semi.c
@@ -34,6 +34,7 @@
#else
#include "qemu-common.h"
#include "gdbstub.h"
+#include "hw/arm-misc.h"
#endif
#define SYS_OPEN 0x01
@@ -369,68 +370,88 @@ uint32_t do_arm_semihosting(CPUState *env)
return syscall_err;
#endif
case SYS_GET_CMDLINE:
-#ifdef CONFIG_USER_ONLY
- /* Build a commandline from the original argv. */
{
- char *arm_cmdline_buffer;
- const char *host_cmdline_buffer;
+ /* Build a command-line from the original argv.
+ *
+ * The inputs are:
+ * * ARG(0), pointer to a buffer of at least the size
+ * specified in ARG(1).
+ * * ARG(1), size of the buffer pointed to by ARG(0) in
+ * bytes.
+ *
+ * The outputs are:
+ * * ARG(0), pointer to null-terminated string of the
+ * command line.
+ * * ARG(1), length of the string pointed to by ARG(0).
+ */
- unsigned int i;
- unsigned int arm_cmdline_len = ARG(1);
- unsigned int host_cmdline_len =
- ts->info->arg_end-ts->info->arg_start;
+ char *output_buffer;
+ size_t input_size = ARG(1);
+ size_t output_size;
+ int status = 0;
- if (!arm_cmdline_len || host_cmdline_len > arm_cmdline_len) {
- return -1; /* not enough space to store command line */
- }
+ /* Compute the size of the output string. */
+#if !defined(CONFIG_USER_ONLY)
+ output_size = strlen(ts->boot_info->kernel_filename)
+ + 1 /* Separating space. */
+ + strlen(ts->boot_info->kernel_cmdline)
+ + 1; /* Terminating null byte. */
+#else
+ unsigned int i;
- if (!host_cmdline_len) {
+ output_size = ts->info->arg_end - ts->info->arg_start;
+ if (!output_size) {
/* We special-case the "empty command line" case (argc==0).
Just provide the terminating 0. */
- arm_cmdline_buffer = lock_user(VERIFY_WRITE, ARG(0), 1, 0);
- arm_cmdline_buffer[0] = 0;
- unlock_user(arm_cmdline_buffer, ARG(0), 1);
+ output_size = 1;
+ }
+#endif
- /* Adjust the commandline length argument. */
- SET_ARG(1, 0);
- return 0;
+ if (output_size > input_size) {
+ /* Not enough space to store command-line arguments. */
+ return -1;
}
- /* lock the buffers on the ARM side */
- arm_cmdline_buffer =
- lock_user(VERIFY_WRITE, ARG(0), host_cmdline_len, 0);
- host_cmdline_buffer =
- lock_user(VERIFY_READ, ts->info->arg_start,
- host_cmdline_len, 1);
+ /* Adjust the command-line length. */
+ SET_ARG(1, output_size - 1);
- if (arm_cmdline_buffer && host_cmdline_buffer)
- {
- /* the last argument is zero-terminated;
- no need for additional termination */
- memcpy(arm_cmdline_buffer, host_cmdline_buffer,
- host_cmdline_len);
+ /* Lock the buffer on the ARM side. */
+ output_buffer = lock_user(VERIFY_WRITE, ARG(0), output_size, 0);
+ if (!output_buffer) {
+ return -1;
+ }
- /* separate arguments by white spaces */
- for (i = 0; i < host_cmdline_len-1; i++) {
- if (arm_cmdline_buffer[i] == 0) {
- arm_cmdline_buffer[i] = ' ';
- }
- }
+ /* Copy the command-line arguments. */
+#if !defined(CONFIG_USER_ONLY)
+ pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename);
+ pstrcat(output_buffer, output_size, " ");
+ pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline);
+#else
+ if (output_size == 1) {
+ /* Empty command-line. */
+ output_buffer[0] = '\0';
+ goto out;
+ }
- /* Adjust the commandline length argument. */
- SET_ARG(1, host_cmdline_len-1);
+ if (copy_from_user(output_buffer, ts->info->arg_start,
+ output_size)) {
+ status = -1;
+ goto out;
}
- /* Unlock the buffers on the ARM side. */
- unlock_user(arm_cmdline_buffer, ARG(0), host_cmdline_len);
- unlock_user((void*)host_cmdline_buffer, ts->info->arg_start, 0);
+ /* Separate arguments by white spaces. */
+ for (i = 0; i < output_size - 1; i++) {
+ if (output_buffer[i] == 0) {
+ output_buffer[i] = ' ';
+ }
+ }
+ out:
+#endif
+ /* Unlock the buffer on the ARM side. */
+ unlock_user(output_buffer, ARG(0), output_size);
- /* Return success if we could return a commandline. */
- return (arm_cmdline_buffer && host_cmdline_buffer) ? 0 : -1;
+ return status;
}
-#else
- return -1;
-#endif
case SYS_HEAPINFO:
{
uint32_t *ptr;
commit 3dc345d5874475a05794e7e1688f133b35384a9a
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Thu Jul 7 15:18:50 2011 +0200
usb-ohci: raise interrupt on attach
Got lost in commit 618c169b577db64ac6589ad48825d2e11760d1a6,
add it back in. Also fix codestyle while we are at it.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index c77a20e..8491d59 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -327,6 +327,7 @@ static void ohci_attach(USBPort *port1)
{
OHCIState *s = port1->opaque;
OHCIPort *port = &s->rhport[port1->index];
+ uint32_t old_state = port->ctrl;
/* set connect status */
port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
@@ -344,6 +345,10 @@ static void ohci_attach(USBPort *port1)
}
DPRINTF("usb-ohci: Attached port %d\n", port1->index);
+
+ if (old_state != port->ctrl) {
+ ohci_set_interrupt(s, OHCI_INTR_RHSC);
+ }
}
static void ohci_detach(USBPort *port1)
@@ -366,8 +371,9 @@ static void ohci_detach(USBPort *port1)
}
DPRINTF("usb-ohci: Detached port %d\n", port1->index);
- if (old_state != port->ctrl)
+ if (old_state != port->ctrl) {
ohci_set_interrupt(s, OHCI_INTR_RHSC);
+ }
}
static void ohci_wakeup(USBPort *port1)
commit 6c2385270b1c495515cd685b2f77c76a1b3fc864
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Thu Jul 7 15:02:58 2011 +0200
usb-hub: remove unused descriptor arrays
Somehow they where left over when converting the hub
to the new usb descriptor infrastructure ...
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index b7557ce..b49a2fe 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -138,74 +138,6 @@ static const USBDesc desc_hub = {
.str = desc_strings,
};
-static const uint8_t qemu_hub_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x10, 0x01, /* u16 bcdUSB; v1.1 */
-
- 0x09, /* u8 bDeviceClass; HUB_CLASSCODE */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- 0x00, 0x00, /* u16 idVendor; */
- 0x00, 0x00, /* u16 idProduct; */
- 0x01, 0x01, /* u16 bcdDevice */
-
- 0x03, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x01, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-/* XXX: patch interrupt size */
-static const uint8_t qemu_hub_config_descriptor[] = {
-
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x19, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x00, /* u8 iConfiguration; */
- 0xe0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 0x00, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */
- 0x00, /* u8 if_bInterfaceSubClass; */
- 0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x00, /* u8 if_iInterface; */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
- 0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
static const uint8_t qemu_hub_hub_descriptor[] =
{
0x00, /* u8 bLength; patched in later */
commit dd850cf2030b99d34019dd50e0df43907a3e1b41
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Jul 6 12:40:28 2011 +0200
usb: fixup bluetooth descriptors
Commit 4696425cd05c7baa0a4b469d43ba4b8488bcfc0f changes some
endpoints from isocrounous to interrupt by mistake. Fix it.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-bt.c b/hw/usb-bt.c
index baae487..e364513 100644
--- a/hw/usb-bt.c
+++ b/hw/usb-bt.c
@@ -99,13 +99,13 @@ static const USBDescIface desc_iface_bluetooth[] = {
.eps = (USBDescEndpoint[]) {
{
.bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0,
.bInterval = 0x01,
},
{
.bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0,
.bInterval = 0x01,
},
@@ -120,13 +120,13 @@ static const USBDescIface desc_iface_bluetooth[] = {
.eps = (USBDescEndpoint[]) {
{
.bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0x09,
.bInterval = 0x01,
},
{
.bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0x09,
.bInterval = 0x01,
},
@@ -141,13 +141,13 @@ static const USBDescIface desc_iface_bluetooth[] = {
.eps = (USBDescEndpoint[]) {
{
.bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0x11,
.bInterval = 0x01,
},
{
.bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0x11,
.bInterval = 0x01,
},
@@ -162,13 +162,13 @@ static const USBDescIface desc_iface_bluetooth[] = {
.eps = (USBDescEndpoint[]) {
{
.bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0x19,
.bInterval = 0x01,
},
{
.bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0x19,
.bInterval = 0x01,
},
@@ -183,13 +183,13 @@ static const USBDescIface desc_iface_bluetooth[] = {
.eps = (USBDescEndpoint[]) {
{
.bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0x21,
.bInterval = 0x01,
},
{
.bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0x21,
.bInterval = 0x01,
},
@@ -204,13 +204,13 @@ static const USBDescIface desc_iface_bluetooth[] = {
.eps = (USBDescEndpoint[]) {
{
.bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0x31,
.bInterval = 0x01,
},
{
.bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bmAttributes = USB_ENDPOINT_XFER_ISOC,
.wMaxPacketSize = 0x31,
.bInterval = 0x01,
},
commit eb3b58f96f6740ab1cc64ba514367ce1814779e4
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date: Mon Jul 4 17:33:05 2011 +0200
usb_register_port(): do not set port->opaque and port->index twice
Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index c8347e9..f1dd55e 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -143,8 +143,6 @@ static void usb_fill_port(USBPort *port, void *opaque, int index,
{
port->opaque = opaque;
port->index = index;
- port->opaque = opaque;
- port->index = index;
port->ops = ops;
port->speedmask = speedmask;
usb_port_location(port, NULL, index + 1);
commit 76f30473da752ee8448e80dfd1e050cedd482b6c
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Tue Jul 5 16:58:41 2011 +0200
usb: update documentation
Add a paragraph on companion controller mode and a
configuration file which sets it all up for you.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/docs/ich9-ehci-uhci.cfg b/docs/ich9-ehci-uhci.cfg
new file mode 100644
index 0000000..a0e9b96
--- /dev/null
+++ b/docs/ich9-ehci-uhci.cfg
@@ -0,0 +1,37 @@
+###########################################################################
+#
+# You can pass this file directly to qemu using the -readconfig
+# command line switch.
+#
+# This config file creates a EHCI adapter with companion UHCI
+# controllers as multifunction device in PCI slot "1d".
+#
+# Specify "bus=ehci.0" when creating usb devices to hook them up
+# there.
+#
+
+[device "ehci"]
+ driver = "ich9-usb-ehci1"
+ addr = "1d.7"
+ multifunction = "on"
+
+[device "uhci-1"]
+ driver = "ich9-usb-uhci1"
+ addr = "1d.0"
+ multifunction = "on"
+ masterbus = "ehci.0"
+ firstport = "0"
+
+[device "uhci-2"]
+ driver = "ich9-usb-uhci2"
+ addr = "1d.1"
+ multifunction = "on"
+ masterbus = "ehci.0"
+ firstport = "2"
+
+[device "uhci-3"]
+ driver = "ich9-usb-uhci3"
+ addr = "1d.2"
+ multifunction = "on"
+ masterbus = "ehci.0"
+ firstport = "4"
diff --git a/docs/usb2.txt b/docs/usb2.txt
index 5950c71..228aa33 100644
--- a/docs/usb2.txt
+++ b/docs/usb2.txt
@@ -2,11 +2,13 @@
USB 2.0 Quick Start
===================
-The QEMU EHCI Adapter does *not* support companion controllers. That
-implies there are two completely separate USB busses: One USB 1.1 bus
-driven by the UHCI controller and one USB 2.0 bus driven by the EHCI
-controller. Devices must be attached to the correct controller
-manually.
+The QEMU EHCI Adapter can be used with and without companion
+controllers. See below for the companion controller mode.
+
+When not running in companion controller mode there are two completely
+separate USB busses: One USB 1.1 bus driven by the UHCI controller and
+one USB 2.0 bus driven by the EHCI controller. Devices must be
+attached to the correct controller manually.
The '-usb' switch will make qemu create the UHCI controller as part of
the PIIX3 chipset. The USB 1.1 bus will carry the name "usb.0".
@@ -32,6 +34,27 @@ This attaches a usb tablet to the UHCI adapter and a usb mass storage
device to the EHCI adapter.
+Companion controller support
+----------------------------
+
+Companion controller support has been added recently. The operational
+model described above with two completely separate busses still works
+fine. Additionally the UHCI and OHCI controllers got the ability to
+attach to a usb bus created by EHCI as companion controllers. This is
+done by specifying the masterbus and firstport properties. masterbus
+specifies the bus name the controller should attach to. firstport
+specifies the first port the controller should attach to, which is
+needed as usually one ehci controller with six ports has three uhci
+companion controllers with two ports each.
+
+There is a config file in docs which will do all this for you, just
+try ...
+
+ qemu -readconfig docs/ich9-ehci-uhci.cfg
+
+... then use "bus=ehci.0" to assign your usb devices to that bus.
+
+
More USB tips & tricks
======================
commit 3028376ea0239e3820842bb596b21822e2373e9d
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Fri Jul 1 11:51:02 2011 +0200
ehci: add ich9 controller.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 0b959ca..a4758f9 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2244,19 +2244,34 @@ static USBBusOps ehci_bus_ops = {
.register_companion = ehci_register_companion,
};
-static PCIDeviceInfo ehci_info = {
- .qdev.name = "usb-ehci",
- .qdev.size = sizeof(EHCIState),
- .init = usb_ehci_initfn,
- .vendor_id = PCI_VENDOR_ID_INTEL,
- .device_id = PCI_DEVICE_ID_INTEL_82801D,
- .revision = 0x10,
- .class_id = PCI_CLASS_SERIAL_USB,
- .qdev.props = (Property[]) {
- DEFINE_PROP_UINT32("freq", EHCIState, freq, FRAME_TIMER_FREQ),
- DEFINE_PROP_UINT32("maxframes", EHCIState, maxframes, 128),
- DEFINE_PROP_END_OF_LIST(),
- },
+static Property ehci_properties[] = {
+ DEFINE_PROP_UINT32("freq", EHCIState, freq, FRAME_TIMER_FREQ),
+ DEFINE_PROP_UINT32("maxframes", EHCIState, maxframes, 128),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static PCIDeviceInfo ehci_info[] = {
+ {
+ .qdev.name = "usb-ehci",
+ .qdev.size = sizeof(EHCIState),
+ .init = usb_ehci_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801D, /* ich4 */
+ .revision = 0x10,
+ .class_id = PCI_CLASS_SERIAL_USB,
+ .qdev.props = ehci_properties,
+ },{
+ .qdev.name = "ich9-usb-ehci1",
+ .qdev.size = sizeof(EHCIState),
+ .init = usb_ehci_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1,
+ .revision = 0x03,
+ .class_id = PCI_CLASS_SERIAL_USB,
+ .qdev.props = ehci_properties,
+ },{
+ /* end of list */
+ }
};
static int usb_ehci_initfn(PCIDevice *dev)
@@ -2335,7 +2350,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
static void ehci_register(void)
{
- pci_qdev_register(&ehci_info);
+ pci_qdev_register_many(ehci_info);
}
device_init(ehci_register);
commit 5cc194caeb019cf1dae7f74ccbdf0401a56c2ac6
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Fri Jul 1 09:56:43 2011 +0200
ehci: fix port count.
The ICH4 EHCI controller which we emulate has six ports not four.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index ec68c29..0b959ca 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -130,7 +130,7 @@
#define FRAME_TIMER_NS (1000000000 / FRAME_TIMER_FREQ)
#define NB_MAXINTRATE 8 // Max rate at which controller issues ints
-#define NB_PORTS 4 // Number of downstream ports
+#define NB_PORTS 6 // Number of downstream ports
#define BUFF_SIZE 5*4096 // Max bytes to transfer per transaction
#define MAX_ITERATIONS 20 // Max number of QH before we break the loop
#define MAX_QH 100 // Max allowable queue heads in a chain
commit 1b5a757067a5ecd3504a067937b6494811a62f46
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Fri Jul 1 09:48:49 2011 +0200
uhci: add ich9 controllers
Add ich9 controllers, Factor out properties to a separate
struct and reference it to reduce duplication.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 925c03b..2ef4c5b 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1176,6 +1176,12 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
return usb_uhci_common_initfn(dev);
}
+static Property uhci_properties[] = {
+ DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
+ DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static PCIDeviceInfo uhci_info[] = {
{
.qdev.name = "piix3-usb-uhci",
@@ -1186,11 +1192,7 @@ static PCIDeviceInfo uhci_info[] = {
.device_id = PCI_DEVICE_ID_INTEL_82371SB_2,
.revision = 0x01,
.class_id = PCI_CLASS_SERIAL_USB,
- .qdev.props = (Property[]) {
- DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
- DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
- DEFINE_PROP_END_OF_LIST(),
- },
+ .qdev.props = uhci_properties,
},{
.qdev.name = "piix4-usb-uhci",
.qdev.size = sizeof(UHCIState),
@@ -1200,11 +1202,7 @@ static PCIDeviceInfo uhci_info[] = {
.device_id = PCI_DEVICE_ID_INTEL_82371AB_2,
.revision = 0x01,
.class_id = PCI_CLASS_SERIAL_USB,
- .qdev.props = (Property[]) {
- DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
- DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
- DEFINE_PROP_END_OF_LIST(),
- },
+ .qdev.props = uhci_properties,
},{
.qdev.name = "vt82c686b-usb-uhci",
.qdev.size = sizeof(UHCIState),
@@ -1214,11 +1212,37 @@ static PCIDeviceInfo uhci_info[] = {
.device_id = PCI_DEVICE_ID_VIA_UHCI,
.revision = 0x01,
.class_id = PCI_CLASS_SERIAL_USB,
- .qdev.props = (Property[]) {
- DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
- DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
- DEFINE_PROP_END_OF_LIST(),
- },
+ .qdev.props = uhci_properties,
+ },{
+ .qdev.name = "ich9-usb-uhci1",
+ .qdev.size = sizeof(UHCIState),
+ .qdev.vmsd = &vmstate_uhci,
+ .init = usb_uhci_common_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
+ .revision = 0x03,
+ .class_id = PCI_CLASS_SERIAL_USB,
+ .qdev.props = uhci_properties,
+ },{
+ .qdev.name = "ich9-usb-uhci2",
+ .qdev.size = sizeof(UHCIState),
+ .qdev.vmsd = &vmstate_uhci,
+ .init = usb_uhci_common_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
+ .revision = 0x03,
+ .class_id = PCI_CLASS_SERIAL_USB,
+ .qdev.props = uhci_properties,
+ },{
+ .qdev.name = "ich9-usb-uhci3",
+ .qdev.size = sizeof(UHCIState),
+ .qdev.vmsd = &vmstate_uhci,
+ .init = usb_uhci_common_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
+ .revision = 0x03,
+ .class_id = PCI_CLASS_SERIAL_USB,
+ .qdev.props = uhci_properties,
},{
/* end of list */
}
commit f9ebf5e564efe10115b48b743d3e175917917248
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Fri Jul 1 11:45:02 2011 +0200
pci: add ich9 usb controller ids
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index d94578c..927f2b0 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -109,5 +109,13 @@
#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
+#define PCI_DEVICE_ID_INTEL_82801I_UHCI1 0x2934
+#define PCI_DEVICE_ID_INTEL_82801I_UHCI2 0x2935
+#define PCI_DEVICE_ID_INTEL_82801I_UHCI3 0x2936
+#define PCI_DEVICE_ID_INTEL_82801I_UHCI4 0x2937
+#define PCI_DEVICE_ID_INTEL_82801I_UHCI5 0x2938
+#define PCI_DEVICE_ID_INTEL_82801I_UHCI6 0x2939
+#define PCI_DEVICE_ID_INTEL_82801I_EHCI1 0x293a
+#define PCI_DEVICE_ID_INTEL_82801I_EHCI2 0x293c
#define PCI_VENDOR_ID_XENSOURCE 0x5853
commit 9c9fc3346bd6ff87babd0e5f7ea0f500d3af5765
Author: Hans de Goede <hdegoede at redhat.com>
Date: Fri Jun 24 20:29:05 2011 +0200
usb-ohci: Add support for being a companion controller
To use as a companion controller, use pci-ohci as device and set the
masterbus and num-ports properties, ie:
-device usb-ehci,addr=0b.1,multifunction=on,id=ehci0
-device pci-ohci,addr=0b.0,multifunction=on,masterbus=ehci0.0,num-ports=4
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 46f0bcb..c77a20e 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1716,8 +1716,9 @@ static USBPortOps ohci_port_ops = {
static USBBusOps ohci_bus_ops = {
};
-static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
- int num_ports, uint32_t localmem_base)
+static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
+ int num_ports, uint32_t localmem_base,
+ char *masterbus, uint32_t firstport)
{
int i;
@@ -1737,38 +1738,58 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
usb_frame_time, usb_bit_time);
}
+ ohci->num_ports = num_ports;
+ if (masterbus) {
+ USBPort *ports[OHCI_MAX_PORTS];
+ for(i = 0; i < num_ports; i++) {
+ ports[i] = &ohci->rhport[i].port;
+ }
+ if (usb_register_companion(masterbus, ports, num_ports,
+ firstport, ohci, &ohci_port_ops,
+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) {
+ return -1;
+ }
+ } else {
+ usb_bus_new(&ohci->bus, &ohci_bus_ops, dev);
+ for (i = 0; i < num_ports; i++) {
+ usb_register_port(&ohci->bus, &ohci->rhport[i].port,
+ ohci, i, &ohci_port_ops,
+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
+ }
+ }
+
ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci,
DEVICE_LITTLE_ENDIAN);
ohci->localmem_base = localmem_base;
ohci->name = dev->info->name;
- usb_bus_new(&ohci->bus, &ohci_bus_ops, dev);
- ohci->num_ports = num_ports;
- for (i = 0; i < num_ports; i++) {
- usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, &ohci_port_ops,
- USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
- }
-
ohci->async_td = 0;
qemu_register_reset(ohci_reset, ohci);
+
+ return 0;
}
typedef struct {
PCIDevice pci_dev;
OHCIState state;
+ char *masterbus;
+ uint32_t num_ports;
+ uint32_t firstport;
} OHCIPCIState;
static int usb_ohci_initfn_pci(struct PCIDevice *dev)
{
OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev);
- int num_ports = 3;
ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */
/* TODO: RST# value should be 0. */
ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */
- usb_ohci_init(&ohci->state, &dev->qdev, num_ports, 0);
+ if (usb_ohci_init(&ohci->state, &dev->qdev, ohci->num_ports, 0,
+ ohci->masterbus, ohci->firstport) != 0) {
+ return -1;
+ }
ohci->state.irq = ohci->pci_dev.irq[0];
/* TODO: avoid cast below by using dev */
@@ -1792,7 +1813,8 @@ static int ohci_init_pxa(SysBusDevice *dev)
{
OHCISysBusState *s = FROM_SYSBUS(OHCISysBusState, dev);
- usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset);
+ /* Cannot fail as we pass NULL for masterbus */
+ usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset, NULL, 0);
sysbus_init_irq(dev, &s->ohci.irq);
sysbus_init_mmio(dev, 0x1000, s->ohci.mem);
@@ -1807,6 +1829,12 @@ static PCIDeviceInfo ohci_pci_info = {
.vendor_id = PCI_VENDOR_ID_APPLE,
.device_id = PCI_DEVICE_ID_APPLE_IPID_USB,
.class_id = PCI_CLASS_SERIAL_USB,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus),
+ DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3),
+ DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0),
+ DEFINE_PROP_END_OF_LIST(),
+ },
};
static SysBusDeviceInfo ohci_sysbus_info = {
commit 35e4977f575a377fc1fa05d819a533b2c5c8646f
Author: Hans de Goede <hdegoede at redhat.com>
Date: Fri Jun 24 17:44:53 2011 +0200
usb-uhci: Add support for being a companion controller
To use as a companion controller set the masterbus property.
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index a46d61a..925c03b 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -132,7 +132,7 @@ typedef struct UHCIPort {
struct UHCIState {
PCIDevice dev;
- USBBus bus;
+ USBBus bus; /* Note unused when we're a companion controller */
uint16_t cmd; /* cmd register */
uint16_t status;
uint16_t intr; /* interrupt enable register */
@@ -150,6 +150,10 @@ struct UHCIState {
/* Active packets */
QTAILQ_HEAD(,UHCIAsync) async_pending;
uint8_t num_ports_vmstate;
+
+ /* Properties */
+ char *masterbus;
+ uint32_t firstport;
};
typedef struct UHCI_TD {
@@ -1126,10 +1130,22 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
pci_conf[PCI_INTERRUPT_PIN] = 4; // interrupt pin 3
pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
- usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev);
- for(i = 0; i < NB_PORTS; i++) {
- usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
- USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
+ if (s->masterbus) {
+ USBPort *ports[NB_PORTS];
+ for(i = 0; i < NB_PORTS; i++) {
+ ports[i] = &s->ports[i].port;
+ }
+ if (usb_register_companion(s->masterbus, ports, NB_PORTS,
+ s->firstport, s, &uhci_port_ops,
+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) {
+ return -1;
+ }
+ } else {
+ usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev);
+ for (i = 0; i < NB_PORTS; i++) {
+ usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
+ }
}
s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s);
s->num_ports_vmstate = NB_PORTS;
@@ -1170,6 +1186,11 @@ static PCIDeviceInfo uhci_info[] = {
.device_id = PCI_DEVICE_ID_INTEL_82371SB_2,
.revision = 0x01,
.class_id = PCI_CLASS_SERIAL_USB,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
+ DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
+ DEFINE_PROP_END_OF_LIST(),
+ },
},{
.qdev.name = "piix4-usb-uhci",
.qdev.size = sizeof(UHCIState),
@@ -1179,6 +1200,11 @@ static PCIDeviceInfo uhci_info[] = {
.device_id = PCI_DEVICE_ID_INTEL_82371AB_2,
.revision = 0x01,
.class_id = PCI_CLASS_SERIAL_USB,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
+ DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
+ DEFINE_PROP_END_OF_LIST(),
+ },
},{
.qdev.name = "vt82c686b-usb-uhci",
.qdev.size = sizeof(UHCIState),
@@ -1188,6 +1214,11 @@ static PCIDeviceInfo uhci_info[] = {
.device_id = PCI_DEVICE_ID_VIA_UHCI,
.revision = 0x01,
.class_id = PCI_CLASS_SERIAL_USB,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
+ DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
+ DEFINE_PROP_END_OF_LIST(),
+ },
},{
/* end of list */
}
commit a0a3167a910d4ff9b43c9e69000f43753719909a
Author: Hans de Goede <hdegoede at redhat.com>
Date: Fri Jun 24 16:18:13 2011 +0200
usb-ehci: Add support for registering companion controllers
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 973c342..ec68c29 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -20,9 +20,6 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * TODO:
- * o Downstream port handoff
*/
#include "hw.h"
@@ -106,7 +103,7 @@
* Bits that are reserved or are read-only are masked out of values
* written to us by software
*/
-#define PORTSC_RO_MASK 0x007021c0
+#define PORTSC_RO_MASK 0x007001c0
#define PORTSC_RWC_MASK 0x0000002a
#define PORTSC_WKOC_E (1 << 22) // Wake on Over Current Enable
#define PORTSC_WKDS_E (1 << 21) // Wake on Disconnect Enable
@@ -373,6 +370,7 @@ struct EHCIState {
qemu_irq irq;
target_phys_addr_t mem_base;
int mem;
+ int companion_count;
/* properties */
uint32_t freq;
@@ -408,6 +406,7 @@ struct EHCIState {
int astate; // Current state in asynchronous schedule
int pstate; // Current state in periodic schedule
USBPort ports[NB_PORTS];
+ USBPort *companion_ports[NB_PORTS];
uint32_t usbsts_pending;
QTAILQ_HEAD(, EHCIQueue) queues;
@@ -730,17 +729,17 @@ static void ehci_attach(USBPort *port)
trace_usb_ehci_port_attach(port->index, port->dev->product_desc);
+ if (*portsc & PORTSC_POWNER) {
+ USBPort *companion = s->companion_ports[port->index];
+ companion->dev = port->dev;
+ companion->ops->attach(companion);
+ return;
+ }
+
*portsc |= PORTSC_CONNECT;
*portsc |= PORTSC_CSC;
- /*
- * If a high speed device is attached then we own this port(indicated
- * by zero in the PORTSC_POWNER bit field) so set the status bit
- * and set an interrupt if enabled.
- */
- if ( !(*portsc & PORTSC_POWNER)) {
- ehci_set_interrupt(s, USBSTS_PCD);
- }
+ ehci_set_interrupt(s, USBSTS_PCD);
}
static void ehci_detach(USBPort *port)
@@ -750,36 +749,110 @@ static void ehci_detach(USBPort *port)
trace_usb_ehci_port_detach(port->index);
+ if (*portsc & PORTSC_POWNER) {
+ USBPort *companion = s->companion_ports[port->index];
+ companion->ops->detach(companion);
+ companion->dev = NULL;
+ return;
+ }
+
ehci_queues_rip_device(s, port->dev);
*portsc &= ~(PORTSC_CONNECT|PORTSC_PED);
*portsc |= PORTSC_CSC;
- /*
- * If a high speed device is attached then we own this port(indicated
- * by zero in the PORTSC_POWNER bit field) so set the status bit
- * and set an interrupt if enabled.
- */
- if ( !(*portsc & PORTSC_POWNER)) {
- ehci_set_interrupt(s, USBSTS_PCD);
- }
+ ehci_set_interrupt(s, USBSTS_PCD);
}
static void ehci_child_detach(USBPort *port, USBDevice *child)
{
EHCIState *s = port->opaque;
+ uint32_t portsc = s->portsc[port->index];
+
+ if (portsc & PORTSC_POWNER) {
+ USBPort *companion = s->companion_ports[port->index];
+ companion->ops->child_detach(companion, child);
+ companion->dev = NULL;
+ return;
+ }
ehci_queues_rip_device(s, child);
}
+static void ehci_wakeup(USBPort *port)
+{
+ EHCIState *s = port->opaque;
+ uint32_t portsc = s->portsc[port->index];
+
+ if (portsc & PORTSC_POWNER) {
+ USBPort *companion = s->companion_ports[port->index];
+ if (companion->ops->wakeup) {
+ companion->ops->wakeup(companion);
+ }
+ }
+}
+
+static int ehci_register_companion(USBBus *bus, USBPort *ports[],
+ uint32_t portcount, uint32_t firstport)
+{
+ EHCIState *s = container_of(bus, EHCIState, bus);
+ uint32_t i;
+
+ if (firstport + portcount > NB_PORTS) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "firstport",
+ "firstport on masterbus");
+ error_printf_unless_qmp(
+ "firstport value of %u makes companion take ports %u - %u, which "
+ "is outside of the valid range of 0 - %u\n", firstport, firstport,
+ firstport + portcount - 1, NB_PORTS - 1);
+ return -1;
+ }
+
+ for (i = 0; i < portcount; i++) {
+ if (s->companion_ports[firstport + i]) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "masterbus",
+ "an USB masterbus");
+ error_printf_unless_qmp(
+ "port %u on masterbus %s already has a companion assigned\n",
+ firstport + i, bus->qbus.name);
+ return -1;
+ }
+ }
+
+ for (i = 0; i < portcount; i++) {
+ s->companion_ports[firstport + i] = ports[i];
+ s->ports[firstport + i].speedmask |=
+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL;
+ /* Ensure devs attached before the initial reset go to the companion */
+ s->portsc[firstport + i] = PORTSC_POWNER;
+ }
+
+ s->companion_count++;
+ s->mmio[0x05] = (s->companion_count << 4) | portcount;
+
+ return 0;
+}
+
/* 4.1 host controller initialization */
static void ehci_reset(void *opaque)
{
EHCIState *s = opaque;
int i;
+ USBDevice *devs[NB_PORTS];
trace_usb_ehci_reset();
+ /*
+ * Do the detach before touching portsc, so that it correctly gets send to
+ * us or to our companion based on PORTSC_POWNER before the reset.
+ */
+ for(i = 0; i < NB_PORTS; i++) {
+ devs[i] = s->ports[i].dev;
+ if (devs[i]) {
+ usb_attach(&s->ports[i], NULL);
+ }
+ }
+
memset(&s->mmio[OPREGBASE], 0x00, MMIO_SIZE - OPREGBASE);
s->usbcmd = NB_MAXINTRATE << USBCMD_ITC_SH;
@@ -791,10 +864,13 @@ static void ehci_reset(void *opaque)
s->attach_poll_counter = 0;
for(i = 0; i < NB_PORTS; i++) {
- s->portsc[i] = PORTSC_POWNER | PORTSC_PPOWER;
-
- if (s->ports[i].dev) {
- usb_attach(&s->ports[i], s->ports[i].dev);
+ if (s->companion_ports[i]) {
+ s->portsc[i] = PORTSC_POWNER | PORTSC_PPOWER;
+ } else {
+ s->portsc[i] = PORTSC_PPOWER;
+ }
+ if (devs[i]) {
+ usb_attach(&s->ports[i], devs[i]);
}
}
ehci_queues_rip_all(s);
@@ -844,6 +920,34 @@ static void ehci_mem_writew(void *ptr, target_phys_addr_t addr, uint32_t val)
exit(1);
}
+static void handle_port_owner_write(EHCIState *s, int port, uint32_t owner)
+{
+ USBDevice *dev = s->ports[port].dev;
+ uint32_t *portsc = &s->portsc[port];
+ uint32_t orig;
+
+ if (s->companion_ports[port] == NULL)
+ return;
+
+ owner = owner & PORTSC_POWNER;
+ orig = *portsc & PORTSC_POWNER;
+
+ if (!(owner ^ orig)) {
+ return;
+ }
+
+ if (dev) {
+ usb_attach(&s->ports[port], NULL);
+ }
+
+ *portsc &= ~PORTSC_POWNER;
+ *portsc |= owner;
+
+ if (dev) {
+ usb_attach(&s->ports[port], dev);
+ }
+}
+
static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
{
uint32_t *portsc = &s->portsc[port];
@@ -853,6 +957,9 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
*portsc &= ~(val & PORTSC_RWC_MASK);
/* The guest may clear, but not set the PED bit */
*portsc &= val | ~PORTSC_PED;
+ /* POWNER is masked out by RO_MASK as it is RO when we've no companion */
+ handle_port_owner_write(s, port, val);
+ /* And finally apply RO_MASK */
val &= PORTSC_RO_MASK;
if ((val & PORTSC_PRESET) && !(*portsc & PORTSC_PRESET)) {
@@ -956,7 +1063,7 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
val &= 0x1;
if (val) {
for(i = 0; i < NB_PORTS; i++)
- s->portsc[i] &= ~PORTSC_POWNER;
+ handle_port_owner_write(s, i, 0);
}
break;
@@ -1114,8 +1221,17 @@ static int ehci_buffer_rw(EHCIQueue *q, int bytes, int rw)
static void ehci_async_complete_packet(USBPort *port, USBPacket *packet)
{
- EHCIQueue *q = container_of(packet, EHCIQueue, packet);
+ EHCIQueue *q;
+ EHCIState *s = port->opaque;
+ uint32_t portsc = s->portsc[port->index];
+
+ if (portsc & PORTSC_POWNER) {
+ USBPort *companion = s->companion_ports[port->index];
+ companion->ops->complete(companion, packet);
+ return;
+ }
+ q = container_of(packet, EHCIQueue, packet);
trace_usb_ehci_queue_action(q, "wakeup");
assert(q->async == EHCI_ASYNC_INFLIGHT);
q->async = EHCI_ASYNC_FINISHED;
@@ -1245,8 +1361,6 @@ static int ehci_execute(EHCIQueue *q)
port = &q->ehci->ports[i];
dev = port->dev;
- // TODO sometime we will also need to check if we are the port owner
-
if (!(q->ehci->portsc[i] &(PORTSC_CONNECT))) {
DPRINTF("Port %d, no exec, not connected(%08X)\n",
i, q->ehci->portsc[i]);
@@ -1339,8 +1453,6 @@ static int ehci_process_itd(EHCIState *ehci,
port = &ehci->ports[j];
dev = port->dev;
- // TODO sometime we will also need to check if we are the port owner
-
if (!(ehci->portsc[j] &(PORTSC_CONNECT))) {
continue;
}
@@ -2124,10 +2236,12 @@ static USBPortOps ehci_port_ops = {
.attach = ehci_attach,
.detach = ehci_detach,
.child_detach = ehci_child_detach,
+ .wakeup = ehci_wakeup,
.complete = ehci_async_complete_packet,
};
static USBBusOps ehci_bus_ops = {
+ .register_companion = ehci_register_companion,
};
static PCIDeviceInfo ehci_info = {
commit fbd97532d22b6989fc71d64471c905d3c8174f5d
Author: Hans de Goede <hdegoede at redhat.com>
Date: Fri Jun 24 14:36:13 2011 +0200
usb-ehci: Fix handling of PED and PEDC port status bits
The PED bit should only be set for highspeed devices and the PEDC bit
should not be set on "normal" PED bit changes, only on io errors.
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index d85e0a9..973c342 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -106,7 +106,7 @@
* Bits that are reserved or are read-only are masked out of values
* written to us by software
*/
-#define PORTSC_RO_MASK 0x007021c4
+#define PORTSC_RO_MASK 0x007021c0
#define PORTSC_RWC_MASK 0x0000002a
#define PORTSC_WKOC_E (1 << 22) // Wake on Over Current Enable
#define PORTSC_WKDS_E (1 << 21) // Wake on Disconnect Enable
@@ -752,7 +752,7 @@ static void ehci_detach(USBPort *port)
ehci_queues_rip_device(s, port->dev);
- *portsc &= ~PORTSC_CONNECT;
+ *portsc &= ~(PORTSC_CONNECT|PORTSC_PED);
*portsc |= PORTSC_CSC;
/*
@@ -847,16 +847,14 @@ static void ehci_mem_writew(void *ptr, target_phys_addr_t addr, uint32_t val)
static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
{
uint32_t *portsc = &s->portsc[port];
- int rwc;
USBDevice *dev = s->ports[port].dev;
- rwc = val & PORTSC_RWC_MASK;
+ /* Clear rwc bits */
+ *portsc &= ~(val & PORTSC_RWC_MASK);
+ /* The guest may clear, but not set the PED bit */
+ *portsc &= val | ~PORTSC_PED;
val &= PORTSC_RO_MASK;
- // handle_read_write_clear(&val, portsc, PORTSC_PEDC | PORTSC_CSC);
-
- *portsc &= ~rwc;
-
if ((val & PORTSC_PRESET) && !(*portsc & PORTSC_PRESET)) {
trace_usb_ehci_port_reset(port, 1);
}
@@ -869,13 +867,13 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
*portsc &= ~PORTSC_CSC;
}
- /* Table 2.16 Set the enable bit(and enable bit change) to indicate
+ /*
+ * Table 2.16 Set the enable bit(and enable bit change) to indicate
* to SW that this port has a high speed device attached
- *
- * TODO - when to disable?
*/
- val |= PORTSC_PED;
- val |= PORTSC_PEDC;
+ if (dev && (dev->speedmask & USB_SPEED_MASK_HIGH)) {
+ val |= PORTSC_PED;
+ }
}
*portsc &= ~PORTSC_RO_MASK;
commit 45b9fd348061ab793cf4521bb3621f07a5bd7bf6
Author: Hans de Goede <hdegoede at redhat.com>
Date: Fri Jun 24 14:26:18 2011 +0200
usb: assert on calling usb_attach(port, NULL) on a port without a dev
with the "usb-ehci: cleanup port reset handling" patch in place no callers
are calling usb_attach(port, NULL) for a port where port->dev is NULL.
Doing that makes no sense as that causes the port detach op to get called
for a port with nothing attached. Add an assert that port->dev != NULL when
dev == NULL, and remove the check for not having a port->dev in the dev == NULL
case.
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb.c b/hw/usb.c
index 735ffd1..27a983c 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -40,12 +40,11 @@ void usb_attach(USBPort *port, USBDevice *dev)
} else {
/* detach */
dev = port->dev;
+ assert(dev);
port->ops->detach(port);
- if (dev) {
- usb_send_msg(dev, USB_MSG_DETACH);
- dev->port = NULL;
- port->dev = NULL;
- }
+ usb_send_msg(dev, USB_MSG_DETACH);
+ dev->port = NULL;
+ port->dev = NULL;
}
}
commit fbf9db645765a22b796e128967bebb64c073938a
Author: Hans de Goede <hdegoede at redhat.com>
Date: Tue Jun 21 12:23:40 2011 +0200
usb-ehci: cleanup port reset handling
Doing a usb_attach when dev is NULL will just result in the
port detach op getting called even though nothing was connected in
the first place.
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index ce1a432..d85e0a9 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -863,14 +863,9 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
if (!(val & PORTSC_PRESET) &&(*portsc & PORTSC_PRESET)) {
trace_usb_ehci_port_reset(port, 0);
- usb_attach(&s->ports[port], dev);
-
- // TODO how to handle reset of ports with no device
if (dev) {
+ usb_attach(&s->ports[port], dev);
usb_send_msg(dev, USB_MSG_RESET);
- }
-
- if (s->ports[port].dev) {
*portsc &= ~PORTSC_CSC;
}
commit c44fd61c0f38aa7927fd41bd7e59cb3e60fd4d75
Author: Hans de Goede <hdegoede at redhat.com>
Date: Tue Jun 21 12:12:35 2011 +0200
usb-ehci: Connect Status bit is read only, don't allow changing it by the guest
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 87e1de3..ce1a432 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -103,10 +103,10 @@
#define PORTSC_BEGIN PORTSC
#define PORTSC_END (PORTSC + 4 * NB_PORTS)
/*
- * Bits that are reserverd or are read-only are masked out of values
+ * Bits that are reserved or are read-only are masked out of values
* written to us by software
*/
-#define PORTSC_RO_MASK 0x007021c5
+#define PORTSC_RO_MASK 0x007021c4
#define PORTSC_RWC_MASK 0x0000002a
#define PORTSC_WKOC_E (1 << 22) // Wake on Over Current Enable
#define PORTSC_WKDS_E (1 << 21) // Wake on Disconnect Enable
commit 053f9fcfb1d84ab2f1d8fbd608d5e31aae58cbb7
Author: Hans de Goede <hdegoede at redhat.com>
Date: Fri Jun 17 15:26:29 2011 +0200
usb-ehci: drop unused num-ports state member
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 96451f3..87e1de3 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -373,7 +373,6 @@ struct EHCIState {
qemu_irq irq;
target_phys_addr_t mem_base;
int mem;
- int num_ports;
/* properties */
uint32_t freq;
commit 4706ab6cc0af86d3f38806664420cc3eb8999bd9
Author: Hans de Goede <hdegoede at redhat.com>
Date: Fri Jun 24 12:31:11 2011 +0200
usb: Replace device_destroy bus op with a child_detach port op
Note this fixes 2 things in one go, first of all the device_destroy bus
op should be a device_detach bus op, as pending async packets from the
device should be cancelled on detach not on destroy.
Secondly having this as a bus op won't work with companion controllers, since
then there will be 1 bus driven by the ehci controller and thus 1 set of bus
ops, but the device being detached may be downstream of a handed over port.
Making the detach of a downstream device a port op allows the ehci controller
to forward this to the companion controller port for handed over ports.
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index 5ab35c3..ce2bfc6 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -247,16 +247,21 @@ static void softusb_attach(USBPort *port)
{
}
-static void softusb_device_destroy(USBBus *bus, USBDevice *dev)
+static void softusb_detach(USBPort *port)
+{
+}
+
+static void softusb_child_detach(USBPort *port, USBDevice *child)
{
}
static USBPortOps softusb_ops = {
.attach = softusb_attach,
+ .detach = softusb_detach,
+ .child_detach = softusb_child_detach,
};
static USBBusOps softusb_bus_ops = {
- .device_destroy = softusb_device_destroy,
};
static void milkymist_softusb_reset(DeviceState *d)
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index b511bac..c8347e9 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -82,12 +82,10 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
static int usb_qdev_exit(DeviceState *qdev)
{
USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
- USBBus *bus = usb_bus_from_device(dev);
if (dev->attached) {
usb_device_detach(dev);
}
- bus->ops->device_destroy(bus, dev);
if (dev->info->handle_destroy) {
dev->info->handle_destroy(dev);
}
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 428c90b..96451f3 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -751,6 +751,8 @@ static void ehci_detach(USBPort *port)
trace_usb_ehci_port_detach(port->index);
+ ehci_queues_rip_device(s, port->dev);
+
*portsc &= ~PORTSC_CONNECT;
*portsc |= PORTSC_CSC;
@@ -764,6 +766,13 @@ static void ehci_detach(USBPort *port)
}
}
+static void ehci_child_detach(USBPort *port, USBDevice *child)
+{
+ EHCIState *s = port->opaque;
+
+ ehci_queues_rip_device(s, child);
+}
+
/* 4.1 host controller initialization */
static void ehci_reset(void *opaque)
{
@@ -2117,23 +2126,16 @@ static void ehci_map(PCIDevice *pci_dev, int region_num,
cpu_register_physical_memory(addr, size, s->mem);
}
-static void ehci_device_destroy(USBBus *bus, USBDevice *dev)
-{
- EHCIState *s = container_of(bus, EHCIState, bus);
-
- ehci_queues_rip_device(s, dev);
-}
-
static int usb_ehci_initfn(PCIDevice *dev);
static USBPortOps ehci_port_ops = {
.attach = ehci_attach,
.detach = ehci_detach,
+ .child_detach = ehci_child_detach,
.complete = ehci_async_complete_packet,
};
static USBBusOps ehci_bus_ops = {
- .device_destroy = ehci_device_destroy,
};
static PCIDeviceInfo ehci_info = {
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index d324bba..b7557ce 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -238,6 +238,9 @@ static void usb_hub_detach(USBPort *port1)
USBHubState *s = port1->opaque;
USBHubPort *port = &s->ports[port1->index];
+ /* Let upstream know the device on this port is gone */
+ s->dev.port->ops->child_detach(s->dev.port, port1->dev);
+
port->wPortStatus &= ~PORT_STAT_CONNECTION;
port->wPortChange |= PORT_STAT_C_CONNECTION;
if (port->wPortStatus & PORT_STAT_ENABLE) {
@@ -246,6 +249,14 @@ static void usb_hub_detach(USBPort *port1)
}
}
+static void usb_hub_child_detach(USBPort *port1, USBDevice *child)
+{
+ USBHubState *s = port1->opaque;
+
+ /* Pass along upstream */
+ s->dev.port->ops->child_detach(s->dev.port, child);
+}
+
static void usb_hub_wakeup(USBPort *port1)
{
USBHubState *s = port1->opaque;
@@ -537,6 +548,7 @@ static void usb_hub_handle_destroy(USBDevice *dev)
static USBPortOps usb_hub_port_ops = {
.attach = usb_hub_attach,
.detach = usb_hub_detach,
+ .child_detach = usb_hub_child_detach,
.wakeup = usb_hub_wakeup,
.complete = usb_hub_complete,
};
diff --git a/hw/usb-musb.c b/hw/usb-musb.c
index 580bdc8..035dda8 100644
--- a/hw/usb-musb.c
+++ b/hw/usb-musb.c
@@ -261,17 +261,18 @@
static void musb_attach(USBPort *port);
static void musb_detach(USBPort *port);
+static void musb_child_detach(USBPort *port, USBDevice *child);
static void musb_schedule_cb(USBPort *port, USBPacket *p);
-static void musb_device_destroy(USBBus *bus, USBDevice *dev);
+static void musb_async_cancel_device(MUSBState *s, USBDevice *dev);
static USBPortOps musb_port_ops = {
.attach = musb_attach,
.detach = musb_detach,
+ .child_detach = musb_child_detach,
.complete = musb_schedule_cb,
};
static USBBusOps musb_bus_ops = {
- .device_destroy = musb_device_destroy,
};
typedef struct MUSBPacket MUSBPacket;
@@ -497,10 +498,19 @@ static void musb_detach(USBPort *port)
{
MUSBState *s = (MUSBState *) port->opaque;
+ musb_async_cancel_device(s, port->dev);
+
musb_intr_set(s, musb_irq_disconnect, 1);
musb_session_update(s, 1, s->session);
}
+static void musb_child_detach(USBPort *port, USBDevice *child)
+{
+ MUSBState *s = (MUSBState *) port->opaque;
+
+ musb_async_cancel_device(s, child);
+}
+
static void musb_cb_tick0(void *opaque)
{
MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
@@ -782,9 +792,8 @@ static void musb_rx_packet_complete(USBPacket *packey, void *opaque)
musb_rx_intr_set(s, epnum, 1);
}
-static void musb_device_destroy(USBBus *bus, USBDevice *dev)
+static void musb_async_cancel_device(MUSBState *s, USBDevice *dev)
{
- MUSBState *s = container_of(bus, MUSBState, bus);
int ep, dir;
for (ep = 0; ep < 16; ep++) {
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index bd92c31..46f0bcb 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -124,6 +124,7 @@ struct ohci_hcca {
};
static void ohci_bus_stop(OHCIState *ohci);
+static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev);
/* Bitfields for the first word of an Endpoint Desciptor. */
#define OHCI_ED_FA_SHIFT 0
@@ -351,6 +352,8 @@ static void ohci_detach(USBPort *port1)
OHCIPort *port = &s->rhport[port1->index];
uint32_t old_state = port->ctrl;
+ ohci_async_cancel_device(s, port1->dev);
+
/* set connect status */
if (port->ctrl & OHCI_PORT_CCS) {
port->ctrl &= ~OHCI_PORT_CCS;
@@ -392,6 +395,13 @@ static void ohci_wakeup(USBPort *port1)
ohci_set_interrupt(s, intr);
}
+static void ohci_child_detach(USBPort *port1, USBDevice *child)
+{
+ OHCIState *s = port1->opaque;
+
+ ohci_async_cancel_device(s, child);
+}
+
/* Reset the controller */
static void ohci_reset(void *opaque)
{
@@ -1673,10 +1683,8 @@ static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val)
}
}
-static void ohci_device_destroy(USBBus *bus, USBDevice *dev)
+static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev)
{
- OHCIState *ohci = container_of(bus, OHCIState, bus);
-
if (ohci->async_td && ohci->usb_packet.owner == dev) {
usb_cancel_packet(&ohci->usb_packet);
ohci->async_td = 0;
@@ -1700,12 +1708,12 @@ static CPUWriteMemoryFunc * const ohci_writefn[3]={
static USBPortOps ohci_port_ops = {
.attach = ohci_attach,
.detach = ohci_detach,
+ .child_detach = ohci_child_detach,
.wakeup = ohci_wakeup,
.complete = ohci_async_complete_packet,
};
static USBBusOps ohci_bus_ops = {
- .device_destroy = ohci_device_destroy,
};
static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index ab635f6..a46d61a 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -606,6 +606,8 @@ static void uhci_detach(USBPort *port1)
UHCIState *s = port1->opaque;
UHCIPort *port = &s->ports[port1->index];
+ uhci_async_cancel_device(s, port1->dev);
+
/* set connect status */
if (port->ctrl & UHCI_PORT_CCS) {
port->ctrl &= ~UHCI_PORT_CCS;
@@ -620,6 +622,13 @@ static void uhci_detach(USBPort *port1)
uhci_resume(s);
}
+static void uhci_child_detach(USBPort *port1, USBDevice *child)
+{
+ UHCIState *s = port1->opaque;
+
+ uhci_async_cancel_device(s, child);
+}
+
static void uhci_wakeup(USBPort *port1)
{
UHCIState *s = port1->opaque;
@@ -1095,22 +1104,15 @@ static void uhci_map(PCIDevice *pci_dev, int region_num,
register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
}
-static void uhci_device_destroy(USBBus *bus, USBDevice *dev)
-{
- UHCIState *s = container_of(bus, UHCIState, bus);
-
- uhci_async_cancel_device(s, dev);
-}
-
static USBPortOps uhci_port_ops = {
.attach = uhci_attach,
.detach = uhci_detach,
+ .child_detach = uhci_child_detach,
.wakeup = uhci_wakeup,
.complete = uhci_async_complete,
};
static USBBusOps uhci_bus_ops = {
- .device_destroy = uhci_device_destroy,
};
static int usb_uhci_common_initfn(PCIDevice *dev)
diff --git a/hw/usb.h b/hw/usb.h
index 65f45a0..ded2de2 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -252,6 +252,11 @@ struct USBDeviceInfo {
typedef struct USBPortOps {
void (*attach)(USBPort *port);
void (*detach)(USBPort *port);
+ /*
+ * This gets called when a device downstream from the device attached to
+ * the port (iow attached through a hub) gets detached.
+ */
+ void (*child_detach)(USBPort *port, USBDevice *child);
void (*wakeup)(USBPort *port);
/*
* Note that port->dev will be different then the device from which
@@ -351,7 +356,6 @@ struct USBBus {
struct USBBusOps {
int (*register_companion)(USBBus *bus, USBPort *ports[],
uint32_t portcount, uint32_t firstport);
- void (*device_destroy)(USBBus *bus, USBDevice *dev);
};
void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host);
commit d47e59b8b8adc96a2052f7e004cb12b6ff62edd9
Author: Hans de Goede <hdegoede at redhat.com>
Date: Tue Jun 21 11:52:28 2011 +0200
usb: Make port wakeup and complete ops take a USBPort instead of a Device
This makes them consistent with the attach and detach ops, and in general
it makes sense to make portops take a port as argument. This also makes
adding support for a companion controller easier / cleaner.
[ kraxel: fix usb-musb.c build ]
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 88cb2c2..428c90b 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -1111,7 +1111,7 @@ static int ehci_buffer_rw(EHCIQueue *q, int bytes, int rw)
return 0;
}
-static void ehci_async_complete_packet(USBDevice *dev, USBPacket *packet)
+static void ehci_async_complete_packet(USBPort *port, USBPacket *packet)
{
EHCIQueue *q = container_of(packet, EHCIQueue, packet);
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 6e2a358..d324bba 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -246,10 +246,10 @@ static void usb_hub_detach(USBPort *port1)
}
}
-static void usb_hub_wakeup(USBDevice *dev)
+static void usb_hub_wakeup(USBPort *port1)
{
- USBHubState *s = dev->port->opaque;
- USBHubPort *port = &s->ports[dev->port->index];
+ USBHubState *s = port1->opaque;
+ USBHubPort *port = &s->ports[port1->index];
if (port->wPortStatus & PORT_STAT_SUSPEND) {
port->wPortChange |= PORT_STAT_C_SUSPEND;
@@ -257,9 +257,9 @@ static void usb_hub_wakeup(USBDevice *dev)
}
}
-static void usb_hub_complete(USBDevice *dev, USBPacket *packet)
+static void usb_hub_complete(USBPort *port, USBPacket *packet)
{
- USBHubState *s = dev->port->opaque;
+ USBHubState *s = port->opaque;
/*
* Just pass it along upstream for now.
diff --git a/hw/usb-musb.c b/hw/usb-musb.c
index 84e6017..580bdc8 100644
--- a/hw/usb-musb.c
+++ b/hw/usb-musb.c
@@ -261,7 +261,7 @@
static void musb_attach(USBPort *port);
static void musb_detach(USBPort *port);
-static void musb_schedule_cb(USBDevice *dev, USBPacket *p);
+static void musb_schedule_cb(USBPort *port, USBPacket *p);
static void musb_device_destroy(USBBus *bus, USBDevice *dev);
static USBPortOps musb_port_ops = {
@@ -517,7 +517,7 @@ static void musb_cb_tick1(void *opaque)
#define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0)
-static void musb_schedule_cb(USBDevice *dev, USBPacket *packey)
+static void musb_schedule_cb(USBPort *port, USBPacket *packey)
{
MUSBPacket *p = container_of(packey, MUSBPacket, p);
MUSBEndPoint *ep = p->ep;
@@ -615,7 +615,7 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
}
ep->status[dir] = ret;
- musb_schedule_cb(s->port.dev, &ep->packey[dir].p);
+ musb_schedule_cb(&s->port, &ep->packey[dir].p);
}
static void musb_tx_packet_complete(USBPacket *packey, void *opaque)
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 95e4623..bd92c31 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -367,15 +367,13 @@ static void ohci_detach(USBPort *port1)
ohci_set_interrupt(s, OHCI_INTR_RHSC);
}
-static void ohci_wakeup(USBDevice *dev)
+static void ohci_wakeup(USBPort *port1)
{
- USBBus *bus = usb_bus_from_device(dev);
- OHCIState *s = container_of(bus, OHCIState, bus);
- int portnum = dev->port->index;
- OHCIPort *port = &s->rhport[portnum];
+ OHCIState *s = port1->opaque;
+ OHCIPort *port = &s->rhport[port1->index];
uint32_t intr = 0;
if (port->ctrl & OHCI_PORT_PSS) {
- DPRINTF("usb-ohci: port %d: wakeup\n", portnum);
+ DPRINTF("usb-ohci: port %d: wakeup\n", port1->index);
port->ctrl |= OHCI_PORT_PSSC;
port->ctrl &= ~OHCI_PORT_PSS;
intr = OHCI_INTR_RHSC;
@@ -602,7 +600,7 @@ static void ohci_copy_iso_td(OHCIState *ohci,
static void ohci_process_lists(OHCIState *ohci, int completion);
-static void ohci_async_complete_packet(USBDevice *dev, USBPacket *packet)
+static void ohci_async_complete_packet(USBPort *port, USBPacket *packet)
{
OHCIState *ohci = container_of(packet, OHCIState, usb_packet);
#ifdef DEBUG_PACKET
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index fd25d2a..ab635f6 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -620,11 +620,10 @@ static void uhci_detach(USBPort *port1)
uhci_resume(s);
}
-static void uhci_wakeup(USBDevice *dev)
+static void uhci_wakeup(USBPort *port1)
{
- USBBus *bus = usb_bus_from_device(dev);
- UHCIState *s = container_of(bus, UHCIState, bus);
- UHCIPort *port = s->ports + dev->port->index;
+ UHCIState *s = port1->opaque;
+ UHCIPort *port = &s->ports[port1->index];
if (port->ctrl & UHCI_PORT_SUSPEND && !(port->ctrl & UHCI_PORT_RD)) {
port->ctrl |= UHCI_PORT_RD;
@@ -657,7 +656,7 @@ static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
return ret;
}
-static void uhci_async_complete(USBDevice *dev, USBPacket *packet);
+static void uhci_async_complete(USBPort *port, USBPacket *packet);
static void uhci_process_frame(UHCIState *s);
/* return -1 if fatal error (frame must be stopped)
@@ -849,7 +848,7 @@ done:
return len;
}
-static void uhci_async_complete(USBDevice *dev, USBPacket *packet)
+static void uhci_async_complete(USBPort *port, USBPacket *packet)
{
UHCIAsync *async = container_of(packet, UHCIAsync, packet);
UHCIState *s = async->uhci;
diff --git a/hw/usb.c b/hw/usb.c
index 4a39cbc..735ffd1 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -52,7 +52,7 @@ void usb_attach(USBPort *port, USBDevice *dev)
void usb_wakeup(USBDevice *dev)
{
if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
- dev->port->ops->wakeup(dev);
+ dev->port->ops->wakeup(dev->port);
}
}
@@ -335,7 +335,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
{
/* Note: p->owner != dev is possible in case dev is a hub */
assert(p->owner != NULL);
- dev->port->ops->complete(dev, p);
+ dev->port->ops->complete(dev->port, p);
p->owner = NULL;
}
diff --git a/hw/usb.h b/hw/usb.h
index a5f2efa..65f45a0 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -252,8 +252,13 @@ struct USBDeviceInfo {
typedef struct USBPortOps {
void (*attach)(USBPort *port);
void (*detach)(USBPort *port);
- void (*wakeup)(USBDevice *dev);
- void (*complete)(USBDevice *dev, USBPacket *p);
+ void (*wakeup)(USBPort *port);
+ /*
+ * Note that port->dev will be different then the device from which
+ * the packet originated when a hub is involved, if you want the orginating
+ * device use p->owner
+ */
+ void (*complete)(USBPort *port, USBPacket *p);
} USBPortOps;
/* USB port on which a device can be connected */
commit ae60fea97c78e7f855794f2770517244d93def73
Author: Hans de Goede <hdegoede at redhat.com>
Date: Fri Jun 24 11:29:56 2011 +0200
usb: Add a register_companion USB bus op.
This is a preparation patch for adding support for USB companion controllers.
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index e37e8a2..b511bac 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -160,6 +160,37 @@ void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
bus->nfree++;
}
+int usb_register_companion(const char *masterbus, USBPort *ports[],
+ uint32_t portcount, uint32_t firstport,
+ void *opaque, USBPortOps *ops, int speedmask)
+{
+ USBBus *bus;
+ int i;
+
+ QTAILQ_FOREACH(bus, &busses, next) {
+ if (strcmp(bus->qbus.name, masterbus) == 0) {
+ break;
+ }
+ }
+
+ if (!bus || !bus->ops->register_companion) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "masterbus",
+ "an USB masterbus");
+ if (bus) {
+ error_printf_unless_qmp(
+ "USB bus '%s' does not allow companion controllers\n",
+ masterbus);
+ }
+ return -1;
+ }
+
+ for (i = 0; i < portcount; i++) {
+ usb_fill_port(ports[i], opaque, i, ops, speedmask);
+ }
+
+ return bus->ops->register_companion(bus, ports, portcount, firstport);
+}
+
void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr)
{
if (upstream) {
diff --git a/hw/usb.h b/hw/usb.h
index 076e2ff..a5f2efa 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -344,6 +344,8 @@ struct USBBus {
};
struct USBBusOps {
+ int (*register_companion)(USBBus *bus, USBPort *ports[],
+ uint32_t portcount, uint32_t firstport);
void (*device_destroy)(USBBus *bus, USBDevice *dev);
};
@@ -356,6 +358,9 @@ USBDevice *usb_create_simple(USBBus *bus, const char *name);
USBDevice *usbdevice_create(const char *cmdline);
void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
USBPortOps *ops, int speedmask);
+int usb_register_companion(const char *masterbus, USBPort *ports[],
+ uint32_t portcount, uint32_t firstport,
+ void *opaque, USBPortOps *ops, int speedmask);
void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr);
void usb_unregister_port(USBBus *bus, USBPort *port);
int usb_device_attach(USBDevice *dev);
commit 3631e6c8c263528ca159707b9255117a2c3bb175
Author: Hans de Goede <hdegoede at redhat.com>
Date: Thu Jun 30 12:05:19 2011 +0200
usb: Move (initial) call of usb_port_location to usb_fill_port
Cleanup / preparation patch for companion controller support. Note that
as a "side-effect" this patch also fixes the milkymist-softusb controller
not having a port_location set for its ports.
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 776974e..e37e8a2 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -149,6 +149,7 @@ static void usb_fill_port(USBPort *port, void *opaque, int index,
port->index = index;
port->ops = ops;
port->speedmask = speedmask;
+ usb_port_location(port, NULL, index + 1);
}
void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 91fb7de..88cb2c2 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2206,7 +2206,6 @@ static int usb_ehci_initfn(PCIDevice *dev)
for(i = 0; i < NB_PORTS; i++) {
usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops,
USB_SPEED_MASK_HIGH);
- usb_port_location(&s->ports[i], NULL, i+1);
s->ports[i].dev = 0;
}
diff --git a/hw/usb-musb.c b/hw/usb-musb.c
index d15971f..84e6017 100644
--- a/hw/usb-musb.c
+++ b/hw/usb-musb.c
@@ -369,7 +369,6 @@ struct MUSBState *musb_init(qemu_irq *irqs)
usb_bus_new(&s->bus, &musb_bus_ops, NULL /* FIXME */);
usb_register_port(&s->bus, &s->port, s, 0, &musb_port_ops,
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
- usb_port_location(&s->port, NULL, 1);
return s;
}
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 1c29b9f..95e4623 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1742,7 +1742,6 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
for (i = 0; i < num_ports; i++) {
usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, &ohci_port_ops,
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
- usb_port_location(&ohci->rhport[i].port, NULL, i+1);
}
ohci->async_td = 0;
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 405fa7b..fd25d2a 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1129,7 +1129,6 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
for(i = 0; i < NB_PORTS; i++) {
usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
- usb_port_location(&s->ports[i].port, NULL, i+1);
}
s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s);
s->num_ports_vmstate = NB_PORTS;
commit 090ac6425accf5d87be5ff8087080c876a2904e5
Author: Hans de Goede <hdegoede at redhat.com>
Date: Thu Jun 30 11:57:57 2011 +0200
usb: Add a usb_fill_port helper function
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 2abce12..776974e 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -140,8 +140,8 @@ USBDevice *usb_create_simple(USBBus *bus, const char *name)
return dev;
}
-void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
- USBPortOps *ops, int speedmask)
+static void usb_fill_port(USBPort *port, void *opaque, int index,
+ USBPortOps *ops, int speedmask)
{
port->opaque = opaque;
port->index = index;
@@ -149,6 +149,12 @@ void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
port->index = index;
port->ops = ops;
port->speedmask = speedmask;
+}
+
+void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
+ USBPortOps *ops, int speedmask)
+{
+ usb_fill_port(port, opaque, index, ops, speedmask);
QTAILQ_INSERT_TAIL(&bus->free, port, next);
bus->nfree++;
}
commit 000eb4fa525d0b9b2d2b2a2ad4925863af60e5f7
Author: Peter Maydell <peter.maydell at linaro.org>
Date: Tue Jun 14 12:24:04 2011 +0100
hw/usb-musb.c: Don't misuse usb_packet_complete()
In musb_packet() handle final processing of non-asynchronous
USB packets by directly calling musb_schedule_cb() rather than
going through usb_packet_complete(). The latter will trigger
an assertion because the packet doesn't belong to a device.
Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/usb-musb.c b/hw/usb-musb.c
index 21f35af..d15971f 100644
--- a/hw/usb-musb.c
+++ b/hw/usb-musb.c
@@ -616,7 +616,7 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
}
ep->status[dir] = ret;
- usb_packet_complete(s->port.dev, &ep->packey[dir].p);
+ musb_schedule_cb(s->port.dev, &ep->packey[dir].p);
}
static void musb_tx_packet_complete(USBPacket *packey, void *opaque)
commit c925400ba83bd57bf560e071f400012248f1644a
Author: Kevin Wolf <kwolf at redhat.com>
Date: Mon Jul 4 14:43:58 2011 +0200
ide: Initialise buffers with zeros
Just in case there's still a way how a guest can read out buffers when it's not
supposed to, let's zero the buffers during initialisation so that we don't leak
information to the guest.
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
diff --git a/hw/ide/core.c b/hw/ide/core.c
index a29ae9f..d145b19 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1789,9 +1789,13 @@ static void ide_init1(IDEBus *bus, int unit)
s->unit = unit;
s->drive_serial = drive_serial++;
/* we need at least 2k alignment for accessing CDROMs using O_DIRECT */
- s->io_buffer = qemu_memalign(2048, IDE_DMA_BUF_SECTORS*512 + 4);
s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
+ s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len);
+ memset(s->io_buffer, 0, s->io_buffer_total_len);
+
s->smart_selftest_data = qemu_blockalign(s->bs, 512);
+ memset(s->smart_selftest_data, 0, 512);
+
s->sector_write_timer = qemu_new_timer_ns(vm_clock,
ide_sector_write_timer_cb, s);
}
commit 40c4ed3f95f0b2ffa0848df0fc311556bb7472a1
Author: Kevin Wolf <kwolf at redhat.com>
Date: Mon Jul 4 14:07:50 2011 +0200
ide: Ignore reads during PIO in and writes during PIO out
This fixes https://bugs.launchpad.net/qemu/+bug/786209:
When the DRQ_STAT bit is set, the IDE core permits both data reads
and data writes, regardless of whether the current transfer was
initiated as a read or write.
This potentially leaks uninitialized host memory into the guest,
if, before doing anything else to an IDE device, the guest begins a
write transaction (e.g. WIN_WRITE), but then *reads* from the IO
port instead of writing to it.
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
diff --git a/hw/ide/core.c b/hw/ide/core.c
index ca17a43..a29ae9f 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -56,6 +56,7 @@ static const int smart_attributes[][12] = {
};
static int ide_handle_rw_error(IDEState *s, int error, int op);
+static void ide_dummy_transfer_stop(IDEState *s);
static void padstr(char *str, const char *src, int len)
{
@@ -1532,15 +1533,36 @@ void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
bus->cmd = val;
}
+/*
+ * Returns true if the running PIO transfer is a PIO out (i.e. data is
+ * transferred from the device to the guest), false if it's a PIO in
+ */
+static bool ide_is_pio_out(IDEState *s)
+{
+ if (s->end_transfer_func == ide_sector_write ||
+ s->end_transfer_func == ide_atapi_cmd) {
+ return false;
+ } else if (s->end_transfer_func == ide_sector_read ||
+ s->end_transfer_func == ide_transfer_stop ||
+ s->end_transfer_func == ide_atapi_cmd_reply_end ||
+ s->end_transfer_func == ide_dummy_transfer_stop) {
+ return true;
+ }
+
+ abort();
+}
+
void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
{
IDEBus *bus = opaque;
IDEState *s = idebus_active_if(bus);
uint8_t *p;
- /* PIO data access allowed only when DRQ bit is set */
- if (!(s->status & DRQ_STAT))
+ /* PIO data access allowed only when DRQ bit is set. The result of a write
+ * during PIO out is indeterminate, just ignore it. */
+ if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
return;
+ }
p = s->data_ptr;
*(uint16_t *)p = le16_to_cpu(val);
@@ -1557,9 +1579,11 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr)
uint8_t *p;
int ret;
- /* PIO data access allowed only when DRQ bit is set */
- if (!(s->status & DRQ_STAT))
+ /* PIO data access allowed only when DRQ bit is set. The result of a read
+ * during PIO in is indeterminate, return 0 and don't move forward. */
+ if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
return 0;
+ }
p = s->data_ptr;
ret = cpu_to_le16(*(uint16_t *)p);
@@ -1576,9 +1600,11 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
IDEState *s = idebus_active_if(bus);
uint8_t *p;
- /* PIO data access allowed only when DRQ bit is set */
- if (!(s->status & DRQ_STAT))
+ /* PIO data access allowed only when DRQ bit is set. The result of a write
+ * during PIO out is indeterminate, just ignore it. */
+ if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
return;
+ }
p = s->data_ptr;
*(uint32_t *)p = le32_to_cpu(val);
@@ -1595,9 +1621,11 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
uint8_t *p;
int ret;
- /* PIO data access allowed only when DRQ bit is set */
- if (!(s->status & DRQ_STAT))
+ /* PIO data access allowed only when DRQ bit is set. The result of a read
+ * during PIO in is indeterminate, return 0 and don't move forward. */
+ if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
return 0;
+ }
p = s->data_ptr;
ret = cpu_to_le32(*(uint32_t *)p);
commit e7ff8f0e0c03853c5018d683b28b338b9738588a
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Fri Jul 1 10:46:13 2011 -0300
block: drive_init(): Improve CHS setting error message
The current message doesn't clearly communicate the error cause.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/blockdev.c b/blockdev.c
index 470be71..a97a801 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -310,7 +310,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
media = MEDIA_DISK;
} else if (!strcmp(buf, "cdrom")) {
if (cyls || secs || heads) {
- error_report("'%s' invalid physical CHS format", buf);
+ error_report("CHS can't be set with media=%s", buf);
return NULL;
}
media = MEDIA_CDROM;
commit 2d3999fe13b5e4663fd8ffc3661b1ffd44130e55
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Fri Jul 1 10:46:12 2011 -0300
block: drive_init(): Simplify interface type setting
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
Reviewed-by: Markus Armbruster <armbru at redhat.com>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/blockdev.c b/blockdev.c
index 7d579d6..470be71 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -240,14 +240,6 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
int ret;
translation = BIOS_ATA_TRANSLATION_AUTO;
-
- if (default_to_scsi) {
- type = IF_SCSI;
- pstrcpy(devname, sizeof(devname), "scsi");
- } else {
- type = IF_IDE;
- pstrcpy(devname, sizeof(devname), "ide");
- }
media = MEDIA_DISK;
/* extract parameters */
@@ -273,7 +265,11 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
error_report("unsupported bus type '%s'", buf);
return NULL;
}
+ } else {
+ type = default_to_scsi ? IF_SCSI : IF_IDE;
+ pstrcpy(devname, sizeof(devname), if_name[type]);
}
+
max_devs = if_max_devs[type];
if (cyls || heads || secs) {
commit a8686a9b2b347d0619141e950221c4d6d0311d0b
Author: Markus Armbruster <armbru at redhat.com>
Date: Mon Jun 20 11:35:18 2011 +0200
virtio-blk: Turn drive serial into a qdev property
It needs to be a qdev property, because it belongs to the drive's
guest part. Precedence: commit a0fef654 and 6ced55a5.
Bonus: info qtree now shows the serial number.
Signed-off-by: Markus Armbruster <armbru at redhat.com>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index d4a12f7..2bf4821 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -128,7 +128,8 @@ static int s390_virtio_blk_init(VirtIOS390Device *dev)
{
VirtIODevice *vdev;
- vdev = virtio_blk_init((DeviceState *)dev, &dev->block);
+ vdev = virtio_blk_init((DeviceState *)dev, &dev->block,
+ &dev->block_serial);
if (!vdev) {
return -1;
}
@@ -355,6 +356,7 @@ static VirtIOS390DeviceInfo s390_virtio_blk = {
.qdev.size = sizeof(VirtIOS390Device),
.qdev.props = (Property[]) {
DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
+ DEFINE_PROP_STRING("serial", VirtIOS390Device, block_serial),
DEFINE_PROP_END_OF_LIST(),
},
};
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index 0c412d0..f1bece7 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -42,6 +42,7 @@ typedef struct VirtIOS390Device {
uint8_t feat_len;
VirtIODevice *vdev;
BlockConf block;
+ char *block_serial;
NICConf nic;
uint32_t host_features;
virtio_serial_conf serial;
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 91e0394..6471ac8 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -28,8 +28,8 @@ typedef struct VirtIOBlock
void *rq;
QEMUBH *bh;
BlockConf *conf;
+ char *serial;
unsigned short sector_mask;
- char sn[BLOCK_SERIAL_STRLEN];
DeviceState *qdev;
} VirtIOBlock;
@@ -362,8 +362,13 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
} else if (type & VIRTIO_BLK_T_GET_ID) {
VirtIOBlock *s = req->dev;
- memcpy(req->elem.in_sg[0].iov_base, s->sn,
- MIN(req->elem.in_sg[0].iov_len, sizeof(s->sn)));
+ /*
+ * NB: per existing s/n string convention the string is
+ * terminated by '\0' only when shorter than buffer.
+ */
+ strncpy(req->elem.in_sg[0].iov_base,
+ s->serial ? s->serial : "",
+ MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
} else if (type & VIRTIO_BLK_T_OUT) {
qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
@@ -531,7 +536,8 @@ static void virtio_blk_change_cb(void *opaque, int reason)
}
}
-VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
+VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
+ char **serial)
{
VirtIOBlock *s;
int cylinders, heads, secs;
@@ -547,6 +553,14 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
return NULL;
}
+ if (!*serial) {
+ /* try to fall back to value set with legacy -drive serial=... */
+ dinfo = drive_get_by_blockdev(conf->bs);
+ if (*dinfo->serial) {
+ *serial = strdup(dinfo->serial);
+ }
+ }
+
s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
sizeof(struct virtio_blk_config),
sizeof(VirtIOBlock));
@@ -556,16 +570,11 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
s->vdev.reset = virtio_blk_reset;
s->bs = conf->bs;
s->conf = conf;
+ s->serial = *serial;
s->rq = NULL;
s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
- /* NB: per existing s/n string convention the string is terminated
- * by '\0' only when less than sizeof (s->sn)
- */
- dinfo = drive_get_by_blockdev(s->bs);
- strncpy(s->sn, dinfo->serial, sizeof (s->sn));
-
s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index fff46da..5645d2b 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -34,6 +34,8 @@
#define VIRTIO_BLK_F_WCACHE 9 /* write cache enabled */
#define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */
+#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */
+
struct virtio_blk_config
{
uint64_t capacity;
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index b3e7ba5..d685243 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -700,7 +700,8 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
proxy->class_code != PCI_CLASS_STORAGE_OTHER)
proxy->class_code = PCI_CLASS_STORAGE_SCSI;
- vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
+ vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block,
+ &proxy->block_serial);
if (!vdev) {
return -1;
}
@@ -805,6 +806,7 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.props = (Property[]) {
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
+ DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index b518917..1f0de56 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -26,6 +26,7 @@ typedef struct {
uint32_t class_code;
uint32_t nvectors;
BlockConf block;
+ char *block_serial;
NICConf nic;
uint32_t host_features;
#ifdef CONFIG_LINUX
diff --git a/hw/virtio.h b/hw/virtio.h
index 69e6bb1..0fd0bb0 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -197,7 +197,8 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
void *opaque);
/* Base devices. */
-VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
+VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
+ char **serial);
struct virtio_net_conf;
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
struct virtio_net_conf *net);
commit 343f85685ce3f9613c13e4d0f884698194b6a4f6
Author: Johannes Stezenbach <js at sig21.net>
Date: Wed Jun 29 16:25:17 2011 +0200
block/raw-posix: Linux compat-ioctl warning workaround
On Linux x86_64 host with 32bit userspace, running
qemu or even just "qemu-img create -f qcow2 some.img 1G"
causes a kernel warning:
ioctl32(qemu-img:5296): Unknown cmd fd(3) cmd(00005326){t:'S';sz:0} arg(7fffffff) on some.img
ioctl32(qemu-img:5296): Unknown cmd fd(3) cmd(801c0204){t:02;sz:28} arg(fff77350) on some.img
ioctl 00005326 is CDROM_DRIVE_STATUS,
ioctl 801c0204 is FDGETPRM.
The warning appears because the Linux compat-ioctl handler for these
ioctls only applies to block devices, while qemu also uses the ioctls on
plain files. Work around by calling fstat() the ensure the ioctls are
only used on block devices.
Signed-off-by: Johannes Stezenbach <js at sig21.net>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 4cd7d7a..34b64aa 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -46,6 +46,8 @@
#include <sys/dkio.h>
#endif
#ifdef __linux__
+#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <linux/cdrom.h>
@@ -1188,6 +1190,7 @@ static int floppy_probe_device(const char *filename)
int fd, ret;
int prio = 0;
struct floppy_struct fdparam;
+ struct stat st;
if (strstart(filename, "/dev/fd", NULL))
prio = 50;
@@ -1196,12 +1199,17 @@ static int floppy_probe_device(const char *filename)
if (fd < 0) {
goto out;
}
+ ret = fstat(fd, &st);
+ if (ret == -1 || !S_ISBLK(st.st_mode)) {
+ goto outc;
+ }
/* Attempt to detect via a floppy specific ioctl */
ret = ioctl(fd, FDGETPRM, &fdparam);
if (ret >= 0)
prio = 100;
+outc:
close(fd);
out:
return prio;
@@ -1290,17 +1298,23 @@ static int cdrom_probe_device(const char *filename)
{
int fd, ret;
int prio = 0;
+ struct stat st;
fd = open(filename, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
goto out;
}
+ ret = fstat(fd, &st);
+ if (ret == -1 || !S_ISBLK(st.st_mode)) {
+ goto outc;
+ }
/* Attempt to detect via a CDROM specific ioctl */
ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
if (ret >= 0)
prio = 100;
+outc:
close(fd);
out:
return prio;
commit 661a0f712b7c5b78408d85ba8b7f47ce44f395c0
Author: Federico Simoncelli <fsimonce at redhat.com>
Date: Mon Jun 20 12:48:19 2011 -0400
qemu-img: Add cache command line option
qemu-img currently writes disk images using writeback and filling
up the cache buffers which are then flushed by the kernel preventing
other processes from accessing the storage.
This is particularly bad in cluster environments where time-based
algorithms might be in place and accessing the storage within
certain timeouts is critical.
This patch adds the option to choose a cache method when writing
disk images.
Signed-off-by: Federico Simoncelli <fsimonce at redhat.com>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 3072d38..2b70618 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -22,13 +22,13 @@ STEXI
ETEXI
DEF("commit", img_commit,
- "commit [-f fmt] filename")
+ "commit [-f fmt] [-t cache] filename")
STEXI
@item commit [-f @var{fmt}] @var{filename}
ETEXI
DEF("convert", img_convert,
- "convert [-c] [-p] [-f fmt] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
+ "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
STEXI
@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
ETEXI
@@ -46,7 +46,7 @@ STEXI
ETEXI
DEF("rebase", img_rebase,
- "rebase [-f fmt] [-p] [-u] -b backing_file [-F backing_fmt] filename")
+ "rebase [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
STEXI
@item rebase [-f @var{fmt}] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
ETEXI
diff --git a/qemu-img.c b/qemu-img.c
index 32628b3..54137a4 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -40,6 +40,7 @@ typedef struct img_cmd_t {
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
#define BDRV_O_FLAGS BDRV_O_CACHE_WB
+#define BDRV_DEFAULT_CACHE "writeback"
static void format_print(void *opaque, const char *name)
{
@@ -64,6 +65,8 @@ static void help(void)
"Command parameters:\n"
" 'filename' is a disk image filename\n"
" 'fmt' is the disk image format. It is guessed automatically in most cases\n"
+ " 'cache' is the cache mode used to write the output disk image, the valid\n"
+ " options are: 'none', 'writeback' (default), 'writethrough' and 'unsafe'\n"
" 'size' is the disk image size in bytes. Optional suffixes\n"
" 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
" and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
@@ -180,6 +183,27 @@ static int read_password(char *buf, int buf_size)
}
#endif
+static int set_cache_flag(const char *mode, int *flags)
+{
+ *flags &= ~BDRV_O_CACHE_MASK;
+
+ if (!strcmp(mode, "none") || !strcmp(mode, "off")) {
+ *flags |= BDRV_O_CACHE_WB;
+ *flags |= BDRV_O_NOCACHE;
+ } else if (!strcmp(mode, "writeback")) {
+ *flags |= BDRV_O_CACHE_WB;
+ } else if (!strcmp(mode, "unsafe")) {
+ *flags |= BDRV_O_CACHE_WB;
+ *flags |= BDRV_O_NO_FLUSH;
+ } else if (!strcmp(mode, "writethrough")) {
+ /* this is the default */
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
static int print_block_option_help(const char *filename, const char *fmt)
{
BlockDriver *drv, *proto_drv;
@@ -441,13 +465,14 @@ static int img_check(int argc, char **argv)
static int img_commit(int argc, char **argv)
{
- int c, ret;
- const char *filename, *fmt;
+ int c, ret, flags;
+ const char *filename, *fmt, *cache;
BlockDriverState *bs;
fmt = NULL;
+ cache = BDRV_DEFAULT_CACHE;
for(;;) {
- c = getopt(argc, argv, "f:h");
+ c = getopt(argc, argv, "f:ht:");
if (c == -1) {
break;
}
@@ -459,6 +484,9 @@ static int img_commit(int argc, char **argv)
case 'f':
fmt = optarg;
break;
+ case 't':
+ cache = optarg;
+ break;
}
}
if (optind >= argc) {
@@ -466,7 +494,14 @@ static int img_commit(int argc, char **argv)
}
filename = argv[optind++];
- bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
+ flags = BDRV_O_RDWR;
+ ret = set_cache_flag(cache, &flags);
+ if (ret < 0) {
+ error_report("Invalid cache option: %s", cache);
+ return -1;
+ }
+
+ bs = bdrv_new_open(filename, fmt, flags);
if (!bs) {
return 1;
}
@@ -591,8 +626,8 @@ static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
static int img_convert(int argc, char **argv)
{
int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
- int progress = 0;
- const char *fmt, *out_fmt, *out_baseimg, *out_filename;
+ int progress = 0, flags;
+ const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
BlockDriver *drv, *proto_drv;
BlockDriverState **bs = NULL, *out_bs = NULL;
int64_t total_sectors, nb_sectors, sector_num, bs_offset;
@@ -608,10 +643,11 @@ static int img_convert(int argc, char **argv)
fmt = NULL;
out_fmt = "raw";
+ cache = "unsafe";
out_baseimg = NULL;
compress = 0;
for(;;) {
- c = getopt(argc, argv, "f:O:B:s:hce6o:p");
+ c = getopt(argc, argv, "f:O:B:s:hce6o:pt:");
if (c == -1) {
break;
}
@@ -649,6 +685,9 @@ static int img_convert(int argc, char **argv)
case 'p':
progress = 1;
break;
+ case 't':
+ cache = optarg;
+ break;
}
}
@@ -779,8 +818,14 @@ static int img_convert(int argc, char **argv)
goto out;
}
- out_bs = bdrv_new_open(out_filename, out_fmt,
- BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
+ flags = BDRV_O_RDWR;
+ ret = set_cache_flag(cache, &flags);
+ if (ret < 0) {
+ error_report("Invalid cache option: %s", cache);
+ return -1;
+ }
+
+ out_bs = bdrv_new_open(out_filename, out_fmt, flags);
if (!out_bs) {
ret = -1;
goto out;
@@ -1225,18 +1270,18 @@ static int img_rebase(int argc, char **argv)
BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
BlockDriver *old_backing_drv, *new_backing_drv;
char *filename;
- const char *fmt, *out_basefmt, *out_baseimg;
+ const char *fmt, *cache, *out_basefmt, *out_baseimg;
int c, flags, ret;
int unsafe = 0;
int progress = 0;
/* Parse commandline parameters */
fmt = NULL;
+ cache = BDRV_DEFAULT_CACHE;
out_baseimg = NULL;
out_basefmt = NULL;
-
for(;;) {
- c = getopt(argc, argv, "uhf:F:b:p");
+ c = getopt(argc, argv, "uhf:F:b:pt:");
if (c == -1) {
break;
}
@@ -1260,6 +1305,9 @@ static int img_rebase(int argc, char **argv)
case 'p':
progress = 1;
break;
+ case 't':
+ cache = optarg;
+ break;
}
}
@@ -1271,13 +1319,19 @@ static int img_rebase(int argc, char **argv)
qemu_progress_init(progress, 2.0);
qemu_progress_print(0, 100);
+ flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
+ ret = set_cache_flag(cache, &flags);
+ if (ret < 0) {
+ error_report("Invalid cache option: %s", cache);
+ return -1;
+ }
+
/*
* Open the images.
*
* Ignore the old backing file for unsafe rebase in case we want to correct
* the reference to a renamed or moved backing file.
*/
- flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
bs = bdrv_new_open(filename, fmt, flags);
if (!bs) {
return 1;
commit 02854532c215872b2af5ed48af93b7a309de1b1b
Author: Kevin Wolf <kwolf at redhat.com>
Date: Tue Jun 28 13:41:07 2011 +0200
Documentation: Remove outdated host_device note
People shouldn't explicitly specify host_device any more. raw is doing the
Right Thing.
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/qemu-img.texi b/qemu-img.texi
index ced64a4..526474c 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -173,12 +173,6 @@ Linux or NTFS on Windows), then only the written sectors will reserve
space. Use @code{qemu-img info} to know the real size used by the
image or @code{ls -ls} on Unix/Linux.
- at item host_device
-
-Host device format. This format should be used instead of raw when
-converting to block devices or other devices where "holes" are not
-supported.
-
@item qcow2
QEMU image format, the most versatile format. Use it to have smaller
images (useful if your filesystem does not supports holes, for example
commit 9312805d33e8b106bae356d13a8071fb37d75554
Author: Vasily Khoruzhick <anarsoul at gmail.com>
Date: Fri Jun 17 13:04:36 2011 +0300
pxa2xx_lcd: add proper rotation support
Until now, pxa2xx_lcd only supported 90deg rotation, but
some machines (for example Zipit Z2) needs 270deg rotation.
Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
Signed-off-by: Andrzej Zaborowski <andrew.zaborowski at intel.com>
diff --git a/hw/framebuffer.c b/hw/framebuffer.c
index 24cdf25..56cf16e 100644
--- a/hw/framebuffer.c
+++ b/hw/framebuffer.c
@@ -78,6 +78,9 @@ void framebuffer_update_display(
dest = ds_get_data(ds);
if (dest_col_pitch < 0)
dest -= dest_col_pitch * (cols - 1);
+ if (dest_row_pitch < 0) {
+ dest -= dest_row_pitch * (rows - 1);
+ }
first = -1;
addr = pd;
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index e524802..a5f8c51 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -665,7 +665,7 @@ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
}
}
-static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s,
+static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
target_phys_addr_t addr, int *miny, int *maxy)
{
int src_width, dest_width;
@@ -692,7 +692,7 @@ static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s,
fn, s->dma_ch[0].palette, miny, maxy);
}
-static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s,
+static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
target_phys_addr_t addr, int *miny, int *maxy)
{
int src_width, dest_width;
@@ -720,6 +720,67 @@ static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s,
miny, maxy);
}
+static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
+ target_phys_addr_t addr, int *miny, int *maxy)
+{
+ int src_width, dest_width;
+ drawfn fn = NULL;
+ if (s->dest_width) {
+ fn = s->line_fn[s->transp][s->bpp];
+ }
+ if (!fn) {
+ return;
+ }
+
+ src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
+ if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) {
+ src_width *= 3;
+ } else if (s->bpp > pxa_lcdc_16bpp) {
+ src_width *= 4;
+ } else if (s->bpp > pxa_lcdc_8bpp) {
+ src_width *= 2;
+ }
+
+ dest_width = s->xres * s->dest_width;
+ *miny = 0;
+ framebuffer_update_display(s->ds,
+ addr, s->xres, s->yres,
+ src_width, -dest_width, -s->dest_width,
+ s->invalidated,
+ fn, s->dma_ch[0].palette, miny, maxy);
+}
+
+static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
+ target_phys_addr_t addr, int *miny, int *maxy)
+{
+ int src_width, dest_width;
+ drawfn fn = NULL;
+ if (s->dest_width) {
+ fn = s->line_fn[s->transp][s->bpp];
+ }
+ if (!fn) {
+ return;
+ }
+
+ src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
+ if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) {
+ src_width *= 3;
+ } else if (s->bpp > pxa_lcdc_16bpp) {
+ src_width *= 4;
+ } else if (s->bpp > pxa_lcdc_8bpp) {
+ src_width *= 2;
+ }
+
+ dest_width = s->yres * s->dest_width;
+ *miny = 0;
+ framebuffer_update_display(s->ds,
+ addr, s->xres, s->yres,
+ src_width, -s->dest_width, dest_width,
+ s->invalidated,
+ fn, s->dma_ch[0].palette,
+ miny, maxy);
+}
+
static void pxa2xx_lcdc_resize(PXA2xxLCDState *s)
{
int width, height;
@@ -730,10 +791,11 @@ static void pxa2xx_lcdc_resize(PXA2xxLCDState *s)
height = LCCR2_LPP(s->control[2]) + 1;
if (width != s->xres || height != s->yres) {
- if (s->orientation)
+ if (s->orientation == 90 || s->orientation == 270) {
qemu_console_resize(s->ds, height, width);
- else
+ } else {
qemu_console_resize(s->ds, width, height);
+ }
s->invalidated = 1;
s->xres = width;
s->yres = height;
@@ -797,10 +859,24 @@ static void pxa2xx_update_display(void *opaque)
}
if (miny >= 0) {
- if (s->orientation)
- dpy_update(s->ds, miny, 0, maxy - miny, s->xres);
- else
- dpy_update(s->ds, 0, miny, s->xres, maxy - miny);
+ switch (s->orientation) {
+ case 0:
+ dpy_update(s->ds, 0, miny, s->xres, maxy - miny + 1);
+ break;
+ case 90:
+ dpy_update(s->ds, miny, 0, maxy - miny + 1, s->xres);
+ break;
+ case 180:
+ maxy = s->yres - maxy - 1;
+ miny = s->yres - miny - 1;
+ dpy_update(s->ds, 0, maxy, s->xres, miny - maxy + 1);
+ break;
+ case 270:
+ maxy = s->yres - maxy - 1;
+ miny = s->yres - miny - 1;
+ dpy_update(s->ds, maxy, 0, miny - maxy + 1, s->xres);
+ break;
+ }
}
pxa2xx_lcdc_int_update(s);
@@ -822,10 +898,19 @@ static void pxa2xx_lcdc_orientation(void *opaque, int angle)
{
PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
- if (angle) {
- s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_vert;
- } else {
- s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_horiz;
+ switch (angle) {
+ case 0:
+ s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot0;
+ break;
+ case 90:
+ s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot90;
+ break;
+ case 180:
+ s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot180;
+ break;
+ case 270:
+ s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot270;
+ break;
}
s->orientation = angle;
diff --git a/input.c b/input.c
index 5664d3a..f0a02e7 100644
--- a/input.c
+++ b/input.c
@@ -148,7 +148,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
QEMUPutMouseEntry *entry;
QEMUPutMouseEvent *mouse_event;
void *mouse_event_opaque;
- int width;
+ int width, height;
if (QTAILQ_EMPTY(&mouse_handlers)) {
return;
@@ -160,15 +160,31 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
mouse_event_opaque = entry->qemu_put_mouse_event_opaque;
if (mouse_event) {
- if (graphic_rotate) {
- if (entry->qemu_put_mouse_event_absolute) {
- width = 0x7fff;
- } else {
- width = graphic_width - 1;
- }
- mouse_event(mouse_event_opaque, width - dy, dx, dz, buttons_state);
+ if (entry->qemu_put_mouse_event_absolute) {
+ width = 0x7fff;
+ height = 0x7fff;
} else {
- mouse_event(mouse_event_opaque, dx, dy, dz, buttons_state);
+ width = graphic_width - 1;
+ height = graphic_height - 1;
+ }
+
+ switch (graphic_rotate) {
+ case 0:
+ mouse_event(mouse_event_opaque,
+ dx, dy, dz, buttons_state);
+ break;
+ case 90:
+ mouse_event(mouse_event_opaque,
+ width - dy, dx, dz, buttons_state);
+ break;
+ case 180:
+ mouse_event(mouse_event_opaque,
+ width - dx, height - dy, dz, buttons_state);
+ break;
+ case 270:
+ mouse_event(mouse_event_opaque,
+ dy, height - dx, dz, buttons_state);
+ break;
}
}
}
diff --git a/qemu-options.hx b/qemu-options.hx
index 37e54ee..e6d7adc 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -787,6 +787,15 @@ STEXI
Rotate graphical output 90 deg left (only PXA LCD).
ETEXI
+DEF("rotate", HAS_ARG, QEMU_OPTION_rotate,
+ "-rotate <deg> rotate graphical output some deg left (only PXA LCD)\n",
+ QEMU_ARCH_ALL)
+STEXI
+ at item -rotate
+ at findex -rotate
+Rotate graphical output some deg left (only PXA LCD).
+ETEXI
+
DEF("vga", HAS_ARG, QEMU_OPTION_vga,
"-vga [std|cirrus|vmware|qxl|xenfb|none]\n"
" select video card type\n", QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index 52402a2..fcd7395 100644
--- a/vl.c
+++ b/vl.c
@@ -2300,7 +2300,16 @@ int main(int argc, char **argv, char **envp)
#endif
break;
case QEMU_OPTION_portrait:
- graphic_rotate = 1;
+ graphic_rotate = 90;
+ break;
+ case QEMU_OPTION_rotate:
+ graphic_rotate = strtol(optarg, (char **) &optarg, 10);
+ if (graphic_rotate != 0 && graphic_rotate != 90 &&
+ graphic_rotate != 180 && graphic_rotate != 270) {
+ fprintf(stderr,
+ "qemu: only 90, 180, 270 deg rotation is available\n");
+ exit(1);
+ }
break;
case QEMU_OPTION_kernel:
kernel_filename = optarg;
commit 462a8bc6468912b79629f20f18798558342ce315
Author: Stefan Weil <weil at mail.berlios.de>
Date: Thu Jun 23 17:53:48 2011 +0200
arm: Add const attribute to some arm_boot_info pointers
Parameter 'info' is const, so add the missing attribute.
v2:
Add 'const' to the local variable info in do_cpu_reset() and to
the boot_info field in CPUARMState (suggested by Peter Maydell).
Cc: Andrzej Zaborowski <balrogg at gmail.com>
Cc: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Andrzej Zaborowski <andrew.zaborowski at intel.com>
diff --git a/hw/arm-misc.h b/hw/arm-misc.h
index 010acb4..9aeeaea 100644
--- a/hw/arm-misc.h
+++ b/hw/arm-misc.h
@@ -31,7 +31,7 @@ struct arm_boot_info {
target_phys_addr_t smp_priv_base;
int nb_cpus;
int board_id;
- int (*atag_board)(struct arm_boot_info *info, void *p);
+ int (*atag_board)(const struct arm_boot_info *info, void *p);
/* Used internally by arm_boot.c */
int is_linux;
target_phys_addr_t initrd_size;
diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index bfac982..e021576 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -49,7 +49,7 @@ static uint32_t smpboot[] = {
p += 4; \
} while (0)
-static void set_kernel_args(struct arm_boot_info *info,
+static void set_kernel_args(const struct arm_boot_info *info,
int initrd_size, target_phys_addr_t base)
{
target_phys_addr_t p;
@@ -102,7 +102,7 @@ static void set_kernel_args(struct arm_boot_info *info,
WRITE_WORD(p, 0);
}
-static void set_kernel_args_old(struct arm_boot_info *info,
+static void set_kernel_args_old(const struct arm_boot_info *info,
int initrd_size, target_phys_addr_t base)
{
target_phys_addr_t p;
@@ -178,7 +178,7 @@ static void set_kernel_args_old(struct arm_boot_info *info,
static void do_cpu_reset(void *opaque)
{
CPUState *env = opaque;
- struct arm_boot_info *info = env->boot_info;
+ const struct arm_boot_info *info = env->boot_info;
cpu_reset(env);
if (info) {
diff --git a/hw/nseries.c b/hw/nseries.c
index 2f6f473..2f84f53 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -1254,12 +1254,12 @@ static int n8x0_atag_setup(void *p, int model)
return (void *) w - p;
}
-static int n800_atag_setup(struct arm_boot_info *info, void *p)
+static int n800_atag_setup(const struct arm_boot_info *info, void *p)
{
return n8x0_atag_setup(p, 800);
}
-static int n810_atag_setup(struct arm_boot_info *info, void *p)
+static int n810_atag_setup(const struct arm_boot_info *info, void *p)
{
return n8x0_atag_setup(p, 810);
}
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 116131e..1022a03 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -221,7 +221,7 @@ typedef struct CPUARMState {
void *opaque;
} cp[15];
void *nvic;
- struct arm_boot_info *boot_info;
+ const struct arm_boot_info *boot_info;
} CPUARMState;
CPUARMState *cpu_arm_init(const char *cpu_model);
commit a3d14054d727efb8ff4c5060a4c3171bae2046ef
Author: Alon Levy <alevy at redhat.com>
Date: Wed Jun 29 13:57:11 2011 +0200
qxl: allow QXL_IO_LOG also in vga
The driver may change us to vga mode and still issue a QXL_IO_LOG,
which we can easily support.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/qxl.c b/hw/qxl.c
index 848c90f..0b9a4c7 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -943,6 +943,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
case QXL_IO_MEMSLOT_DEL:
case QXL_IO_CREATE_PRIMARY:
case QXL_IO_UPDATE_IRQ:
+ case QXL_IO_LOG:
break;
default:
if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
commit 81144d1a3675faf3c314ff2c7a369f809361d3ed
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Fri Jun 24 12:23:44 2011 +0200
qxl: put QXL_IO_UPDATE_IRQ into vgamode whitelist
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/qxl.c b/hw/qxl.c
index 5e49536..848c90f 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -942,6 +942,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
case QXL_IO_MEMSLOT_ADD:
case QXL_IO_MEMSLOT_DEL:
case QXL_IO_CREATE_PRIMARY:
+ case QXL_IO_UPDATE_IRQ:
break;
default:
if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
commit 868379ce6994a72c617fbc29bcc95e8166833400
Author: Yonit Halperin <yhalperi at redhat.com>
Date: Mon Jul 4 15:08:01 2011 +0300
qxl: make sure primary surface is saved on migration
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/qxl.c b/hw/qxl.c
index d55b68d..5e49536 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1184,11 +1184,14 @@ static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
qemu_spice_vm_change_state_handler(&qxl->ssd, running, reason);
if (!running && qxl->mode == QXL_MODE_NATIVE) {
- /* dirty all vram (which holds surfaces) to make sure it is saved */
+ /* dirty all vram (which holds surfaces) and devram (primary surface)
+ * to make sure they are saved */
/* FIXME #1: should go out during "live" stage */
/* FIXME #2: we only need to save the areas which are actually used */
- ram_addr_t addr = qxl->vram_offset;
- qxl_set_dirty(addr, addr + qxl->vram_size);
+ ram_addr_t vram_addr = qxl->vram_offset;
+ ram_addr_t surface0_addr = qxl->vga.vram_offset + qxl->shadow_rom.draw_area_offset;
+ qxl_set_dirty(vram_addr, vram_addr + qxl->vram_size);
+ qxl_set_dirty(surface0_addr, surface0_addr + qxl->shadow_rom.surface0_area_size);
}
}
commit 6ebebb551ad1a5c4e24d3fccd246c5111450c1b3
Author: Alon Levy <alevy at redhat.com>
Date: Wed Jun 29 13:57:15 2011 +0200
qxl: add dev id to guest prints
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/qxl.c b/hw/qxl.c
index 3722f55..d55b68d 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -985,7 +985,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
break;
case QXL_IO_LOG:
if (d->guestdebug) {
- fprintf(stderr, "qxl/guest: %s", d->ram->log_buf);
+ fprintf(stderr, "qxl/guest-%d: %ld: %s", d->id,
+ qemu_get_clock_ns(vm_clock), d->ram->log_buf);
}
break;
case QXL_IO_RESET:
commit 1f0ff2fb99eb5043ea38474c961e0fb9f6ff8a63
Author: Alon Levy <alevy at redhat.com>
Date: Wed Jun 29 13:57:13 2011 +0200
qxl-logger: add timestamp to command log
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/qxl-logger.c b/hw/qxl-logger.c
index 76f43e6..74cadba 100644
--- a/hw/qxl-logger.c
+++ b/hw/qxl-logger.c
@@ -19,6 +19,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu-timer.h"
#include "qxl.h"
static const char *qxl_type[] = {
@@ -223,7 +224,8 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
if (!qxl->cmdlog) {
return;
}
- fprintf(stderr, "qxl-%d/%s:", qxl->id, ring);
+ fprintf(stderr, "%ld qxl-%d/%s:", qemu_get_clock_ns(vm_clock),
+ qxl->id, ring);
fprintf(stderr, " cmd @ 0x%" PRIx64 " %s%s", ext->cmd.data,
qxl_name(qxl_type, ext->cmd.type),
compat ? "(compat)" : "");
commit 5b77870ce0edde6cf6dd242fa892e28f5c87b4fd
Author: Alon Levy <alevy at redhat.com>
Date: Fri Jun 24 15:02:47 2011 +0200
qxl: interface_get_command: fix reported mode
report correct mode when in undefined mode.
introduces qxl_mode_to_string(), and uses it in other places too.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/qxl.c b/hw/qxl.c
index e95d6f7..3722f55 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -336,6 +336,21 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
info->n_surfaces = NUM_SURFACES;
}
+static const char *qxl_mode_to_string(int mode)
+{
+ switch (mode) {
+ case QXL_MODE_COMPAT:
+ return "compat";
+ case QXL_MODE_NATIVE:
+ return "native";
+ case QXL_MODE_UNDEFINED:
+ return "undefined";
+ case QXL_MODE_VGA:
+ return "vga";
+ }
+ return "INVALID";
+}
+
/* called from spice server thread context only */
static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
{
@@ -358,18 +373,19 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
}
qemu_mutex_unlock(&qxl->ssd.lock);
if (ret) {
+ dprint(qxl, 2, "%s %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
qxl_log_command(qxl, "vga", ext);
}
return ret;
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
case QXL_MODE_UNDEFINED:
- dprint(qxl, 2, "%s: %s\n", __FUNCTION__,
- qxl->cmdflags ? "compat" : "native");
+ dprint(qxl, 4, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
ring = &qxl->ram->cmd_ring;
if (SPICE_RING_IS_EMPTY(ring)) {
return false;
}
+ dprint(qxl, 2, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
SPICE_RING_CONS_ITEM(ring, cmd);
ext->cmd = *cmd;
ext->group_id = MEMSLOT_GROUP_GUEST;
@@ -993,7 +1009,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
break;
case QXL_IO_DESTROY_PRIMARY:
PANIC_ON(val != 0);
- dprint(d, 1, "QXL_IO_DESTROY_PRIMARY\n");
+ dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
qxl_destroy_primary(d);
break;
case QXL_IO_DESTROY_SURFACE_WAIT:
@@ -1368,7 +1384,8 @@ static int qxl_post_load(void *opaque, int version)
d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset);
- dprint(d, 1, "%s: restore mode\n", __FUNCTION__);
+ dprint(d, 1, "%s: restore mode (%s)\n", __FUNCTION__,
+ qxl_mode_to_string(d->mode));
newmode = d->mode;
d->mode = QXL_MODE_UNDEFINED;
switch (newmode) {
commit 22795174a37e02200944c0d093d518e832650686
Author: Alon Levy <alevy at redhat.com>
Date: Wed Jun 15 20:44:38 2011 +0200
qxl: set mm_time in vga update
This fixes a problem where on windows 7 startup phase, before the qxl driver
is loaded, the drawables are sufficiently large and video like to trigger a
stream, but the lack of a filled mm time field triggers a warning in spice-gtk.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 15f0704..feeee73 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -70,6 +70,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
QXLCommand *cmd;
uint8_t *src, *dst;
int by, bw, bh;
+ struct timespec time_space;
if (qemu_spice_rect_is_empty(&ssd->dirty)) {
return NULL;
@@ -96,6 +97,10 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
drawable->surfaces_dest[0] = -1;
drawable->surfaces_dest[1] = -1;
drawable->surfaces_dest[2] = -1;
+ clock_gettime(CLOCK_MONOTONIC, &time_space);
+ /* time in milliseconds from epoch. */
+ drawable->mm_time = time_space.tv_sec * 1000
+ + time_space.tv_nsec / 1000 / 1000;
drawable->u.copy.rop_descriptor = SPICE_ROPD_OP_PUT;
drawable->u.copy.src_bitmap = (intptr_t)image;
commit fba810f1f67b411c209aa0e3d90724127cbd9c0f
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Jun 15 13:11:33 2011 +0200
spice: catch spice server initialization failures.
When the spice server initialization fails report this and exit instead
of ignoring the error.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/ui/spice-core.c b/ui/spice-core.c
index dd9905b..e142452 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -602,7 +602,10 @@ void qemu_spice_init(void)
qemu_opt_foreach(opts, add_channel, NULL, 0);
- spice_server_init(spice_server, &core_interface);
+ if (0 != spice_server_init(spice_server, &core_interface)) {
+ fprintf(stderr, "failed to initialize spice server");
+ exit(1);
+ };
using_spice = 1;
migration_state.notify = migration_state_notifier;
commit 638f4e47798725cef2a5ae5bf83d508fbde36605
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Jun 29 15:45:16 2011 +0200
qxl: device id fixup
Move device ID to PCIDeviceInfo.
Remove support for the unused unstable device ID.
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
diff --git a/hw/qxl.c b/hw/qxl.c
index 16316f2..e95d6f7 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1207,7 +1207,6 @@ static DisplayChangeListener display_listener = {
static int qxl_init_common(PCIQXLDevice *qxl)
{
uint8_t* config = qxl->pci.config;
- uint32_t pci_device_id;
uint32_t pci_device_rev;
uint32_t io_size;
@@ -1218,20 +1217,14 @@ static int qxl_init_common(PCIQXLDevice *qxl)
switch (qxl->revision) {
case 1: /* spice 0.4 -- qxl-1 */
- pci_device_id = QXL_DEVICE_ID_STABLE;
pci_device_rev = QXL_REVISION_STABLE_V04;
break;
case 2: /* spice 0.6 -- qxl-2 */
- pci_device_id = QXL_DEVICE_ID_STABLE;
+ default:
pci_device_rev = QXL_REVISION_STABLE_V06;
break;
- default: /* experimental */
- pci_device_id = QXL_DEVICE_ID_DEVEL;
- pci_device_rev = 1;
- break;
}
- pci_config_set_device_id(config, pci_device_id);
pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
@@ -1492,6 +1485,7 @@ static PCIDeviceInfo qxl_info_primary = {
.config_write = qxl_write_config,
.romfile = "vgabios-qxl.bin",
.vendor_id = REDHAT_PCI_VENDOR_ID,
+ .device_id = QXL_DEVICE_ID_STABLE,
.class_id = PCI_CLASS_DISPLAY_VGA,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
@@ -1512,6 +1506,7 @@ static PCIDeviceInfo qxl_info_secondary = {
.qdev.vmsd = &qxl_vmstate,
.init = qxl_init_secondary,
.vendor_id = REDHAT_PCI_VENDOR_ID,
+ .device_id = QXL_DEVICE_ID_STABLE,
.class_id = PCI_CLASS_DISPLAY_OTHER,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
More information about the Spice-commits
mailing list