mirror of https://github.com/xemu-project/xemu.git
Xen 2016/11/22
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJYNJFTAAoJEIlPj0hw4a6QeoQP/0EZQQCM2N0xUjiuaJ3tkl7I LSVQACtkSZ8ZHXilu30cmav9+HoyO1kE2lTeLAW9nkKAdiwhumVodBxBYYMbxL3m nVzccXnOzj1kJ3ObffZY/cIegiJEoDjJR/QqC6LmmyrV68KlYoaU9nD1GXoz/Moc ScOe6o/mOdbYfRP7CJITLzKQ3wu6eg6Azgks/jjoZ14Kjjl0kPPg2uiCew0m52Q6 2/9d24db5QABVrokG6/7DNTy7/knOBug4dHIQhkgQuTY6US+97Ovw2xK5V5oUlsJ QaA5EF5Fz55Ifc1H4dpFytRVI6ljGqfpv9xPyn0M4eycVZL5fpuMA3l1g3wExNoo bI3YV/akIYNNBTmNcKZiS7xcAZF6IGkcpjhoSoTK0xAX2NVxA0kTX9Zw6A6q+YGI jk/lvm1NnHqZjhqe1LqhVX7kTIdNqxH9Eom/Y8yfIDwb3QKKSRPFu1ySQ/yGmQsR Dxk/IxLN8b3BkxvhaTr7K9F+3DUwa8c+9JmVg4ejVoIh/B+20SQGjSjAmQhWNa8g eHJHx498dgReWkft30T/iB0PzcsbpUvz7057cTTB3qCbf9MoyQdaZvgxO+2xUUrm JuHhGd2beWH4O3O1Nx8GkhrAWW0027Gb2BBR4sDyGpC0zTivNw3cdar0UUITdI+E 3DKBdrec0c2Y5E7PLvgJ =DmJS -----END PGP SIGNATURE----- Merge remote-tracking branch 'sstabellini/tags/xen-20161122-tag' into staging Xen 2016/11/22 # gpg: Signature made Tue 22 Nov 2016 06:41:23 PM GMT # gpg: using RSA key 0x894F8F4870E1AE90 # gpg: Good signature from "Stefano Stabellini <sstabellini@kernel.org>" # gpg: aka "Stefano Stabellini <stefano.stabellini@eu.citrix.com>" # Primary key fingerprint: D04E 33AB A51F 67BA 07D3 0AEA 894F 8F48 70E1 AE90 * sstabellini/tags/xen-20161122-tag: xen: attach pvusb usb bus to backend qdev xen: create qdev for each backend device qdev: add function qdev_set_id() xen: add an own bus for xen backend devices xen: fix ioreq handling Message-id: alpine.DEB.2.10.1611221037010.21858@sstabellini-ThinkPad-X260 Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
01d7d15ce3
|
@ -712,15 +712,10 @@ static void usbback_portid_detach(struct usbback_info *usbif, unsigned port)
|
||||||
|
|
||||||
static void usbback_portid_remove(struct usbback_info *usbif, unsigned port)
|
static void usbback_portid_remove(struct usbback_info *usbif, unsigned port)
|
||||||
{
|
{
|
||||||
USBPort *p;
|
|
||||||
|
|
||||||
if (!usbif->ports[port - 1].dev) {
|
if (!usbif->ports[port - 1].dev) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = &(usbif->ports[port - 1].port);
|
|
||||||
snprintf(p->path, sizeof(p->path), "%d", 99);
|
|
||||||
|
|
||||||
object_unparent(OBJECT(usbif->ports[port - 1].dev));
|
object_unparent(OBJECT(usbif->ports[port - 1].dev));
|
||||||
usbif->ports[port - 1].dev = NULL;
|
usbif->ports[port - 1].dev = NULL;
|
||||||
usbback_portid_detach(usbif, port);
|
usbback_portid_detach(usbif, port);
|
||||||
|
@ -733,10 +728,10 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
|
||||||
{
|
{
|
||||||
unsigned speed;
|
unsigned speed;
|
||||||
char *portname;
|
char *portname;
|
||||||
USBPort *p;
|
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
QDict *qdict;
|
QDict *qdict;
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
if (usbif->ports[port - 1].dev) {
|
if (usbif->ports[port - 1].dev) {
|
||||||
return;
|
return;
|
||||||
|
@ -749,11 +744,16 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
portname++;
|
portname++;
|
||||||
p = &(usbif->ports[port - 1].port);
|
|
||||||
snprintf(p->path, sizeof(p->path), "%s", portname);
|
|
||||||
|
|
||||||
qdict = qdict_new();
|
qdict = qdict_new();
|
||||||
qdict_put(qdict, "driver", qstring_from_str("usb-host"));
|
qdict_put(qdict, "driver", qstring_from_str("usb-host"));
|
||||||
|
tmp = g_strdup_printf("%s.0", usbif->xendev.qdev.id);
|
||||||
|
qdict_put(qdict, "bus", qstring_from_str(tmp));
|
||||||
|
g_free(tmp);
|
||||||
|
tmp = g_strdup_printf("%s-%u", usbif->xendev.qdev.id, port);
|
||||||
|
qdict_put(qdict, "id", qstring_from_str(tmp));
|
||||||
|
g_free(tmp);
|
||||||
|
qdict_put(qdict, "port", qint_from_int(port));
|
||||||
qdict_put(qdict, "hostbus", qint_from_int(atoi(busid)));
|
qdict_put(qdict, "hostbus", qint_from_int(atoi(busid)));
|
||||||
qdict_put(qdict, "hostport", qstring_from_str(portname));
|
qdict_put(qdict, "hostport", qstring_from_str(portname));
|
||||||
opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
|
opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
|
||||||
|
@ -765,7 +765,6 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
QDECREF(qdict);
|
QDECREF(qdict);
|
||||||
snprintf(p->path, sizeof(p->path), "%d", port);
|
|
||||||
speed = usbif->ports[port - 1].dev->speed;
|
speed = usbif->ports[port - 1].dev->speed;
|
||||||
switch (speed) {
|
switch (speed) {
|
||||||
case USB_SPEED_LOW:
|
case USB_SPEED_LOW:
|
||||||
|
@ -799,7 +798,6 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
|
||||||
|
|
||||||
err:
|
err:
|
||||||
QDECREF(qdict);
|
QDECREF(qdict);
|
||||||
snprintf(p->path, sizeof(p->path), "%d", 99);
|
|
||||||
xen_pv_printf(&usbif->xendev, 0, "device %s could not be opened\n", busid);
|
xen_pv_printf(&usbif->xendev, 0, "device %s could not be opened\n", busid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1012,13 +1010,13 @@ static void usbback_alloc(struct XenDevice *xendev)
|
||||||
|
|
||||||
usbif = container_of(xendev, struct usbback_info, xendev);
|
usbif = container_of(xendev, struct usbback_info, xendev);
|
||||||
|
|
||||||
usb_bus_new(&usbif->bus, sizeof(usbif->bus), &xen_usb_bus_ops, xen_sysdev);
|
usb_bus_new(&usbif->bus, sizeof(usbif->bus), &xen_usb_bus_ops,
|
||||||
|
DEVICE(&xendev->qdev));
|
||||||
for (i = 0; i < USBBACK_MAXPORTS; i++) {
|
for (i = 0; i < USBBACK_MAXPORTS; i++) {
|
||||||
p = &(usbif->ports[i].port);
|
p = &(usbif->ports[i].port);
|
||||||
usb_register_port(&usbif->bus, p, usbif, i, &xen_usb_port_ops,
|
usb_register_port(&usbif->bus, p, usbif, i, &xen_usb_port_ops,
|
||||||
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL |
|
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL |
|
||||||
USB_SPEED_MASK_HIGH);
|
USB_SPEED_MASK_HIGH);
|
||||||
snprintf(p->path, sizeof(p->path), "%d", 99);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTAILQ_INIT(&usbif->req_free_q);
|
QTAILQ_INIT(&usbif->req_free_q);
|
||||||
|
@ -1066,7 +1064,6 @@ static int usbback_free(struct XenDevice *xendev)
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_bus_release(&usbif->bus);
|
usb_bus_release(&usbif->bus);
|
||||||
object_unparent(OBJECT(&usbif->bus));
|
|
||||||
|
|
||||||
TR_BUS(xendev, "finished\n");
|
TR_BUS(xendev, "finished\n");
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,18 @@
|
||||||
|
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
|
#include "hw/boards.h"
|
||||||
#include "sysemu/char.h"
|
#include "sysemu/char.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
#include "hw/xen/xen_backend.h"
|
#include "hw/xen/xen_backend.h"
|
||||||
#include "hw/xen/xen_pvdev.h"
|
#include "hw/xen/xen_pvdev.h"
|
||||||
|
#include "monitor/qdev.h"
|
||||||
|
|
||||||
#include <xen/grant_table.h>
|
#include <xen/grant_table.h>
|
||||||
|
|
||||||
#define TYPE_XENSYSDEV "xensysdev"
|
|
||||||
|
|
||||||
DeviceState *xen_sysdev;
|
DeviceState *xen_sysdev;
|
||||||
|
BusState *xen_sysbus;
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -121,6 +123,12 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
|
||||||
|
|
||||||
/* init new xendev */
|
/* init new xendev */
|
||||||
xendev = g_malloc0(ops->size);
|
xendev = g_malloc0(ops->size);
|
||||||
|
object_initialize(&xendev->qdev, ops->size, TYPE_XENBACKEND);
|
||||||
|
qdev_set_parent_bus(&xendev->qdev, xen_sysbus);
|
||||||
|
qdev_set_id(&xendev->qdev, g_strdup_printf("xen-%s-%d", type, dev));
|
||||||
|
qdev_init_nofail(&xendev->qdev);
|
||||||
|
object_unref(OBJECT(&xendev->qdev));
|
||||||
|
|
||||||
xendev->type = type;
|
xendev->type = type;
|
||||||
xendev->dom = dom;
|
xendev->dom = dom;
|
||||||
xendev->dev = dev;
|
xendev->dev = dev;
|
||||||
|
@ -528,6 +536,8 @@ int xen_be_init(void)
|
||||||
|
|
||||||
xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV);
|
xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV);
|
||||||
qdev_init_nofail(xen_sysdev);
|
qdev_init_nofail(xen_sysdev);
|
||||||
|
xen_sysbus = qbus_create(TYPE_XENSYSBUS, DEVICE(xen_sysdev), "xen-sysbus");
|
||||||
|
qbus_set_bus_hotplug_handler(xen_sysbus, &error_abort);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -539,6 +549,15 @@ err:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xen_set_dynamic_sysbus(void)
|
||||||
|
{
|
||||||
|
Object *machine = qdev_get_machine();
|
||||||
|
ObjectClass *oc = object_get_class(machine);
|
||||||
|
MachineClass *mc = MACHINE_CLASS(oc);
|
||||||
|
|
||||||
|
mc->has_dynamic_sysbus = true;
|
||||||
|
}
|
||||||
|
|
||||||
int xen_be_register(const char *type, struct XenDevOps *ops)
|
int xen_be_register(const char *type, struct XenDevOps *ops)
|
||||||
{
|
{
|
||||||
char path[50];
|
char path[50];
|
||||||
|
@ -560,6 +579,8 @@ int xen_be_register(const char *type, struct XenDevOps *ops)
|
||||||
|
|
||||||
void xen_be_register_common(void)
|
void xen_be_register_common(void)
|
||||||
{
|
{
|
||||||
|
xen_set_dynamic_sysbus();
|
||||||
|
|
||||||
xen_be_register("console", &xen_console_ops);
|
xen_be_register("console", &xen_console_ops);
|
||||||
xen_be_register("vkbd", &xen_kbdmouse_ops);
|
xen_be_register("vkbd", &xen_kbdmouse_ops);
|
||||||
xen_be_register("qdisk", &xen_blkdev_ops);
|
xen_be_register("qdisk", &xen_blkdev_ops);
|
||||||
|
@ -586,6 +607,42 @@ int xen_be_bind_evtchn(struct XenDevice *xendev)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Property xendev_properties[] = {
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void xendev_class_init(ObjectClass *klass, void *data)
|
||||||
|
{
|
||||||
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
|
||||||
|
dc->props = xendev_properties;
|
||||||
|
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo xendev_type_info = {
|
||||||
|
.name = TYPE_XENBACKEND,
|
||||||
|
.parent = TYPE_XENSYSDEV,
|
||||||
|
.class_init = xendev_class_init,
|
||||||
|
.instance_size = sizeof(struct XenDevice),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void xen_sysbus_class_init(ObjectClass *klass, void *data)
|
||||||
|
{
|
||||||
|
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
|
||||||
|
|
||||||
|
hc->unplug = qdev_simple_device_unplug_cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo xensysbus_info = {
|
||||||
|
.name = TYPE_XENSYSBUS,
|
||||||
|
.parent = TYPE_BUS,
|
||||||
|
.class_init = xen_sysbus_class_init,
|
||||||
|
.interfaces = (InterfaceInfo[]) {
|
||||||
|
{ TYPE_HOTPLUG_HANDLER },
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static int xen_sysdev_init(SysBusDevice *dev)
|
static int xen_sysdev_init(SysBusDevice *dev)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -602,6 +659,7 @@ static void xen_sysdev_class_init(ObjectClass *klass, void *data)
|
||||||
|
|
||||||
k->init = xen_sysdev_init;
|
k->init = xen_sysdev_init;
|
||||||
dc->props = xen_sysdev_properties;
|
dc->props = xen_sysdev_properties;
|
||||||
|
dc->bus_type = TYPE_XENSYSBUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo xensysdev_info = {
|
static const TypeInfo xensysdev_info = {
|
||||||
|
@ -613,7 +671,9 @@ static const TypeInfo xensysdev_info = {
|
||||||
|
|
||||||
static void xenbe_register_types(void)
|
static void xenbe_register_types(void)
|
||||||
{
|
{
|
||||||
|
type_register_static(&xensysbus_info);
|
||||||
type_register_static(&xensysdev_info);
|
type_register_static(&xensysdev_info);
|
||||||
|
type_register_static(&xendev_type_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
type_init(xenbe_register_types);
|
type_init(xenbe_register_types)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
#include "hw/qdev-core.h"
|
||||||
#include "hw/xen/xen_backend.h"
|
#include "hw/xen/xen_backend.h"
|
||||||
#include "hw/xen/xen_pvdev.h"
|
#include "hw/xen/xen_pvdev.h"
|
||||||
|
|
||||||
|
@ -307,7 +308,8 @@ void xen_pv_del_xendev(struct XenDevice *xendev)
|
||||||
}
|
}
|
||||||
|
|
||||||
QTAILQ_REMOVE(&xendevs, xendev, next);
|
QTAILQ_REMOVE(&xendevs, xendev, next);
|
||||||
g_free(xendev);
|
|
||||||
|
qdev_unplug(&xendev->qdev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xen_pv_insert_xendev(struct XenDevice *xendev)
|
void xen_pv_insert_xendev(struct XenDevice *xendev)
|
||||||
|
|
|
@ -6,12 +6,20 @@
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "net/net.h"
|
#include "net/net.h"
|
||||||
|
|
||||||
|
#define TYPE_XENSYSDEV "xen-sysdev"
|
||||||
|
#define TYPE_XENSYSBUS "xen-sysbus"
|
||||||
|
#define TYPE_XENBACKEND "xen-backend"
|
||||||
|
|
||||||
|
#define XENBACKEND_DEVICE(obj) \
|
||||||
|
OBJECT_CHECK(XenDevice, (obj), TYPE_XENBACKEND)
|
||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
extern xc_interface *xen_xc;
|
extern xc_interface *xen_xc;
|
||||||
extern xenforeignmemory_handle *xen_fmem;
|
extern xenforeignmemory_handle *xen_fmem;
|
||||||
extern struct xs_handle *xenstore;
|
extern struct xs_handle *xenstore;
|
||||||
extern const char *xen_protocol;
|
extern const char *xen_protocol;
|
||||||
extern DeviceState *xen_sysdev;
|
extern DeviceState *xen_sysdev;
|
||||||
|
extern BusState *xen_sysbus;
|
||||||
|
|
||||||
int xenstore_mkdir(char *path, int p);
|
int xenstore_mkdir(char *path, int p);
|
||||||
int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val);
|
int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val);
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct XenDevOps {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XenDevice {
|
struct XenDevice {
|
||||||
|
DeviceState qdev;
|
||||||
const char *type;
|
const char *type;
|
||||||
int dom;
|
int dom;
|
||||||
int dev;
|
int dev;
|
||||||
|
|
|
@ -12,5 +12,6 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp);
|
||||||
|
|
||||||
int qdev_device_help(QemuOpts *opts);
|
int qdev_device_help(QemuOpts *opts);
|
||||||
DeviceState *qdev_device_add(QemuOpts *opts, Error **errp);
|
DeviceState *qdev_device_add(QemuOpts *opts, Error **errp);
|
||||||
|
void qdev_set_id(DeviceState *dev, const char *id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -539,10 +539,28 @@ static BusState *qbus_find(const char *path, Error **errp)
|
||||||
return bus;
|
return bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qdev_set_id(DeviceState *dev, const char *id)
|
||||||
|
{
|
||||||
|
if (id) {
|
||||||
|
dev->id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->id) {
|
||||||
|
object_property_add_child(qdev_get_peripheral(), dev->id,
|
||||||
|
OBJECT(dev), NULL);
|
||||||
|
} else {
|
||||||
|
static int anon_count;
|
||||||
|
gchar *name = g_strdup_printf("device[%d]", anon_count++);
|
||||||
|
object_property_add_child(qdev_get_peripheral_anon(), name,
|
||||||
|
OBJECT(dev), NULL);
|
||||||
|
g_free(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
|
DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
|
||||||
{
|
{
|
||||||
DeviceClass *dc;
|
DeviceClass *dc;
|
||||||
const char *driver, *path, *id;
|
const char *driver, *path;
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
BusState *bus = NULL;
|
BusState *bus = NULL;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
@ -591,21 +609,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
|
||||||
qdev_set_parent_bus(dev, bus);
|
qdev_set_parent_bus(dev, bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
id = qemu_opts_id(opts);
|
qdev_set_id(dev, qemu_opts_id(opts));
|
||||||
if (id) {
|
|
||||||
dev->id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->id) {
|
|
||||||
object_property_add_child(qdev_get_peripheral(), dev->id,
|
|
||||||
OBJECT(dev), NULL);
|
|
||||||
} else {
|
|
||||||
static int anon_count;
|
|
||||||
gchar *name = g_strdup_printf("device[%d]", anon_count++);
|
|
||||||
object_property_add_child(qdev_get_peripheral_anon(), name,
|
|
||||||
OBJECT(dev), NULL);
|
|
||||||
g_free(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set properties */
|
/* set properties */
|
||||||
if (qemu_opt_foreach(opts, set_property, dev, &err)) {
|
if (qemu_opt_foreach(opts, set_property, dev, &err)) {
|
||||||
|
|
16
xen-hvm.c
16
xen-hvm.c
|
@ -810,6 +810,10 @@ static void cpu_ioreq_pio(ioreq_t *req)
|
||||||
trace_cpu_ioreq_pio(req, req->dir, req->df, req->data_is_ptr, req->addr,
|
trace_cpu_ioreq_pio(req, req->dir, req->df, req->data_is_ptr, req->addr,
|
||||||
req->data, req->count, req->size);
|
req->data, req->count, req->size);
|
||||||
|
|
||||||
|
if (req->size > sizeof(uint32_t)) {
|
||||||
|
hw_error("PIO: bad size (%u)", req->size);
|
||||||
|
}
|
||||||
|
|
||||||
if (req->dir == IOREQ_READ) {
|
if (req->dir == IOREQ_READ) {
|
||||||
if (!req->data_is_ptr) {
|
if (!req->data_is_ptr) {
|
||||||
req->data = do_inp(req->addr, req->size);
|
req->data = do_inp(req->addr, req->size);
|
||||||
|
@ -846,6 +850,10 @@ static void cpu_ioreq_move(ioreq_t *req)
|
||||||
trace_cpu_ioreq_move(req, req->dir, req->df, req->data_is_ptr, req->addr,
|
trace_cpu_ioreq_move(req, req->dir, req->df, req->data_is_ptr, req->addr,
|
||||||
req->data, req->count, req->size);
|
req->data, req->count, req->size);
|
||||||
|
|
||||||
|
if (req->size > sizeof(req->data)) {
|
||||||
|
hw_error("MMIO: bad size (%u)", req->size);
|
||||||
|
}
|
||||||
|
|
||||||
if (!req->data_is_ptr) {
|
if (!req->data_is_ptr) {
|
||||||
if (req->dir == IOREQ_READ) {
|
if (req->dir == IOREQ_READ) {
|
||||||
for (i = 0; i < req->count; i++) {
|
for (i = 0; i < req->count; i++) {
|
||||||
|
@ -1010,11 +1018,13 @@ static int handle_buffered_iopage(XenIOState *state)
|
||||||
req.df = 1;
|
req.df = 1;
|
||||||
req.type = buf_req->type;
|
req.type = buf_req->type;
|
||||||
req.data_is_ptr = 0;
|
req.data_is_ptr = 0;
|
||||||
|
xen_rmb();
|
||||||
qw = (req.size == 8);
|
qw = (req.size == 8);
|
||||||
if (qw) {
|
if (qw) {
|
||||||
buf_req = &buf_page->buf_ioreq[(rdptr + 1) %
|
buf_req = &buf_page->buf_ioreq[(rdptr + 1) %
|
||||||
IOREQ_BUFFER_SLOT_NUM];
|
IOREQ_BUFFER_SLOT_NUM];
|
||||||
req.data |= ((uint64_t)buf_req->data) << 32;
|
req.data |= ((uint64_t)buf_req->data) << 32;
|
||||||
|
xen_rmb();
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_ioreq(state, &req);
|
handle_ioreq(state, &req);
|
||||||
|
@ -1045,7 +1055,11 @@ static void cpu_handle_ioreq(void *opaque)
|
||||||
|
|
||||||
handle_buffered_iopage(state);
|
handle_buffered_iopage(state);
|
||||||
if (req) {
|
if (req) {
|
||||||
handle_ioreq(state, req);
|
ioreq_t copy = *req;
|
||||||
|
|
||||||
|
xen_rmb();
|
||||||
|
handle_ioreq(state, ©);
|
||||||
|
req->data = copy.data;
|
||||||
|
|
||||||
if (req->state != STATE_IOREQ_INPROCESS) {
|
if (req->state != STATE_IOREQ_INPROCESS) {
|
||||||
fprintf(stderr, "Badness in I/O request ... not in service?!: "
|
fprintf(stderr, "Badness in I/O request ... not in service?!: "
|
||||||
|
|
Loading…
Reference in New Issue